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