Bonjour/Zerconf library

Dependencies:   mbed

services/mDNS/mDNSResponder.h

Committer:
dirkx
Date:
2010-07-31
Revision:
4:d9f5c4abc5f8
Parent:
2:816cbd922d3e

File content as of revision 4:d9f5c4abc5f8:

#ifndef MDNS_RESPONDER_H
#define MDNS_RESPONDER_H


#include "lwip/opt.h"

#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */

#include "if/net/net.h"
#include "api/UDPSocket.h"
#include "api/DNSRequest.h"
#include "mbed.h"

#include "lwip/udp.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/dns.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

#ifndef MDNS_QCACHE
#define MDNS_QCACHE 1
#endif

#ifndef MDNS_MAXCACHEDNSLABELS
#define MDNS_MAXCACHEDNSLABELS (10)
#endif

class mDNSResponder : protected NetService
{
public:
  mDNSResponder();
  virtual ~mDNSResponder();
  void close();
  void 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(); // Needed for timer, to fire off regular updates.
  
  // Main inbound packet handler
  void onUDPSocketEvent(UDPSocketEvent e);

  // 3 functions to keep a QName chace. If enabled with MDNS_QCACHE
  void initLabelCache(char * off);
  uint16_t checkLabelCache(char * name);
  void addLabelCache(char * p, char * name);
  
  // Handing functions
  char * breakname(char *p, char *name); // Break FQDNs at the dots, understanding QCaching.
  
  // reply building functions; see RFC for names/defintion.
  char * mRR(char *p, char * name, uint16_t tpe, uint16_t cls, uint32_t ttl);
  char * mRRLABEL(char *p, char * name, uint16_t tpe, char ** rr); 
  char * mPTR(char *p, char * name, char * r); 
  char * mTXT(char *p, char * name, char ** rr);
  char * mARR(char *p, char * name, IpAddr ip);
  char * mSRV(char *p, char * name, uint16_t port, char * rr);
  char * qANY(char *p, char * name, uint16_t tpe, uint16_t cls);

  // build query part of a reply.
  char * qPTR(char *p, char *name);
  char * qA(char *p, char *name);
  char * qSRV(char *p, char *name);
  
  // Sent out the actual DNS packet.
  void sendReply(uint16_t t, uint16_t tid, Host dst);
  
  // Decode the query part of a DNS inbound packet.
  char * decodeQBlock(char * udp, int len, char *p, char  * fqdn, int fqdn_size, uint32_t *Qclass, uint32_t *Qtype);

PACK_STRUCT_BEGIN
struct DNSPacket
  {
    PACK_STRUCT_FIELD(uint16_t tid);
    PACK_STRUCT_FIELD(uint16_t flags);
    PACK_STRUCT_FIELD(uint16_t question_count);
    PACK_STRUCT_FIELD(uint16_t answer_count);
    PACK_STRUCT_FIELD(uint16_t a_count);
    PACK_STRUCT_FIELD(uint16_t aa_count);
    PACK_STRUCT_FIELD(char answers);
  } PACK_STRUCT_STRUCT;
PACK_STRUCT_END
  
  // Services
  char ** moi_txt; /* Null terminated list */
  
  // Endpoint
  uint16_t moi_port;
  IpAddr moi_ip;
  
  // Local name construction.
  const char * moi_name, * moi_proto;
  char * moi_local_proto, * moi_local_name, * moi_local_pglue;
  
  Timer announcer;
    
  UDPSocket* m_pUDPSocket;

  // For the QCache
#ifdef MDNS_QCACHE
  int labelCacheCnt;
  char * labelCacheOffset;
  
  uint16_t _cache_off[MDNS_MAXCACHEDNSLABELS];
  char * _cache_och[MDNS_MAXCACHEDNSLABELS];
#endif
};



#endif

// 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

#endif