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