| /* | |
| * Copyright (C) 2016 The Android Open Source Project | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); | |
| * you may not use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| #include "adb_mdns.h" | |
| #include "sysdeps.h" | |
| #include <dns_sd.h> | |
| #include <endian.h> | |
| #include <unistd.h> | |
| #include <chrono> | |
| #include <mutex> | |
| #include <thread> | |
| #include <android-base/logging.h> | |
| #include <android-base/properties.h> | |
| using namespace std::chrono_literals; | |
| static std::mutex& mdns_lock = *new std::mutex(); | |
| static int port; | |
| static DNSServiceRef mdns_ref; | |
| static bool mdns_registered = false; | |
| static void start_mdns() { | |
| if (android::base::GetProperty("init.svc.mdnsd", "") == "running") { | |
| return; | |
| } | |
| android::base::SetProperty("ctl.start", "mdnsd"); | |
| if (! android::base::WaitForProperty("init.svc.mdnsd", "running", 5s)) { | |
| LOG(ERROR) << "Could not start mdnsd."; | |
| } | |
| } | |
| static void mdns_callback(DNSServiceRef /*ref*/, | |
| DNSServiceFlags /*flags*/, | |
| DNSServiceErrorType errorCode, | |
| const char* /*name*/, | |
| const char* /*regtype*/, | |
| const char* /*domain*/, | |
| void* /*context*/) { | |
| if (errorCode != kDNSServiceErr_NoError) { | |
| LOG(ERROR) << "Encountered mDNS registration error (" | |
| << errorCode << ")."; | |
| } | |
| } | |
| static void setup_mdns_thread() { | |
| start_mdns(); | |
| std::lock_guard<std::mutex> lock(mdns_lock); | |
| std::string hostname = "adb-"; | |
| hostname += android::base::GetProperty("ro.serialno", "unidentified"); | |
| auto error = DNSServiceRegister(&mdns_ref, 0, 0, hostname.c_str(), | |
| kADBServiceType, nullptr, nullptr, | |
| htobe16((uint16_t)port), 0, nullptr, | |
| mdns_callback, nullptr); | |
| if (error != kDNSServiceErr_NoError) { | |
| LOG(ERROR) << "Could not register mDNS service (" << error << ")."; | |
| mdns_registered = false; | |
| } | |
| mdns_registered = true; | |
| } | |
| static void teardown_mdns() { | |
| std::lock_guard<std::mutex> lock(mdns_lock); | |
| if (mdns_registered) { | |
| DNSServiceRefDeallocate(mdns_ref); | |
| } | |
| } | |
| void setup_mdns(int port_in) { | |
| port = port_in; | |
| std::thread(setup_mdns_thread).detach(); | |
| // TODO: Make this more robust against a hard kill. | |
| atexit(teardown_mdns); | |
| } |