blob: 85c5a07d46e25c3fd3b3ce892a081fce4a85bd79 [file] [log] [blame]
Casey Dahlin6cd5e0b2016-05-06 16:19:13 -07001/*
2 * Copyright (C) 2016 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 "sysdeps.h"
18
19#include <chrono>
20#include <dns_sd.h>
21#include <endian.h>
22#include <mutex>
23#include <unistd.h>
24
25#include <android-base/logging.h>
26#include <android-base/properties.h>
27
28using namespace std::chrono_literals;
29
30static std::mutex& mdns_lock = *new std::mutex();
31static int port;
32static DNSServiceRef mdns_ref;
33static bool mdns_registered = false;
34
35static void start_mdns() {
36 if (android::base::GetProperty("init.svc.mdnsd", "") == "running") {
37 return;
38 }
39
40 android::base::SetProperty("ctl.start", "mdnsd");
41
42 if (! android::base::WaitForProperty("init.svc.mdnsd", "running", 5s)) {
43 LOG(ERROR) << "Could not start mdnsd.";
44 }
45}
46
47static void mdns_callback(DNSServiceRef /*ref*/,
48 DNSServiceFlags /*flags*/,
49 DNSServiceErrorType errorCode,
50 const char* /*name*/,
51 const char* /*regtype*/,
52 const char* /*domain*/,
53 void* /*context*/) {
54 if (errorCode != kDNSServiceErr_NoError) {
55 LOG(ERROR) << "Encountered mDNS registration error ("
56 << errorCode << ").";
57 }
58}
59
60static void setup_mdns_thread(void* /* unused */) {
61 start_mdns();
62 std::lock_guard<std::mutex> lock(mdns_lock);
63
64 auto error = DNSServiceRegister(&mdns_ref, 0, 0, nullptr, "_adb._tcp",
65 nullptr, nullptr, htobe16((uint16_t)port),
66 0, nullptr, mdns_callback, nullptr);
67
68 if (error != kDNSServiceErr_NoError) {
69 LOG(ERROR) << "Could not register mDNS service (" << error << ").";
70 mdns_registered = false;
71 }
72
73 mdns_registered = true;
74}
75
76static void teardown_mdns() {
77 std::lock_guard<std::mutex> lock(mdns_lock);
78
79 if (mdns_registered) {
80 DNSServiceRefDeallocate(mdns_ref);
81 }
82}
83
84void setup_mdns(int port_in) {
85 port = port_in;
86 adb_thread_create(setup_mdns_thread, nullptr, nullptr);
87
88 // TODO: Make this more robust against a hard kill.
89 atexit(teardown_mdns);
90}