How do i get a Peer-to-peer WiFi service discovery to work?

android, wifi-direct, wifip2p

Solution

I have some experience with working with Wi-Fi Direct on Android devices, I am writing an app to connect devices ad-hoc and enabling chatting across this link.

To be discoverable on Wi-Fi Direct, both devices needs to be scanning, ie. `mWifiP2pManager.discoverPeers()`. Strangely, this also affects the discovery of `DnsTxtRecordServices`. Thus, I have found it works if you start your `scanning( discoverPeers())` on both devices and then start `discoverPeers()`.

Hope this helps! :)

Problem

I'm trying to build a server-client architecture using two Android devices with a peer-to-peer WiFi connection. I've got a clear distinction between client and server, so I'm trying to prune out unnecessary code. Using directions from http://developer.android.com/training/connect-devices-wirelessly/nsd-wifi-direct.html I've got... PeerToPeerService ``` public class PeerToPeerService { private static final Logger LOG = LoggerFactory.getLogger(PeerToPeerService.class); private WifiP2pManager mManager; private WifiP2pManager.Channel mChannel; private final Context mContext; private final WifiP2pDnsSdServiceInfo mService; public PeerToPeerService(Context context, String name) { mContext = context; Map<String, String> record = new HashMap<String, String>(); record.put(Constants.SERVICE_PROPERTY_NAME, name); record.put(Constants.SERVICE_PROPERTY_PORT, "12345"); mService = WifiP2pDnsSdServiceInfo.newInstance( "_test", "_presence._tcp", record); } public void start() { mManager = (WifiP2pManager) mContext.getSystemService(Context.WIFI_P2P_SERVICE); mChannel = mManager.initialize(mContext, mContext.getMainLooper(), null); mManager.addLocalService(mChannel, mService, new ActionListener() { @Override public void onSuccess() { LOG.info("Started Service"); } @Override public void onFailure(int error) { LOG.warn("Failed to Start Service: {}", error); } }); } public void stop() { mManager.removeLocalService(mChannel, mService, null); mManager = null; LOG.info("Stopped Service"); } } ``` PeerToPeerClient ``` public class PeerToPeerClient { private static final Logger LOG = LoggerFactory.getLogger(PeerToPeerClient.class); private WifiP2pManager mManager; private WifiP2pManager.Channel mChannel; private final Context mContext; public PeerToPeerClient(Context context) { mContext = context; } public void findServices() { mManager = (WifiP2pManager) mContext.getSystemService(Context.WIFI_P2P_SERVICE); mChannel = mManager.initialize(mContext, mContext.getMainLooper(), null); mManager.setDnsSdResponseListeners(mChannel, new DnsSdServiceResponseListener() { @Override public void onDnsSdServiceAvailable(String instanceName, String registrationType, WifiP2pDevice device) { LOG.info("A"); LOG.info("Service Found: {}:{}", instanceName, registrationType); } }, new DnsSdTxtRecordListener() { @Override public void onDnsSdTxtRecordAvailable(String fullDomainName, Map<String, String> record, WifiP2pDevice device) { LOG.info("B"); LOG.info("{}:{} is {}", device.deviceName, record.get(Constants.SERVICE_PROPERTY_PORT), record.get(Constants.SERVICE_PROPERTY_NAME)); } }); WifiP2pDnsSdServiceRequest serviceRequest = WifiP2pDnsSdServiceRequest.newInstance(); mManager.addServiceRequest(mChannel, serviceRequest, new ActionListener() { @Override public void onSuccess() { LOG.info("Added service discovery request"); } @Override public void onFailure(int error) { LOG.info("Failed adding service discovery request: {}", error); } }); mManager.discoverServices(mChannel, new ActionListener() { @Override public void onSuccess() { LOG.info("Service discovery initiated"); } @Override public void onFailure(int arg0) { LOG.info("Service discovery failed"); } }); } } ``` Every single ActionListener has onSuccess called, no failures anywhere. But I never get any of the setDnsSdResponseListeners callbacks. Any ideas where I might have gone wrong?

Original source