Bonjour/Zerconf library

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
dirkx
Date:
Thu Jul 22 00:08:38 2010 +0000
Parent:
0:355018f44c9f
Child:
2:816cbd922d3e
Commit message:

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
services/mDNS/mDNSResponder.cpp Show annotated file Show diff for this revision Revisions of this file
services/mDNS/mDNSResponder.h Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Wed Jul 21 19:25:56 2010 +0000
+++ b/main.cpp	Thu Jul 22 00:08:38 2010 +0000
@@ -1,13 +1,14 @@
 #include "mbed.h"
 
-// Ethernet, DHCP
 #include "EthernetNetIf.h"
+#include "HTTPServer.h"
 
 // mDNS response to announce oneselve
 #include "services/mDNS/mDNSResponder.h"
 
 DigitalOut myled(LED1);
 EthernetNetIf eth;
+HTTPServer srv;
 mDNSResponder mdns;
 
 int main() {
@@ -16,11 +17,32 @@
         printf("Error %d in setup on DHCP.\r\n", ethErr);
         return -1;
     }
-    printf("Trying to get IP address\r\n");
+    srv.addHandler<SimpleHandler>("/"); // Something.
+    srv.addHandler<SimpleHandler>("/sample"); // Something too
+    srv.bind(80);
+        
     IpAddr ip = eth.getIp();
     printf("mbed IP Address is %d.%d.%d.%d\r\n", ip[0], ip[1], ip[2], ip[3]);
 
-    mdns.announce(ip, "_http._tcp", 80, "May the blood run free", "path=/sample");
+    // Announce above web server - and keep doing that every minute or so.
+    //
+    mdns.announce(
+        ip,                         // (My) IP address - where announced service runs.
+        "propername",               // DNS name server or service
+        "_http._tcp",               // protocol
+        80,                         // Port number
+        "May the blood run free",   // User interface name service
+        (char *[]) {                // NULL terminated list of KV's = see                                     // http://www.zeroconf.org/Rendezvous/txtrecords.html
+            "path=/sample",         // http://www.zeroconf.org/Rendezvous/txtrecords.html
+//          "key2=someval", 
+//          "and=more",
+            NULL
+        }
+    );
+    
+    // So that clicking on 'May the blood run free' will jump to:
+    //
+    //   http://propername.local.:80/sample (or http://propername/sample in the bar)
 
     printf("Entering while loop Net::poll()ing\r\n");
     while (1) {
--- a/services/mDNS/mDNSResponder.cpp	Wed Jul 21 19:25:56 2010 +0000
+++ b/services/mDNS/mDNSResponder.cpp	Thu Jul 22 00:08:38 2010 +0000
@@ -26,12 +26,15 @@
  *   printf("mbed IP Address is %d.%d.%d.%d\r\n", ip[0], ip[1], ip[2], ip[3]);
  *
  *   // Announce ourselves.
- *   mdns.announce(ip, "_http._tcp", 80, "The Little Server that Could", "path=/demo");
+ *   mdns.announce(ip, "fred", "_http._tcp", 80, "The Little Server that Could", "path=/demo");
  *
  *   while()... enter some run loop
- *   
- *   Or as another example: (http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt)
- *   and the various RFCs:
+ *   ...
+ *
+ *  This will cause http://fred.local./demo to be announced as 'The Little Server that Could'.
+ *
+ *  Or as another example: (http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt)
+ *  and the various RFCs:
  *
  *     mdns.announce(ip, "_ssh._tcp", 22, SSH to Serial Gateway", NULL);
  *
@@ -59,7 +62,7 @@
       close();
 }
 
-void mDNSResponder::announce(IpAddr ip, const char * proto, uint16_t port, const char * name, const char * txt) {
+void mDNSResponder::announce(IpAddr ip, const char * ldn, const char * proto, uint16_t port, const char * name, char ** txt) {
     Host localhost(IpAddr(MCAST), MDNS_PORT, NULL /* fqdn */);
 
     m_pUDPSocket = new UDPSocket;
@@ -79,7 +82,7 @@
 
     #define LOCAL "local"
     snprintf(moi_local_proto,128,"%s.%s.", moi_proto, LOCAL);
-    snprintf(moi_local_name,128,"%s.%s.", moi_name, LOCAL);
+    snprintf(moi_local_name,128,"%s.%s.", ldn, LOCAL);
     snprintf(moi_local_pglue,128,"%s.%s.%s.", moi_name,moi_proto, LOCAL);
     
     // Gratuis intro - and repeat such regularly..
@@ -140,7 +143,7 @@
     _cache_och[labelCacheCnt] = name;
 
     labelCacheCnt++;
-    // we intentionally do not wack the first two - as they are the most
+    // we intentionally do not wack the first entries - as they are the most
     // likely ones to be used.
     if (labelCacheCnt>=MAXCACHEDNSLABELS)
         labelCacheCnt = MAXCACHEDNSLABELS / 3;
@@ -207,25 +210,28 @@
     return p;
 }
 
-char * mRRLABEL(char *p, char * name, uint16_t tpe, char * rr) {
+char * mRRLABEL(char *p, char * name, uint16_t tpe, char ** rr) {
     uint16_t i;
 
     p = mRR(p, name, tpe, 1, MDNS_TTL); // Type, IN, TTL
 
     // RR String
     char * q = p + 2;
-    q = breakname(q, rr);
-
+    
+    for(;*rr;rr++) 
+        q = breakname(q, *rr);
+    
     i = htons(q - p - 2); // RDLEN
     memcpy(p, &i, 2);
     return q;
 }    
 
-char * mPTR(char *p, char * name, char * rr) {
-    return mRRLABEL(p, name, 12 /* PTR */, rr);
+char * mPTR(char *p, char * name, char * r) {
+    char *rr[] = { r, NULL };
+    return mRRLABEL(p, name, 12 /* PTR */, rr );
 }
     
-char * mTXT(char *p, char * name, char * rr) {
+char * mTXT(char *p, char * name, char ** rr) {
     return mRRLABEL(p, name, 16 /* TXT */, rr);
 }
 
@@ -309,8 +315,8 @@
     p = qPTR(p,moi_local_proto);
     p = mPTR(p,moi_local_proto, moi_local_pglue);
     p = mSRV(p,moi_local_pglue,80, moi_local_name);
-    if (moi_txt)
-         p = mTXT(p,moi_local_pglue,(char *)moi_txt);
+    if (moi_txt && * moi_txt)
+         p = mTXT(p,moi_local_pglue,moi_txt);
     p = mARR(p,moi_local_name,moi_ip); // fill out my own IP address.
 
     m_pUDPSocket->sendto(out,p-out,&dst);
@@ -337,7 +343,7 @@
 
                 #define MAXDEPTH 64
                 #define MAXRR 192 /* including dot */
-
+                
                 // assume nQ zero terminated fields followed by Qtype & Qclass
                 char * p = udp + 12;
                 for (int i = 0; i < nQ; i++) {
@@ -388,6 +394,8 @@
                     unsigned int Qt = htons(q[0] + q[1]*256);
                     unsigned int Qc = htons(q[2] + q[3]*256);
                     p = q + 4;
+                    
+                    printf("Q for %s\r\n", buff);
                     // We want PTR records on the INternet of our type
                     if ((Qt == 12) && (Qc == 1) && !(strcmp(buff,moi_local_proto))) 
                         sendReply(tid,from);                        
--- a/services/mDNS/mDNSResponder.h	Wed Jul 21 19:25:56 2010 +0000
+++ b/services/mDNS/mDNSResponder.h	Thu Jul 22 00:08:38 2010 +0000
@@ -1,78 +1,79 @@
-
-#ifndef MDNS_RESPONDER_H
-#define MDNS_RESPONDER_H
-
-#include "if/net/net.h"
-#include "api/UDPSocket.h"
-#include "api/DNSRequest.h"
-#include "mbed.h"
-
-// As defined by IANA.
-//
-#define MDNS_PORT (5353)
-#define MCAST 224,0,0,251
-
-// How long we announce our IP and URLs to be valid. Should
-// ideally be 1/3 or so of the DHCP lease time. But we do 
-// not know that.
-//
-#define MDNS_TTL ( 100 )
-
-// Rebroadcast our details more regularly than the TTL as 
-// we otherwise get dropped.
-//
-#ifndef MDNS_INTERVAL
-#define MDNS_INTERVAL ( MDNS_TTL * 2 / 3 )
-#endif
-
-class mDNSResponder : protected NetService
-{
-public:
-  mDNSResponder();
-  virtual ~mDNSResponder();
-  void close();
-void mDNSResponder::announce(IpAddr ip, const char * proto, uint16_t port, const char * name, const char * txt);
-  
-protected:
-  virtual void poll(); //Called by NetServices - not actually needed.
-  
-private:
-  void process(); //Main state-machine
-  void onUDPSocketEvent(UDPSocketEvent e);
-  void sendReply(uint16_t tid, Host dst); // temp
-  
-// Just in case - there is prolly some nice ARM6 assembler already linked in.
-#ifndef htons
-#define htons( x ) ( (( x << 8 ) & 0xFF00) | (( x >> 8 ) & 0x00FF) )
-#define ntohs( x ) (htons(x))
-#endif
-
-#ifndef htonl
-#define htonl( x ) ( (( x << 24 ) & 0xff000000)  \
-                   | (( x <<  8 ) & 0x00ff0000)  \
-                   | (( x >>  8 ) & 0x0000ff00)  \
-                   | (( x >> 24 ) & 0x000000ff)  )
-#define ntohl( x ) (htonl(x))
-#endif
-
-  __packed struct DNSPacket
-  {
-    uint16_t tid;
-    uint16_t flags;
-    uint16_t question_count;
-    uint16_t answer_count;
-    uint16_t a_count;
-    uint16_t aa_count;
-    char answers;
-  };
-  const char * moi_name, * moi_proto, * moi_txt;
-  char * moi_local_proto, * moi_local_name, * moi_local_pglue;
-  uint16_t moi_port;
-  IpAddr moi_ip;
-  
-  Timer announcer;
-    
-  UDPSocket* m_pUDPSocket;
-};
-
-#endif
+
+#ifndef MDNS_RESPONDER_H
+#define MDNS_RESPONDER_H
+
+#include "if/net/net.h"
+#include "api/UDPSocket.h"
+#include "api/DNSRequest.h"
+#include "mbed.h"
+
+// As defined by IANA.
+//
+#define MDNS_PORT (5353)
+#define MCAST 224,0,0,251
+
+// How long we announce our IP and URLs to be valid. Should
+// ideally be 1/3 or so of the DHCP lease time. But we do 
+// not know that.
+//
+#define MDNS_TTL ( 100 )
+
+// Rebroadcast our details more regularly than the TTL as 
+// we otherwise get dropped.
+//
+#ifndef MDNS_INTERVAL
+#define MDNS_INTERVAL ( MDNS_TTL * 2 / 3 )
+#endif
+
+class mDNSResponder : protected NetService
+{
+public:
+  mDNSResponder();
+  virtual ~mDNSResponder();
+  void close();
+void mDNSResponder::announce(IpAddr ip, const char * ldn, const char * proto, uint16_t port, const char * name, char ** txts);
+  
+protected:
+  virtual void poll(); //Called by NetServices - not actually needed.
+  
+private:
+  void process(); //Main state-machine
+  void onUDPSocketEvent(UDPSocketEvent e);
+  void sendReply(uint16_t tid, Host dst); // temp
+  
+// Just in case - there is prolly some nice ARM6 assembler already linked in.
+#ifndef htons
+#define htons( x ) ( (( x << 8 ) & 0xFF00) | (( x >> 8 ) & 0x00FF) )
+#define ntohs( x ) (htons(x))
+#endif
+
+#ifndef htonl
+#define htonl( x ) ( (( x << 24 ) & 0xff000000)  \
+                   | (( x <<  8 ) & 0x00ff0000)  \
+                   | (( x >>  8 ) & 0x0000ff00)  \
+                   | (( x >> 24 ) & 0x000000ff)  )
+#define ntohl( x ) (htonl(x))
+#endif
+
+  __packed struct DNSPacket
+  {
+    uint16_t tid;
+    uint16_t flags;
+    uint16_t question_count;
+    uint16_t answer_count;
+    uint16_t a_count;
+    uint16_t aa_count;
+    char answers;
+  };
+  const char * moi_name, * moi_proto;
+  char ** moi_txt; /* Null terminated list */
+  char * moi_local_proto, * moi_local_name, * moi_local_pglue;
+  uint16_t moi_port;
+  IpAddr moi_ip;
+  
+  Timer announcer;
+    
+  UDPSocket* m_pUDPSocket;
+};
+
+#endif