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