• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "chpp/clients/wifi.h"
18 
19 #include <inttypes.h>
20 #include <stdbool.h>
21 #include <stddef.h>
22 #include <stdint.h>
23 #include <string.h>
24 
25 #include "chpp/app.h"
26 #include "chpp/clients.h"
27 #include "chpp/clients/discovery.h"
28 #ifdef CHPP_CLIENT_ENABLED_TIMESYNC
29 #include "chpp/clients/timesync.h"
30 #endif
31 #include "chpp/common/standard_uuids.h"
32 #include "chpp/common/wifi.h"
33 #include "chpp/common/wifi_types.h"
34 #include "chpp/common/wifi_utils.h"
35 #include "chpp/log.h"
36 #include "chpp/macros.h"
37 #include "chpp/memory.h"
38 #include "chre/pal/wifi.h"
39 #include "chre_api/chre/wifi.h"
40 
41 #ifndef CHPP_WIFI_DISCOVERY_TIMEOUT_MS
42 #define CHPP_WIFI_DISCOVERY_TIMEOUT_MS CHPP_DISCOVERY_DEFAULT_TIMEOUT_MS
43 #endif
44 
45 #ifndef CHPP_WIFI_MAX_TIMESYNC_AGE_NS
46 #define CHPP_WIFI_MAX_TIMESYNC_AGE_NS CHPP_TIMESYNC_DEFAULT_MAX_AGE_NS
47 #endif
48 
49 /************************************************
50  *  Prototypes
51  ***********************************************/
52 
53 static enum ChppAppErrorCode chppDispatchWifiResponse(void *clientContext,
54                                                       uint8_t *buf, size_t len);
55 static enum ChppAppErrorCode chppDispatchWifiNotification(void *clientContext,
56                                                           uint8_t *buf,
57                                                           size_t len);
58 static bool chppWifiClientInit(void *clientContext, uint8_t handle,
59                                struct ChppVersion serviceVersion);
60 static void chppWifiClientDeinit(void *clientContext);
61 static void chppWifiClientNotifyReset(void *clientContext);
62 static void chppWifiClientNotifyMatch(void *clientContext);
63 
64 /************************************************
65  *  Private Definitions
66  ***********************************************/
67 
68 /**
69  * Structure to maintain state for the WiFi client and its Request/Response
70  * (RR) functionality.
71  */
72 struct ChppWifiClientState {
73   struct ChppClientState client;     // WiFi client state
74   const struct chrePalWifiApi *api;  // WiFi PAL API
75 
76   struct ChppRequestResponseState rRState[CHPP_WIFI_CLIENT_REQUEST_MAX + 1];
77 
78   uint32_t capabilities;            // Cached GetCapabilities result
79   bool scanMonitorEnabled;          // Scan monitoring is enabled
80   bool scanMonitorSilenceCallback;  // Silence callback during recovery from a
81                                     // service reset
82   bool capabilitiesValid;  // Flag to indicate if the capabilities result
83                            // is valid
84 };
85 
86 // Note: This global definition of gWifiClientContext supports only one
87 // instance of the CHPP WiFi client at a time.
88 struct ChppWifiClientState gWifiClientContext;
89 static const struct chrePalSystemApi *gSystemApi;
90 static const struct chrePalWifiCallbacks *gCallbacks;
91 
92 /**
93  * Configuration parameters for this client
94  */
95 static const struct ChppClient kWifiClientConfig = {
96     .descriptor.uuid = CHPP_UUID_WIFI_STANDARD,
97 
98     // Version
99     .descriptor.version.major = 1,
100     .descriptor.version.minor = 0,
101     .descriptor.version.patch = 0,
102 
103     // Notifies client if CHPP is reset
104     .resetNotifierFunctionPtr = &chppWifiClientNotifyReset,
105 
106     // Notifies client if they are matched to a service
107     .matchNotifierFunctionPtr = &chppWifiClientNotifyMatch,
108 
109     // Service response dispatch function pointer
110     .responseDispatchFunctionPtr = &chppDispatchWifiResponse,
111 
112     // Service notification dispatch function pointer
113     .notificationDispatchFunctionPtr = &chppDispatchWifiNotification,
114 
115     // Service response dispatch function pointer
116     .initFunctionPtr = &chppWifiClientInit,
117 
118     // Service notification dispatch function pointer
119     .deinitFunctionPtr = &chppWifiClientDeinit,
120 
121     // Number of request-response states in the rRStates array.
122     .rRStateCount = ARRAY_SIZE(gWifiClientContext.rRState),
123 
124     // Min length is the entire header
125     .minLength = sizeof(struct ChppAppHeader),
126 };
127 
128 /************************************************
129  *  Prototypes
130  ***********************************************/
131 
132 static bool chppWifiClientOpen(const struct chrePalSystemApi *systemApi,
133                                const struct chrePalWifiCallbacks *callbacks);
134 static void chppWifiClientClose(void);
135 static uint32_t chppWifiClientGetCapabilities(void);
136 static bool chppWifiClientConfigureScanMonitor(bool enable);
137 static bool chppWifiClientRequestScan(const struct chreWifiScanParams *params);
138 static void chppWifiClientReleaseScanEvent(struct chreWifiScanEvent *event);
139 static bool chppWifiClientRequestRanging(
140     const struct chreWifiRangingParams *params);
141 static void chppWifiClientReleaseRangingEvent(
142     struct chreWifiRangingEvent *event);
143 
144 static void chppWiFiRecoverScanMonitor(
145     struct ChppWifiClientState *clientContext);
146 static void chppWifiCloseResult(struct ChppWifiClientState *clientContext,
147                                 uint8_t *buf, size_t len);
148 static void chppWifiGetCapabilitiesResult(
149     struct ChppWifiClientState *clientContext, uint8_t *buf, size_t len);
150 static void chppWifiConfigureScanMonitorResult(
151     struct ChppWifiClientState *clientContext, uint8_t *buf, size_t len);
152 static void chppWifiRequestScanResult(struct ChppWifiClientState *clientContext,
153                                       uint8_t *buf, size_t len);
154 static void chppWifiRequestRangingResult(
155     struct ChppWifiClientState *clientContext, uint8_t *buf, size_t len);
156 static void chppWifiRequestNanSubscribeResult(uint8_t *buf, size_t len);
157 
158 static void chppWifiScanEventNotification(
159     struct ChppWifiClientState *clientContext, uint8_t *buf, size_t len);
160 static void chppWifiRangingEventNotification(
161     struct ChppWifiClientState *clientContext, uint8_t *buf, size_t len);
162 static void chppWifiDiscoveryEventNotification(uint8_t *buf, size_t len);
163 static void chppWifiNanServiceLostEventNotification(uint8_t *buf, size_t len);
164 static void chppWifiNanServiceTerminatedEventNotification(uint8_t *buf,
165                                                           size_t len);
166 static void chppWifiRequestNanSubscribeNotification(uint8_t *buf, size_t len);
167 static void chppWifiNanSubscriptionCanceledNotification(uint8_t *buf,
168                                                         size_t len);
169 static void chppWifiNanSubscriptionCanceledResult(uint8_t *buf, size_t len);
170 
171 /************************************************
172  *  Private Functions
173  ***********************************************/
174 
175 /**
176  * Dispatches a service response from the transport layer that is determined to
177  * be for the WiFi client.
178  *
179  * This function is called from the app layer using its function pointer given
180  * during client registration.
181  *
182  * @param clientContext Maintains status for each client instance.
183  * @param buf Input data. Cannot be null.
184  * @param len Length of input data in bytes.
185  *
186  * @return Indicates the result of this function call.
187  */
chppDispatchWifiResponse(void * clientContext,uint8_t * buf,size_t len)188 static enum ChppAppErrorCode chppDispatchWifiResponse(void *clientContext,
189                                                       uint8_t *buf,
190                                                       size_t len) {
191   struct ChppAppHeader *rxHeader = (struct ChppAppHeader *)buf;
192   struct ChppWifiClientState *wifiClientContext =
193       (struct ChppWifiClientState *)clientContext;
194   enum ChppAppErrorCode error = CHPP_APP_ERROR_NONE;
195 
196   if (rxHeader->command > CHPP_WIFI_CLIENT_REQUEST_MAX) {
197     error = CHPP_APP_ERROR_INVALID_COMMAND;
198 
199   } else if (!chppClientTimestampResponse(
200                  &wifiClientContext->client,
201                  &wifiClientContext->rRState[rxHeader->command], rxHeader)) {
202     error = CHPP_APP_ERROR_UNEXPECTED_RESPONSE;
203 
204   } else {
205     switch (rxHeader->command) {
206       case CHPP_WIFI_OPEN: {
207         chppClientProcessOpenResponse(&wifiClientContext->client, buf, len);
208         chppWiFiRecoverScanMonitor(wifiClientContext);
209         break;
210       }
211 
212       case CHPP_WIFI_CLOSE: {
213         chppWifiCloseResult(wifiClientContext, buf, len);
214         break;
215       }
216 
217       case CHPP_WIFI_GET_CAPABILITIES: {
218         chppWifiGetCapabilitiesResult(wifiClientContext, buf, len);
219         break;
220       }
221 
222       case CHPP_WIFI_CONFIGURE_SCAN_MONITOR_ASYNC: {
223         chppWifiConfigureScanMonitorResult(wifiClientContext, buf, len);
224         break;
225       }
226 
227       case CHPP_WIFI_REQUEST_SCAN_ASYNC: {
228         chppWifiRequestScanResult(wifiClientContext, buf, len);
229         break;
230       }
231 
232       case CHPP_WIFI_REQUEST_RANGING_ASYNC:
233       case CHPP_WIFI_REQUEST_NAN_RANGING_ASYNC: {
234         chppWifiRequestRangingResult(wifiClientContext, buf, len);
235         break;
236       }
237 
238       case CHPP_WIFI_REQUEST_NAN_SUB: {
239         chppWifiRequestNanSubscribeResult(buf, len);
240         break;
241       }
242 
243       case CHPP_WIFI_REQUEST_NAN_SUB_CANCEL: {
244         chppWifiNanSubscriptionCanceledResult(buf, len);
245         break;
246       }
247 
248       default: {
249         error = CHPP_APP_ERROR_INVALID_COMMAND;
250         break;
251       }
252     }
253   }
254 
255   return error;
256 }
257 
258 /**
259  * Dispatches a service notification from the transport layer that is determined
260  * to be for the WiFi client.
261  *
262  * This function is called from the app layer using its function pointer given
263  * during client registration.
264  *
265  * @param clientContext Maintains status for each client instance.
266  * @param buf Input data. Cannot be null.
267  * @param len Length of input data in bytes.
268  *
269  * @return Indicates the result of this function call.
270  */
chppDispatchWifiNotification(void * clientContext,uint8_t * buf,size_t len)271 static enum ChppAppErrorCode chppDispatchWifiNotification(void *clientContext,
272                                                           uint8_t *buf,
273                                                           size_t len) {
274   struct ChppAppHeader *rxHeader = (struct ChppAppHeader *)buf;
275   struct ChppWifiClientState *wifiClientContext =
276       (struct ChppWifiClientState *)clientContext;
277   enum ChppAppErrorCode error = CHPP_APP_ERROR_NONE;
278 
279   switch (rxHeader->command) {
280     case CHPP_WIFI_REQUEST_SCAN_ASYNC: {
281       chppWifiScanEventNotification(wifiClientContext, buf, len);
282       break;
283     }
284 
285     case CHPP_WIFI_REQUEST_RANGING_ASYNC:
286     case CHPP_WIFI_REQUEST_NAN_RANGING_ASYNC: {
287       chppWifiRangingEventNotification(wifiClientContext, buf, len);
288       break;
289     }
290 
291     case CHPP_WIFI_NOTIFICATION_NAN_SERVICE_DISCOVERY: {
292       chppWifiDiscoveryEventNotification(buf, len);
293       break;
294     }
295 
296     case CHPP_WIFI_NOTIFICATION_NAN_SERVICE_LOST: {
297       chppWifiNanServiceLostEventNotification(buf, len);
298       break;
299     }
300 
301     case CHPP_WIFI_NOTIFICATION_NAN_SERVICE_TERMINATED: {
302       chppWifiNanServiceTerminatedEventNotification(buf, len);
303       break;
304     }
305 
306     case CHPP_WIFI_REQUEST_NAN_SUB: {
307       chppWifiRequestNanSubscribeNotification(buf, len);
308       break;
309     }
310 
311     case CHPP_WIFI_REQUEST_NAN_SUB_CANCEL: {
312       chppWifiNanSubscriptionCanceledNotification(buf, len);
313       break;
314     }
315 
316     default: {
317       error = CHPP_APP_ERROR_INVALID_COMMAND;
318       break;
319     }
320   }
321 
322   return error;
323 }
324 
325 /**
326  * Initializes the client and provides its handle number and the version of the
327  * matched service when/if it the client is matched with a service during
328  * discovery.
329  *
330  * @param clientContext Maintains status for each client instance.
331  * @param handle Handle number for this client.
332  * @param serviceVersion Version of the matched service.
333  *
334  * @return True if client is compatible and successfully initialized.
335  */
chppWifiClientInit(void * clientContext,uint8_t handle,struct ChppVersion serviceVersion)336 static bool chppWifiClientInit(void *clientContext, uint8_t handle,
337                                struct ChppVersion serviceVersion) {
338   UNUSED_VAR(serviceVersion);
339 
340   struct ChppWifiClientState *wifiClientContext =
341       (struct ChppWifiClientState *)clientContext;
342   chppClientInit(&wifiClientContext->client, handle);
343 
344   return true;
345 }
346 
347 /**
348  * Deinitializes the client.
349  *
350  * @param clientContext Maintains status for each client instance.
351  */
chppWifiClientDeinit(void * clientContext)352 static void chppWifiClientDeinit(void *clientContext) {
353   struct ChppWifiClientState *wifiClientContext =
354       (struct ChppWifiClientState *)clientContext;
355   chppClientDeinit(&wifiClientContext->client);
356 }
357 
358 /**
359  * Notifies the client of an incoming reset.
360  *
361  * @param clientContext Maintains status for each client instance.
362  */
chppWifiClientNotifyReset(void * clientContext)363 static void chppWifiClientNotifyReset(void *clientContext) {
364   struct ChppWifiClientState *wifiClientContext =
365       (struct ChppWifiClientState *)clientContext;
366 
367   chppClientCloseOpenRequests(&wifiClientContext->client, &kWifiClientConfig,
368                               false /* clearOnly */);
369   chppCheckWifiScanEventNotificationReset();
370 
371   if (wifiClientContext->client.openState != CHPP_OPEN_STATE_OPENED &&
372       !wifiClientContext->client.pseudoOpen) {
373     CHPP_LOGW("WiFi client reset but wasn't open");
374   } else {
375     CHPP_LOGI("WiFi client reopening from state=%" PRIu8,
376               wifiClientContext->client.openState);
377     chppClientSendOpenRequest(&wifiClientContext->client,
378                               &wifiClientContext->rRState[CHPP_WIFI_OPEN],
379                               CHPP_WIFI_OPEN,
380                               /*blocking=*/false);
381   }
382 }
383 
384 /**
385  * Notifies the client of being matched to a service.
386  *
387  * @param clientContext Maintains status for each client instance.
388  */
chppWifiClientNotifyMatch(void * clientContext)389 static void chppWifiClientNotifyMatch(void *clientContext) {
390   struct ChppWifiClientState *wifiClientContext =
391       (struct ChppWifiClientState *)clientContext;
392 
393   if (wifiClientContext->client.pseudoOpen) {
394     CHPP_LOGD("Pseudo-open WiFi client opening");
395     chppClientSendOpenRequest(&wifiClientContext->client,
396                               &wifiClientContext->rRState[CHPP_WIFI_OPEN],
397                               CHPP_WIFI_OPEN,
398                               /*blocking=*/false);
399   }
400 }
401 
402 /**
403  * Restores the state of scan monitoring after an incoming reset.
404  *
405  * @param clientContext Maintains status for each client instance.
406  */
chppWiFiRecoverScanMonitor(struct ChppWifiClientState * clientContext)407 static void chppWiFiRecoverScanMonitor(
408     struct ChppWifiClientState *clientContext) {
409   if (clientContext->scanMonitorEnabled) {
410     CHPP_LOGI("Re-enabling WiFi scan monitoring after reset");
411     clientContext->scanMonitorEnabled = false;
412     clientContext->scanMonitorSilenceCallback = true;
413 
414     if (!chppWifiClientConfigureScanMonitor(true)) {
415       clientContext->scanMonitorSilenceCallback = false;
416       CHPP_DEBUG_ASSERT_LOG(false, "Failed to re-enable WiFi scan monitoring");
417     }
418   }
419 }
420 
421 /**
422  * Handles the service response for the close client request.
423  *
424  * This function is called from chppDispatchWifiResponse().
425  *
426  * @param clientContext Maintains status for each client instance.
427  * @param buf Input data. Cannot be null.
428  * @param len Length of input data in bytes.
429  */
chppWifiCloseResult(struct ChppWifiClientState * clientContext,uint8_t * buf,size_t len)430 static void chppWifiCloseResult(struct ChppWifiClientState *clientContext,
431                                 uint8_t *buf, size_t len) {
432   // TODO
433   UNUSED_VAR(clientContext);
434   UNUSED_VAR(buf);
435   UNUSED_VAR(len);
436 }
437 
438 /**
439  * Handles the service response for the get capabilities client request.
440  *
441  * This function is called from chppDispatchWifiResponse().
442  *
443  * @param clientContext Maintains status for each client instance.
444  * @param buf Input data. Cannot be null.
445  * @param len Length of input data in bytes.
446  */
chppWifiGetCapabilitiesResult(struct ChppWifiClientState * clientContext,uint8_t * buf,size_t len)447 static void chppWifiGetCapabilitiesResult(
448     struct ChppWifiClientState *clientContext, uint8_t *buf, size_t len) {
449   if (len < sizeof(struct ChppWifiGetCapabilitiesResponse)) {
450     CHPP_LOGE("Bad WiFi capabilities len=%" PRIuSIZE, len);
451 
452   } else {
453     struct ChppWifiGetCapabilitiesParameters *result =
454         &((struct ChppWifiGetCapabilitiesResponse *)buf)->params;
455 
456     CHPP_LOGD("chppWifiGetCapabilitiesResult received capabilities=0x%" PRIx32,
457               result->capabilities);
458 
459     CHPP_ASSERT((result->capabilities & CHPP_WIFI_DEFAULT_CAPABILITIES) ==
460                 CHPP_WIFI_DEFAULT_CAPABILITIES);
461     if (result->capabilities != CHPP_WIFI_DEFAULT_CAPABILITIES) {
462       CHPP_LOGE("WiFi capabilities 0x%" PRIx32 " != 0x%" PRIx32,
463                 result->capabilities, CHPP_WIFI_DEFAULT_CAPABILITIES);
464     }
465 
466     clientContext->capabilitiesValid = true;
467     clientContext->capabilities = result->capabilities;
468   }
469 }
470 
471 /**
472  * Handles the service response for the Configure Scan Monitor client request.
473  *
474  * This function is called from chppDispatchWifiResponse().
475  *
476  * @param clientContext Maintains status for each client instance.
477  * @param buf Input data. Cannot be null.
478  * @param len Length of input data in bytes.
479  */
chppWifiConfigureScanMonitorResult(struct ChppWifiClientState * clientContext,uint8_t * buf,size_t len)480 static void chppWifiConfigureScanMonitorResult(
481     struct ChppWifiClientState *clientContext, uint8_t *buf, size_t len) {
482   UNUSED_VAR(clientContext);
483 
484   if (len < sizeof(struct ChppWifiConfigureScanMonitorAsyncResponse)) {
485     // Short response length indicates an error
486     gCallbacks->scanMonitorStatusChangeCallback(
487         false, chppAppShortResponseErrorHandler(buf, len, "ScanMonitor"));
488 
489   } else {
490     struct ChppWifiConfigureScanMonitorAsyncResponseParameters *result =
491         &((struct ChppWifiConfigureScanMonitorAsyncResponse *)buf)->params;
492 
493     gWifiClientContext.scanMonitorEnabled = result->enabled;
494     CHPP_LOGD(
495         "chppWifiConfigureScanMonitorResult received enable=%d, "
496         "errorCode=%" PRIu8,
497         result->enabled, result->errorCode);
498 
499     if (!gWifiClientContext.scanMonitorSilenceCallback) {
500       // Per the scanMonitorStatusChangeCallback API contract, unsolicited
501       // calls to scanMonitorStatusChangeCallback must not be made, and it
502       // should only be invoked as the direct result of an earlier call to
503       // configureScanMonitor.
504       gCallbacks->scanMonitorStatusChangeCallback(result->enabled,
505                                                   result->errorCode);
506     }  // Else, the WiFi subsystem has been reset and we are required to
507        // silently reenable the scan monitor.
508 
509     gWifiClientContext.scanMonitorSilenceCallback = false;
510   }
511 }
512 
513 /**
514  * Handles the service response for the Request Scan Result client request.
515  *
516  * This function is called from chppDispatchWifiResponse().
517  *
518  * @param clientContext Maintains status for each client instance.
519  * @param buf Input data. Cannot be null.
520  * @param len Length of input data in bytes.
521  */
chppWifiRequestScanResult(struct ChppWifiClientState * clientContext,uint8_t * buf,size_t len)522 static void chppWifiRequestScanResult(struct ChppWifiClientState *clientContext,
523                                       uint8_t *buf, size_t len) {
524   UNUSED_VAR(clientContext);
525 
526   if (len < sizeof(struct ChppWifiRequestScanResponse)) {
527     // Short response length indicates an error
528     gCallbacks->scanResponseCallback(
529         false, chppAppShortResponseErrorHandler(buf, len, "ScanRequest"));
530 
531   } else {
532     struct ChppWifiRequestScanResponseParameters *result =
533         &((struct ChppWifiRequestScanResponse *)buf)->params;
534     CHPP_LOGI("Scan request success=%d at service", result->pending);
535     gCallbacks->scanResponseCallback(result->pending, result->errorCode);
536   }
537 }
538 
539 /**
540  * Handles the service response for the Request Ranging Result client request.
541  *
542  * This function is called from chppDispatchWifiResponse().
543  *
544  * @param clientContext Maintains status for each client instance.
545  * @param buf Input data. Cannot be null.
546  * @param len Length of input data in bytes.
547  */
chppWifiRequestRangingResult(struct ChppWifiClientState * clientContext,uint8_t * buf,size_t len)548 static void chppWifiRequestRangingResult(
549     struct ChppWifiClientState *clientContext, uint8_t *buf, size_t len) {
550   UNUSED_VAR(clientContext);
551   UNUSED_VAR(len);
552 
553   struct ChppAppHeader *rxHeader = (struct ChppAppHeader *)buf;
554 
555   if (rxHeader->error != CHPP_APP_ERROR_NONE) {
556     CHPP_LOGE("Ranging failed at service" PRIu8);
557     gCallbacks->rangingEventCallback(chppAppErrorToChreError(rxHeader->error),
558                                      NULL);
559 
560   } else {
561     CHPP_LOGD("Ranging request accepted at service");
562   }
563 }
564 
565 /**
566  * Handles the service response for the NAN subscribe client request.
567  *
568  * This function is called from chppDispatchWifiResponse().
569  *
570  * @param buf Input data. Cannot be null.
571  * @param len Length of input data in bytes.
572  */
chppWifiRequestNanSubscribeResult(uint8_t * buf,size_t len)573 static void chppWifiRequestNanSubscribeResult(uint8_t *buf, size_t len) {
574   UNUSED_VAR(len);
575 
576   struct ChppAppHeader *rxHeader = (struct ChppAppHeader *)buf;
577 
578   if (rxHeader->error != CHPP_APP_ERROR_NONE) {
579     gCallbacks->nanServiceIdentifierCallback(
580         chppAppErrorToChreError(rxHeader->error), 0 /* subscriptionId */);
581 
582   } else {
583     CHPP_LOGD("NAN sub accepted at service");
584   }
585 }
586 
587 /**
588  * Handles the service response for the NAN subscription cancel client request.
589  *
590  * This function is called from chppDispatchWifiResponse().
591  *
592  * @param buf Input data. Cannot be null.
593  * @param len Length of input data in bytes.
594  */
chppWifiNanSubscriptionCanceledResult(uint8_t * buf,size_t len)595 static void chppWifiNanSubscriptionCanceledResult(uint8_t *buf, size_t len) {
596   UNUSED_VAR(len);
597 
598   struct ChppAppHeader *rxHeader = (struct ChppAppHeader *)buf;
599 
600   if (rxHeader->error != CHPP_APP_ERROR_NONE) {
601     gCallbacks->nanSubscriptionCanceledCallback(
602         chppAppErrorToChreError(rxHeader->error), 0 /* subscriptionId */);
603 
604   } else {
605     CHPP_LOGD("NAN sub cancel accepted at service");
606   }
607 }
608 
609 /**
610  * Handles the WiFi scan event service notification.
611  *
612  * This function is called from chppDispatchWifiNotification().
613  *
614  * @param clientContext Maintains status for each client instance.
615  * @param buf Input data. Cannot be null.
616  * @param len Length of input data in bytes.
617  */
chppWifiScanEventNotification(struct ChppWifiClientState * clientContext,uint8_t * buf,size_t len)618 static void chppWifiScanEventNotification(
619     struct ChppWifiClientState *clientContext, uint8_t *buf, size_t len) {
620   UNUSED_VAR(clientContext);
621   CHPP_LOGD("chppWifiScanEventNotification received data len=%" PRIuSIZE, len);
622 
623   buf += sizeof(struct ChppAppHeader);
624   len -= sizeof(struct ChppAppHeader);
625 
626   struct chreWifiScanEvent *chre =
627       chppWifiScanEventToChre((struct ChppWifiScanEvent *)buf, len);
628 
629   if (chre == NULL) {
630     CHPP_LOGE("Scan event conversion failed len=%" PRIuSIZE, len);
631   } else {
632 #ifdef CHPP_CLIENT_ENABLED_TIMESYNC
633     uint64_t correctedTime =
634         chre->referenceTime -
635         (uint64_t)chppTimesyncGetOffset(gWifiClientContext.client.appContext,
636                                         CHPP_WIFI_MAX_TIMESYNC_AGE_NS);
637     CHPP_LOGD("WiFi scan time corrected from %" PRIu64 "to %" PRIu64,
638               chre->referenceTime / CHPP_NSEC_PER_MSEC,
639               correctedTime / CHPP_NSEC_PER_MSEC);
640     chre->referenceTime = correctedTime;
641 #endif
642 
643     CHPP_DEBUG_ASSERT(chppCheckWifiScanEventNotification(chre));
644 
645     gCallbacks->scanEventCallback(chre);
646   }
647 }
648 
649 /**
650  * Handles the WiFi ranging event service notification.
651  *
652  * This function is called from chppDispatchWifiNotification().
653  *
654  * @param clientContext Maintains status for each client instance.
655  * @param buf Input data. Cannot be null.
656  * @param len Length of input data in bytes.
657  */
chppWifiRangingEventNotification(struct ChppWifiClientState * clientContext,uint8_t * buf,size_t len)658 static void chppWifiRangingEventNotification(
659     struct ChppWifiClientState *clientContext, uint8_t *buf, size_t len) {
660   UNUSED_VAR(clientContext);
661 
662   CHPP_LOGD("chppWifiRangingEventNotification received data len=%" PRIuSIZE,
663             len);
664 
665   buf += sizeof(struct ChppAppHeader);
666   len -= sizeof(struct ChppAppHeader);
667 
668   // Timestamp correction prior to conversion to avoid const casting issues.
669 #ifdef CHPP_CLIENT_ENABLED_TIMESYNC
670   struct ChppWifiRangingEvent *event = (struct ChppWifiRangingEvent *)buf;
671 
672   for (size_t i = 0; i < event->resultCount; i++) {
673     struct ChppWifiRangingResult *results =
674         (struct ChppWifiRangingResult *)&buf[event->results.offset];
675 
676     uint64_t correctedTime =
677         results[i].timestamp -
678         (uint64_t)chppTimesyncGetOffset(gWifiClientContext.client.appContext,
679                                         CHPP_WIFI_MAX_TIMESYNC_AGE_NS);
680     CHPP_LOGD("WiFi ranging result time corrected from %" PRIu64 "to %" PRIu64,
681               results[i].timestamp / CHPP_NSEC_PER_MSEC,
682               correctedTime / CHPP_NSEC_PER_MSEC);
683     results[i].timestamp = correctedTime;
684   }
685 #endif
686 
687   struct chreWifiRangingEvent *chre =
688       chppWifiRangingEventToChre((struct ChppWifiRangingEvent *)buf, len);
689 
690   uint8_t error = CHRE_ERROR_NONE;
691   if (chre == NULL) {
692     error = CHRE_ERROR;
693     CHPP_LOGE("Ranging event conversion failed len=%" PRIuSIZE, len);
694   }
695 
696   gCallbacks->rangingEventCallback(error, chre);
697 }
698 
699 /**
700  * Handles the NAN discovery event service notification.
701  *
702  * This function is called from chppDispatchWifiNotification().
703  *
704  * @param buf Input data. Cannot be null.
705  * @param len Length of input data in bytes.
706  */
chppWifiDiscoveryEventNotification(uint8_t * buf,size_t len)707 static void chppWifiDiscoveryEventNotification(uint8_t *buf, size_t len) {
708   CHPP_LOGD("chppWifiDiscoveryEventNotification data len=%" PRIuSIZE, len);
709 
710   buf += sizeof(struct ChppAppHeader);
711   len -= sizeof(struct ChppAppHeader);
712 
713   struct ChppWifiNanDiscoveryEvent *chppEvent =
714       (struct ChppWifiNanDiscoveryEvent *)buf;
715   struct chreWifiNanDiscoveryEvent *event =
716       chppWifiNanDiscoveryEventToChre(chppEvent, len);
717 
718   if (event == NULL) {
719     CHPP_LOGE("Discovery event CHPP -> CHRE conversion failed");
720   } else {
721     gCallbacks->nanServiceDiscoveryCallback(event);
722   }
723 }
724 
725 /**
726  * Handles the NAN connection lost event service notification.
727  *
728  * This function is called from chppDispatchWifiNotification().
729  *
730  * @param buf Input data. Cannot be null.
731  * @param len Length of input data in bytes.
732  */
chppWifiNanServiceLostEventNotification(uint8_t * buf,size_t len)733 static void chppWifiNanServiceLostEventNotification(uint8_t *buf, size_t len) {
734   buf += sizeof(struct ChppAppHeader);
735   len -= sizeof(struct ChppAppHeader);
736 
737   struct ChppWifiNanSessionLostEvent *chppEvent =
738       (struct ChppWifiNanSessionLostEvent *)buf;
739   struct chreWifiNanSessionLostEvent *event =
740       chppWifiNanSessionLostEventToChre(chppEvent, len);
741 
742   if (event == NULL) {
743     CHPP_LOGE("Session lost event CHPP -> CHRE conversion failed");
744   } else {
745     gCallbacks->nanServiceLostCallback(event->id, event->peerId);
746   }
747 }
748 
749 /**
750  * Handles the NAN subscription termination event service notification.
751  *
752  * This function is called from chppDispatchWifiNotification().
753  *
754  * @param buf Input data. Cannot be null.
755  * @param len Length of input data in bytes.
756  */
chppWifiNanServiceTerminatedEventNotification(uint8_t * buf,size_t len)757 static void chppWifiNanServiceTerminatedEventNotification(uint8_t *buf,
758                                                           size_t len) {
759   buf += sizeof(struct ChppAppHeader);
760   len -= sizeof(struct ChppAppHeader);
761 
762   struct ChppWifiNanSessionTerminatedEvent *chppEvent =
763       (struct ChppWifiNanSessionTerminatedEvent *)buf;
764   struct chreWifiNanSessionTerminatedEvent *event =
765       chppWifiNanSessionTerminatedEventToChre(chppEvent, len);
766 
767   if (event == NULL) {
768     CHPP_LOGE("Session terminated event CHPP -> CHRE conversion failed");
769   } else {
770     gCallbacks->nanServiceTerminatedCallback(event->reason, event->id);
771   }
772 }
773 
774 /**
775  * Handles the service response for the NAN subscribe client request.
776  *
777  * This function is called from chppDispatchWifiNotification().
778  *
779  * @param buf Input data. Cannot be null.
780  * @param len Length of input data in bytes.
781  */
chppWifiRequestNanSubscribeNotification(uint8_t * buf,size_t len)782 static void chppWifiRequestNanSubscribeNotification(uint8_t *buf, size_t len) {
783   uint8_t errorCode = CHRE_ERROR_NONE;
784   uint32_t subscriptionId = 0;
785 
786   if (len < sizeof(struct ChppWifiNanServiceIdentifier)) {
787     errorCode = CHRE_ERROR;
788   } else {
789     struct ChppWifiNanServiceIdentifier *id =
790         (struct ChppWifiNanServiceIdentifier *)buf;
791     errorCode = id->errorCode;
792     subscriptionId = id->subscriptionId;
793   }
794   gCallbacks->nanServiceIdentifierCallback(errorCode, subscriptionId);
795 }
796 
797 /**
798  * Handles the service response for the NAN subscription cancel client request.
799  *
800  * This function is called from chppDispatchWifiNotification().
801  *
802  * @param buf Input data. Cannot be null.
803  * @param len Length of input data in bytes.
804  */
chppWifiNanSubscriptionCanceledNotification(uint8_t * buf,size_t len)805 static void chppWifiNanSubscriptionCanceledNotification(uint8_t *buf,
806                                                         size_t len) {
807   uint8_t errorCode = CHRE_ERROR_NONE;
808   uint32_t subscriptionId = 0;
809   if (len < (sizeof(struct ChppWifiNanSubscriptionCanceledResponse))) {
810     errorCode = CHRE_ERROR;
811   } else {
812     struct ChppWifiNanSubscriptionCanceledResponse *chppNotif =
813         (struct ChppWifiNanSubscriptionCanceledResponse *)buf;
814     errorCode = chppNotif->errorCode;
815     subscriptionId = chppNotif->subscriptionId;
816   }
817   gCallbacks->nanSubscriptionCanceledCallback(errorCode, subscriptionId);
818 }
819 
820 /**
821  * Initializes the WiFi client upon an open request from CHRE and responds
822  * with the result.
823  *
824  * @param systemApi CHRE system function pointers.
825  * @param callbacks CHRE entry points.
826  *
827  * @return True if successful. False otherwise.
828  */
chppWifiClientOpen(const struct chrePalSystemApi * systemApi,const struct chrePalWifiCallbacks * callbacks)829 static bool chppWifiClientOpen(const struct chrePalSystemApi *systemApi,
830                                const struct chrePalWifiCallbacks *callbacks) {
831   CHPP_DEBUG_ASSERT(systemApi != NULL);
832   CHPP_DEBUG_ASSERT(callbacks != NULL);
833 
834   bool result = false;
835   gSystemApi = systemApi;
836   gCallbacks = callbacks;
837 
838   CHPP_LOGD("WiFi client opening");
839   if (gWifiClientContext.client.appContext == NULL) {
840     CHPP_LOGE("WiFi client app is null");
841   } else {
842     if (chppWaitForDiscoveryComplete(gWifiClientContext.client.appContext,
843                                      CHPP_WIFI_DISCOVERY_TIMEOUT_MS)) {
844       result = chppClientSendOpenRequest(
845           &gWifiClientContext.client,
846           &gWifiClientContext.rRState[CHPP_WIFI_OPEN], CHPP_WIFI_OPEN,
847           /*blocking=*/true);
848     }
849 
850     // Since CHPP_WIFI_DEFAULT_CAPABILITIES is mandatory, we can always
851     // pseudo-open and return true. Otherwise, these should have been gated.
852     chppClientPseudoOpen(&gWifiClientContext.client);
853     result = true;
854   }
855 
856   return result;
857 }
858 
859 /**
860  * Deinitializes the WiFi client.
861  */
chppWifiClientClose(void)862 static void chppWifiClientClose(void) {
863   // Remote
864   struct ChppAppHeader *request = chppAllocClientRequestCommand(
865       &gWifiClientContext.client, CHPP_WIFI_CLOSE);
866 
867   if (request == NULL) {
868     CHPP_LOG_OOM();
869   } else if (chppSendTimestampedRequestAndWait(
870                  &gWifiClientContext.client,
871                  &gWifiClientContext.rRState[CHPP_WIFI_CLOSE], request,
872                  sizeof(*request))) {
873     gWifiClientContext.client.openState = CHPP_OPEN_STATE_CLOSED;
874     gWifiClientContext.capabilities = CHRE_WIFI_CAPABILITIES_NONE;
875     gWifiClientContext.capabilitiesValid = false;
876     chppClientCloseOpenRequests(&gWifiClientContext.client, &kWifiClientConfig,
877                                 true /* clearOnly */);
878   }
879 }
880 
881 /**
882  * Retrieves a set of flags indicating the WiFi features supported by the
883  * current implementation.
884  *
885  * @return Capabilities flags.
886  */
chppWifiClientGetCapabilities(void)887 static uint32_t chppWifiClientGetCapabilities(void) {
888   uint32_t capabilities = CHPP_WIFI_DEFAULT_CAPABILITIES;
889 
890   if (gWifiClientContext.capabilitiesValid) {
891     // Result already cached
892     capabilities = gWifiClientContext.capabilities;
893 
894   } else {
895     struct ChppAppHeader *request = chppAllocClientRequestCommand(
896         &gWifiClientContext.client, CHPP_WIFI_GET_CAPABILITIES);
897 
898     if (request == NULL) {
899       CHPP_LOG_OOM();
900     } else {
901       if (chppSendTimestampedRequestAndWait(
902               &gWifiClientContext.client,
903               &gWifiClientContext.rRState[CHPP_WIFI_GET_CAPABILITIES], request,
904               sizeof(*request))) {
905         // Success. gWifiClientContext.capabilities is now populated
906         if (gWifiClientContext.capabilitiesValid) {
907           capabilities = gWifiClientContext.capabilities;
908         }
909       }
910     }
911   }
912 
913   return capabilities;
914 }
915 
916 /**
917  * Enables/disables receiving unsolicited scan results (scan monitoring).
918  *
919  * @param enable True to enable.
920  *
921  * @return True indicates the request was sent off to the service.
922  */
chppWifiClientConfigureScanMonitor(bool enable)923 static bool chppWifiClientConfigureScanMonitor(bool enable) {
924   bool result = false;
925 
926   struct ChppWifiConfigureScanMonitorAsyncRequest *request =
927       chppAllocClientRequestFixed(
928           &gWifiClientContext.client,
929           struct ChppWifiConfigureScanMonitorAsyncRequest);
930 
931   if (request == NULL) {
932     CHPP_LOG_OOM();
933   } else {
934     request->header.command = CHPP_WIFI_CONFIGURE_SCAN_MONITOR_ASYNC;
935     request->params.enable = enable;
936     request->params.cookie =
937         &gWifiClientContext.rRState[CHPP_WIFI_CONFIGURE_SCAN_MONITOR_ASYNC];
938 
939     result = chppSendTimestampedRequestOrFail(
940         &gWifiClientContext.client,
941         &gWifiClientContext.rRState[CHPP_WIFI_CONFIGURE_SCAN_MONITOR_ASYNC],
942         request, sizeof(*request), CHPP_CLIENT_REQUEST_TIMEOUT_DEFAULT);
943   }
944 
945   return result;
946 }
947 
948 /**
949  * Request that the WiFi chipset perform a scan or deliver results from its
950  * cache.
951  *
952  * @param params See chreWifiRequestScanAsync().
953  *
954  * @return True indicates the request was sent off to the service.
955  */
chppWifiClientRequestScan(const struct chreWifiScanParams * params)956 static bool chppWifiClientRequestScan(const struct chreWifiScanParams *params) {
957   struct ChppWifiScanParamsWithHeader *request;
958   size_t requestLen;
959 
960   bool result = chppWifiScanParamsFromChre(params, &request, &requestLen);
961 
962   if (!result) {
963     CHPP_LOG_OOM();
964   } else {
965     request->header.handle = gWifiClientContext.client.handle;
966     request->header.type = CHPP_MESSAGE_TYPE_CLIENT_REQUEST;
967     request->header.transaction = gWifiClientContext.client.transaction++;
968     request->header.error = CHPP_APP_ERROR_NONE;
969     request->header.command = CHPP_WIFI_REQUEST_SCAN_ASYNC;
970 
971     result = chppSendTimestampedRequestOrFail(
972         &gWifiClientContext.client,
973         &gWifiClientContext.rRState[CHPP_WIFI_REQUEST_SCAN_ASYNC], request,
974         requestLen, CHRE_WIFI_SCAN_RESULT_TIMEOUT_NS);
975   }
976 
977   return result;
978 }
979 
980 /**
981  * Releases the memory held for the scan event callback.
982  *
983  * @param event Location event to be released.
984  */
chppWifiClientReleaseScanEvent(struct chreWifiScanEvent * event)985 static void chppWifiClientReleaseScanEvent(struct chreWifiScanEvent *event) {
986   if (event->scannedFreqListLen > 0) {
987     void *scannedFreqList = CHPP_CONST_CAST_POINTER(event->scannedFreqList);
988     CHPP_FREE_AND_NULLIFY(scannedFreqList);
989   }
990 
991   if (event->resultCount > 0) {
992     void *results = CHPP_CONST_CAST_POINTER(event->results);
993     CHPP_FREE_AND_NULLIFY(results);
994   }
995 
996   CHPP_FREE_AND_NULLIFY(event);
997 }
998 
999 /**
1000  * Request that the WiFi chipset perform RTT ranging.
1001  *
1002  * @param params See chreWifiRequestRangingAsync().
1003  *
1004  * @return True indicates the request was sent off to the service.
1005  */
chppWifiClientRequestRanging(const struct chreWifiRangingParams * params)1006 static bool chppWifiClientRequestRanging(
1007     const struct chreWifiRangingParams *params) {
1008   struct ChppWifiRangingParamsWithHeader *request;
1009   size_t requestLen;
1010 
1011   bool result = chppWifiRangingParamsFromChre(params, &request, &requestLen);
1012 
1013   if (!result) {
1014     CHPP_LOG_OOM();
1015   } else {
1016     request->header.handle = gWifiClientContext.client.handle;
1017     request->header.type = CHPP_MESSAGE_TYPE_CLIENT_REQUEST;
1018     request->header.transaction = gWifiClientContext.client.transaction++;
1019     request->header.error = CHPP_APP_ERROR_NONE;
1020     request->header.command = CHPP_WIFI_REQUEST_RANGING_ASYNC;
1021 
1022     result = chppSendTimestampedRequestOrFail(
1023         &gWifiClientContext.client,
1024         &gWifiClientContext.rRState[CHPP_WIFI_REQUEST_RANGING_ASYNC], request,
1025         requestLen, CHRE_WIFI_RANGING_RESULT_TIMEOUT_NS);
1026   }
1027 
1028   return result;
1029 }
1030 
1031 /**
1032  * Releases the memory held for the RTT ranging event callback.
1033  *
1034  * @param event Location event to be released.
1035  */
chppWifiClientReleaseRangingEvent(struct chreWifiRangingEvent * event)1036 static void chppWifiClientReleaseRangingEvent(
1037     struct chreWifiRangingEvent *event) {
1038   if (event->resultCount > 0) {
1039     void *results = CHPP_CONST_CAST_POINTER(event->results);
1040     CHPP_FREE_AND_NULLIFY(results);
1041   }
1042 
1043   CHPP_FREE_AND_NULLIFY(event);
1044 }
1045 
1046 /**
1047  * Request that the WiFi chipset perform a NAN subscription.
1048  * @see chreWifiNanSubscribe for more information.
1049  *
1050  * @param config NAN service subscription configuration.
1051  * @return true if subscribe request was successful, false otherwise.
1052  */
chppWifiClientNanSubscribe(const struct chreWifiNanSubscribeConfig * config)1053 static bool chppWifiClientNanSubscribe(
1054     const struct chreWifiNanSubscribeConfig *config) {
1055   struct ChppWifiNanSubscribeConfigWithHeader *request;
1056   size_t requestLen;
1057 
1058   bool result =
1059       chppWifiNanSubscribeConfigFromChre(config, &request, &requestLen);
1060 
1061   if (!result) {
1062     CHPP_LOG_OOM();
1063   } else {
1064     request->header.handle = gWifiClientContext.client.handle;
1065     request->header.type = CHPP_MESSAGE_TYPE_CLIENT_REQUEST;
1066     request->header.transaction = gWifiClientContext.client.transaction++;
1067     request->header.error = CHPP_APP_ERROR_NONE;
1068     request->header.command = CHPP_WIFI_REQUEST_NAN_SUB;
1069 
1070     result = chppSendTimestampedRequestOrFail(
1071         &gWifiClientContext.client,
1072         &gWifiClientContext.rRState[CHPP_WIFI_REQUEST_NAN_SUB], request,
1073         requestLen, CHRE_ASYNC_RESULT_TIMEOUT_NS);
1074   }
1075   return result;
1076 }
1077 
1078 /**
1079  * Request the WiFi chipset to cancel a NAN subscription.
1080  * @param subscriptionId Identifier assigned by the NAN engine for a service
1081  *        subscription.
1082  * @return true if cancelation request was successfully dispatched, false
1083  *         otherwise.
1084  */
chppWifiClientNanSubscribeCancel(uint32_t subscriptionId)1085 static bool chppWifiClientNanSubscribeCancel(uint32_t subscriptionId) {
1086   bool result = false;
1087   struct ChppWifiNanSubscribeCancelRequest *request =
1088       chppAllocClientRequestFixed(&gWifiClientContext.client,
1089                                   struct ChppWifiNanSubscribeCancelRequest);
1090 
1091   if (request == NULL) {
1092     CHPP_LOG_OOM();
1093   } else {
1094     request->header.handle = gWifiClientContext.client.handle;
1095     request->header.command = CHPP_WIFI_REQUEST_NAN_SUB_CANCEL;
1096     request->header.type = CHPP_MESSAGE_TYPE_CLIENT_REQUEST;
1097     request->header.transaction = gWifiClientContext.client.transaction++;
1098     request->header.error = CHPP_APP_ERROR_NONE;
1099     request->subscriptionId = subscriptionId;
1100 
1101     result = chppSendTimestampedRequestAndWait(
1102         &gWifiClientContext.client,
1103         &gWifiClientContext.rRState[CHPP_WIFI_REQUEST_NAN_SUB_CANCEL], request,
1104         sizeof(*request));
1105   }
1106   return result;
1107 }
1108 
1109 /**
1110  * Release the memory held for the NAN service discovery callback.
1111  *
1112  * @param event Discovery event to be freed.
1113  */
chppWifiClientNanReleaseDiscoveryEvent(struct chreWifiNanDiscoveryEvent * event)1114 static void chppWifiClientNanReleaseDiscoveryEvent(
1115     struct chreWifiNanDiscoveryEvent *event) {
1116   if (event != NULL) {
1117     if (event->serviceSpecificInfo != NULL) {
1118       void *info = CHPP_CONST_CAST_POINTER(event->serviceSpecificInfo);
1119       CHPP_FREE_AND_NULLIFY(info);
1120     }
1121     CHPP_FREE_AND_NULLIFY(event);
1122   }
1123 }
1124 
1125 /**
1126  * Request that the WiFi chipset perform NAN ranging.
1127  *
1128  * @param params WiFi NAN ranging parameters.
1129  * @return true if the ranging request was successfully dispatched, false
1130  *         otherwise.
1131  */
chppWifiClientNanRequestNanRanging(const struct chreWifiNanRangingParams * params)1132 static bool chppWifiClientNanRequestNanRanging(
1133     const struct chreWifiNanRangingParams *params) {
1134   struct ChppWifiNanRangingParamsWithHeader *request;
1135   size_t requestLen;
1136   bool result = chppWifiNanRangingParamsFromChre(params, &request, &requestLen);
1137 
1138   if (!result) {
1139     CHPP_LOG_OOM();
1140   } else {
1141     request->header.handle = gWifiClientContext.client.handle;
1142     request->header.command = CHPP_WIFI_REQUEST_NAN_RANGING_ASYNC;
1143     request->header.type = CHPP_MESSAGE_TYPE_CLIENT_REQUEST;
1144     request->header.transaction = gWifiClientContext.client.transaction++;
1145     request->header.error = CHPP_APP_ERROR_NONE;
1146 
1147     result = chppSendTimestampedRequestOrFail(
1148         &gWifiClientContext.client,
1149         &gWifiClientContext.rRState[CHPP_WIFI_REQUEST_NAN_RANGING_ASYNC],
1150         request, requestLen, CHRE_ASYNC_RESULT_TIMEOUT_NS);
1151   }
1152   return result;
1153 }
1154 
1155 /************************************************
1156  *  Public Functions
1157  ***********************************************/
1158 
chppRegisterWifiClient(struct ChppAppState * appContext)1159 void chppRegisterWifiClient(struct ChppAppState *appContext) {
1160   chppRegisterClient(appContext, (void *)&gWifiClientContext,
1161                      &gWifiClientContext.client, gWifiClientContext.rRState,
1162                      &kWifiClientConfig);
1163 }
1164 
chppDeregisterWifiClient(struct ChppAppState * appContext)1165 void chppDeregisterWifiClient(struct ChppAppState *appContext) {
1166   // TODO
1167 
1168   UNUSED_VAR(appContext);
1169 }
1170 
getChppWifiClientState(void)1171 struct ChppClientState *getChppWifiClientState(void) {
1172   return &gWifiClientContext.client;
1173 }
1174 
1175 #ifdef CHPP_CLIENT_ENABLED_WIFI
1176 
1177 #ifdef CHPP_CLIENT_ENABLED_CHRE_WIFI
chrePalWifiGetApi(uint32_t requestedApiVersion)1178 const struct chrePalWifiApi *chrePalWifiGetApi(uint32_t requestedApiVersion) {
1179 #else
1180 const struct chrePalWifiApi *chppPalWifiGetApi(uint32_t requestedApiVersion) {
1181 #endif
1182 
1183   static const struct chrePalWifiApi api = {
1184       .moduleVersion = CHPP_PAL_WIFI_API_VERSION,
1185       .open = chppWifiClientOpen,
1186       .close = chppWifiClientClose,
1187       .getCapabilities = chppWifiClientGetCapabilities,
1188       .configureScanMonitor = chppWifiClientConfigureScanMonitor,
1189       .requestScan = chppWifiClientRequestScan,
1190       .releaseScanEvent = chppWifiClientReleaseScanEvent,
1191       .requestRanging = chppWifiClientRequestRanging,
1192       .releaseRangingEvent = chppWifiClientReleaseRangingEvent,
1193       .nanSubscribe = chppWifiClientNanSubscribe,
1194       .nanSubscribeCancel = chppWifiClientNanSubscribeCancel,
1195       .releaseNanDiscoveryEvent = chppWifiClientNanReleaseDiscoveryEvent,
1196       .requestNanRanging = chppWifiClientNanRequestNanRanging,
1197   };
1198 
1199   CHPP_STATIC_ASSERT(
1200       CHRE_PAL_WIFI_API_CURRENT_VERSION == CHPP_PAL_WIFI_API_VERSION,
1201       "A newer CHRE PAL API version is available. Please update.");
1202 
1203   if (!CHRE_PAL_VERSIONS_ARE_COMPATIBLE(api.moduleVersion,
1204                                         requestedApiVersion)) {
1205     return NULL;
1206   } else {
1207     return &api;
1208   }
1209 }
1210 
1211 #endif
1212