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 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) 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 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 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 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 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 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 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