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 <chrono> 18 #include <string> 19 #include <thread> 20 21 #include <android-base/logging.h> 22 #include <android-base/properties.h> 23 #include <hidl/HidlTransportSupport.h> 24 #include <utils/StrongPointer.h> 25 26 // Select the implementation 27 #include <esecpp/NxpPn80tNqNci.h> 28 using EseInterfaceImpl = android::NxpPn80tNqNci; 29 30 #include "Weaver.h" 31 32 using android::OK; 33 using android::sp; 34 using android::status_t; 35 using android::hardware::configureRpcThreadpool; 36 using android::hardware::joinRpcThreadpool; 37 38 using namespace std::chrono_literals; 39 40 // HALs 41 using android::esed::Weaver; 42 main(int,char **)43int main(int /* argc */, char** /* argv */) { 44 LOG(INFO) << "Waiting for property..."; 45 android::base::WaitForProperty("init.svc.vendor.ese_load", "stopped"); 46 LOG(INFO) << "Starting esed..."; 47 48 // Open connection to the eSE 49 EseInterfaceImpl ese; 50 uint32_t failCount = 0; 51 while (true) { 52 ese.init(); 53 if (ese.open() < 0) { 54 std::string errMsg = "Failed to open connection to eSE"; 55 if (ese.error()) { 56 errMsg += " (" + std::to_string(ese.error_code()) + "): " + ese.error_message(); 57 } else { 58 errMsg += ": reason unknown"; 59 } 60 LOG(ERROR) << errMsg; 61 62 // FIXME: this loop with sleep is a hack to avoid the process repeatedly crashing 63 ++failCount; 64 std::this_thread::sleep_for(failCount * 5s); 65 continue; 66 } 67 LOG(INFO) << "Opened connection to the eSE"; 68 break; 69 } 70 // Close it until use. 71 ese.close(); 72 73 74 // This will be a single threaded daemon. This is important as libese is not 75 // thread safe so we use binder to synchronize requests for us. 76 constexpr bool thisThreadWillJoinPool = true; 77 configureRpcThreadpool(1, thisThreadWillJoinPool); 78 79 // Create Weaver HAL instance 80 sp<Weaver> weaver = new Weaver{ese}; 81 const status_t status = weaver->registerAsService(); 82 if (status != OK) { 83 LOG(ERROR) << "Failed to register Weaver as a service (status: " << status << ")"; 84 } 85 86 87 joinRpcThreadpool(); 88 return -1; // Should never reach here 89 } 90