Dirk-Willem van Gulik (NXP/mbed)
/
Bonjour
Bonjour/Zerconf library
Revision 1:59820ca5c83a, committed 2010-07-22
- Comitter:
- dirkx
- Date:
- Thu Jul 22 00:08:38 2010 +0000
- Parent:
- 0:355018f44c9f
- Child:
- 2:816cbd922d3e
- Commit message:
Changed in this revision
--- 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