1 /*
2  * Copyright (C) 2017 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 #include <general_test/wwan_cell_info_test.h>
17 
18 #include <general_test/cell_info_base.h>
19 #include <general_test/cell_info_cdma.h>
20 #include <general_test/cell_info_gsm.h>
21 #include <general_test/cell_info_lte.h>
22 #include <general_test/cell_info_nr.h>
23 #include <general_test/cell_info_tdscdma.h>
24 #include <general_test/cell_info_wcdma.h>
25 
26 #include <shared/send_message.h>
27 
28 #include "chre/util/macros.h"
29 
30 /*
31  * General philosophy behind this test:
32  *   Make a call to chreWwanGetCellInfoAsync and then ensure the following:
33  *     1) Data is received within CHRE_ASYNC_RESULT_TIMEOUT_NS + small buffer.
34  *     2) Various fields in the returned data are correct.
35  */
36 
37 namespace general_test {
38 
WwanCellInfoTest()39 WwanCellInfoTest::WwanCellInfoTest() : Test(CHRE_API_VERSION_1_1) {}
40 
setUp(uint32_t messageSize,const void * message)41 void WwanCellInfoTest::setUp(uint32_t messageSize, const void *message) {
42   UNUSED_VAR(messageSize);
43   UNUSED_VAR(message);
44 
45   if ((chreWwanGetCapabilities() & CHRE_WWAN_GET_CELL_INFO) == 0) {
46     sendMessageToHost(nanoapp_testing::MessageType::kSkipped);
47   } else if (!chreWwanGetCellInfoAsync(&mTimerHandle)) {
48     nanoapp_testing::sendFatalFailureToHost(
49         "chreWwanGetCellInfo failed unexpectedly");
50   } else {
51     mTimerHandle = chreTimerSet(CHRE_ASYNC_RESULT_TIMEOUT_NS, &mTimerHandle,
52                                 true /* oneShot */);
53 
54     if (mTimerHandle == CHRE_TIMER_INVALID) {
55       nanoapp_testing::sendFatalFailureToHost(
56           "Unable to set timer for automatic failure");
57     }
58   }
59 }
60 
~WwanCellInfoTest()61 WwanCellInfoTest::~WwanCellInfoTest() {
62   // Ensure the timer is cancelled
63   cancelTimer();
64 }
65 
handleEvent(uint32_t senderInstanceId,uint16_t eventType,const void * eventData)66 void WwanCellInfoTest::handleEvent(uint32_t senderInstanceId,
67                                    uint16_t eventType, const void *eventData) {
68   // The only expected message is from the async call
69   if (senderInstanceId != CHRE_INSTANCE_ID) {
70     nanoapp_testing::sendFatalFailureToHost(
71         "handleEvent received event from unexpected sender:",
72         &senderInstanceId);
73   } else if (eventType == CHRE_EVENT_WWAN_CELL_INFO_RESULT) {
74     cancelTimer();
75     validateCellInfoResult(eventData);
76   } else if (eventType == CHRE_EVENT_TIMER) {
77     nanoapp_testing::sendFatalFailureToHost(
78         "chreWwanGetCellInfo did not return data in time");
79   } else {
80     uint32_t type = eventType;
81     nanoapp_testing::sendFatalFailureToHost(
82         "handleEvent received an unexpected eventType:", &type);
83   }
84 }
85 
cancelTimer()86 void WwanCellInfoTest::cancelTimer() {
87   if (mTimerHandle != CHRE_TIMER_INVALID) {
88     chreTimerCancel(mTimerHandle);
89     mTimerHandle = CHRE_TIMER_INVALID;
90   }
91 }
92 
validateCellInfo(uint8_t count,const struct chreWwanCellInfo * cells) const93 void WwanCellInfoTest::validateCellInfo(
94     uint8_t count, const struct chreWwanCellInfo *cells) const {
95   bool valid = true;
96 
97   for (int i = 0; (i < count) && valid; ++i) {
98     if (cells[i].reserved != 0) {
99       valid = false;
100       CellInfoBase::sendFatalFailureUint8("Invalid reserved CellInfo field: %d",
101                                           cells[i].reserved);
102     }
103 
104     if ((cells[i].timeStampType != CHRE_WWAN_CELL_TIMESTAMP_TYPE_UNKNOWN) &&
105         (cells[i].timeStampType != CHRE_WWAN_CELL_TIMESTAMP_TYPE_ANTENNA) &&
106         (cells[i].timeStampType != CHRE_WWAN_CELL_TIMESTAMP_TYPE_MODEM) &&
107         (cells[i].timeStampType != CHRE_WWAN_CELL_TIMESTAMP_TYPE_OEM_RIL) &&
108         (cells[i].timeStampType != CHRE_WWAN_CELL_TIMESTAMP_TYPE_JAVA_RIL)) {
109       valid = false;
110       CellInfoBase::sendFatalFailureUint8("Invalid timeStampType: %d",
111                                           cells[i].timeStampType);
112     }
113 
114     if (cells[i].cellInfoType == CHRE_WWAN_CELL_INFO_TYPE_GSM) {
115       valid &= CellInfoGsm::validate(cells[i].CellInfo.gsm);
116     } else if (cells[i].cellInfoType == CHRE_WWAN_CELL_INFO_TYPE_CDMA) {
117       valid &= CellInfoCdma::validate(cells[i].CellInfo.cdma);
118     } else if (cells[i].cellInfoType == CHRE_WWAN_CELL_INFO_TYPE_LTE) {
119       valid &= CellInfoLte::validate(cells[i].CellInfo.lte);
120     } else if (cells[i].cellInfoType == CHRE_WWAN_CELL_INFO_TYPE_WCDMA) {
121       valid &= CellInfoWcdma::validate(cells[i].CellInfo.wcdma);
122     } else if (cells[i].cellInfoType == CHRE_WWAN_CELL_INFO_TYPE_TD_SCDMA) {
123       valid &= CellInfoTdscdma::validate(cells[i].CellInfo.tdscdma);
124     } else if (cells[i].cellInfoType == CHRE_WWAN_CELL_INFO_TYPE_NR) {
125       valid &=
126           CellInfoNr::validate(cells[i].CellInfo.nr, cells[i].registered != 0);
127     } else {
128       valid = false;
129       CellInfoBase::sendFatalFailureUint8("Invalid cellInfoType: %d",
130                                           cells[i].cellInfoType);
131     }
132   }
133 
134   if (valid) {
135     nanoapp_testing::sendSuccessToHost();
136   }
137 }
138 
validateCellInfoResult(const void * eventData) const139 void WwanCellInfoTest::validateCellInfoResult(const void *eventData) const {
140   const struct chreWwanCellInfoResult *result =
141       static_cast<const chreWwanCellInfoResult *>(eventData);
142 
143   if (eventData == nullptr) {
144     nanoapp_testing::sendFatalFailureToHost("Received eventData is null");
145   } else if (result->version != CHRE_WWAN_CELL_INFO_RESULT_VERSION) {
146     nanoapp_testing::sendFatalFailureToHost(
147         "Received version is unexpected value");
148   } else if (result->reserved != 0) {
149     nanoapp_testing::sendFatalFailureToHost("Received reserved field non-zero");
150   } else {
151     const uint32_t *receivedCookie =
152         static_cast<const uint32_t *>(result->cookie);
153 
154     if (receivedCookie != &mTimerHandle) {
155       nanoapp_testing::sendFatalFailureToHost("Received cookie does not match");
156     } else if (result->cellInfoCount != 0) {
157       validateCellInfo(result->cellInfoCount, result->cells);
158     } else {
159       nanoapp_testing::sendSuccessToHost();
160     }
161   }
162 }
163 
164 }  // namespace general_test
165