Spark Core and MDNS

Spark Core and MDNS

Here is the Spark Core port of Adafruit MDNS library. The library provides the ability to setup a name for the Spark Core and resolve it. We can name the Core anything we want, the library will append “.local” to the name and we can access the Core using the URL “name.local”.

The sample application names the Core as “myspark”. If the MDNS is setup correctly then it creates a TCPServer on port 80. The Core can be accessed using the URL “http://myspark.local”. The server simply prints a test message.

Requirement

  1. For Mac OSX support is built in through Bonjour already.
  2. For Linux, install Avahi.
  3. For Windows, install Bonjour.
8 Likes

I think your library url was eaten up… :ghost:

Oh… my mistake, its corrected. Thanks @kennethlimcp for pointing out.

Sorry about that :frowning:

1 Like

Hi @kvarma

I have tried this out with both an iOS device and a Mac and it is not working for me. I have a couple Bonjour explorer type programs and none can see the core. I see the request packets on wireshark but I don’t see responses. The core eventually goes into flashing cyan and reboots–I am not sure why.

Is there something else you did to get this to work?

@bko, the following code works for me when I am connected to same network.

// This #include statement was automatically added by the Spark IDE.
#include "mdns/mdns.h"

#define LISTEN_PORT 7

TCPServer echoServer(LISTEN_PORT);
MDNSResponder mdns;

char szIP[64];
bool isStarted;
char szHTML[] = "<html><body><p>Spark Core and MDNS Working :)</p></body></html>";

TCPServer server = TCPServer(80);

void setup() {
    // Retrieve and convert to integer format
    IPAddress addr = Network.localIP();
    uint32_t ip = (addr[0] * 16777216) + (addr[1] * 65536) + (addr[2] * 256) + (addr[3]);
    
    // Begin MDNS
    isStarted = mdns.begin("myspark", ip);
    
    // If started, set the variable to IP address of the Spark Core
    // else set error message
    if(isStarted){
        sprintf(szIP, "%d.%d.%d.%d (%u)", addr[0], addr[1], addr[2], addr[3], ip);
         server.begin();
    }
    else{
        sprintf(szIP, "Error starting MDNS.");
    }
    
    Spark.variable("mdnsstatus", szIP, STRING);
}

void loop() {
    // If we started successfully, then wait for the client to connect
    // else do nothing
    if(isStarted){
        mdns.update();
        
        TCPClient client = server.available();
        if (client){
            client.write(szHTML);
            client.flush();
            client.stop();
        }
    }
    
    delay(2000);
}

I experienced this issue while developing and when I forgot to add the mdns.update(); in loop. Once it is added it is working on Mac, I didn’t test on Windows. Will that be the issue in your case?. Also could you please check the mdnsstatus variable?

OK, that must be it. I had pulled your example out from your github. If you haven’t already updated it, that might be good to do. I will try it again tonight.

Thanks!

2 Likes

Yes, I updated example the code already, by mistake I pushed the example code with out the mdns.update() first, then I corrected it later. I should be more careful next time :smile:

Thanks @bko and please update the result.

1 Like

Cool stuff. Does the mDNS library work on the Photon?
Or is there some other way of doing service discovery on the Photon that people have used?

@mars, it didn’t check it but it should work.

1 Like

Hello krvarma,it is this example is suitable for Spark Photon either? I vertifyed your example in the particle build and it showed some errors.Can you help me ?thanks!

mdns.cpp:136:54: error: 'socket' was not declared in this scope
     int soc = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
mdns.cpp:141:5: error: 'sockaddr_in' was not declared in this scope
     sockaddr_in address;
mdns.cpp:141:17: error: expected ';' before 'address'
     sockaddr_in address;
mdns.cpp:142:13: error: 'address' was not declared in this scope
     memset(&address, 0, sizeof(address));
mdns.cpp:144:34: error: 'htons' was not declared in this scope
     address.sin_port = htons(5353);
mdns.cpp:145:59: error: 'htonl' was not declared in this scope
     address.sin_addr.s_addr = htonl(ip2int(224, 0, 0, 251));                                                       ^
mdns.cpp:147:20: error: 'sockaddr' was not declared in this scope
     if (bind(soc, (sockaddr*) &address, sizeof(address)) < 0) {
mdns.cpp:147:29: error: expected primary-expression before ')' token
     if (bind(soc, (sockaddr*) &address, sizeof(address)) < 0) {                         
mdns.cpp:147:56: error: 'bind' was not declared in this scope
     if (bind(soc, (sockaddr*) &address, sizeof(address)) < 0) {
mdns.cpp:146:15: warning: unused variable 'len' [-Wunused-variable]
     socklen_t len = sizeof(address);
mdns.cpp: In member function 'void MDNSResponder::update()':
mdns.cpp:167:3: error: 'timeval' was not declared in this scope
   timeval timeout;
mdns.cpp:167:11: error: expected ';' before 'timeout'
   timeval timeout;
mdns.cpp:168:3: error: 'timeout' was not declared in this scope
   timeout.tv_sec = 0;
mdns.cpp:170:3: error: '_types_fd_set_cc3000' was not declared in this scope
   _types_fd_set_cc3000 reads
mdns.cpp:170:24: error: expected ';' before 'reads'
   _types_fd_set_cc3000 reads;
mdns.cpp:171:12: error: 'reads' was not declared in this scope
   FD_ZERO(&reads);      ^
mdns.cpp:172:24: error: 'reads' was not declared in this scope
   FD_SET(_mdnsSocket, &reads);
mdns.cpp:173:55: error: 'select' was not declared in this scope
   select(_mdnsSocket + 1, &reads, NULL, NULL, &timeout);
mdns.cpp:180:55: error: 'recv' was not declared in this scope
   int n = recv(_mdnsSocket, &buffer, sizeof(buffer), 0);
mdns.cpp: In member function 'void MDNSResponder::sendResponse()':
mdns.cpp:241:47: error: 'send' was not declared in this scope
   send(_mdnsSocket, _response, _responseLen, 0);

@Jackson_lv, I think we need to chage the socket functions, let me take a look at it and get back to you.

Hi krvarma, Me too getting same errors as Jackson_Iv. Can you please help us with this.

I am trying it for photon.

@sravanjosh, I too facing this problem but because of some time restriction I didn’t work on that. There are some changes for Photons we need to make, like passing network interface to the socket functions. I am not sure about what all the changes we need to make. Hopefully I can work on it this weekend. Will let you know the progress.

1 Like