MDnsSdListener.h revision 745e09fc5694e73920aaad18a626275597bdddb1
1745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt/* 2745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt * Copyright (C) 2012 The Android Open Source Project 3745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt * 4745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt * Licensed under the Apache License, Version 2.0 (the "License"); 5745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt * you may not use this file except in compliance with the License. 6745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt * You may obtain a copy of the License at 7745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt * 8745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt * http://www.apache.org/licenses/LICENSE-2.0 9745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt * 10745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt * Unless required by applicable law or agreed to in writing, software 11745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt * distributed under the License is distributed on an "AS IS" BASIS, 12745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt * See the License for the specific language governing permissions and 14745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt * limitations under the License. 15745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt */ 16745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 17745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt#ifndef _MDNSSDLISTENER_H__ 18745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt#define _MDNSSDLISTENER_H__ 19745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 20745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt#include <pthread.h> 21745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt#include <sysutils/FrameworkListener.h> 22745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt#include <dns_sd.h> 23745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 24745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt#include "NetdCommand.h" 25745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 26745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt// callbacks 27745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwaltvoid MDnsSdListenerDiscoverCallback(DNSServiceRef sdRef, DNSServiceFlags flags, 28745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt uint32_t interfaceIndex, DNSServiceErrorType errorCode, 29745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt const char *serviceName, const char *regType, const char *replyDomain, 30745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt void *inContext); 31745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 32745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwaltvoid MDnsSdListenerRegisterCallback(DNSServiceRef sdRef, DNSServiceFlags flags, 33745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt DNSServiceErrorType errorCode, const char *serviceName, const char *regType, 34745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt const char *domain, void *inContext); 35745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 36745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwaltvoid MDnsSdListenerResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interface, 37745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t port, 38745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt uint16_t txtLen, const unsigned char *txtRecord, void *inContext); 39745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 40745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwaltvoid MDnsSdListenerSetHostnameCallback(DNSServiceRef, DNSServiceFlags flags, 41745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt DNSServiceErrorType errorCode, const char *hostname, void *inContext); 42745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 43745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwaltvoid MDnsSdListenerGetAddrInfoCallback(DNSServiceRef sdRef, DNSServiceFlags flags, 44745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt uint32_t interface, DNSServiceErrorType errorCode, const char *hostname, 45745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt const struct sockaddr *const sa, uint32_t ttl, void *inContext); 46745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 47745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt#define RESCAN "1" 48745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 49745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwaltclass MDnsSdListener : public FrameworkListener { 50745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwaltpublic: 51745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt MDnsSdListener(); 52745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt virtual ~MDnsSdListener() {} 53745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 54745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt class Context { 55745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt public: 56745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt MDnsSdListener *mListener; 57745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt int mRefNumber; 58745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 59745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt Context(int refNumber, MDnsSdListener *m) { 60745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt mRefNumber = refNumber; 61745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt mListener = m; 62745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt } 63745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 64745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt ~Context() { 65745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt } 66745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt }; 67745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 68745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt class Monitor { 69745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt public: 70745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt Monitor(); 71745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt virtual ~Monitor() {} 72745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt DNSServiceRef *allocateServiceRef(int id, Context *c); 73745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt void startMonitoring(int id); 74745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt DNSServiceRef *lookupServiceRef(int id); 75745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt void freeServiceRef(int id); 76745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt static void *threadStart(void *handler); 77745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt int startService(); 78745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt int stopService(); 79745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt private: 80745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt void run(); 81745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt int rescan(); // returns the number of elements in the poll 82745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt class Element { 83745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt public: 84745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt int mId; 85745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt Element *mNext; 86745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt DNSServiceRef mRef; 87745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt Context *mContext; 88745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt int mReady; 89745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt Element(int id, Context *context) 90745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt : mId(id), mNext(NULL), mContext(context), mReady(0) {} 91745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt virtual ~Element() { delete(mContext); } 92745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt }; 93745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt Element *mHead; 94745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt int mLiveCount; 95745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt struct pollfd *mPollFds; 96745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt DNSServiceRef **mPollRefs; 97745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt int mPollSize; 98745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt pthread_t mThread; 99745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt int mCtrlSocketPair[2]; 100745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt pthread_mutex_t mHeadMutex; 101745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt }; 102745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 103745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt class Handler : public NetdCommand { 104745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt public: 105745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt Handler(Monitor *m, MDnsSdListener *listener); 106745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt virtual ~Handler(); 107745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt int runCommand(SocketClient *c, int argc, char** argv); 108745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 109745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt MDnsSdListener *mListener; // needed for broadcast purposes 110745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt private: 111745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt void stop(SocketClient *cli, int argc, char **argv, const char *str); 112745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 113745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt void discover(SocketClient *cli, const char *iface, const char *regType, 114745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt const char *domain, const int requestNumber, 115745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt const int requestFlags); 116745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 117745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt void serviceRegister(SocketClient *cli, int requestId, const char *interfaceName, 118745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt const char *serviceName, const char *serviceType, const char *domain, 119745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt const char *host, int port, int textLen, void *txtRecord); 120745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 121745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt void resolveService(SocketClient *cli, int requestId, 122745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt const char *interfaceName, const char *serviceName, const char *regType, 123745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt const char *domain); 124745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 125745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt void setHostname(SocketClient *cli, int requestId, const char *hostname); 126745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 127745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt void getAddrInfo(SocketClient *cli, int requestId, const char *interfaceName, 128745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt uint32_t protocol, const char *hostname); 129745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 130745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt int ifaceNameToI(const char *iface); 131745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt const char *iToIfaceName(int i); 132745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt DNSServiceFlags iToFlags(int i); 133745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt int flagsToI(DNSServiceFlags flags); 134745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt Monitor *mMonitor; 135745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt }; 136745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt}; 137745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 138745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwaltstatic int wait_for_property(const char *name, const char *desired_value, int maxwait); 139745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt 140745e09fc5694e73920aaad18a626275597bdddb1Robert Greenwalt#endif 141