/*
 * 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 <arpa/inet.h>
#include <dirent.h>
#include <errno.h>
#include <linux/if.h>
#include <netdb.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdlib.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>

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

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

#include "MDnsSdListener.h"
#include "ResponseCode.h"

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

MDnsSdListener::MDnsSdListener() :
                 FrameworkListener("mdns", 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 == NULL) {
        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 = atoi(argv[2]);
    DNSServiceRef *ref = mMonitor->lookupServiceRef(requestId);
    if (ref == NULL) {
        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);
    DNSServiceRefDeallocate(*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 == NULL) {
        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 == NULL) {
        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);
        asprintf(&msg, "%d %s %s %d %d", refNumber, quotedFullName, quotedHostTarget, port, txtLen);
        free(quotedFullName);
        free(quotedHostTarget);
        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 == NULL) {
        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 == NULL) {
        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 NULL;
}

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 = NULL;
        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 = atoi(argv[2]);
        char *serviceType = argv[3];

        discover(cli, NULL, serviceType, NULL, requestId, 0);
    } else if (strcmp(cmd, "stop-discover") == 0) {
        stop(cli, argc, argv, "discover");
    } else if (strcmp(cmd, "register") == 0) {
        if (argc != 6) {
            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 = atoi(argv[5]);
        char *interfaceName = NULL; // will use all
        char *domain = NULL;        // will use default
        char *host = NULL;          // will use default hostname
        int textLen = 0;
        void *textRecord = NULL;

        serviceRegister(cli, requestId, interfaceName, serviceName,
                serviceType, domain, host, port, textLen, textRecord);
    } 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 = NULL;  // 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 = atoi(argv[2]);
        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 = NULL;  // 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 = NULL;
    pthread_mutex_init(&mHeadMutex, NULL);
    socketpair(AF_LOCAL, SOCK_STREAM, 0, mCtrlSocketPair);
    pthread_create(&mThread, NULL, MDnsSdListener::Monitor::threadStart, this);
}

void *MDnsSdListener::Monitor::threadStart(void *obj) {
    Monitor *monitor = reinterpret_cast<Monitor *>(obj);

    monitor->run();
    delete monitor;
    pthread_exit(NULL);
    return NULL;
}

int MDnsSdListener::Monitor::startService() {
    int result = 0;
    char property_value[PROPERTY_VALUE_MAX];
    pthread_mutex_lock(&mHeadMutex);
    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);
        result = -1;
    } else {
        result = 0;
    }
    pthread_mutex_unlock(&mHeadMutex);
    return result;
}

int MDnsSdListener::Monitor::stopService() {
    int result = 0;
    pthread_mutex_lock(&mHeadMutex);
    if (mHead == NULL) {
        ALOGD("Stopping MDNSD");
        property_set("ctl.stop", MDNS_SERVICE_NAME);
        wait_for_property(MDNS_SERVICE_STATUS, "stopped", 5);
        result = -1;
    } else {
        result = 0;
    }
    pthread_mutex_unlock(&mHeadMutex);
    return result;
}

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

    mPollFds = (struct pollfd *)calloc(sizeof(struct pollfd), mPollSize);
    mPollRefs = (DNSServiceRef **)calloc(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);
                    }
                    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);
    }
    int count = 0;
    pthread_mutex_lock(&mHeadMutex);
    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);
    } else {
        memset(mPollFds, sizeof(struct pollfd) * mPollSize, 0);
        memset(mPollRefs, sizeof(DNSServiceRef *) * mPollSize, 0);
    }
    mPollFds[0].fd = mCtrlSocketPair[0];
    mPollFds[0].events = POLLIN;
    if (DBG_RESCAN) ALOGD("mHead = %p", mHead);
    while (*prevPtr != NULL) {
        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;
        }
    }
    pthread_mutex_unlock(&mHeadMutex);
    return i;
}

DNSServiceRef *MDnsSdListener::Monitor::allocateServiceRef(int id, Context *context) {
    if (lookupServiceRef(id) != NULL) {
        delete(context);
        return NULL;
    }
    Element *e = new Element(id, context);
    pthread_mutex_lock(&mHeadMutex);
    e->mNext = mHead;
    mHead = e;
    pthread_mutex_unlock(&mHeadMutex);
    return &(e->mRef);
}

DNSServiceRef *MDnsSdListener::Monitor::lookupServiceRef(int id) {
    pthread_mutex_lock(&mHeadMutex);
    Element *cur = mHead;
    while (cur != NULL) {
        if (cur->mId == id) {
            DNSServiceRef *result = &(cur->mRef);
            pthread_mutex_unlock(&mHeadMutex);
            return result;
        }
        cur = cur->mNext;
    }
    pthread_mutex_unlock(&mHeadMutex);
    return NULL;
}

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

#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, NULL)) {
            if (desired_value == NULL || strcmp(value, desired_value) == 0) {
                return 0;
            }
        }
    }
    return -1; /* failure */
}

void MDnsSdListener::Monitor::freeServiceRef(int id) {
    if (VDBG) ALOGD("freeServiceRef %d", id);
    pthread_mutex_lock(&mHeadMutex);
    Element **prevPtr = &mHead;
    Element *cur;
    while (*prevPtr != NULL) {
        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
                write(mCtrlSocketPair[1], RESCAN, 1); // trigger a rescan for a fresh poll
                if (VDBG) ALOGD("triggering rescan");
            } else {
                *prevPtr = cur->mNext;
                delete cur;
            }
            pthread_mutex_unlock(&mHeadMutex);
            return;
        }
        prevPtr = &(cur->mNext);
    }
    pthread_mutex_unlock(&mHeadMutex);
}
