• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <gtest/gtest.h>
18 #include <stddef.h>
19 
20 #include <string.h>
21 
22 #include "chpp/common/wwan_types.h"
23 #include "chpp/memory.h"
24 
25 namespace {
26 
27 // clang-format off
28 const chreWwanCellInfo kChreCells[] = {
29   {
30     .timeStamp = 1234,
31     .cellInfoType = CHRE_WWAN_CELL_INFO_TYPE_LTE,
32     .timeStampType = CHRE_WWAN_CELL_TIMESTAMP_TYPE_MODEM,
33     .registered = 1,
34     .reserved = 111,  // ignored
35     .CellInfo = {
36       .lte = {
37         .cellIdentityLte = {
38           .mcc = 777,
39           .mnc = 888,
40           .ci = 4321,
41           .pci = 333,
42           .tac = 9876,
43           .earfcn = 5432,
44         },
45         .signalStrengthLte = {
46           .signalStrength = 27,
47           .rsrp = 96,
48           .rsrq = 18,
49           .rssnr = 157,
50           .cqi = 13,
51           .timingAdvance = INT32_MAX,
52         }
53       }
54     }
55   },
56   {
57     .timeStamp = 1235,
58     .cellInfoType = CHRE_WWAN_CELL_INFO_TYPE_WCDMA,
59     .timeStampType = CHRE_WWAN_CELL_TIMESTAMP_TYPE_ANTENNA,
60     .registered = 0,
61     .CellInfo = {
62       .wcdma = {
63         .cellIdentityWcdma = {
64           .mcc = 123,
65           .mnc = 456,
66           .lac = 789,
67           .cid = 012,
68           .psc = 345,
69           .uarfcn = 678,
70         },
71         .signalStrengthWcdma = {
72           .signalStrength = 99,
73           .bitErrorRate = INT32_MAX,
74         }
75       }
76     }
77   },
78 };
79 const chreWwanCellInfoResult kChreResultOneCell = {
80   .errorCode = 0,
81   .cellInfoCount = 1,
82   .cells = kChreCells,
83 };
84 const chreWwanCellInfoResult kChreResultTwoCell = {
85   .errorCode = 0,
86   .cellInfoCount = 2,
87   .cells = kChreCells,
88 };
89 // clang-format on
90 
compareCellInfo(const chreWwanCellInfo * chre,const ChppWwanCellInfo * chppIn)91 void compareCellInfo(const chreWwanCellInfo *chre,
92                      const ChppWwanCellInfo *chppIn) {
93   // Local variable needed to avoid unaligned memory access.
94   ChppWwanCellInfo chppLocal;
95   memcpy(&chppLocal, chppIn, sizeof(ChppWwanCellInfo));
96   const ChppWwanCellInfo *chpp = &chppLocal;
97 
98   EXPECT_EQ(chpp->timeStamp, chre->timeStamp);
99   EXPECT_EQ(chpp->cellInfoType, chre->cellInfoType);
100   EXPECT_EQ(chpp->timeStampType, chre->timeStampType);
101   EXPECT_EQ(chpp->registered, chre->registered);
102 
103   switch (chpp->cellInfoType) {
104     case CHRE_WWAN_CELL_INFO_TYPE_LTE:
105       EXPECT_EQ(chpp->CellInfo.lte.cellIdentityLte.mcc,
106                 chre->CellInfo.lte.cellIdentityLte.mcc);
107       EXPECT_EQ(chpp->CellInfo.lte.cellIdentityLte.mnc,
108                 chre->CellInfo.lte.cellIdentityLte.mnc);
109       EXPECT_EQ(chpp->CellInfo.lte.cellIdentityLte.ci,
110                 chre->CellInfo.lte.cellIdentityLte.ci);
111       EXPECT_EQ(chpp->CellInfo.lte.cellIdentityLte.pci,
112                 chre->CellInfo.lte.cellIdentityLte.pci);
113       EXPECT_EQ(chpp->CellInfo.lte.cellIdentityLte.tac,
114                 chre->CellInfo.lte.cellIdentityLte.tac);
115       EXPECT_EQ(chpp->CellInfo.lte.cellIdentityLte.earfcn,
116                 chre->CellInfo.lte.cellIdentityLte.earfcn);
117 
118       EXPECT_EQ(chpp->CellInfo.lte.signalStrengthLte.signalStrength,
119                 chre->CellInfo.lte.signalStrengthLte.signalStrength);
120       EXPECT_EQ(chpp->CellInfo.lte.signalStrengthLte.rsrp,
121                 chre->CellInfo.lte.signalStrengthLte.rsrp);
122       EXPECT_EQ(chpp->CellInfo.lte.signalStrengthLte.rsrq,
123                 chre->CellInfo.lte.signalStrengthLte.rsrq);
124       EXPECT_EQ(chpp->CellInfo.lte.signalStrengthLte.rssnr,
125                 chre->CellInfo.lte.signalStrengthLte.rssnr);
126       EXPECT_EQ(chpp->CellInfo.lte.signalStrengthLte.cqi,
127                 chre->CellInfo.lte.signalStrengthLte.cqi);
128       EXPECT_EQ(chpp->CellInfo.lte.signalStrengthLte.timingAdvance,
129                 chre->CellInfo.lte.signalStrengthLte.timingAdvance);
130       break;
131 
132     case CHRE_WWAN_CELL_INFO_TYPE_WCDMA:
133       EXPECT_EQ(chpp->CellInfo.wcdma.cellIdentityWcdma.mcc,
134                 chre->CellInfo.wcdma.cellIdentityWcdma.mcc);
135       EXPECT_EQ(chpp->CellInfo.wcdma.cellIdentityWcdma.mnc,
136                 chre->CellInfo.wcdma.cellIdentityWcdma.mnc);
137       EXPECT_EQ(chpp->CellInfo.wcdma.cellIdentityWcdma.lac,
138                 chre->CellInfo.wcdma.cellIdentityWcdma.lac);
139       EXPECT_EQ(chpp->CellInfo.wcdma.cellIdentityWcdma.cid,
140                 chre->CellInfo.wcdma.cellIdentityWcdma.cid);
141       EXPECT_EQ(chpp->CellInfo.wcdma.cellIdentityWcdma.psc,
142                 chre->CellInfo.wcdma.cellIdentityWcdma.psc);
143       EXPECT_EQ(chpp->CellInfo.wcdma.cellIdentityWcdma.uarfcn,
144                 chre->CellInfo.wcdma.cellIdentityWcdma.uarfcn);
145 
146       EXPECT_EQ(chpp->CellInfo.wcdma.signalStrengthWcdma.signalStrength,
147                 chre->CellInfo.wcdma.signalStrengthWcdma.signalStrength);
148       EXPECT_EQ(chpp->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate,
149                 chre->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate);
150       break;
151 
152     default:
153       // Other types not supported yet
154       ASSERT_TRUE(false);
155   }
156 }
157 
158 //! Test for correct handling of a malformed ChppWwanCellInfoResult (e.g. short
159 //! payload, invalid offset/length)
testMalformedCellInfoResultDecoding(struct ChppWwanCellInfoResult * chpp,size_t inputSize)160 void testMalformedCellInfoResultDecoding(struct ChppWwanCellInfoResult *chpp,
161                                          size_t inputSize) {
162   chreWwanCellInfoResult *chreMalformed;
163 
164   inputSize--;
165   chreMalformed = chppWwanCellInfoResultToChre(chpp, inputSize);
166   EXPECT_EQ(chreMalformed, nullptr);
167   inputSize++;
168 
169   chpp->cells.offset++;
170   chreMalformed = chppWwanCellInfoResultToChre(chpp, inputSize);
171   EXPECT_EQ(chreMalformed, nullptr);
172   chpp->cells.offset--;
173 
174   chpp->cells.length++;
175   chreMalformed = chppWwanCellInfoResultToChre(chpp, inputSize);
176   EXPECT_EQ(chreMalformed, nullptr);
177   chpp->cells.length--;
178 
179   chpp->cellInfoCount++;
180   chreMalformed = chppWwanCellInfoResultToChre(chpp, inputSize);
181   EXPECT_EQ(chreMalformed, nullptr);
182   chpp->cellInfoCount--;
183 
184   chpp->cellInfoCount--;
185   chreMalformed = chppWwanCellInfoResultToChre(chpp, inputSize);
186   EXPECT_EQ(chreMalformed, nullptr);
187   chpp->cellInfoCount++;
188 }
189 
TEST(WwanConvert,EncodeErrorCode)190 TEST(WwanConvert, EncodeErrorCode) {
191   const chreWwanCellInfoResult chreResult = {
192       .version = 200,  // ignored
193       .errorCode = 2,
194       .cellInfoCount = 0,
195       .reserved = 3,         // ignored
196       .cookie = (void *)-1,  // ignored
197       .cells = nullptr,
198   };
199 
200   ChppWwanCellInfoResultWithHeader *chppWithHeader = nullptr;
201   size_t outputSize = 999;
202   bool result =
203       chppWwanCellInfoResultFromChre(&chreResult, &chppWithHeader, &outputSize);
204   ASSERT_TRUE(result);
205   ASSERT_NE(chppWithHeader, nullptr);
206   EXPECT_EQ(outputSize, sizeof(ChppWwanCellInfoResultWithHeader));
207 
208   ChppWwanCellInfoResult *chpp = &chppWithHeader->payload;
209   EXPECT_EQ(chpp->version, CHRE_WWAN_CELL_INFO_RESULT_VERSION);
210   EXPECT_EQ(chpp->errorCode, chreResult.errorCode);
211   EXPECT_EQ(chpp->cellInfoCount, chreResult.cellInfoCount);
212   EXPECT_EQ(chpp->reserved, 0);
213   EXPECT_EQ(chpp->cookie, 0u);
214   EXPECT_EQ(chpp->cells.offset, 0);
215   EXPECT_EQ(chpp->cells.length, 0);
216 
217   chppFree(chppWithHeader);
218 }
219 
TEST(WwanConvert,DecodeErrorCode)220 TEST(WwanConvert, DecodeErrorCode) {
221   const ChppWwanCellInfoResult chpp = {
222       .version = 200,  // ignored
223       .errorCode = 2,
224       .cellInfoCount = 0,
225       .reserved = 3,  // ignored
226       .cookie = 100,  // ignored
227       .cells.offset = 0,
228       .cells.length = 0,
229   };
230 
231   size_t outputSize = sizeof(struct ChppWwanCellInfoResult);
232   chreWwanCellInfoResult *chre =
233       chppWwanCellInfoResultToChre(&chpp, outputSize);
234   ASSERT_NE(chre, nullptr);
235 
236   EXPECT_EQ(chre->version, CHRE_WWAN_CELL_INFO_RESULT_VERSION);
237   EXPECT_EQ(chre->errorCode, chpp.errorCode);
238   EXPECT_EQ(chre->cellInfoCount, chpp.cellInfoCount);
239   EXPECT_EQ(chre->reserved, 0);
240   EXPECT_EQ(chre->cookie, (void *)0);
241 
242   // Handling of short payload
243   chreWwanCellInfoResult *chreShort =
244       chppWwanCellInfoResultToChre(&chpp, outputSize - 1);
245   ASSERT_EQ(chreShort, nullptr);
246 
247   chppFree(chre);
248 }
249 
TEST(WwanConvert,EncodeOneCell)250 TEST(WwanConvert, EncodeOneCell) {
251   ChppWwanCellInfoResultWithHeader *chppWithHeader = nullptr;
252   size_t outputSize = 999;
253   bool result = chppWwanCellInfoResultFromChre(&kChreResultOneCell,
254                                                &chppWithHeader, &outputSize);
255   ASSERT_TRUE(result);
256   ASSERT_NE(chppWithHeader, nullptr);
257   EXPECT_EQ(outputSize, sizeof(ChppWwanCellInfoResultWithHeader) +
258                             sizeof(ChppWwanCellInfo));
259 
260   ChppWwanCellInfoResult *chpp = &chppWithHeader->payload;
261   EXPECT_EQ(chpp->errorCode, kChreResultOneCell.errorCode);
262   EXPECT_EQ(chpp->cellInfoCount, kChreResultOneCell.cellInfoCount);
263   EXPECT_EQ(chpp->cells.offset, sizeof(ChppWwanCellInfoResult));
264   EXPECT_EQ(chpp->cells.length, sizeof(ChppWwanCellInfo));
265 
266   ChppWwanCellInfo *chppCell =
267       (ChppWwanCellInfo *)((uint8_t *)chpp + chpp->cells.offset);
268   EXPECT_EQ(chppCell->reserved, 0);
269   compareCellInfo(&kChreCells[0], chppCell);
270 
271   chppFree(chppWithHeader);
272 }
273 
TEST(WwanConvert,EncodeDecodeOneCell)274 TEST(WwanConvert, EncodeDecodeOneCell) {
275   ChppWwanCellInfoResultWithHeader *chppWithHeader;
276   size_t outputSize;
277   bool result = chppWwanCellInfoResultFromChre(&kChreResultOneCell,
278                                                &chppWithHeader, &outputSize);
279   ASSERT_TRUE(result);
280   ASSERT_NE(chppWithHeader, nullptr);
281 
282   ChppWwanCellInfoResult *chpp = &chppWithHeader->payload;
283   ChppWwanCellInfo *chppCell =
284       (ChppWwanCellInfo *)((uint8_t *)chpp + chpp->cells.offset);
285 
286   chpp->version = 100;  // ignored
287   chpp->reserved = 10;  // ignored
288   chpp->cookie = -10;   // ignored
289 
290   size_t inputSize = outputSize - sizeof(struct ChppAppHeader);
291 
292   chreWwanCellInfoResult *chre = chppWwanCellInfoResultToChre(chpp, inputSize);
293   ASSERT_NE(chre, nullptr);
294 
295   EXPECT_EQ(chre->version, CHRE_WWAN_CELL_INFO_RESULT_VERSION);
296   EXPECT_EQ(chre->reserved, 0);
297   EXPECT_EQ(chre->cookie, (void *)0);
298 
299   EXPECT_EQ(chre->errorCode, chpp->errorCode);
300   EXPECT_EQ(chre->errorCode, kChreResultOneCell.errorCode);
301   EXPECT_EQ(chre->cellInfoCount, chpp->cellInfoCount);
302   EXPECT_EQ(chre->cellInfoCount, kChreResultOneCell.cellInfoCount);
303 
304   EXPECT_EQ(chre->cells[0].reserved, 0);
305   compareCellInfo(&kChreCells[0], chppCell);
306   compareCellInfo(&chre->cells[0], chppCell);
307 
308   testMalformedCellInfoResultDecoding(chpp, inputSize);
309 
310   chppFree(chppWithHeader);
311   chppFree(chre);
312 }
313 
TEST(WwanConvert,EncodeTwoCells)314 TEST(WwanConvert, EncodeTwoCells) {
315   ChppWwanCellInfoResultWithHeader *chppWithHeader = nullptr;
316   size_t outputSize = 999;
317   bool result = chppWwanCellInfoResultFromChre(&kChreResultTwoCell,
318                                                &chppWithHeader, &outputSize);
319   ASSERT_TRUE(result);
320   ASSERT_NE(chppWithHeader, nullptr);
321   EXPECT_EQ(outputSize, sizeof(ChppWwanCellInfoResultWithHeader) +
322                             2 * sizeof(ChppWwanCellInfo));
323 
324   ChppWwanCellInfoResult *chpp = &chppWithHeader->payload;
325   EXPECT_EQ(chpp->errorCode, kChreResultTwoCell.errorCode);
326   EXPECT_EQ(chpp->cellInfoCount, kChreResultTwoCell.cellInfoCount);
327   EXPECT_EQ(chpp->cells.offset, sizeof(ChppWwanCellInfoResult));
328   EXPECT_EQ(chpp->cells.length, 2 * sizeof(ChppWwanCellInfo));
329 
330   ChppWwanCellInfo *chppCells =
331       (ChppWwanCellInfo *)((uint8_t *)chpp + chpp->cells.offset);
332   EXPECT_EQ(chppCells[0].reserved, 0);
333   EXPECT_EQ(chppCells[1].reserved, 0);
334   compareCellInfo(&kChreCells[0], &chppCells[0]);
335   compareCellInfo(&kChreCells[1], &chppCells[1]);
336 
337   // Ensure unused bytes in the union are zeroed out
338   uint8_t *pastEnd =
339       (uint8_t *)&chppCells[1].CellInfo.wcdma.signalStrengthWcdma.bitErrorRate +
340       sizeof(chppCells[1].CellInfo.wcdma.signalStrengthWcdma.bitErrorRate);
341   size_t sizePastEnd = sizeof(chreWwanCellInfo::chreWwanCellInfoPerRat) -
342                        sizeof(chreWwanCellInfoWcdma);
343   uint8_t zeros[sizePastEnd];
344   memset(zeros, 0, sizePastEnd);
345   EXPECT_EQ(memcmp(pastEnd, zeros, sizeof(zeros)), 0);
346 
347   chppFree(chppWithHeader);
348 }
349 
TEST(WwanConvert,EncodeDecodeTwoCells)350 TEST(WwanConvert, EncodeDecodeTwoCells) {
351   ChppWwanCellInfoResultWithHeader *chppWithHeader;
352   size_t outputSize;
353   bool result = chppWwanCellInfoResultFromChre(&kChreResultTwoCell,
354                                                &chppWithHeader, &outputSize);
355   ASSERT_TRUE(result);
356   ASSERT_NE(chppWithHeader, nullptr);
357 
358   ChppWwanCellInfoResult *chpp = &chppWithHeader->payload;
359   ChppWwanCellInfo *chppCells =
360       (ChppWwanCellInfo *)((uint8_t *)chpp + chpp->cells.offset);
361 
362   chpp->version = 100;  // ignored
363   chpp->reserved = 10;  // ignored
364   chpp->cookie = -10;   // ignored
365 
366   size_t inputSize = outputSize - sizeof(struct ChppAppHeader);
367 
368   chreWwanCellInfoResult *chre = chppWwanCellInfoResultToChre(chpp, inputSize);
369   ASSERT_NE(chre, nullptr);
370 
371   EXPECT_EQ(chre->version, CHRE_WWAN_CELL_INFO_RESULT_VERSION);
372   EXPECT_EQ(chre->reserved, 0);
373   EXPECT_EQ(chre->cookie, (void *)0);
374 
375   EXPECT_EQ(chre->errorCode, chpp->errorCode);
376   EXPECT_EQ(chpp->errorCode, kChreResultTwoCell.errorCode);
377   EXPECT_EQ(chre->cellInfoCount, chpp->cellInfoCount);
378   EXPECT_EQ(chpp->cellInfoCount, kChreResultTwoCell.cellInfoCount);
379 
380   EXPECT_EQ(chre->cells[0].reserved, 0);
381   compareCellInfo(&kChreCells[0], &chppCells[0]);
382   compareCellInfo(&chre->cells[0], &chppCells[0]);
383 
384   EXPECT_EQ(chre->cells[1].reserved, 0);
385   compareCellInfo(&kChreCells[1], &chppCells[1]);
386   compareCellInfo(&chre->cells[1], &chppCells[1]);
387 
388   testMalformedCellInfoResultDecoding(chpp, inputSize);
389 
390   chppFree(chppWithHeader);
391   chppFree(chre);
392 }
393 
394 }  // namespace
395