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