Android NsdManager resolve return errorCode 0

446 Views Asked by At

I want to resolve an IPaddress of a custom IOT device(esp8266) with an Android device.

After some research I think there are two great options to do this. First option is the android NsdManager. The second option is Android mDNSResponder.

I prefer to do this with the NsdManager.

I used the android manual and some other posts to get a good example. When I try to resolve a service to get an Ip address and port number I constantly get a 0 as result.(internal failure error).

To be sure that the ESP is working correctly I installed a app with mdns-sd browser to test it. This is working fine.

Can someone give me a hint why i get a 0 as result?

ESP8266:

AsyncWebServer server(80);
DNSServer dns;

uint16_t GetDeviceId()
{
    return ESP.getChipId();
}


String MakeMine(const char *NameTemplate)
{
    uint16_t uChipId = GetDeviceId();
    String Result = String(NameTemplate) + String(uChipId, HEX);
    return Result;
}

void setup() {
    Serial.begin(115200);

    AsyncWiFiManager wifiManager(&server,&dns);

    wifiManager.autoConnect("AutoConnectAP");
    if (MDNS.begin("lego-test")) {             
        String MyName = MakeMine("LegoSensor");
        MDNS.addService(MyName.c_str(), "tcp", 23);
    }else{
        Serial.println("Error setting up MDNS responder!");
    }
}

void loop() {
    MDNS.update();
} 

Android:

public class MainActivity extends BridgeActivity {
  public String TAG = "test_mdns";
  private NsdManager.DiscoveryListener discoveryListener;
  private NsdManager mgr;
  

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Initializes the Bridge
    registerPlugin(ToiletLegoPlugin.class);
    mgr = (NsdManager) getSystemService(Context.NSD_SERVICE);

    initializeDiscoveryListener();
    this.discoverServices();
  }

  public void discoverServices() {
    mgr.discoverServices("_services._dns-sd._udp", NsdManager.PROTOCOL_DNS_SD, discoveryListener);
  }

  public void stopDiscovery() {
    mgr.stopServiceDiscovery(discoveryListener);
  }

  public void initializeDiscoveryListener() {
    discoveryListener = new NsdManager.DiscoveryListener() {
      @Override
      public void onDiscoveryStarted(String regType) {
        Log.d(TAG, "Service discovery started");
      }

      @Override
      public void onServiceFound(NsdServiceInfo service) {
        if(service.getServiceName().contains("LegoSensor")){
          Log.d(TAG, "Service discovery success" + service);
          Log.d(TAG, "Type: " + service.getServiceType());
          Log.d(TAG, "Service Name: " + service.getServiceName());
          Log.d(TAG, "Service discovery success = " + service.toString());

            mgr.resolveService(service, new InitializeResolveListener());
        }
      }

      @Override
      public void onServiceLost(NsdServiceInfo service) {
         Log.e(TAG, "service lost: " + service);
      }

      @Override
      public void onDiscoveryStopped(String serviceType) {
        Log.i(TAG, "Discovery stopped: " + serviceType);
      }

      @Override
      public void onStartDiscoveryFailed(String serviceType, int errorCode) {
        Log.e(TAG, "Discovery failed: Error code:" + errorCode);
        mgr.stopServiceDiscovery(this);
      }

      @Override
      public void onStopDiscoveryFailed(String serviceType, int errorCode) {
        Log.e(TAG, "Discovery failed: Error code:" + errorCode);
        mgr.stopServiceDiscovery(this);
      }
    };
  }

  public class InitializeResolveListener implements NsdManager.ResolveListener {
    @Override
    public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
      Log.e(TAG, "Resolve failed" + errorCode);
    }

    @Override
    public void onServiceResolved(NsdServiceInfo serviceInfo) {
      Log.e(TAG, "Resolve Succeeded. " + serviceInfo);

      int port = serviceInfo.getPort();
      InetAddress host = serviceInfo.getHost(); // getHost() will work now

      Log.d(TAG, "Host: " + host.getHostAddress());
    }
  };

}

Logcat:

2022-01-03 17:42:26.506 548-642/? E/NsdService: Failed to execute mdnssd [resolve, 152552, _LegoSensora15f, _tcp.local., local.]
    com.android.server.NativeDaemonConnector$NativeDaemonArgumentException: command '152710 mdnssd resolve 152552 _LegoSensora15f _tcp.local. local.' failed with '501 152710 resolveService got an error from DNSServiceResolve'
        at com.android.server.NativeDaemonConnector.executeForList(NativeDaemonConnector.java:512)
        at com.android.server.NativeDaemonConnector.execute(NativeDaemonConnector.java:411)
        at com.android.server.NativeDaemonConnector.execute(NativeDaemonConnector.java:406)
        at com.android.server.NsdService$DaemonConnection.execute(NsdService.java:698)
        at com.android.server.NsdService.resolveService(NsdService.java:749)
        at com.android.server.NsdService.access$2300(NsdService.java:61)
        at com.android.server.NsdService$NsdStateMachine$EnabledState.processMessage(NsdService.java:363)
        at com.android.internal.util.StateMachine$SmHandler.processMsg(StateMachine.java:992)
        at com.android.internal.util.StateMachine$SmHandler.handleMessage(StateMachine.java:809)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.os.HandlerThread.run(HandlerThread.java:65)
2022-01-03 17:42:26.507 315-23443/? I/ADB_SERVICES: post waitpid (pid=23442) status=0000
2022-01-03 17:42:26.514 23388-23438/com.lego.frontend E/test_mdns: Resolve failed0
1

There are 1 best solutions below

2
On

I found the problem. I mixed the name of MDNS with the name service type. Argh after 5 hours debugging.