diff options
author | Irfan Sheriff <isheriff@google.com> | 2012-04-12 17:55:15 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-04-12 17:55:15 -0700 |
commit | cbba37c6096486cbc8ce6f0c4eb7df9a352d54b1 (patch) | |
tree | 381c4788296568fdeed935cd425eae245c0106c1 | |
parent | 6c70ef1fb2efd705406d73272b87573900812aff (diff) | |
parent | 817388e056a5d1d0e7cd7de2c6b0c9c80617bc5f (diff) | |
download | frameworks_base-cbba37c6096486cbc8ce6f0c4eb7df9a352d54b1.zip frameworks_base-cbba37c6096486cbc8ce6f0c4eb7df9a352d54b1.tar.gz frameworks_base-cbba37c6096486cbc8ce6f0c4eb7df9a352d54b1.tar.bz2 |
Merge "Bonjour fixes"
-rw-r--r-- | core/java/android/net/nsd/DnsSdServiceInfo.java | 47 | ||||
-rw-r--r-- | core/java/android/net/nsd/NsdManager.java | 50 | ||||
-rw-r--r-- | services/java/com/android/server/NsdService.java | 376 |
3 files changed, 418 insertions, 55 deletions
diff --git a/core/java/android/net/nsd/DnsSdServiceInfo.java b/core/java/android/net/nsd/DnsSdServiceInfo.java index 47d6ec6..33c3eb9 100644 --- a/core/java/android/net/nsd/DnsSdServiceInfo.java +++ b/core/java/android/net/nsd/DnsSdServiceInfo.java @@ -19,6 +19,8 @@ package android.net.nsd; import android.os.Parcelable; import android.os.Parcel; +import java.net.InetAddress; + /** * Defines a service based on DNS service discovery * {@hide} @@ -27,20 +29,20 @@ public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable { private String mServiceName; - private String mRegistrationType; + private String mServiceType; private DnsSdTxtRecord mTxtRecord; - private String mHostname; + private InetAddress mHost; private int mPort; - DnsSdServiceInfo() { + public DnsSdServiceInfo() { } - DnsSdServiceInfo(String sn, String rt, DnsSdTxtRecord tr) { + public DnsSdServiceInfo(String sn, String rt, DnsSdTxtRecord tr) { mServiceName = sn; - mRegistrationType = rt; + mServiceType = rt; mTxtRecord = tr; } @@ -59,13 +61,13 @@ public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable { @Override /** @hide */ public String getServiceType() { - return mRegistrationType; + return mServiceType; } @Override /** @hide */ public void setServiceType(String s) { - mRegistrationType = s; + mServiceType = s; } public DnsSdTxtRecord getTxtRecord() { @@ -76,12 +78,12 @@ public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable { mTxtRecord = new DnsSdTxtRecord(t); } - public String getHostName() { - return mHostname; + public InetAddress getHost() { + return mHost; } - public void setHostName(String s) { - mHostname = s; + public void setHost(InetAddress s) { + mHost = s; } public int getPort() { @@ -96,7 +98,9 @@ public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable { StringBuffer sb = new StringBuffer(); sb.append("name: ").append(mServiceName). - append("type: ").append(mRegistrationType). + append("type: ").append(mServiceType). + append("host: ").append(mHost). + append("port: ").append(mPort). append("txtRecord: ").append(mTxtRecord); return sb.toString(); } @@ -109,9 +113,14 @@ public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable { /** Implement the Parcelable interface */ public void writeToParcel(Parcel dest, int flags) { dest.writeString(mServiceName); - dest.writeString(mRegistrationType); + dest.writeString(mServiceType); dest.writeParcelable(mTxtRecord, flags); - dest.writeString(mHostname); + if (mHost != null) { + dest.writeByte((byte)1); + dest.writeByteArray(mHost.getAddress()); + } else { + dest.writeByte((byte)0); + } dest.writeInt(mPort); } @@ -121,9 +130,15 @@ public class DnsSdServiceInfo implements NetworkServiceInfo, Parcelable { public DnsSdServiceInfo createFromParcel(Parcel in) { DnsSdServiceInfo info = new DnsSdServiceInfo(); info.mServiceName = in.readString(); - info.mRegistrationType = in.readString(); + info.mServiceType = in.readString(); info.mTxtRecord = in.readParcelable(null); - info.mHostname = in.readString(); + + if (in.readByte() == 1) { + try { + info.mHost = InetAddress.getByAddress(in.createByteArray()); + } catch (java.net.UnknownHostException e) {} + } + info.mPort = in.readInt(); return info; } diff --git a/core/java/android/net/nsd/NsdManager.java b/core/java/android/net/nsd/NsdManager.java index a109a98..505f11b 100644 --- a/core/java/android/net/nsd/NsdManager.java +++ b/core/java/android/net/nsd/NsdManager.java @@ -93,6 +93,15 @@ public class NsdManager { /** @hide */ public static final int RESOLVE_SERVICE_SUCCEEDED = BASE + 17; + /** @hide */ + public static final int STOP_RESOLVE = BASE + 18; + /** @hide */ + public static final int STOP_RESOLVE_FAILED = BASE + 19; + /** @hide */ + public static final int STOP_RESOLVE_SUCCEEDED = BASE + 20; + + + /** * Create a new Nsd instance. Applications use * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve @@ -117,10 +126,23 @@ public class NsdManager { /** * Indicates that the operation failed because the framework is busy and - * unable to service the request + * unable to service the request. */ public static final int BUSY = 2; + /** + * Indicates that the operation failed because it is already active. + */ + public static final int ALREADY_ACTIVE = 3; + + /** + * Indicates that the operation failed because maximum limit on + * service registrations has reached. + */ + public static final int MAX_REGS_REACHED = 4; + + + /** Interface for callback invocation when framework channel is connected or lost */ public interface ChannelListener { public void onChannelConnected(Channel c); @@ -188,6 +210,7 @@ public class NsdManager { private DnsSdRegisterListener mDnsSdRegisterListener; private DnsSdUpdateRegistrationListener mDnsSdUpdateListener; private DnsSdResolveListener mDnsSdResolveListener; + private ActionListener mDnsSdStopResolveListener; AsyncChannel mAsyncChannel; ServiceHandler mHandler; @@ -278,6 +301,16 @@ public class NsdManager { (DnsSdServiceInfo) message.obj); } break; + case STOP_RESOLVE_FAILED: + if (mDnsSdStopResolveListener!= null) { + mDnsSdStopResolveListener.onFailure(message.arg1); + } + break; + case STOP_RESOLVE_SUCCEEDED: + if (mDnsSdStopResolveListener != null) { + mDnsSdStopResolveListener.onSuccess(); + } + break; default: Log.d(TAG, "Ignored " + message); break; @@ -345,6 +378,14 @@ public class NsdManager { c.mDnsSdResolveListener = b; } + /** + * Set the listener for stopping service resolution. Can be null. + */ + public void setStopResolveListener(Channel c, ActionListener b) { + if (c == null) throw new IllegalArgumentException("Channel needs to be initialized"); + c.mDnsSdStopResolveListener = b; + } + public void registerService(Channel c, DnsSdServiceInfo serviceInfo) { if (c == null) throw new IllegalArgumentException("Channel needs to be initialized"); if (serviceInfo == null) throw new IllegalArgumentException("Null serviceInfo"); @@ -378,6 +419,13 @@ public class NsdManager { c.mAsyncChannel.sendMessage(RESOLVE_SERVICE, serviceInfo); } + public void stopServiceResolve(Channel c) { + if (c == null) throw new IllegalArgumentException("Channel needs to be initialized"); + if (c.mDnsSdResolveListener == null) throw new + IllegalStateException("Resolve listener needs to be set first"); + c.mAsyncChannel.sendMessage(STOP_RESOLVE); + } + /** * Get a reference to NetworkService handler. This is used to establish * an AsyncChannel communication with the service diff --git a/services/java/com/android/server/NsdService.java b/services/java/com/android/server/NsdService.java index 768be7d..a3ac8d0 100644 --- a/services/java/com/android/server/NsdService.java +++ b/services/java/com/android/server/NsdService.java @@ -32,9 +32,11 @@ import android.util.Slog; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.net.InetAddress; import java.util.ArrayList; -import java.util.concurrent.CountDownLatch; +import java.util.HashMap; import java.util.List; +import java.util.concurrent.CountDownLatch; import com.android.internal.app.IBatteryStats; import com.android.internal.telephony.TelephonyIntents; @@ -60,10 +62,13 @@ public class NsdService extends INsdManager.Stub { /** * Clients receiving asynchronous messages */ - private List<AsyncChannel> mClients = new ArrayList<AsyncChannel>(); + private HashMap<Messenger, ClientInfo> mClients = new HashMap<Messenger, ClientInfo>(); private AsyncChannel mReplyChannel = new AsyncChannel(); + private int INVALID_ID = 0; + private int mUniqueId = 1; + /** * Handles client(app) connections */ @@ -75,13 +80,19 @@ public class NsdService extends INsdManager.Stub { @Override public void handleMessage(Message msg) { + ClientInfo clientInfo; + DnsSdServiceInfo servInfo; switch (msg.what) { case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { AsyncChannel c = (AsyncChannel) msg.obj; if (DBG) Slog.d(TAG, "New client listening to asynchronous messages"); c.sendMessage(AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED); - mClients.add(c); + ClientInfo cInfo = new ClientInfo(c, msg.replyTo); + if (mClients.size() == 0) { + startMDnsDaemon(); + } + mClients.put(msg.replyTo, cInfo); } else { Slog.e(TAG, "Client connection failure, error=" + msg.arg1); } @@ -92,7 +103,10 @@ public class NsdService extends INsdManager.Stub { } else { if (DBG) Slog.d(TAG, "Client connection lost with reason: " + msg.arg1); } - mClients.remove((AsyncChannel) msg.obj); + mClients.remove(msg.replyTo); + if (mClients.size() == 0) { + stopMDnsDaemon(); + } break; case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: AsyncChannel ac = new AsyncChannel(); @@ -100,22 +114,98 @@ public class NsdService extends INsdManager.Stub { break; case NsdManager.DISCOVER_SERVICES: if (DBG) Slog.d(TAG, "Discover services"); - DnsSdServiceInfo s = (DnsSdServiceInfo) msg.obj; - discoverServices(1, s.getServiceType()); - mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_STARTED); + servInfo = (DnsSdServiceInfo) msg.obj; + clientInfo = mClients.get(msg.replyTo); + if (clientInfo.mDiscoveryId != INVALID_ID) { + //discovery already in progress + if (DBG) Slog.d(TAG, "discovery in progress"); + mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED, + NsdManager.ALREADY_ACTIVE); + break; + } + clientInfo.mDiscoveryId = getUniqueId(); + if (discoverServices(clientInfo.mDiscoveryId, servInfo.getServiceType())) { + mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_STARTED); + } else { + mReplyChannel.replyToMessage(msg, NsdManager.DISCOVER_SERVICES_FAILED, + NsdManager.ERROR); + clientInfo.mDiscoveryId = INVALID_ID; + } break; case NsdManager.STOP_DISCOVERY: if (DBG) Slog.d(TAG, "Stop service discovery"); - mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED); + clientInfo = mClients.get(msg.replyTo); + if (clientInfo.mDiscoveryId == INVALID_ID) { + //already stopped + if (DBG) Slog.d(TAG, "discovery already stopped"); + mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED, + NsdManager.ALREADY_ACTIVE); + break; + } + if (stopServiceDiscovery(clientInfo.mDiscoveryId)) { + clientInfo.mDiscoveryId = INVALID_ID; + mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_SUCCEEDED); + } else { + mReplyChannel.replyToMessage(msg, NsdManager.STOP_DISCOVERY_FAILED, + NsdManager.ERROR); + } break; case NsdManager.REGISTER_SERVICE: if (DBG) Slog.d(TAG, "Register service"); - mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED); + clientInfo = mClients.get(msg.replyTo); + if (clientInfo.mRegisteredIds.size() >= ClientInfo.MAX_REG) { + if (DBG) Slog.d(TAG, "register service exceeds limit"); + mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED, + NsdManager.MAX_REGS_REACHED); + } + + int id = getUniqueId(); + if (registerService(id, (DnsSdServiceInfo) msg.obj)) { + clientInfo.mRegisteredIds.add(id); + } else { + mReplyChannel.replyToMessage(msg, NsdManager.REGISTER_SERVICE_FAILED, + NsdManager.ERROR); + } break; case NsdManager.UPDATE_SERVICE: if (DBG) Slog.d(TAG, "Update service"); + //TODO: implement mReplyChannel.replyToMessage(msg, NsdManager.UPDATE_SERVICE_FAILED); break; + case NsdManager.RESOLVE_SERVICE: + if (DBG) Slog.d(TAG, "Resolve service"); + servInfo = (DnsSdServiceInfo) msg.obj; + clientInfo = mClients.get(msg.replyTo); + if (clientInfo.mResolveId != INVALID_ID) { + //first cancel existing resolve + stopResolveService(clientInfo.mResolveId); + } + + clientInfo.mResolveId = getUniqueId(); + if (!resolveService(clientInfo.mResolveId, servInfo)) { + mReplyChannel.replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED, + NsdManager.ERROR); + clientInfo.mResolveId = INVALID_ID; + } + break; + case NsdManager.STOP_RESOLVE: + if (DBG) Slog.d(TAG, "Stop resolve"); + clientInfo = mClients.get(msg.replyTo); + if (clientInfo.mResolveId == INVALID_ID) { + //already stopped + if (DBG) Slog.d(TAG, "resolve already stopped"); + mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED, + NsdManager.ALREADY_ACTIVE); + break; + } + if (stopResolveService(clientInfo.mResolveId)) { + clientInfo.mResolveId = INVALID_ID; + mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_SUCCEEDED); + } else { + mReplyChannel.replyToMessage(msg, NsdManager.STOP_RESOLVE_FAILED, + NsdManager.ERROR); + } + break; default: Slog.d(TAG, "NsdServicehandler.handleMessage ignoring msg=" + msg); break; @@ -134,12 +224,10 @@ public class NsdService extends INsdManager.Stub { nsdThread.start(); mAsyncServiceHandler = new AsyncServiceHandler(nsdThread.getLooper()); - /* mNativeConnector = new NativeDaemonConnector(new NativeCallbackReceiver(), "mdns", 10, MDNS_TAG, 25); Thread th = new Thread(mNativeConnector, MDNS_TAG); th.start(); - */ } public static NsdService create(Context context) throws InterruptedException { @@ -152,22 +240,29 @@ public class NsdService extends INsdManager.Stub { return new Messenger(mAsyncServiceHandler); } + private int getUniqueId() { + if (++mUniqueId == INVALID_ID) return ++mUniqueId; + return mUniqueId; + } + /* These should be in sync with system/netd/mDnsResponseCode.h */ class NativeResponseCode { - public static final int SERVICE_FOUND = 101; - public static final int SERVICE_LOST = 102; - public static final int SERVICE_DISCOVERY_FAILED = 103; + public static final int SERVICE_DISCOVERY_FAILED = 602; + public static final int SERVICE_FOUND = 603; + public static final int SERVICE_LOST = 604; - public static final int SERVICE_REGISTERED = 104; - public static final int SERVICE_REGISTRATION_FAILED = 105; + public static final int SERVICE_REGISTRATION_FAILED = 605; + public static final int SERVICE_REGISTERED = 606; - public static final int SERVICE_UPDATED = 106; - public static final int SERVICE_UPDATE_FAILED = 107; + public static final int SERVICE_RESOLUTION_FAILED = 607; + public static final int SERVICE_RESOLVED = 608; - public static final int SERVICE_RESOLVED = 108; - public static final int SERVICE_RESOLUTION_FAILED = 109; - } + public static final int SERVICE_UPDATED = 609; + public static final int SERVICE_UPDATE_FAILED = 610; + public static final int SERVICE_GET_ADDR_FAILED = 611; + public static final int SERVICE_GET_ADDR_SUCCESS = 612; + } class NativeCallbackReceiver implements INativeDaemonConnectorCallbacks { public void onDaemonConnected() { @@ -175,21 +270,55 @@ public class NsdService extends INsdManager.Stub { } public boolean onEvent(int code, String raw, String[] cooked) { + ClientInfo clientInfo; + DnsSdServiceInfo servInfo; + int id = Integer.parseInt(cooked[1]); switch (code) { case NativeResponseCode.SERVICE_FOUND: - /* NNN uniqueId serviceName regType */ + /* NNN uniqueId serviceName regType domain */ + if (DBG) Slog.d(TAG, "SERVICE_FOUND Raw: " + raw); + clientInfo = getClientByDiscovery(id); + if (clientInfo == null) break; + + servInfo = new DnsSdServiceInfo(cooked[2], cooked[3], null); + clientInfo.mChannel.sendMessage(NsdManager.SERVICE_FOUND, servInfo); break; case NativeResponseCode.SERVICE_LOST: - /* NNN uniqueId serviceName regType */ + /* NNN uniqueId serviceName regType domain */ + if (DBG) Slog.d(TAG, "SERVICE_LOST Raw: " + raw); + clientInfo = getClientByDiscovery(id); + if (clientInfo == null) break; + + servInfo = new DnsSdServiceInfo(cooked[2], cooked[3], null); + clientInfo.mChannel.sendMessage(NsdManager.SERVICE_LOST, servInfo); break; case NativeResponseCode.SERVICE_DISCOVERY_FAILED: /* NNN uniqueId errorCode */ + if (DBG) Slog.d(TAG, "SERVICE_DISC_FAILED Raw: " + raw); + clientInfo = getClientByDiscovery(id); + if (clientInfo == null) break; + + clientInfo.mChannel.sendMessage(NsdManager.DISCOVER_SERVICES_FAILED, + NsdManager.ERROR); break; case NativeResponseCode.SERVICE_REGISTERED: /* NNN regId serviceName regType */ + if (DBG) Slog.d(TAG, "SERVICE_REGISTERED Raw: " + raw); + clientInfo = getClientByRegistration(id); + if (clientInfo == null) break; + + servInfo = new DnsSdServiceInfo(cooked[2], null, null); + clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_SUCCEEDED, + id, 0, servInfo); break; case NativeResponseCode.SERVICE_REGISTRATION_FAILED: /* NNN regId errorCode */ + if (DBG) Slog.d(TAG, "SERVICE_REGISTER_FAILED Raw: " + raw); + clientInfo = getClientByRegistration(id); + if (clientInfo == null) break; + + clientInfo.mChannel.sendMessage(NsdManager.REGISTER_SERVICE_FAILED, + NsdManager.ERROR); break; case NativeResponseCode.SERVICE_UPDATED: /* NNN regId */ @@ -199,9 +328,52 @@ public class NsdService extends INsdManager.Stub { break; case NativeResponseCode.SERVICE_RESOLVED: /* NNN resolveId fullName hostName port txtlen txtdata */ + if (DBG) Slog.d(TAG, "SERVICE_RESOLVED Raw: " + raw); + clientInfo = getClientByResolve(id); + if (clientInfo == null) break; + + int index = cooked[2].indexOf("."); + if (index == -1) { + Slog.e(TAG, "Invalid service found " + raw); + break; + } + String name = cooked[2].substring(0, index); + String rest = cooked[2].substring(index); + String type = rest.replace(".local.", ""); + + clientInfo.mResolvedService = new DnsSdServiceInfo(name, type, null); + clientInfo.mResolvedService.setPort(Integer.parseInt(cooked[4])); + + stopResolveService(id); + getAddrInfo(id, cooked[3]); break; case NativeResponseCode.SERVICE_RESOLUTION_FAILED: - /* NNN resovleId errorCode */ + case NativeResponseCode.SERVICE_GET_ADDR_FAILED: + /* NNN resolveId errorCode */ + if (DBG) Slog.d(TAG, "SERVICE_RESOLVE_FAILED Raw: " + raw); + clientInfo = getClientByResolve(id); + if (clientInfo == null) break; + + clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED, + NsdManager.ERROR); + break; + case NativeResponseCode.SERVICE_GET_ADDR_SUCCESS: + /* NNN resolveId hostname ttl addr */ + if (DBG) Slog.d(TAG, "SERVICE_GET_ADDR_SUCCESS Raw: " + raw); + clientInfo = getClientByResolve(id); + if (clientInfo == null || clientInfo.mResolvedService == null) break; + + try { + clientInfo.mResolvedService.setHost(InetAddress.getByName(cooked[4])); + clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_SUCCEEDED, + clientInfo.mResolvedService); + clientInfo.mResolvedService = null; + clientInfo.mResolveId = INVALID_ID; + } catch (java.net.UnknownHostException e) { + clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED, + NsdManager.ERROR); + } + stopGetAddrInfo(id); break; default: break; @@ -210,48 +382,129 @@ public class NsdService extends INsdManager.Stub { } } - private void registerService(int regId, DnsSdServiceInfo service) { + private boolean startMDnsDaemon() { + if (DBG) Slog.d(TAG, "startMDnsDaemon"); + try { + mNativeConnector.execute("mdnssd", "start-service"); + } catch(NativeDaemonConnectorException e) { + Slog.e(TAG, "Failed to start daemon" + e); + return false; + } + return true; + } + + private boolean stopMDnsDaemon() { + if (DBG) Slog.d(TAG, "stopMDnsDaemon"); + try { + mNativeConnector.execute("mdnssd", "stop-service"); + } catch(NativeDaemonConnectorException e) { + Slog.e(TAG, "Failed to start daemon" + e); + return false; + } + return true; + } + + private boolean registerService(int regId, DnsSdServiceInfo service) { + if (DBG) Slog.d(TAG, "registerService: " + regId + " " + service); try { //Add txtlen and txtdata mNativeConnector.execute("mdnssd", "register", regId, service.getServiceName(), service.getServiceType(), service.getPort()); } catch(NativeDaemonConnectorException e) { - Slog.e(TAG, "Failed to execute registerService"); + Slog.e(TAG, "Failed to execute registerService " + e); + return false; + } + return true; + } + + private boolean unregisterService(int regId) { + if (DBG) Slog.d(TAG, "unregisterService: " + regId); + try { + mNativeConnector.execute("mdnssd", "stop-register", regId); + } catch(NativeDaemonConnectorException e) { + Slog.e(TAG, "Failed to execute unregisterService " + e); + return false; } + return true; } - private void updateService(int regId, DnsSdTxtRecord t) { + private boolean updateService(int regId, DnsSdTxtRecord t) { + if (DBG) Slog.d(TAG, "updateService: " + regId + " " + t); try { - if (t == null) return; + if (t == null) return false; mNativeConnector.execute("mdnssd", "update", regId, t.size(), t.getRawData()); } catch(NativeDaemonConnectorException e) { - Slog.e(TAG, "Failed to updateServices"); + Slog.e(TAG, "Failed to updateServices " + e); + return false; } + return true; } - private void discoverServices(int discoveryId, String serviceType) { + private boolean discoverServices(int discoveryId, String serviceType) { + if (DBG) Slog.d(TAG, "discoverServices: " + discoveryId + " " + serviceType); try { mNativeConnector.execute("mdnssd", "discover", discoveryId, serviceType); } catch(NativeDaemonConnectorException e) { - Slog.e(TAG, "Failed to discoverServices"); + Slog.e(TAG, "Failed to discoverServices " + e); + return false; + } + return true; + } + + private boolean stopServiceDiscovery(int discoveryId) { + if (DBG) Slog.d(TAG, "stopServiceDiscovery: " + discoveryId); + try { + mNativeConnector.execute("mdnssd", "stop-discover", discoveryId); + } catch(NativeDaemonConnectorException e) { + Slog.e(TAG, "Failed to stopServiceDiscovery " + e); + return false; + } + return true; + } + + private boolean resolveService(int resolveId, DnsSdServiceInfo service) { + if (DBG) Slog.d(TAG, "resolveService: " + resolveId + " " + service); + try { + mNativeConnector.execute("mdnssd", "resolve", resolveId, service.getServiceName(), + service.getServiceType(), "local."); + } catch(NativeDaemonConnectorException e) { + Slog.e(TAG, "Failed to resolveService " + e); + return false; + } + return true; + } + + private boolean stopResolveService(int resolveId) { + if (DBG) Slog.d(TAG, "stopResolveService: " + resolveId); + try { + mNativeConnector.execute("mdnssd", "stop-resolve", resolveId); + } catch(NativeDaemonConnectorException e) { + Slog.e(TAG, "Failed to stop resolve " + e); + return false; } + return true; } - private void stopServiceDiscovery(int discoveryId) { + private boolean getAddrInfo(int resolveId, String hostname) { + if (DBG) Slog.d(TAG, "getAdddrInfo: " + resolveId); try { - mNativeConnector.execute("mdnssd", "stopdiscover", discoveryId); + mNativeConnector.execute("mdnssd", "getaddrinfo", resolveId, hostname); } catch(NativeDaemonConnectorException e) { - Slog.e(TAG, "Failed to stopServiceDiscovery"); + Slog.e(TAG, "Failed to getAddrInfo " + e); + return false; } + return true; } - private void resolveService(DnsSdServiceInfo service) { + private boolean stopGetAddrInfo(int resolveId) { + if (DBG) Slog.d(TAG, "stopGetAdddrInfo: " + resolveId); try { - mNativeConnector.execute("mdnssd", "resolve", service.getServiceName(), - service.getServiceType()); + mNativeConnector.execute("mdnssd", "stop-getaddrinfo", resolveId); } catch(NativeDaemonConnectorException e) { - Slog.e(TAG, "Failed to resolveService"); + Slog.e(TAG, "Failed to stopGetAddrInfo " + e); + return false; } + return true; } @Override @@ -266,4 +519,51 @@ public class NsdService extends INsdManager.Stub { pw.println("Internal state:"); } + + private ClientInfo getClientByDiscovery(int discoveryId) { + for (ClientInfo c: mClients.values()) { + if (c.mDiscoveryId == discoveryId) { + return c; + } + } + return null; + } + + private ClientInfo getClientByResolve(int resolveId) { + for (ClientInfo c: mClients.values()) { + if (c.mResolveId == resolveId) { + return c; + } + } + return null; + } + + private ClientInfo getClientByRegistration(int regId) { + for (ClientInfo c: mClients.values()) { + if (c.mRegisteredIds.contains(regId)) { + return c; + } + } + return null; + } + + /* Information tracked per client */ + private class ClientInfo { + + private static final int MAX_REG = 5; + private AsyncChannel mChannel; + private Messenger mMessenger; + private int mDiscoveryId; + private int mResolveId; + /* Remembers a resolved service until getaddrinfo completes */ + private DnsSdServiceInfo mResolvedService; + private ArrayList<Integer> mRegisteredIds = new ArrayList<Integer>(); + + private ClientInfo(AsyncChannel c, Messenger m) { + mChannel = c; + mMessenger = m; + mDiscoveryId = mResolveId = INVALID_ID; + if (DBG) Slog.d(TAG, "New client, channel: " + c + " messenger: " + m); + } + } } |