/*
 * Copyright (C) 2010 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 "MDnsSdListener.h"

#include <arpa/inet.h>
#include <dirent.h>
#include <errno.h>
#include <linux/if.h>
#include <netdb.h>
#include <netinet/in.h>
#include <pthread.h>
#include <resolv.h>
#include <stdlib.h>
#include <string.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/types.h>

#define LOG_TAG "MDnsDS"
#define DBG 1
#define VDBG 1

#include <cutils/properties.h>
#include <log/log.h>
#include <netdutils/ResponseCode.h>
#include <netdutils/ThreadUtil.h>
#include <sysutils/SocketClient.h>

#define MDNS_SERVICE_NAME "mdnsd"
#define MDNS_SERVICE_STATUS "init.svc.mdnsd"

#define CEIL(x, y) (((x) + (y) - 1) / (y))

constexpr char RESCAN[] = "1";

using android::netdutils::ResponseCode;

MDnsSdListener::MDnsSdListener() : FrameworkListener(SOCKET_NAME, true) {
    Monitor *m = new Monitor();
    registerCmd(new Handler(m, this));
}

MDnsSdListener::Handler::Handler(Monitor *m, MDnsSdListener *listener) :
   NetdCommand("mdnssd") {
   if (DBG) ALOGD("MDnsSdListener::Hander starting up");
   mMonitor = m;
   mListener = listener;
}

MDnsSdListener::Handler::~Handler() {}

void MDnsSdListener::Handler::discover(SocketClient *cli,
        const char *iface,
        const char *regType,
        const char *domain,
        const int requestId,
        const int requestFlags) {
    if (VDBG) {
        ALOGD("discover(%s, %s, %s, %d, %d)", iface, regType, domain, requestId,
                requestFlags);
    }
    Context *context = new Context(requestId, mListener);
    DNSServiceRef *ref = mMonitor->allocateServiceRef(requestId, context);
    if (ref == nullptr) {
        ALOGE("requestId %d already in use during discover call", requestId);
        cli->sendMsg(ResponseCode::CommandParameterError,
                "RequestId already in use during discover call", false);
        return;
    }
    if (VDBG) ALOGD("using ref %p", ref);
    DNSServiceFlags nativeFlags = iToFlags(requestFlags);
    int interfaceInt = ifaceNameToI(iface);

    DNSServiceErrorType result = DNSServiceBrowse(ref, nativeFlags, interfaceInt, regType,
            domain, &MDnsSdListenerDiscoverCallback, context);
    if (result != kDNSServiceErr_NoError) {
        ALOGE("Discover request %d got an error from DNSServiceBrowse %d", requestId, result);
        mMonitor->freeServiceRef(requestId);
        cli->sendMsg(ResponseCode::CommandParameterError,
                "Discover request got an error from DNSServiceBrowse", false);
        return;
    }
    mMonitor->startMonitoring(requestId);
    if (VDBG) ALOGD("discover successful");
    cli->sendMsg(ResponseCode::CommandOkay, "Discover operation started", false);
    return;
}

void MDnsSdListenerDiscoverCallback(DNSServiceRef /* sdRef */, DNSServiceFlags flags,
        uint32_t /* interfaceIndex */, DNSServiceErrorType errorCode, const char *serviceName,
        const char *regType, const char *replyDomain, void *inContext) {
    MDnsSdListener::Context *context = reinterpret_cast<MDnsSdListener::Context *>(inContext);
    char *msg;
    int refNumber = context->mRefNumber;

    if (errorCode != kDNSServiceErr_NoError) {
        asprintf(&msg, "%d %d", refNumber, errorCode);
        context->mListener->sendBroadcast(ResponseCode::ServiceDiscoveryFailed, msg, false);
        if (DBG) ALOGE("discover failure for %d, error= %d", refNumber, errorCode);
    } else {
        int respCode;
        char *quotedServiceName = SocketClient::quoteArg(serviceName);
        if (flags & kDNSServiceFlagsAdd) {
            if (VDBG) {
                ALOGD("Discover found new serviceName %s, regType %s and domain %s for %d",
                        serviceName, regType, replyDomain, refNumber);
            }
            respCode = ResponseCode::ServiceDiscoveryServiceAdded;
        } else {
            if (VDBG) {
                ALOGD("Discover lost serviceName %s, regType %s and domain %s for %d",
                        serviceName, regType, replyDomain, refNumber);
            }
            respCode = ResponseCode::ServiceDiscoveryServiceRemoved;
        }
        asprintf(&msg, "%d %s %s %s", refNumber, quotedServiceName, regType, replyDomain);
        free(quotedServiceName);
        context->mListener->sendBroadcast(respCode, msg, false);
    }
    free(msg);
}

void MDnsSdListener::Handler::stop(SocketClient *cli, int argc, char **argv, const char *str) {
    if (argc != 3) {
        char *msg;
        asprintf(&msg, "Invalid number of arguments to %s", str);
        cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
        free(msg);
        return;
    }
    int requestId = strtol(argv[2], nullptr, 10);
    DNSServiceRef *ref = mMonitor->lookupServiceRef(requestId);
    if (ref == nullptr) {
        if (DBG) ALOGE("%s stop used unknown requestId %d", str, requestId);
        cli->sendMsg(ResponseCode::CommandParameterError, "Unknown requestId", false);
        return;
    }
    if (VDBG) ALOGD("Stopping %s with ref %p", str, ref);
    mMonitor->deallocateServiceRef(ref);
    mMonitor->freeServiceRef(requestId);
    char *msg;
    asprintf(&msg, "%s stopped", str);
    cli->sendMsg(ResponseCode::CommandOkay, msg, false);
    free(msg);
}

void MDnsSdListener::Handler::serviceRegister(SocketClient *cli, int requestId,
        const char *interfaceName, const char *serviceName, const char *serviceType,
        const char *domain, const char *host, int port, int txtLen, void *txtRecord) {
    if (VDBG) {
        ALOGD("serviceRegister(%d, %s, %s, %s, %s, %s, %d, %d, <binary>)", requestId,
                interfaceName, serviceName, serviceType, domain, host, port, txtLen);
    }
    Context *context = new Context(requestId, mListener);
    DNSServiceRef *ref = mMonitor->allocateServiceRef(requestId, context);
    port = htons(port);
    if (ref == nullptr) {
        ALOGE("requestId %d already in use during register call", requestId);
        cli->sendMsg(ResponseCode::CommandParameterError,
                "RequestId already in use during register call", false);
        return;
    }
    DNSServiceFlags nativeFlags = 0;
    int interfaceInt = ifaceNameToI(interfaceName);
    DNSServiceErrorType result = DNSServiceRegister(ref, interfaceInt, nativeFlags, serviceName,
            serviceType, domain, host, port, txtLen, txtRecord, &MDnsSdListenerRegisterCallback,
            context);
    if (result != kDNSServiceErr_NoError) {
        ALOGE("service register request %d got an error from DNSServiceRegister %d", requestId,
                result);
        mMonitor->freeServiceRef(requestId);
        cli->sendMsg(ResponseCode::CommandParameterError,
                "serviceRegister request got an error from DNSServiceRegister", false);
        return;
    }
    mMonitor->startMonitoring(requestId);
    if (VDBG) ALOGD("serviceRegister successful");
    cli->sendMsg(ResponseCode::CommandOkay, "serviceRegister started", false);
    return;
}

void MDnsSdListenerRegisterCallback(DNSServiceRef /* sdRef */, DNSServiceFlags /* flags */,
        DNSServiceErrorType errorCode, const char *serviceName, const char * /* regType */,
        const char * /* domain */, void *inContext) {
    MDnsSdListener::Context *context = reinterpret_cast<MDnsSdListener::Context *>(inContext);
    char *msg;
    int refNumber = context->mRefNumber;
    if (errorCode != kDNSServiceErr_NoError) {
        asprintf(&msg, "%d %d", refNumber, errorCode);
        context->mListener->sendBroadcast(ResponseCode::ServiceRegistrationFailed, msg, false);
        if (DBG) ALOGE("register failure for %d, error= %d", refNumber, errorCode);
    } else {
        char *quotedServiceName = SocketClient::quoteArg(serviceName);
        asprintf(&msg, "%d %s", refNumber, quotedServiceName);
        free(quotedServiceName);
        context->mListener->sendBroadcast(ResponseCode::ServiceRegistrationSucceeded, msg, false);
        if (VDBG) ALOGD("register succeeded for %d as %s", refNumber, serviceName);
    }
    free(msg);
}


void MDnsSdListener::Handler::resolveService(SocketClient *cli, int requestId,
        const char *interfaceName, const char *serviceName, const char *regType,
        const char *domain) {
    if (VDBG) {
        ALOGD("resolveService(%d, %s, %s, %s, %s)", requestId, interfaceName,
                serviceName, regType, domain);
    }
    Context *context = new Context(requestId, mListener);
    DNSServiceRef *ref = mMonitor->allocateServiceRef(requestId, context);
    if (ref == nullptr) {
        ALOGE("request Id %d already in use during resolve call", requestId);
        cli->sendMsg(ResponseCode::CommandParameterError,
                "RequestId already in use during resolve call", false);
        return;
    }
    DNSServiceFlags nativeFlags = 0;
    int interfaceInt = ifaceNameToI(interfaceName);
    DNSServiceErrorType result = DNSServiceResolve(ref, nativeFlags, interfaceInt, serviceName,
            regType, domain, &MDnsSdListenerResolveCallback, context);
    if (result != kDNSServiceErr_NoError) {
        ALOGE("service resolve request %d got an error from DNSServiceResolve %d", requestId,
                result);
        mMonitor->freeServiceRef(requestId);
        cli->sendMsg(ResponseCode::CommandParameterError,
                "resolveService got an error from DNSServiceResolve", false);
        return;
    }
    mMonitor->startMonitoring(requestId);
    if (VDBG) ALOGD("resolveService successful");
    cli->sendMsg(ResponseCode::CommandOkay, "resolveService started", false);
    return;
}

void MDnsSdListenerResolveCallback(DNSServiceRef /* sdRef */, DNSServiceFlags /* flags */,
        uint32_t /* interface */, DNSServiceErrorType errorCode, const char *fullname,
        const char *hosttarget, uint16_t port, uint16_t txtLen,
        const unsigned char *txtRecord , void *inContext) {
    MDnsSdListener::Context *context = reinterpret_cast<MDnsSdListener::Context *>(inContext);
    char *msg;
    int refNumber = context->mRefNumber;
    port = ntohs(port);
    if (errorCode != kDNSServiceErr_NoError) {
        asprintf(&msg, "%d %d", refNumber, errorCode);
        context->mListener->sendBroadcast(ResponseCode::ServiceResolveFailed, msg, false);
        if (DBG) ALOGE("resolve failure for %d, error= %d", refNumber, errorCode);
    } else {
        char *quotedFullName = SocketClient::quoteArg(fullname);
        char *quotedHostTarget = SocketClient::quoteArg(hosttarget);

        // Base 64 encodes every 3 bytes into 4 characters, but then adds padding to the next
        // multiple of 4 and a \0
        size_t dstLength = CEIL(CEIL(txtLen * 4, 3), 4) * 4 + 1;

        char *dst = (char *)malloc(dstLength);
        b64_ntop(txtRecord, txtLen, dst, dstLength);

        asprintf(&msg, "%d %s %s %d %d \"%s\"", refNumber, quotedFullName, quotedHostTarget, port,
                 txtLen, dst);
        free(quotedFullName);
        free(quotedHostTarget);
        free(dst);
        context->mListener->sendBroadcast(ResponseCode::ServiceResolveSuccess, msg, false);
        if (VDBG) {
            ALOGD("resolve succeeded for %d finding %s at %s:%d with txtLen %d",
                    refNumber, fullname, hosttarget, port, txtLen);
        }
    }
    free(msg);
}

void MDnsSdListener::Handler::getAddrInfo(SocketClient *cli, int requestId,
        const char *interfaceName, uint32_t protocol, const char *hostname) {
    if (VDBG) ALOGD("getAddrInfo(%d, %s %d, %s)", requestId, interfaceName, protocol, hostname);
    Context *context = new Context(requestId, mListener);
    DNSServiceRef *ref = mMonitor->allocateServiceRef(requestId, context);
    if (ref == nullptr) {
        ALOGE("request ID %d already in use during getAddrInfo call", requestId);
        cli->sendMsg(ResponseCode::CommandParameterError,
                "RequestId already in use during getAddrInfo call", false);
        return;
    }
    DNSServiceFlags nativeFlags = 0;
    int interfaceInt = ifaceNameToI(interfaceName);
    DNSServiceErrorType result = DNSServiceGetAddrInfo(ref, nativeFlags, interfaceInt, protocol,
            hostname, &MDnsSdListenerGetAddrInfoCallback, context);
    if (result != kDNSServiceErr_NoError) {
        ALOGE("getAddrInfo request %d got an error from DNSServiceGetAddrInfo %d", requestId,
                result);
        mMonitor->freeServiceRef(requestId);
        cli->sendMsg(ResponseCode::CommandParameterError,
                "getAddrInfo request got an error from DNSServiceGetAddrInfo", false);
        return;
    }
    mMonitor->startMonitoring(requestId);
    if (VDBG) ALOGD("getAddrInfo successful");
    cli->sendMsg(ResponseCode::CommandOkay, "getAddrInfo started", false);
    return;
}

void MDnsSdListenerGetAddrInfoCallback(DNSServiceRef /* sdRef */, DNSServiceFlags /* flags */,
        uint32_t /* interface */, DNSServiceErrorType errorCode, const char *hostname,
        const struct sockaddr *const sa, uint32_t ttl, void *inContext) {
    MDnsSdListener::Context *context = reinterpret_cast<MDnsSdListener::Context *>(inContext);
    int refNumber = context->mRefNumber;

    if (errorCode != kDNSServiceErr_NoError) {
        char *msg;
        asprintf(&msg, "%d %d", refNumber, errorCode);
        context->mListener->sendBroadcast(ResponseCode::ServiceGetAddrInfoFailed, msg, false);
        if (DBG) ALOGE("getAddrInfo failure for %d, error= %d", refNumber, errorCode);
        free(msg);
    } else {
        char addr[INET6_ADDRSTRLEN];
        char *msg;
        char *quotedHostname = SocketClient::quoteArg(hostname);
        if (sa->sa_family == AF_INET) {
            inet_ntop(sa->sa_family, &(((struct sockaddr_in *)sa)->sin_addr), addr, sizeof(addr));
        } else {
            inet_ntop(sa->sa_family, &(((struct sockaddr_in6 *)sa)->sin6_addr), addr, sizeof(addr));
        }
        asprintf(&msg, "%d %s %d %s", refNumber, quotedHostname, ttl, addr);
        free(quotedHostname);
        context->mListener->sendBroadcast(ResponseCode::ServiceGetAddrInfoSuccess, msg, false);
        if (VDBG) {
            ALOGD("getAddrInfo succeeded for %d: %s", refNumber, msg);
        }
        free(msg);
    }
}

void MDnsSdListener::Handler::setHostname(SocketClient *cli, int requestId,
        const char *hostname) {
    if (VDBG) ALOGD("setHostname(%d, %s)", requestId, hostname);
    Context *context = new Context(requestId, mListener);
    DNSServiceRef *ref = mMonitor->allocateServiceRef(requestId, context);
    if (ref == nullptr) {
        ALOGE("request Id %d already in use during setHostname call", requestId);
        cli->sendMsg(ResponseCode::CommandParameterError,
                "RequestId already in use during setHostname call", false);
        return;
    }
    DNSServiceFlags nativeFlags = 0;
    DNSServiceErrorType result = DNSSetHostname(ref, nativeFlags, hostname,
            &MDnsSdListenerSetHostnameCallback, context);
    if (result != kDNSServiceErr_NoError) {
        ALOGE("setHostname request %d got an error from DNSSetHostname %d", requestId, result);
        mMonitor->freeServiceRef(requestId);
        cli->sendMsg(ResponseCode::CommandParameterError,
                "setHostname got an error from DNSSetHostname", false);
        return;
    }
    mMonitor->startMonitoring(requestId);
    if (VDBG) ALOGD("setHostname successful");
    cli->sendMsg(ResponseCode::CommandOkay, "setHostname started", false);
    return;
}

void MDnsSdListenerSetHostnameCallback(DNSServiceRef /* sdRef */, DNSServiceFlags /* flags */,
        DNSServiceErrorType errorCode, const char *hostname, void *inContext) {
    MDnsSdListener::Context *context = reinterpret_cast<MDnsSdListener::Context *>(inContext);
    char *msg;
    int refNumber = context->mRefNumber;
    if (errorCode != kDNSServiceErr_NoError) {
        asprintf(&msg, "%d %d", refNumber, errorCode);
        context->mListener->sendBroadcast(ResponseCode::ServiceSetHostnameFailed, msg, false);
        if (DBG) ALOGE("setHostname failure for %d, error= %d", refNumber, errorCode);
    } else {
        char *quotedHostname = SocketClient::quoteArg(hostname);
        asprintf(&msg, "%d %s", refNumber, quotedHostname);
        free(quotedHostname);
        context->mListener->sendBroadcast(ResponseCode::ServiceSetHostnameSuccess, msg, false);
        if (VDBG) ALOGD("setHostname succeeded for %d.  Set to %s", refNumber, hostname);
    }
    free(msg);
}


int MDnsSdListener::Handler::ifaceNameToI(const char * /* iface */) {
    return 0;
}

const char *MDnsSdListener::Handler::iToIfaceName(int /* i */) {
    return nullptr;
}

DNSServiceFlags MDnsSdListener::Handler::iToFlags(int /* i */) {
    return 0;
}

int MDnsSdListener::Handler::flagsToI(DNSServiceFlags /* flags */) {
    return 0;
}

int MDnsSdListener::Handler::runCommand(SocketClient *cli,
                                        int argc, char **argv) {
    if (argc < 2) {
        char* msg = nullptr;
        asprintf( &msg, "Invalid number of arguments to mdnssd: %i", argc);
        ALOGW("%s", msg);
        cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
        free(msg);
        return -1;
    }

    char* cmd = argv[1];

    if (strcmp(cmd, "discover") == 0) {
        if (argc != 4) {
            cli->sendMsg(ResponseCode::CommandParameterError,
                    "Invalid number of arguments to mdnssd discover", false);
            return 0;
        }
        int requestId = strtol(argv[2], nullptr, 10);
        char *serviceType = argv[3];

        discover(cli, nullptr, serviceType, nullptr, requestId, 0);
    } else if (strcmp(cmd, "stop-discover") == 0) {
        stop(cli, argc, argv, "discover");
    } else if (strcmp(cmd, "register") == 0) {
        if (argc != 7) {
            cli->sendMsg(ResponseCode::CommandParameterError,
                    "Invalid number of arguments to mdnssd register", false);
            return 0;
        }
        int requestId = atoi(argv[2]);
        char *serviceName = argv[3];
        char *serviceType = argv[4];
        int port = strtol(argv[5], nullptr, 10);
        char *interfaceName = nullptr; // will use all
        char *domain = nullptr;        // will use default
        char *host = nullptr;          // will use default hostname

        // TXT record length is <= 1300, see NsdServiceInfo.setAttribute
        char dst[1300];

        int length = b64_pton(argv[6], (u_char *)dst, 1300);

        if (length < 0) {
           cli->sendMsg(ResponseCode::CommandParameterError,
                    "Could not decode txtRecord", false);
           return 0;
        }

        serviceRegister(cli, requestId, interfaceName, serviceName,
                serviceType, domain, host, port, length, dst);
    } else if (strcmp(cmd, "stop-register") == 0) {
        stop(cli, argc, argv, "register");
    } else if (strcmp(cmd, "resolve") == 0) {
        if (argc != 6) {
            cli->sendMsg(ResponseCode::CommandParameterError,
                    "Invalid number of arguments to mdnssd resolve", false);
            return 0;
        }
        int requestId = atoi(argv[2]);
        char *interfaceName = nullptr;  // will use all
        char *serviceName = argv[3];
        char *regType = argv[4];
        char *domain = argv[5];
        resolveService(cli, requestId, interfaceName, serviceName, regType, domain);
    } else if (strcmp(cmd, "stop-resolve") == 0) {
        stop(cli, argc, argv, "resolve");
    } else if (strcmp(cmd, "start-service") == 0) {
        if (mMonitor->startService()) {
            cli->sendMsg(ResponseCode::CommandOkay, "Service Started", false);
        } else {
            cli->sendMsg(ResponseCode::ServiceStartFailed, "Service already running", false);
        }
    } else if (strcmp(cmd, "stop-service") == 0) {
        if (mMonitor->stopService()) {
            cli->sendMsg(ResponseCode::CommandOkay, "Service Stopped", false);
        } else {
            cli->sendMsg(ResponseCode::ServiceStopFailed, "Service still in use", false);
        }
    } else if (strcmp(cmd, "sethostname") == 0) {
        if (argc != 4) {
            cli->sendMsg(ResponseCode::CommandParameterError,
                    "Invalid number of arguments to mdnssd sethostname", false);
            return 0;
        }
        int requestId = strtol(argv[2], nullptr, 10);
        char *hostname = argv[3];
        setHostname(cli, requestId, hostname);
    } else if (strcmp(cmd, "stop-sethostname") == 0) {
        stop(cli, argc, argv, "sethostname");
    } else if (strcmp(cmd, "getaddrinfo") == 0) {
        if (argc != 4) {
            cli->sendMsg(ResponseCode::CommandParameterError,
                    "Invalid number of arguments to mdnssd getaddrinfo", false);
            return 0;
        }
        int requestId = atoi(argv[2]);
        char *hostname = argv[3];
        char *interfaceName = nullptr;  // default
        int protocol = 0;            // intelligient heuristic (both v4 + v6)
        getAddrInfo(cli, requestId, interfaceName, protocol, hostname);
    } else if (strcmp(cmd, "stop-getaddrinfo") == 0) {
        stop(cli, argc, argv, "getaddrinfo");
    } else {
        if (VDBG) ALOGE("Unknown cmd %s", cmd);
        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown mdnssd cmd", false);
        return 0;
    }
    return 0;
}

MDnsSdListener::Monitor::Monitor() {
    mHead = nullptr;
    mLiveCount = 0;
    mPollFds = nullptr;
    mPollRefs = nullptr;
    mPollSize = 10;
    socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, mCtrlSocketPair);

    const int rval = ::android::netdutils::threadLaunch(this);
    if (rval != 0) {
        ALOGW("Error spawning monitor thread: %s (%d)", strerror(-rval), -rval);
    }
}

#define NAP_TIME 200  // 200 ms between polls
static int wait_for_property(const char *name, const char *desired_value, int maxwait)
{
    char value[PROPERTY_VALUE_MAX] = {'\0'};
    int maxnaps = (maxwait * 1000) / NAP_TIME;

    if (maxnaps < 1) {
        maxnaps = 1;
    }

    while (maxnaps-- > 0) {
        usleep(NAP_TIME * 1000);
        if (property_get(name, value, nullptr)) {
            if (desired_value == nullptr || strcmp(value, desired_value) == 0) {
                return 0;
            }
        }
    }
    return -1; /* failure */
}

int MDnsSdListener::Monitor::startService() {
    char property_value[PROPERTY_VALUE_MAX];
    std::lock_guard guard(mMutex);
    property_get(MDNS_SERVICE_STATUS, property_value, "");
    if (strcmp("running", property_value) != 0) {
        ALOGD("Starting MDNSD");
        property_set("ctl.start", MDNS_SERVICE_NAME);
        wait_for_property(MDNS_SERVICE_STATUS, "running", 5);
        return -1;
    }
    return 0;
}

int MDnsSdListener::Monitor::stopService() {
    std::lock_guard guard(mMutex);
    if (mHead == nullptr) {
        ALOGD("Stopping MDNSD");
        property_set("ctl.stop", MDNS_SERVICE_NAME);
        wait_for_property(MDNS_SERVICE_STATUS, "stopped", 5);
        return -1;
    }
    return 0;
}

void MDnsSdListener::Monitor::run() {
    int pollCount = 1;

    mPollFds = (struct pollfd *)calloc(sizeof(struct pollfd), mPollSize);
    mPollRefs = (DNSServiceRef **)calloc(sizeof(DNSServiceRef *), mPollSize);
    LOG_ALWAYS_FATAL_IF((mPollFds == nullptr), "initial calloc failed on mPollFds with a size of %d",
            ((int)sizeof(struct pollfd)) * mPollSize);
    LOG_ALWAYS_FATAL_IF((mPollRefs == nullptr), "initial calloc failed on mPollRefs with a size of %d",
            ((int)sizeof(DNSServiceRef *)) * mPollSize);

    mPollFds[0].fd = mCtrlSocketPair[0];
    mPollFds[0].events = POLLIN;

    if (VDBG) ALOGD("MDnsSdListener starting to monitor");
    while (1) {
        if (VDBG) ALOGD("Going to poll with pollCount %d", pollCount);
        int pollResults = poll(mPollFds, pollCount, 10000000);
        if (pollResults < 0) {
            ALOGE("Error in poll - got %d", errno);
        } else if (pollResults > 0) {
            if (VDBG) ALOGD("Monitor poll got data pollCount = %d, %d", pollCount, pollResults);
            for(int i = 1; i < pollCount; i++) {
                if (mPollFds[i].revents != 0) {
                    if (VDBG) {
                        ALOGD("Monitor found [%d].revents = %d - calling ProcessResults",
                                i, mPollFds[i].revents);
                    }
                    std::lock_guard guard(mMutex);
                    DNSServiceProcessResult(*(mPollRefs[i]));
                    mPollFds[i].revents = 0;
                }
            }
            if (VDBG) ALOGD("controlSocket shows revent= %d", mPollFds[0].revents);
            switch (mPollFds[0].revents) {
                case POLLIN: {
                    char readBuf[2];
                    read(mCtrlSocketPair[0], &readBuf, 1);
                    if (DBG) ALOGD("MDnsSdListener::Monitor got %c", readBuf[0]);
                    if (memcmp(RESCAN, readBuf, 1) == 0) {
                        pollCount = rescan();
                    }
                }
            }
            mPollFds[0].revents = 0;
        } else {
            if (VDBG) ALOGD("MDnsSdListener::Monitor poll timed out");
        }
    }
    free(mPollFds);
    free(mPollRefs);
}

#define DBG_RESCAN 0

int MDnsSdListener::Monitor::rescan() {
// rescan the list from mHead and make new pollfds and serviceRefs
    if (VDBG) {
        ALOGD("MDnsSdListener::Monitor poll rescanning - size=%d, live=%d", mPollSize, mLiveCount);
    }
    std::lock_guard guard(mMutex);
    Element **prevPtr = &mHead;
    int i = 1;
    if (mPollSize <= mLiveCount) {
        mPollSize = mLiveCount + 5;
        free(mPollFds);
        free(mPollRefs);
        mPollFds = (struct pollfd *)calloc(sizeof(struct pollfd), mPollSize);
        mPollRefs = (DNSServiceRef **)calloc(sizeof(DNSServiceRef *), mPollSize);
        LOG_ALWAYS_FATAL_IF((mPollFds == nullptr), "calloc failed on mPollFds with a size of %d",
                ((int)sizeof(struct pollfd)) * mPollSize);
        LOG_ALWAYS_FATAL_IF((mPollRefs == nullptr), "calloc failed on mPollRefs with a size of %d",
                ((int)sizeof(DNSServiceRef *)) * mPollSize);
    } else {
        memset(mPollFds, 0, sizeof(struct pollfd) * mPollSize);
        memset(mPollRefs, 0, sizeof(DNSServiceRef *) * mPollSize);
    }
    mPollFds[0].fd = mCtrlSocketPair[0];
    mPollFds[0].events = POLLIN;
    if (DBG_RESCAN) ALOGD("mHead = %p", mHead);
    while (*prevPtr != nullptr) {
        if (DBG_RESCAN) ALOGD("checking %p, mReady = %d", *prevPtr, (*prevPtr)->mReady);
        if ((*prevPtr)->mReady == 1) {
            int fd = DNSServiceRefSockFD((*prevPtr)->mRef);
            if (fd != -1) {
                if (DBG_RESCAN) ALOGD("  adding FD %d", fd);
                mPollFds[i].fd = fd;
                mPollFds[i].events = POLLIN;
                mPollRefs[i] = &((*prevPtr)->mRef);
                i++;
            } else {
                ALOGE("Error retreving socket FD for live ServiceRef");
            }
            prevPtr = &((*prevPtr)->mNext); // advance to the next element
        } else if ((*prevPtr)->mReady == -1) {
            if (DBG_RESCAN) ALOGD("  removing %p from  play", *prevPtr);
            Element *cur = *prevPtr;
            *prevPtr = (cur)->mNext; // change our notion of this element and don't advance
            delete cur;
        } else if ((*prevPtr)->mReady == 0) {
            // Not ready so just skip this node and continue on
            if (DBG_RESCAN) ALOGD("%p not ready.  Continuing.", *prevPtr);
            prevPtr = &((*prevPtr)->mNext);
        }
    }

    return i;
}

DNSServiceRef *MDnsSdListener::Monitor::allocateServiceRef(int id, Context *context) {
    if (lookupServiceRef(id) != nullptr) {
        delete(context);
        return nullptr;
    }
    Element *e = new Element(id, context);
    std::lock_guard guard(mMutex);
    e->mNext = mHead;
    mHead = e;
    return &(e->mRef);
}

DNSServiceRef *MDnsSdListener::Monitor::lookupServiceRef(int id) {
    std::lock_guard guard(mMutex);
    Element *cur = mHead;
    while (cur != nullptr) {
        if (cur->mId == id) {
            DNSServiceRef *result = &(cur->mRef);
            return result;
        }
        cur = cur->mNext;
    }
    return nullptr;
}

void MDnsSdListener::Monitor::startMonitoring(int id) {
    if (VDBG) ALOGD("startMonitoring %d", id);
    std::lock_guard guard(mMutex);
    for (Element* cur = mHead; cur != nullptr; cur = cur->mNext) {
        if (cur->mId == id) {
            if (DBG_RESCAN) ALOGD("marking %p as ready to be added", cur);
            mLiveCount++;
            cur->mReady = 1;
            write(mCtrlSocketPair[1], RESCAN, 1);  // trigger a rescan for a fresh poll
            if (VDBG) ALOGD("triggering rescan");
            return;
        }
    }
}

void MDnsSdListener::Monitor::freeServiceRef(int id) {
    if (VDBG) ALOGD("freeServiceRef %d", id);
    std::lock_guard guard(mMutex);
    Element* cur;
    for (Element** prevPtr = &mHead; *prevPtr != nullptr; prevPtr = &(cur->mNext)) {
        cur = *prevPtr;
        if (cur->mId == id) {
            if (DBG_RESCAN) ALOGD("marking %p as ready to be removed", cur);
            mLiveCount--;
            if (cur->mReady == 1) {
                cur->mReady = -1; // tell poll thread to delete
                cur->mRef = nullptr; // do not process further results
                write(mCtrlSocketPair[1], RESCAN, 1); // trigger a rescan for a fresh poll
                if (VDBG) ALOGD("triggering rescan");
            } else {
                *prevPtr = cur->mNext;
                delete cur;
            }
            return;
        }
    }
}

void MDnsSdListener::Monitor::deallocateServiceRef(DNSServiceRef* ref) {
    std::lock_guard guard(mMutex);
    DNSServiceRefDeallocate(*ref);
    *ref = nullptr;
}
