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