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, 35 const void *cookie) { 36 CHRE_ASSERT(nanoapp); 37 38 bool success = false; 39 if (!mCellInfoRequestingNanoappInstanceId.has_value()) { 40 success = mPlatformWwan.requestCellInfo(); 41 if (success) { 42 nanoapp->registerForBroadcastEvent(CHRE_EVENT_WWAN_CELL_INFO_RESULT); 43 mCellInfoRequestingNanoappInstanceId = nanoapp->getInstanceId(); 44 mCellInfoRequestingNanoappCookie = cookie; 45 } 46 } else { 47 LOGE("Cell info request made while a request is in flight"); 48 } 49 50 return success; 51 } 52 53 void WwanRequestManager::handleCellInfoResult(chreWwanCellInfoResult *result) { 54 auto callback = [](uint16_t /* eventType */, void *eventData) { 55 auto *cellInfoResult = static_cast<chreWwanCellInfoResult *>(eventData); 56 EventLoopManagerSingleton::get()->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 bool eventPosted = EventLoopManagerSingleton::get()->getEventLoop() 69 .postEvent(CHRE_EVENT_WWAN_CELL_INFO_RESULT, result, 70 freeCellInfoResultCallback, kSystemInstanceId, 71 mCellInfoRequestingNanoappInstanceId.value()); 72 if (!eventPosted) { 73 FATAL_ERROR("Failed to send WWAN cell info event"); 74 } 75 } else { 76 LOGE("Cell info results received unexpectedly"); 77 } 78 } 79 80 bool WwanRequestManager::logStateToBuffer(char *buffer, size_t *bufferPos, 81 size_t bufferSize) const { 82 bool success = debugDumpPrint(buffer, bufferPos, bufferSize, "\nWWAN:\n"); 83 if (mCellInfoRequestingNanoappInstanceId.has_value()) { 84 success &= debugDumpPrint(buffer, bufferPos, bufferSize, 85 " WWAN request pending nanoappId=%" PRIu32 "\n", 86 mCellInfoRequestingNanoappInstanceId.value()); 87 } 88 return success; 89 } 90 91 void WwanRequestManager::handleFreeCellInfoResult( 92 chreWwanCellInfoResult *result) { 93 if (mCellInfoRequestingNanoappInstanceId.has_value()) { 94 Nanoapp *nanoapp = EventLoopManagerSingleton::get()->getEventLoop() 95 .findNanoappByInstanceId(*mCellInfoRequestingNanoappInstanceId); 96 if (nanoapp != nullptr) { 97 nanoapp->unregisterForBroadcastEvent(CHRE_EVENT_WWAN_CELL_INFO_RESULT); 98 } else { 99 LOGE("Freeing cell info for non-existent nanoapp"); 100 } 101 102 mCellInfoRequestingNanoappInstanceId.reset(); 103 } else { 104 LOGE("Cell info released with no pending request"); 105 } 106 107 mPlatformWwan.releaseCellInfoResult(result); 108 } 109 110 void WwanRequestManager::freeCellInfoResultCallback(uint16_t eventType, 111 void *eventData) { 112 auto *result = static_cast<chreWwanCellInfoResult *>(eventData); 113 EventLoopManagerSingleton::get()->getWwanRequestManager() 114 .handleFreeCellInfoResult(result); 115 } 116 117 } // namespace chre 118