Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 638
Hounshell Avatar asked Feb 12 '14 08:02

Hounshell


1 Answers

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! :)

like image 95
Daniel Schoonwinkel Avatar answered Nov 09 '22 22:11

Daniel Schoonwinkel