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