xref: /aosp_15_r20/system/chre/core/wwan_request_manager.cc (revision 84e339476a462649f82315436d70fd732297a399)
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 
17 #ifdef CHRE_WWAN_SUPPORT_ENABLED
18 
19 #include "chre/core/wwan_request_manager.h"
20 
21 #include "chre/core/event_loop_manager.h"
22 #include "chre/platform/fatal_error.h"
23 #include "chre/platform/log.h"
24 #include "chre/util/system/debug_dump.h"
25 
26 namespace chre {
27 
init()28 void WwanRequestManager::init() {
29   return mPlatformWwan.init();
30 }
31 
getCapabilities()32 uint32_t WwanRequestManager::getCapabilities() {
33   return mPlatformWwan.getCapabilities();
34 }
35 
requestCellInfo(Nanoapp * nanoapp,const void * cookie)36 bool WwanRequestManager::requestCellInfo(Nanoapp *nanoapp, const void *cookie) {
37   CHRE_ASSERT(nanoapp);
38 
39   bool success = false;
40   if (!mCellInfoRequestingNanoappInstanceId.has_value()) {
41     success = mPlatformWwan.requestCellInfo();
42     if (success) {
43       nanoapp->registerForBroadcastEvent(CHRE_EVENT_WWAN_CELL_INFO_RESULT);
44       mCellInfoRequestingNanoappInstanceId = nanoapp->getInstanceId();
45       mCellInfoRequestingNanoappCookie = cookie;
46     }
47   } else {
48     LOGE("Cell info request made while a request is in flight");
49   }
50 
51   return success;
52 }
53 
handleCellInfoResult(struct chreWwanCellInfoResult * result)54 void WwanRequestManager::handleCellInfoResult(
55     struct chreWwanCellInfoResult *result) {
56   auto callback = [](uint16_t /*type*/, void *data, void * /*extraData*/) {
57     auto *cellInfoResult = static_cast<chreWwanCellInfoResult *>(data);
58     EventLoopManagerSingleton::get()
59         ->getWwanRequestManager()
60         .handleCellInfoResultSync(cellInfoResult);
61   };
62 
63   EventLoopManagerSingleton::get()->deferCallback(
64       SystemCallbackType::WwanHandleCellInfoResult, result, callback);
65 }
66 
handleCellInfoResultSync(chreWwanCellInfoResult * result)67 void WwanRequestManager::handleCellInfoResultSync(
68     chreWwanCellInfoResult *result) {
69   if (mCellInfoRequestingNanoappInstanceId.has_value()) {
70     result->cookie = mCellInfoRequestingNanoappCookie;
71 
72     uint8_t errorCode = result->errorCode;
73     if (errorCode < CHRE_ERROR_SIZE) {
74       mCellInfoErrorHistogram[errorCode]++;
75     } else {
76       LOGE("Undefined error in cellInfoResult: %" PRIu8, errorCode);
77     }
78 
79     EventLoopManagerSingleton::get()->getEventLoop().postEventOrDie(
80         CHRE_EVENT_WWAN_CELL_INFO_RESULT, result, freeCellInfoResultCallback,
81         mCellInfoRequestingNanoappInstanceId.value());
82   } else {
83     LOGE("Cell info results received unexpectedly");
84   }
85 }
86 
logStateToBuffer(DebugDumpWrapper & debugDump) const87 void WwanRequestManager::logStateToBuffer(DebugDumpWrapper &debugDump) const {
88   debugDump.print("\nWWAN:\n");
89   if (mCellInfoRequestingNanoappInstanceId.has_value()) {
90     debugDump.print(" WWAN request pending nanoappId=%" PRIu16 "\n",
91                     mCellInfoRequestingNanoappInstanceId.value());
92   }
93 
94   debugDump.print(" API error distribution (error-code indexed):\n");
95   debugDump.print("   Cell Scan:\n");
96   debugDump.logErrorHistogram(mCellInfoErrorHistogram,
97                               ARRAY_SIZE(mCellInfoErrorHistogram));
98 }
99 
handleFreeCellInfoResult(chreWwanCellInfoResult * result)100 void WwanRequestManager::handleFreeCellInfoResult(
101     chreWwanCellInfoResult *result) {
102   if (mCellInfoRequestingNanoappInstanceId.has_value()) {
103     Nanoapp *nanoapp =
104         EventLoopManagerSingleton::get()
105             ->getEventLoop()
106             .findNanoappByInstanceId(*mCellInfoRequestingNanoappInstanceId);
107     if (nanoapp != nullptr) {
108       nanoapp->unregisterForBroadcastEvent(CHRE_EVENT_WWAN_CELL_INFO_RESULT);
109     } else {
110       LOGE("Freeing cell info for non-existent nanoapp");
111     }
112 
113     mCellInfoRequestingNanoappInstanceId.reset();
114   } else {
115     LOGE("Cell info released with no pending request");
116   }
117 
118   mPlatformWwan.releaseCellInfoResult(result);
119 }
120 
freeCellInfoResultCallback(uint16_t eventType,void * eventData)121 void WwanRequestManager::freeCellInfoResultCallback(uint16_t eventType,
122                                                     void *eventData) {
123   UNUSED_VAR(eventType);
124 
125   auto *result = static_cast<chreWwanCellInfoResult *>(eventData);
126   EventLoopManagerSingleton::get()
127       ->getWwanRequestManager()
128       .handleFreeCellInfoResult(result);
129 }
130 
131 }  // namespace chre
132 
133 #endif  // CHRE_WWAN_SUPPORT_ENABLED
134