1 /*
2 * Copyright (C) 2021 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 "chre_stress_test_manager.h"
18
19 #include <pb_decode.h>
20 #include <pb_encode.h>
21
22 #include "chre/util/macros.h"
23 #include "chre/util/nanoapp/callbacks.h"
24 #include "chre/util/nanoapp/log.h"
25 #include "chre_stress_test.nanopb.h"
26 #include "send_message.h"
27
28 #define LOG_TAG "[ChreStressTest]"
29
30 namespace chre {
31
32 namespace stress_test {
33
34 namespace {
35
36 //! Additional duration to handle request timeout over the specified
37 //! CHRE API timeout (to account for processing delay).
38 #define TIMEOUT_BUFFER_DELAY_NS (1 * CHRE_NSEC_PER_SEC)
39
40 constexpr chre::Nanoseconds kWifiScanInterval = chre::Seconds(5);
41
isRequestTypeForLocation(uint8_t requestType)42 bool isRequestTypeForLocation(uint8_t requestType) {
43 return (requestType == CHRE_GNSS_REQUEST_TYPE_LOCATION_SESSION_START) ||
44 (requestType == CHRE_GNSS_REQUEST_TYPE_LOCATION_SESSION_STOP);
45 }
46
isRequestTypeForMeasurement(uint8_t requestType)47 bool isRequestTypeForMeasurement(uint8_t requestType) {
48 return (requestType == CHRE_GNSS_REQUEST_TYPE_MEASUREMENT_SESSION_START) ||
49 (requestType == CHRE_GNSS_REQUEST_TYPE_MEASUREMENT_SESSION_STOP);
50 }
51
52 } // anonymous namespace
53
handleEvent(uint32_t senderInstanceId,uint16_t eventType,const void * eventData)54 void Manager::handleEvent(uint32_t senderInstanceId, uint16_t eventType,
55 const void *eventData) {
56 if (eventType == CHRE_EVENT_MESSAGE_FROM_HOST) {
57 handleMessageFromHost(
58 senderInstanceId,
59 static_cast<const chreMessageFromHostData *>(eventData));
60 } else if (senderInstanceId == CHRE_INSTANCE_ID) {
61 handleDataFromChre(eventType, eventData);
62 } else {
63 LOGW("Got unknown event type from senderInstanceId %" PRIu32
64 " and with eventType %" PRIu16,
65 senderInstanceId, eventType);
66 }
67 }
68
handleMessageFromHost(uint32_t senderInstanceId,const chreMessageFromHostData * hostData)69 void Manager::handleMessageFromHost(uint32_t senderInstanceId,
70 const chreMessageFromHostData *hostData) {
71 bool success = false;
72 uint32_t messageType = hostData->messageType;
73 if (senderInstanceId != CHRE_INSTANCE_ID) {
74 LOGE("Incorrect sender instance id: %" PRIu32, senderInstanceId);
75 } else if (messageType == chre_stress_test_MessageType_TEST_HOST_RESTARTED) {
76 // Do nothing and only update the host endpoint
77 mHostEndpoint = hostData->hostEndpoint;
78 success = true;
79 } else if (messageType == chre_stress_test_MessageType_GET_CAPABILITIES) {
80 sendCapabilitiesMessage();
81 success = true;
82 } else if (messageType != chre_stress_test_MessageType_TEST_COMMAND) {
83 LOGE("Invalid message type %" PRIu32, messageType);
84 } else if (mHostEndpoint.has_value() &&
85 hostData->hostEndpoint != mHostEndpoint.value()) {
86 LOGE("Invalid host endpoint %" PRIu16 " expected %" PRIu16,
87 hostData->hostEndpoint, mHostEndpoint.value());
88 } else {
89 pb_istream_t istream = pb_istream_from_buffer(
90 static_cast<const pb_byte_t *>(hostData->message),
91 hostData->messageSize);
92 chre_stress_test_TestCommand testCommand =
93 chre_stress_test_TestCommand_init_default;
94
95 if (!pb_decode(&istream, chre_stress_test_TestCommand_fields,
96 &testCommand)) {
97 LOGE("Failed to decode start command error %s", PB_GET_ERROR(&istream));
98 } else {
99 LOGI("Got message from host: feature %d start %d", testCommand.feature,
100 testCommand.start);
101
102 success = true;
103 switch (testCommand.feature) {
104 case chre_stress_test_TestCommand_Feature_WIFI_ON_DEMAND_SCAN: {
105 handleWifiStartCommand(testCommand.start);
106 break;
107 }
108 case chre_stress_test_TestCommand_Feature_GNSS_LOCATION: {
109 handleGnssLocationStartCommand(testCommand.start);
110 break;
111 }
112 case chre_stress_test_TestCommand_Feature_GNSS_MEASUREMENT: {
113 handleGnssMeasurementStartCommand(testCommand.start);
114 break;
115 }
116 case chre_stress_test_TestCommand_Feature_WWAN: {
117 handleWwanStartCommand(testCommand.start);
118 break;
119 }
120 case chre_stress_test_TestCommand_Feature_WIFI_SCAN_MONITOR: {
121 handleWifiScanMonitoringCommand(testCommand.start);
122 break;
123 }
124 default: {
125 LOGE("Unknown feature %d", testCommand.feature);
126 success = false;
127 break;
128 }
129 }
130 }
131
132 mHostEndpoint = hostData->hostEndpoint;
133 }
134
135 if (!success) {
136 test_shared::sendTestResultWithMsgToHost(
137 hostData->hostEndpoint,
138 chre_stress_test_MessageType_TEST_RESULT /* messageType */, success,
139 nullptr /* errMessage */);
140 }
141 }
142
handleDataFromChre(uint16_t eventType,const void * eventData)143 void Manager::handleDataFromChre(uint16_t eventType, const void *eventData) {
144 switch (eventType) {
145 case CHRE_EVENT_TIMER:
146 handleTimerEvent(static_cast<const uint32_t *>(eventData));
147 break;
148
149 case CHRE_EVENT_WIFI_ASYNC_RESULT:
150 handleWifiAsyncResult(static_cast<const chreAsyncResult *>(eventData));
151 break;
152
153 case CHRE_EVENT_WIFI_SCAN_RESULT:
154 handleWifiScanEvent(static_cast<const chreWifiScanEvent *>(eventData));
155 break;
156
157 case CHRE_EVENT_GNSS_ASYNC_RESULT:
158 handleGnssAsyncResult(static_cast<const chreAsyncResult *>(eventData));
159 break;
160
161 case CHRE_EVENT_GNSS_LOCATION:
162 handleGnssLocationEvent(
163 static_cast<const chreGnssLocationEvent *>(eventData));
164 break;
165
166 case CHRE_EVENT_GNSS_DATA:
167 handleGnssDataEvent(static_cast<const chreGnssDataEvent *>(eventData));
168 break;
169
170 case CHRE_EVENT_WWAN_CELL_INFO_RESULT:
171 handleCellInfoResult(
172 static_cast<const chreWwanCellInfoResult *>(eventData));
173 break;
174
175 default:
176 LOGW("Unknown event type %" PRIu16, eventType);
177 break;
178 }
179 }
180
handleTimerEvent(const uint32_t * handle)181 void Manager::handleTimerEvent(const uint32_t *handle) {
182 if (*handle == mWifiScanTimerHandle) {
183 handleDelayedWifiTimer();
184 } else if (*handle == mWifiScanAsyncTimerHandle) {
185 sendFailure("WiFi scan request timed out");
186 } else if (*handle == mGnssLocationTimerHandle) {
187 makeGnssLocationRequest();
188 } else if (*handle == mGnssMeasurementTimerHandle) {
189 makeGnssMeasurementRequest();
190 } else if (*handle == mGnssLocationAsyncTimerHandle &&
191 mGnssLocationAsyncRequest.has_value()) {
192 sendFailure("GNSS location async result timed out");
193 } else if (*handle == mGnssMeasurementAsyncTimerHandle &&
194 mGnssMeasurementAsyncRequest.has_value()) {
195 sendFailure("GNSS measurement async result timed out");
196 } else if (*handle == mWwanTimerHandle) {
197 makeWwanCellInfoRequest();
198 } else if (*handle == mWifiScanMonitorAsyncTimerHandle) {
199 sendFailure("WiFi scan monitor request timed out");
200 } else {
201 sendFailure("Unknown timer handle");
202 }
203 }
204
handleDelayedWifiTimer()205 void Manager::handleDelayedWifiTimer() {
206 // NOTE: We set the maxScanAgeMs to something smaller than the WiFi
207 // scan periodicity to ensure new scans are generated.
208 static const struct chreWifiScanParams params = {
209 /*.scanType=*/CHRE_WIFI_SCAN_TYPE_NO_PREFERENCE,
210 /*.maxScanAgeMs=*/2000, // 2 seconds
211 /*.frequencyListLen=*/0,
212 /*.frequencyList=*/NULL,
213 /*.ssidListLen=*/0,
214 /*.ssidList=*/NULL,
215 /*.radioChainPref=*/CHRE_WIFI_RADIO_CHAIN_PREF_DEFAULT,
216 /*.channelSet=*/CHRE_WIFI_CHANNEL_SET_NON_DFS};
217
218 bool success = chreWifiRequestScanAsync(¶ms, &kOnDemandWifiScanCookie);
219 LOGI("Requested on demand wifi success ? %d", success);
220 if (!success) {
221 sendFailure("Failed to make WiFi scan request");
222 } else {
223 mWifiScanAsyncRequest = AsyncRequest(&kOnDemandWifiScanCookie);
224 setTimer(CHRE_WIFI_SCAN_RESULT_TIMEOUT_NS + TIMEOUT_BUFFER_DELAY_NS,
225 true /* oneShot */, &mWifiScanAsyncTimerHandle);
226 }
227 }
228
handleWifiAsyncResult(const chreAsyncResult * result)229 void Manager::handleWifiAsyncResult(const chreAsyncResult *result) {
230 if (result->requestType == CHRE_WIFI_REQUEST_TYPE_REQUEST_SCAN) {
231 if (result->success) {
232 LOGI("On-demand scan success");
233 } else {
234 LOGW("On-demand scan failed: code %" PRIu8, result->errorCode);
235 }
236
237 if (!mWifiScanAsyncRequest.has_value()) {
238 sendFailure("Received WiFi async result with no pending request");
239 } else if (result->cookie != mWifiScanAsyncRequest->cookie) {
240 sendFailure("On-demand scan cookie mismatch");
241 }
242
243 cancelTimer(&mWifiScanAsyncTimerHandle);
244 mWifiScanAsyncRequest.reset();
245 requestDelayedWifiScan();
246 } else if (result->requestType ==
247 CHRE_WIFI_REQUEST_TYPE_CONFIGURE_SCAN_MONITOR) {
248 if (!result->success) {
249 LOGE("Scan monitor async failure: code %" PRIu8, result->errorCode);
250 sendFailure("Scan monitor async failed");
251 }
252
253 cancelTimer(&mWifiScanMonitorAsyncTimerHandle);
254 mWifiScanMonitorEnabled = (result->cookie != nullptr);
255 } else {
256 sendFailure("Unknown WiFi async result type");
257 }
258 }
259
handleGnssAsyncResult(const chreAsyncResult * result)260 void Manager::handleGnssAsyncResult(const chreAsyncResult *result) {
261 if (isRequestTypeForLocation(result->requestType)) {
262 validateGnssAsyncResult(result, mGnssLocationAsyncRequest,
263 &mGnssLocationAsyncTimerHandle);
264 } else if (isRequestTypeForMeasurement(result->requestType)) {
265 validateGnssAsyncResult(result, mGnssMeasurementAsyncRequest,
266 &mGnssMeasurementAsyncTimerHandle);
267 } else {
268 sendFailure("Unknown GNSS async result type");
269 }
270 }
271
validateGnssAsyncResult(const chreAsyncResult * result,Optional<AsyncRequest> & request,uint32_t * asyncTimerHandle)272 void Manager::validateGnssAsyncResult(const chreAsyncResult *result,
273 Optional<AsyncRequest> &request,
274 uint32_t *asyncTimerHandle) {
275 if (!request.has_value()) {
276 sendFailure("Received GNSS async result with no pending request");
277 } else if (!result->success) {
278 sendFailure("Async GNSS failure");
279 } else if (result->cookie != request->cookie) {
280 sendFailure("GNSS async cookie mismatch");
281 }
282
283 cancelTimer(asyncTimerHandle);
284 request.reset();
285 }
286
checkTimestamp(uint64_t timestamp,uint64_t pastTimestamp)287 void Manager::checkTimestamp(uint64_t timestamp, uint64_t pastTimestamp) {
288 if (timestamp < pastTimestamp) {
289 sendFailure("Timestamp was too old");
290 } else if (timestamp == pastTimestamp) {
291 sendFailure("Timestamp was duplicate");
292 }
293 }
294
handleGnssLocationEvent(const chreGnssLocationEvent * event)295 void Manager::handleGnssLocationEvent(const chreGnssLocationEvent *event) {
296 LOGI("Received GNSS location event at %" PRIu64 " ms", event->timestamp);
297
298 checkTimestamp(event->timestamp, mPrevGnssLocationEventTimestampMs);
299 mPrevGnssLocationEventTimestampMs = event->timestamp;
300 }
301
handleGnssDataEvent(const chreGnssDataEvent * event)302 void Manager::handleGnssDataEvent(const chreGnssDataEvent *event) {
303 static uint32_t sPrevDiscontCount = 0;
304 LOGI("Received GNSS measurement event at %" PRIu64 " ns count %" PRIu32
305 " flags 0x%" PRIx16,
306 event->clock.time_ns, event->clock.hw_clock_discontinuity_count,
307 event->clock.flags);
308
309 if (sPrevDiscontCount == event->clock.hw_clock_discontinuity_count) {
310 checkTimestamp(event->clock.time_ns, mPrevGnssMeasurementEventTimestampNs);
311 }
312
313 sPrevDiscontCount = event->clock.hw_clock_discontinuity_count;
314 mPrevGnssMeasurementEventTimestampNs = event->clock.time_ns;
315 }
316
handleWifiScanEvent(const chreWifiScanEvent * event)317 void Manager::handleWifiScanEvent(const chreWifiScanEvent *event) {
318 LOGI("Received Wifi scan event of type %" PRIu8 " with %" PRIu8
319 " results at %" PRIu64 " ns",
320 event->scanType, event->resultCount, event->referenceTime);
321
322 if (event->eventIndex == 0) {
323 checkTimestamp(event->referenceTime, mPrevWifiScanEventTimestampNs);
324 mPrevWifiScanEventTimestampNs = event->referenceTime;
325 }
326
327 if (mWifiScanMonitorEnabled) {
328 chreSendMessageToHostEndpoint(
329 nullptr, 0,
330 chre_stress_test_MessageType_TEST_WIFI_SCAN_MONITOR_TRIGGERED,
331 mHostEndpoint.value(), nullptr /* freeCallback */);
332 }
333 }
334
handleCellInfoResult(const chreWwanCellInfoResult * event)335 void Manager::handleCellInfoResult(const chreWwanCellInfoResult *event) {
336 LOGI("Received %" PRIu8 " cell info results", event->cellInfoCount);
337
338 mWwanCellInfoAsyncRequest.reset();
339 if (event->errorCode != CHRE_ERROR_NONE) {
340 LOGE("Cell info request failed with error code %" PRIu8, event->errorCode);
341 sendFailure("Cell info request failed");
342 } else if (event->cellInfoCount > 0) {
343 uint64_t maxTimestamp = 0;
344 for (uint8_t i = 0; i < event->cellInfoCount; i++) {
345 maxTimestamp = MAX(maxTimestamp, event->cells[i].timeStamp);
346 checkTimestamp(event->cells[i].timeStamp,
347 mPrevWwanCellInfoEventTimestampNs);
348 }
349
350 mPrevWwanCellInfoEventTimestampNs = maxTimestamp;
351 }
352 }
353
handleWifiStartCommand(bool start)354 void Manager::handleWifiStartCommand(bool start) {
355 mWifiTestStarted = start;
356 if (start) {
357 requestDelayedWifiScan();
358 } else {
359 cancelTimer(&mWifiScanTimerHandle);
360 }
361 }
362
handleGnssLocationStartCommand(bool start)363 void Manager::handleGnssLocationStartCommand(bool start) {
364 constexpr uint64_t kTimerDelayNs = Seconds(60).toRawNanoseconds();
365
366 if (chreGnssGetCapabilities() & CHRE_GNSS_CAPABILITIES_LOCATION) {
367 mGnssLocationTestStarted = start;
368 makeGnssLocationRequest();
369
370 if (start) {
371 setTimer(kTimerDelayNs, false /* oneShot */, &mGnssLocationTimerHandle);
372 } else {
373 cancelTimer(&mGnssLocationTimerHandle);
374 }
375 } else {
376 sendFailure("Platform has no location capability");
377 }
378 }
379
handleGnssMeasurementStartCommand(bool start)380 void Manager::handleGnssMeasurementStartCommand(bool start) {
381 constexpr uint64_t kTimerDelayNs = Seconds(60).toRawNanoseconds();
382
383 if (chreGnssGetCapabilities() & CHRE_GNSS_CAPABILITIES_MEASUREMENTS) {
384 mGnssMeasurementTestStarted = start;
385 makeGnssMeasurementRequest();
386
387 if (start) {
388 setTimer(kTimerDelayNs, false /* oneShot */,
389 &mGnssMeasurementTimerHandle);
390 } else {
391 cancelTimer(&mGnssMeasurementTimerHandle);
392 }
393 } else {
394 sendFailure("Platform has no GNSS measurement capability");
395 }
396 }
397
handleWwanStartCommand(bool start)398 void Manager::handleWwanStartCommand(bool start) {
399 constexpr uint64_t kTimerDelayNs =
400 CHRE_ASYNC_RESULT_TIMEOUT_NS + TIMEOUT_BUFFER_DELAY_NS;
401
402 if (chreWwanGetCapabilities() & CHRE_WWAN_GET_CELL_INFO) {
403 mWwanTestStarted = start;
404 makeWwanCellInfoRequest();
405
406 if (start) {
407 setTimer(kTimerDelayNs, false /* oneShot */, &mWwanTimerHandle);
408 } else {
409 cancelTimer(&mWwanTimerHandle);
410 }
411 } else {
412 sendFailure("Platform has no WWAN cell info capability");
413 }
414 }
415
handleWifiScanMonitoringCommand(bool start)416 void Manager::handleWifiScanMonitoringCommand(bool start) {
417 if (chreWifiGetCapabilities() & CHRE_WIFI_CAPABILITIES_SCAN_MONITORING) {
418 const uint32_t kWifiScanMonitorEnabledCookie = 0x1234;
419 bool success = chreWifiConfigureScanMonitorAsync(
420 start, start ? &kWifiScanMonitorEnabledCookie : nullptr);
421 LOGI("Scan monitor enable %d request success ? %d", start, success);
422
423 if (!success) {
424 sendFailure("Scan monitor request failed");
425 } else {
426 setTimer(CHRE_ASYNC_RESULT_TIMEOUT_NS + TIMEOUT_BUFFER_DELAY_NS,
427 true /* oneShot */, &mWifiScanMonitorAsyncTimerHandle);
428 }
429 } else {
430 sendFailure("Platform has no WiFi scan monitoring capability");
431 }
432 }
433
setTimer(uint64_t delayNs,bool oneShot,uint32_t * timerHandle)434 void Manager::setTimer(uint64_t delayNs, bool oneShot, uint32_t *timerHandle) {
435 *timerHandle = chreTimerSet(delayNs, timerHandle, oneShot);
436 if (*timerHandle == CHRE_TIMER_INVALID) {
437 sendFailure("Failed to set timer");
438 }
439 }
440
cancelTimer(uint32_t * timerHandle)441 void Manager::cancelTimer(uint32_t *timerHandle) {
442 if (*timerHandle != CHRE_TIMER_INVALID) {
443 if (!chreTimerCancel(*timerHandle)) {
444 // We don't treat this as a test failure, because the CHRE API does not
445 // guarantee this method succeeds (e.g. if the timer is one-shot and just
446 // fired).
447 LOGW("Failed to cancel timer");
448 }
449 *timerHandle = CHRE_TIMER_INVALID;
450 }
451 }
452
makeGnssLocationRequest()453 void Manager::makeGnssLocationRequest() {
454 // The list of location intervals to iterate; wraps around.
455 static const uint32_t kMinIntervalMsList[] = {1000, 0};
456 static size_t sIntervalIndex = 0;
457
458 uint32_t minIntervalMs = 0;
459 if (mGnssLocationTestStarted) {
460 minIntervalMs = kMinIntervalMsList[sIntervalIndex];
461 sIntervalIndex = (sIntervalIndex + 1) % ARRAY_SIZE(kMinIntervalMsList);
462 } else {
463 sIntervalIndex = 0;
464 }
465
466 bool success = false;
467 if (minIntervalMs > 0) {
468 success = chreGnssLocationSessionStartAsync(
469 minIntervalMs, 0 /* minTimeToNextFixMs */, &kGnssLocationCookie);
470 } else {
471 success = chreGnssLocationSessionStopAsync(&kGnssLocationCookie);
472 }
473
474 LOGI("Configure GNSS location interval %" PRIu32 " ms success ? %d",
475 minIntervalMs, success);
476
477 if (!success) {
478 sendFailure("Failed to make location request");
479 } else {
480 mGnssLocationAsyncRequest = AsyncRequest(&kGnssLocationCookie);
481 setTimer(CHRE_GNSS_ASYNC_RESULT_TIMEOUT_NS + TIMEOUT_BUFFER_DELAY_NS,
482 true /* oneShot */, &mGnssLocationAsyncTimerHandle);
483 }
484 }
485
makeGnssMeasurementRequest()486 void Manager::makeGnssMeasurementRequest() {
487 // The list of measurement intervals to iterate; wraps around.
488 static const uint32_t kMinIntervalMsList[] = {1000, 0};
489 static size_t sIntervalIndex = 0;
490
491 uint32_t minIntervalMs = 0;
492 if (mGnssMeasurementTestStarted) {
493 minIntervalMs = kMinIntervalMsList[sIntervalIndex];
494 sIntervalIndex = (sIntervalIndex + 1) % ARRAY_SIZE(kMinIntervalMsList);
495 } else {
496 sIntervalIndex = 0;
497 }
498
499 bool success = false;
500 if (minIntervalMs > 0) {
501 success = chreGnssMeasurementSessionStartAsync(minIntervalMs,
502 &kGnssMeasurementCookie);
503 } else {
504 success = chreGnssMeasurementSessionStopAsync(&kGnssMeasurementCookie);
505 // Reset the previous timestamp, since the GNSS internal clock may reset.
506 mPrevGnssMeasurementEventTimestampNs = 0;
507 }
508
509 LOGI("Configure GNSS measurement interval %" PRIu32 " ms success ? %d",
510 minIntervalMs, success);
511
512 if (!success) {
513 sendFailure("Failed to make measurement request");
514 } else {
515 mGnssMeasurementAsyncRequest = AsyncRequest(&kGnssMeasurementCookie);
516 setTimer(CHRE_GNSS_ASYNC_RESULT_TIMEOUT_NS + TIMEOUT_BUFFER_DELAY_NS,
517 true /* oneShot */, &mGnssMeasurementAsyncTimerHandle);
518 }
519 }
520
requestDelayedWifiScan()521 void Manager::requestDelayedWifiScan() {
522 if (mWifiTestStarted) {
523 if (chreWifiGetCapabilities() & CHRE_WIFI_CAPABILITIES_ON_DEMAND_SCAN) {
524 setTimer(kWifiScanInterval.toRawNanoseconds(), true /* oneShot */,
525 &mWifiScanTimerHandle);
526 } else {
527 sendFailure("Platform has no on-demand scan capability");
528 }
529 }
530 }
531
makeWwanCellInfoRequest()532 void Manager::makeWwanCellInfoRequest() {
533 if (mWwanTestStarted) {
534 if (mWwanCellInfoAsyncRequest.has_value()) {
535 if (chreGetTime() > mWwanCellInfoAsyncRequest->requestTimeNs +
536 CHRE_ASYNC_RESULT_TIMEOUT_NS) {
537 sendFailure("Prev cell info request did not complete in time");
538 }
539 } else {
540 bool success = chreWwanGetCellInfoAsync(&kWwanCellInfoCookie);
541
542 LOGI("Cell info request success ? %d", success);
543
544 if (!success) {
545 sendFailure("Failed to make cell info request");
546 } else {
547 mWwanCellInfoAsyncRequest = AsyncRequest(&kWwanCellInfoCookie);
548 }
549 }
550 }
551 }
552
sendFailure(const char * errorMessage)553 void Manager::sendFailure(const char *errorMessage) {
554 test_shared::sendTestResultWithMsgToHost(
555 mHostEndpoint.value(),
556 chre_stress_test_MessageType_TEST_RESULT /* messageType */,
557 false /* success */, errorMessage, false /* abortOnFailure */);
558 }
559
sendCapabilitiesMessage()560 void Manager::sendCapabilitiesMessage() {
561 if (!mHostEndpoint.has_value()) {
562 LOGE("mHostEndpoint is not initialized");
563 return;
564 }
565
566 chre_stress_test_Capabilities capabilities =
567 chre_stress_test_Capabilities_init_default;
568 capabilities.wifi = chreWifiGetCapabilities();
569
570 size_t size;
571 if (!pb_get_encoded_size(&size, chre_stress_test_Capabilities_fields,
572 &capabilities)) {
573 LOGE("Failed to get message size");
574 return;
575 }
576
577 pb_byte_t *bytes = static_cast<pb_byte_t *>(chreHeapAlloc(size));
578 if (size > 0 && bytes == nullptr) {
579 LOG_OOM();
580 } else {
581 pb_ostream_t stream = pb_ostream_from_buffer(bytes, size);
582 if (!pb_encode(&stream, chre_stress_test_Capabilities_fields,
583 &capabilities)) {
584 LOGE("Failed to encode capabilities error %s", PB_GET_ERROR(&stream));
585 chreHeapFree(bytes);
586 } else {
587 chreSendMessageToHostEndpoint(
588 bytes, size, chre_stress_test_MessageType_CAPABILITIES,
589 mHostEndpoint.value(), heapFreeMessageCallback);
590 }
591 }
592 }
593
594 } // namespace stress_test
595
596 } // namespace chre
597