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 "chre/pal/wwan.h"
18 
19 #include "chre/util/memory.h"
20 #include "chre/util/unique_ptr.h"
21 
22 #include <chrono>
23 #include <cinttypes>
24 #include <thread>
25 
26 /**
27  * A simulated implementation of the WWAN PAL for the linux platform.
28  */
29 namespace {
30 const struct chrePalSystemApi *gSystemApi = nullptr;
31 const struct chrePalWwanCallbacks *gCallbacks = nullptr;
32 
33 //! Thread to deliver asynchronous WWAN cell info results after a CHRE request.
34 std::thread gCellInfosThread;
35 
sendCellInfoResult()36 void sendCellInfoResult() {
37   auto result = chre::MakeUniqueZeroFill<struct chreWwanCellInfoResult>();
38   auto cell = chre::MakeUniqueZeroFill<struct chreWwanCellInfo>();
39   cell->timeStamp = gSystemApi->getCurrentTime();
40   cell->cellInfoType = CHRE_WWAN_CELL_INFO_TYPE_GSM;
41   // INT*_MAX == unknown
42   cell->CellInfo.gsm.cellIdentityGsm.mcc = INT32_MAX;
43   cell->CellInfo.gsm.cellIdentityGsm.mnc = INT32_MAX;
44   cell->CellInfo.gsm.cellIdentityGsm.lac = INT32_MAX;
45   cell->CellInfo.gsm.cellIdentityGsm.cid = INT32_MAX;
46   cell->CellInfo.gsm.cellIdentityGsm.arfcn = INT32_MAX;
47   cell->CellInfo.gsm.cellIdentityGsm.bsic = INT8_MAX;
48   cell->CellInfo.gsm.signalStrengthGsm.signalStrength = INT32_MAX;
49   cell->CellInfo.gsm.signalStrengthGsm.signalStrength = INT32_MAX;
50   cell->CellInfo.gsm.signalStrengthGsm.signalStrength = INT32_MAX;
51 
52   result->cellInfoCount = 1;
53   result->errorCode = CHRE_ERROR_NONE;
54   result->cells = cell.release();
55 
56   gCallbacks->cellInfoResultCallback(result.release());
57 }
58 
stopCellInfoThread()59 void stopCellInfoThread() {
60   if (gCellInfosThread.joinable()) {
61     gCellInfosThread.join();
62   }
63 }
64 
chrePalWwanGetCapabilities()65 uint32_t chrePalWwanGetCapabilities() {
66   return CHRE_WWAN_GET_CELL_INFO;
67 }
68 
chrePalWwanRequestCellInfo()69 bool chrePalWwanRequestCellInfo() {
70   stopCellInfoThread();
71 
72   gCellInfosThread = std::thread(sendCellInfoResult);
73 
74   return true;
75 }
76 
chrePalWwanReleaseCellInfoResult(struct chreWwanCellInfoResult * result)77 void chrePalWwanReleaseCellInfoResult(struct chreWwanCellInfoResult *result) {
78   for (uint8_t i = 0; i < result->cellInfoCount; i++) {
79     chre::memoryFree(const_cast<struct chreWwanCellInfo *>(&result->cells[i]));
80   }
81   chre::memoryFree(result);
82 }
83 
chrePalWwanApiClose()84 void chrePalWwanApiClose() {
85   stopCellInfoThread();
86 }
87 
chrePalWwanApiOpen(const struct chrePalSystemApi * systemApi,const struct chrePalWwanCallbacks * callbacks)88 bool chrePalWwanApiOpen(const struct chrePalSystemApi *systemApi,
89                         const struct chrePalWwanCallbacks *callbacks) {
90   chrePalWwanApiClose();
91 
92   bool success = false;
93   if (systemApi != nullptr && callbacks != nullptr) {
94     gSystemApi = systemApi;
95     gCallbacks = callbacks;
96     success = true;
97   }
98 
99   return success;
100 }
101 
102 }  // anonymous namespace
103 
chrePalWwanGetApi(uint32_t requestedApiVersion)104 const struct chrePalWwanApi *chrePalWwanGetApi(uint32_t requestedApiVersion) {
105   static const struct chrePalWwanApi kApi = {
106       .moduleVersion = CHRE_PAL_WWAN_API_CURRENT_VERSION,
107       .open = chrePalWwanApiOpen,
108       .close = chrePalWwanApiClose,
109       .getCapabilities = chrePalWwanGetCapabilities,
110       .requestCellInfo = chrePalWwanRequestCellInfo,
111       .releaseCellInfoResult = chrePalWwanReleaseCellInfoResult,
112   };
113 
114   if (!CHRE_PAL_VERSIONS_ARE_COMPATIBLE(kApi.moduleVersion,
115                                         requestedApiVersion)) {
116     return nullptr;
117   } else {
118     return &kApi;
119   }
120 }
121