dns_sd/ : Initial commit.
This commit is contained in:
parent
a6692e3365
commit
969f1778fd
307
dns_sd/dns_sd.cpp
Normal file
307
dns_sd/dns_sd.cpp
Normal file
@ -0,0 +1,307 @@
|
|||||||
|
#include "dns_sd.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include "dns_sd_const.h"
|
||||||
|
#include "dns_sd_print.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define DNS_SD_SERVICE_TYPE_STRING "_services._dns-sd._udp"
|
||||||
|
|
||||||
|
dns_sd::dns_sd(sendCallback_t sendCbFunc, void* sendCbArg )
|
||||||
|
: _sendCbFunc(sendCbFunc),_sendCbArg(sendCbArg),_serviceName(nullptr),_serviceType(nullptr),_serviceDomain(nullptr),_hostName(nullptr),_hostPort(0),_text(nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
dns_sd::dns_sd( sendCallback_t sendCbFunc, void* sendCbArg, const char* serviceName, const char* serviceType, const char* serviceDomain, const char* hostName, uint32_t hostAddr, uint16_t hostPort, const char* text )
|
||||||
|
: _sendCbFunc(sendCbFunc),_sendCbArg(sendCbArg),_serviceName(nullptr),_serviceType(nullptr),_serviceDomain(nullptr),_hostName(nullptr),_hostPort(0),_text(nullptr)
|
||||||
|
{
|
||||||
|
setup( serviceName, serviceType, serviceDomain, hostName, hostAddr, hostPort, text );
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_sd::~dns_sd()
|
||||||
|
{
|
||||||
|
_free();
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_sd::result_t dns_sd::setup( const char* serviceName, const char* serviceType, const char* serviceDomain, const char* hostName, uint32_t hostAddr, uint16_t hostPort, const char* text )
|
||||||
|
{
|
||||||
|
_free();
|
||||||
|
|
||||||
|
_serviceName = strdup(serviceName);
|
||||||
|
_serviceType = strdup(serviceType);
|
||||||
|
_serviceDomain = strdup(serviceDomain);
|
||||||
|
_hostName = strdup(hostName);
|
||||||
|
_hostAddr = hostAddr;
|
||||||
|
_text = strdup(text);
|
||||||
|
_hostPort = hostPort;
|
||||||
|
|
||||||
|
return kOkRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_sd::result_t dns_sd::receive( const void* buf, unsigned bufByteN )
|
||||||
|
{
|
||||||
|
_parse((const char*)buf,bufByteN);
|
||||||
|
return kOkRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dns_sd::gen_question()
|
||||||
|
{
|
||||||
|
unsigned n = _calc_question_byte_count();
|
||||||
|
unsigned char *b = (unsigned char*)calloc(1,n);
|
||||||
|
_format_question(b, n);
|
||||||
|
_send(b,n);
|
||||||
|
free(b);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void dns_sd::gen_response()
|
||||||
|
{
|
||||||
|
unsigned n = _calc_response_byte_count();
|
||||||
|
unsigned char* b = (unsigned char*)calloc(1,n);
|
||||||
|
_format_response(b, n);
|
||||||
|
_send(b,n);
|
||||||
|
free(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dns_sd::_free()
|
||||||
|
{
|
||||||
|
if( _serviceName ) free( _serviceName );
|
||||||
|
if( _serviceType ) free( _serviceType );
|
||||||
|
if( _serviceDomain) free( _serviceDomain );
|
||||||
|
if( _hostName) free( _hostName );
|
||||||
|
if( _text ) free( _text );
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned dns_sd::_calc_question_byte_count()
|
||||||
|
{
|
||||||
|
unsigned n = kHdrBodyByteN;
|
||||||
|
n += 1 + strlen(_serviceName) + 1 + strlen(_serviceType) + 1 + strlen(_serviceDomain) + 1 + kQuestionBodyByteN;
|
||||||
|
n += 2 + kRsrcBodyByteN + kSrvBodyByteN + 1 + strlen(_hostName) + 2;
|
||||||
|
//n += 2 + kRsrcBodyByteN + strlen(_text) + 1;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dns_sd::_format_question( unsigned char* buf, unsigned bufByteN )
|
||||||
|
{
|
||||||
|
assert( bufByteN > kHdrBodyByteN );
|
||||||
|
unsigned char* bend = buf + bufByteN;
|
||||||
|
|
||||||
|
uint16_t* u = (uint16_t*)buf;
|
||||||
|
u[0] = htons(0); // transaction id
|
||||||
|
u[1] = htons(0); // flags
|
||||||
|
u[2] = htons(1); // question
|
||||||
|
u[3] = htons(0); // answer
|
||||||
|
u[4] = htons(1); // name server
|
||||||
|
u[5] = htons(0); // other
|
||||||
|
|
||||||
|
unsigned char* b = (unsigned char*)(u + 6);
|
||||||
|
|
||||||
|
// Format question
|
||||||
|
unsigned char namePtr[] = {0xc0, (unsigned char)(b - buf)};
|
||||||
|
b = _write_name( b, bend, _serviceName );
|
||||||
|
|
||||||
|
//unsigned char typePtr[] = { 0xc0, (unsigned char)(b - buf)};
|
||||||
|
b = _write_name( b, bend, _serviceType );
|
||||||
|
|
||||||
|
unsigned char domainPtr[] = { 0xc0, (unsigned char)(b - buf) };
|
||||||
|
b = _write_name( b, bend, _serviceDomain, true );
|
||||||
|
|
||||||
|
b = _write_uint16( b, bend, kANY_DnsTId );
|
||||||
|
b = _write_uint16( b, bend, kInClassDnsFl );
|
||||||
|
|
||||||
|
// Format SRV name server
|
||||||
|
b = _write_ptr( namePtr, b, bend ); // name
|
||||||
|
b = _write_uint16( b, bend, kSRV_DnsTId ); // type
|
||||||
|
b = _write_uint16( b, bend, kInClassDnsFl ); // class
|
||||||
|
b = _write_uint32( b, bend, 120 ); // TTL
|
||||||
|
b = _write_uint16( b, bend, kSrvBodyByteN + strlen(_hostName) + 1 + 2 );
|
||||||
|
b = _write_uint16( b, bend, 0 ); // priority
|
||||||
|
b = _write_uint16( b, bend, 0 ); // weight
|
||||||
|
b = _write_uint16( b, bend, _hostPort ); // port
|
||||||
|
b = _write_text( b, bend, _hostName ); // host
|
||||||
|
b = _write_ptr( b, bend, domainPtr ); // host suffix (.local)
|
||||||
|
/*
|
||||||
|
// Format TXT name server
|
||||||
|
b = _write_ptr( namePtr, b, bend ); // name
|
||||||
|
b = _write_uint16( kTXT_DnsTId, b, bend ); // type
|
||||||
|
b = _write_uint16( kInClassDnsFl, b, bend ); // class
|
||||||
|
b = _write_uint32( 4500, b, bend ); // TTL
|
||||||
|
b = _write_uint16( strlen(_text),b, bend ); // dlen
|
||||||
|
b = _write_text( _text, b, bend ); // text
|
||||||
|
*/
|
||||||
|
assert( b == bend );
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char* dns_sd::_write_uint16( unsigned char* b, unsigned char* bend, uint16_t value )
|
||||||
|
{
|
||||||
|
assert( bend - b >= (int)sizeof(value));
|
||||||
|
uint16_t* u = (uint16_t*)b;
|
||||||
|
u[0] = htons(value);
|
||||||
|
return (unsigned char*)(u + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char* dns_sd::_write_uint32( unsigned char* b, unsigned char* bend, uint32_t value )
|
||||||
|
{
|
||||||
|
assert( bend - b >= (int)sizeof(value));
|
||||||
|
uint32_t* u = (uint32_t*)b;
|
||||||
|
u[0] = htonl(value);
|
||||||
|
return (unsigned char*)(u + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char* dns_sd::_write_ptr( unsigned char* b, unsigned char* bend, const unsigned char ptr[2] )
|
||||||
|
{
|
||||||
|
assert( (ptr[0] & 0xc0) == 0xc0 );
|
||||||
|
b[0] = ptr[0];
|
||||||
|
b[1] = ptr[1];
|
||||||
|
return b+2;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char* dns_sd::_write_text( unsigned char* b, unsigned char* bend, const char* name )
|
||||||
|
{ return _write_name( b, bend, name, false, '\n' ); }
|
||||||
|
|
||||||
|
unsigned char* dns_sd::_write_name( unsigned char* b, unsigned char* bend, const char* name, bool zeroTermFl, const unsigned char eosChar )
|
||||||
|
{
|
||||||
|
unsigned char* b0 = b; // segment length prefix pointer
|
||||||
|
unsigned n = 0; // segment length
|
||||||
|
|
||||||
|
|
||||||
|
b += 1; // advance past the first segment length byte
|
||||||
|
|
||||||
|
// for every name char advance both the src and dst location
|
||||||
|
for(; *name; ++name, ++b )
|
||||||
|
{
|
||||||
|
if( *name == eosChar )
|
||||||
|
{
|
||||||
|
*b0 = n; // write the segment length
|
||||||
|
n = 0; // reset the segment length counter
|
||||||
|
b0 = b; // reset the segment length prefix pointer
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert( b < bend );
|
||||||
|
*b = *name; // write a name character
|
||||||
|
++n; // advance the segment length counter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*b0 = n; // write the segment length of the last segment
|
||||||
|
|
||||||
|
if( zeroTermFl )
|
||||||
|
{
|
||||||
|
assert( b < bend );
|
||||||
|
*b = 0; // write the zero termination
|
||||||
|
b += 1; //
|
||||||
|
}
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned dns_sd::_calc_response_byte_count()
|
||||||
|
{
|
||||||
|
unsigned n = kHdrBodyByteN;
|
||||||
|
|
||||||
|
// TXT
|
||||||
|
n += 1 + strlen(_serviceName) + 1 + strlen(_serviceType) + 1 + strlen(_serviceDomain) + 1 + kRsrcBodyByteN + 1 + strlen(_text);
|
||||||
|
|
||||||
|
// PTR
|
||||||
|
n += 2 + kRsrcBodyByteN + 2;
|
||||||
|
|
||||||
|
|
||||||
|
// SRV
|
||||||
|
n += 2 + kRsrcBodyByteN + kSrvBodyByteN + 1 + strlen(_hostName) + 2;
|
||||||
|
|
||||||
|
// A
|
||||||
|
n += 2 + kRsrcBodyByteN + kABodyByteN;
|
||||||
|
|
||||||
|
// PTR
|
||||||
|
n += 1 + strlen(DNS_SD_SERVICE_TYPE_STRING) + 2 + kRsrcBodyByteN + 2;
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dns_sd::_format_response( unsigned char* buf, unsigned bufByteN )
|
||||||
|
{
|
||||||
|
unsigned char* bend = buf + bufByteN;
|
||||||
|
uint16_t* u = (uint16_t*)buf;
|
||||||
|
|
||||||
|
u[0] = htons(0); // transaction id
|
||||||
|
u[1] = htons(0x8400); // flags
|
||||||
|
u[2] = htons(0); // question
|
||||||
|
u[3] = htons(5); // answer
|
||||||
|
u[4] = htons(0); // name server
|
||||||
|
u[5] = htons(0); // other
|
||||||
|
|
||||||
|
unsigned char* b = (unsigned char*)(u+6);
|
||||||
|
|
||||||
|
// Format TXT resource record
|
||||||
|
unsigned char namePtr[] = { 0xc0, (unsigned char)(b-buf) };
|
||||||
|
b = _write_name( b, buf+bufByteN, _serviceName );
|
||||||
|
|
||||||
|
unsigned char typePtr[] = { 0xc0, (unsigned char)(b - buf) };
|
||||||
|
b = _write_name( b, bend, _serviceType );
|
||||||
|
|
||||||
|
unsigned char domainPtr[] = { 0xc0, (unsigned char)(b - buf) };
|
||||||
|
b = _write_name( b, bend, _serviceDomain, true );
|
||||||
|
|
||||||
|
|
||||||
|
b = _write_uint16( b, bend, kTXT_DnsTId ); // type
|
||||||
|
b = _write_uint16( b, bend, kFlushClassDnsFl | kInClassDnsFl ); // class
|
||||||
|
b = _write_uint32( b, bend, 4500 ); // TTL
|
||||||
|
b = _write_uint16( b, bend, strlen(_text)+1 ); // dlen
|
||||||
|
b = _write_text( b, bend, _text ); // text
|
||||||
|
|
||||||
|
// Format a PTR resource record
|
||||||
|
b = _write_ptr( b, bend, typePtr );
|
||||||
|
b = _write_uint16( b, bend, kPTR_DnsTId );
|
||||||
|
b = _write_uint16( b, bend, kInClassDnsFl );
|
||||||
|
b = _write_uint32( b, bend, 4500 );
|
||||||
|
b = _write_uint16( b, bend, 2 );
|
||||||
|
b = _write_ptr( b, bend, namePtr );
|
||||||
|
|
||||||
|
// Format SRV response
|
||||||
|
b = _write_ptr( b, bend, namePtr ); // name
|
||||||
|
b = _write_uint16( b, bend, kSRV_DnsTId ); // type
|
||||||
|
b = _write_uint16( b, bend, kFlushClassDnsFl | kInClassDnsFl ); // class
|
||||||
|
b = _write_uint32( b, bend, 120 ); // TTL
|
||||||
|
b = _write_uint16( b, bend, kSrvBodyByteN + 1 + strlen(_hostName) + 2 );
|
||||||
|
b = _write_uint16( b, bend, 0 ); // priority
|
||||||
|
b = _write_uint16( b, bend, 0 ); // weight
|
||||||
|
b = _write_uint16( b, bend, _hostPort ); // port
|
||||||
|
unsigned char hostPtr[] = { 0xc0, (unsigned char)(b - buf) };
|
||||||
|
b = _write_text( b, bend, _hostName ); // target
|
||||||
|
b = _write_ptr( b, bend, domainPtr );
|
||||||
|
|
||||||
|
// Format A resource record
|
||||||
|
b = _write_ptr( b, bend, hostPtr );
|
||||||
|
b = _write_uint16( b, bend, kA_DnsTId ); // type
|
||||||
|
b = _write_uint16( b, bend, kFlushClassDnsFl | kInClassDnsFl ); // class
|
||||||
|
b = _write_uint32( b, bend, 120 ); // TTL
|
||||||
|
b = _write_uint16( b, bend, kABodyByteN );
|
||||||
|
b = _write_uint32( b, bend, _hostAddr ); // priority
|
||||||
|
|
||||||
|
// Format a PTR resource record
|
||||||
|
b = _write_name( b, bend, DNS_SD_SERVICE_TYPE_STRING );
|
||||||
|
b = _write_ptr( b, bend, domainPtr );
|
||||||
|
b = _write_uint16( b, bend, kPTR_DnsTId );
|
||||||
|
b = _write_uint16( b, bend, kInClassDnsFl );
|
||||||
|
b = _write_uint32( b, bend, 4500 );
|
||||||
|
b = _write_uint16( b, bend, 2 );
|
||||||
|
b = _write_ptr( b, bend, typePtr );
|
||||||
|
|
||||||
|
|
||||||
|
printf("%li %li : %s\n", b - buf, bend - buf, _text );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dns_sd::_parse( const char* buf, unsigned bufByteN )
|
||||||
|
{
|
||||||
|
dns_sd_print(buf,bufByteN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dns_sd::_send( const void* buf, unsigned bufByteN )
|
||||||
|
{
|
||||||
|
if( _sendCbFunc != nullptr )
|
||||||
|
_sendCbFunc(_sendCbArg,buf,bufByteN);
|
||||||
|
}
|
69
dns_sd/dns_sd.h
Normal file
69
dns_sd/dns_sd.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#ifndef dns_sd_h
|
||||||
|
#define dns_sd_h
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
class dns_sd
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
kOkRC
|
||||||
|
} result_t;
|
||||||
|
|
||||||
|
typedef void (*sendCallback_t)( void* arg, const void* buf, unsigned bufByteN );
|
||||||
|
|
||||||
|
dns_sd( sendCallback_t sendCbFunc, void* sendCbArg );
|
||||||
|
dns_sd( sendCallback_t sendCbFunc, void* sendCbArg, const char* serviceName, const char* serviceType, const char* serviceDomain, const char* hostName, uint32_t hostAddr, uint16_t hostPort, const char* text );
|
||||||
|
virtual ~dns_sd();
|
||||||
|
|
||||||
|
result_t setup( const char* serviceName, const char* serviceType, const char* serviceDomain, const char* hostName, uint32_t hostAddr, uint16_t hostPort, const char* text );
|
||||||
|
|
||||||
|
result_t receive( const void* buf, unsigned bufByteN );
|
||||||
|
|
||||||
|
void gen_question();
|
||||||
|
void gen_response();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
kHdrBodyByteN = 12,
|
||||||
|
kQuestionBodyByteN = 4,
|
||||||
|
kRsrcBodyByteN = 10,
|
||||||
|
kABodyByteN = 4,
|
||||||
|
kSrvBodyByteN = 6,
|
||||||
|
kOptBodyByteN = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
sendCallback_t _sendCbFunc;
|
||||||
|
void* _sendCbArg;
|
||||||
|
char* _serviceName;
|
||||||
|
char* _serviceType;
|
||||||
|
char* _serviceDomain;
|
||||||
|
char* _hostName;
|
||||||
|
uint32_t _hostAddr;
|
||||||
|
uint16_t _hostPort;
|
||||||
|
char* _text;
|
||||||
|
|
||||||
|
|
||||||
|
void _free();
|
||||||
|
unsigned _calc_question_byte_count();
|
||||||
|
void _format_question( unsigned char* buf, unsigned bufByteN );
|
||||||
|
unsigned char* _write_uint16( unsigned char* b, unsigned char* bend, uint16_t value );
|
||||||
|
unsigned char* _write_uint32( unsigned char* b, unsigned char* bend, uint32_t value );
|
||||||
|
unsigned char* _write_ptr( unsigned char* b, unsigned char* bend, const unsigned char ptr[2] );
|
||||||
|
unsigned char* _write_text( unsigned char* b, unsigned char* bend, const char* name );
|
||||||
|
unsigned char* _write_name( unsigned char* b, unsigned char* bend, const char* name, bool zeroTermFl=false, const unsigned char eosChar='.' );
|
||||||
|
unsigned _calc_response_byte_count();
|
||||||
|
void _format_response( unsigned char* buf, unsigned bufByteN );
|
||||||
|
void _parse( const char* buf, unsigned bufByteN );
|
||||||
|
void _send( const void* buf, unsigned bufByteN );
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
25
dns_sd/dns_sd_const.h
Normal file
25
dns_sd/dns_sd_const.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef dns_sd_const_h
|
||||||
|
#define dns_sd_const_h
|
||||||
|
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
kA_DnsTId = 1,
|
||||||
|
kPTR_DnsTId = 12,
|
||||||
|
kTXT_DnsTId = 16,
|
||||||
|
kAAAA_DnsTId = 28,
|
||||||
|
kSRV_DnsTId = 33,
|
||||||
|
kOPT_DnsTId = 41,
|
||||||
|
kNSEC_DnsTId = 47,
|
||||||
|
kANY_DnsTId = 255
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
kReplyHdrDnsFl = 0x8000,
|
||||||
|
kAuthoritativeHdrDnsFl = 0x0400,
|
||||||
|
kFlushClassDnsFl = 0x8000,
|
||||||
|
kInClassDnsFl = 0x0001
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
87
dns_sd/dns_sd_print.cpp
Normal file
87
dns_sd/dns_sd_print.cpp
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include "dns_sd_print.h"
|
||||||
|
#include "dns_sd_const.h"
|
||||||
|
|
||||||
|
|
||||||
|
unsigned _print_name( const char* s, const char* buf )
|
||||||
|
{
|
||||||
|
unsigned n = 0; // track allocated length of the name in this record
|
||||||
|
bool incrFl = true; // do not incrmement 'n' if the name switches to a ptr segment
|
||||||
|
|
||||||
|
while( *s )
|
||||||
|
{
|
||||||
|
if( (*s & 0xc0) == 0xc0 )
|
||||||
|
{
|
||||||
|
if( incrFl )
|
||||||
|
n += 2;
|
||||||
|
incrFl = false;
|
||||||
|
s = buf + s[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(char i=0; i<s[0]; ++i)
|
||||||
|
{
|
||||||
|
printf("%c",s[i+1]);
|
||||||
|
if( incrFl )
|
||||||
|
++n;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
s += s[0]+1;
|
||||||
|
n += 1;
|
||||||
|
|
||||||
|
if(*s)
|
||||||
|
{
|
||||||
|
printf(".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dns_sd_print( const void* buf, unsigned bufByteN )
|
||||||
|
{
|
||||||
|
const uint16_t* u = (uint16_t*)buf;
|
||||||
|
const char* b = (const char*)(u+6);
|
||||||
|
|
||||||
|
printf("%s ", ntohs(u[1]) & 0x8000 ? "Response " : "Question ");
|
||||||
|
|
||||||
|
unsigned n = _print_name(b,(const char*)buf);
|
||||||
|
|
||||||
|
printf(" slen:%i ",n);
|
||||||
|
|
||||||
|
u = (uint16_t*)(b + n+1); // advance past name
|
||||||
|
|
||||||
|
switch( ntohs(u[0]) )
|
||||||
|
{
|
||||||
|
case kA_DnsTId: printf("A ");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kPTR_DnsTId: printf("PTR ");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kTXT_DnsTId: printf("TXT ");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kSRV_DnsTId: printf("SRV ");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kAAAA_DnsTId:printf("AAAA ");
|
||||||
|
break;
|
||||||
|
case kOPT_DnsTId: printf("OPT ");
|
||||||
|
break;
|
||||||
|
case kNSEC_DnsTId:printf("NSEC "); break;
|
||||||
|
case kANY_DnsTId: printf("ANY "); break;
|
||||||
|
default:
|
||||||
|
printf("<unk> 0x%2x",ntohs(u[0])); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( ntohs(u[1]) & 0x80 )
|
||||||
|
printf("flush ");
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
7
dns_sd/dns_sd_print.h
Normal file
7
dns_sd/dns_sd_print.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#ifndef print_dns_sd_h
|
||||||
|
#define print_dns_sd_h
|
||||||
|
|
||||||
|
void dns_sd_print( const void* buf, unsigned bufByteN );
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
134
dns_sd/fader.cpp
Normal file
134
dns_sd/fader.cpp
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "fader.h"
|
||||||
|
|
||||||
|
|
||||||
|
fader::fader( const unsigned char faderMac[6], uint32_t faderInetAddr, hostCallback_t hostCbFunc, void* hostCbArg, unsigned chN )
|
||||||
|
: _inetAddr(faderInetAddr),_lastTickSeconds(0),_chArray(nullptr),_hostCbFunc(hostCbFunc),_hostCbArg(hostCbArg),_protoState(kWaitForHandshake_0_Id)
|
||||||
|
{
|
||||||
|
memcpy(_mac,faderMac,6);
|
||||||
|
|
||||||
|
_chArray = new ch_t[chN];
|
||||||
|
_chN = chN;
|
||||||
|
for(unsigned i=0; i<chN; ++i)
|
||||||
|
{
|
||||||
|
_chArray[i].position = 0;
|
||||||
|
_chArray[i].muteFl = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fader::~fader()
|
||||||
|
{
|
||||||
|
delete[] _chArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
fader::rc_t fader::host_receive( const void* buf, unsigned bufByteN )
|
||||||
|
{
|
||||||
|
rc_t rc = kOkRC;
|
||||||
|
|
||||||
|
printf("FDR:%i\n",bufByteN);
|
||||||
|
|
||||||
|
switch( _protoState )
|
||||||
|
{
|
||||||
|
case kWaitForHandshake_0_Id:
|
||||||
|
if( bufByteN>0 && ((uint8_t*)buf)[0] == 10 )
|
||||||
|
{
|
||||||
|
printf("HS 0\n");
|
||||||
|
_send_response_0();
|
||||||
|
_protoState = kWaitForHandshake_Tick_Id;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kWaitForHandshake_Tick_Id:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kWaitForHandshake_1_Id:
|
||||||
|
printf("HS 1: %i",bufByteN);
|
||||||
|
_protoState = kWaitForHeartBeat_Id;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kWaitForHeartBeat_Id:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
fader::rc_t fader::tick()
|
||||||
|
{
|
||||||
|
rc_t rc = kOkRC;
|
||||||
|
switch( _protoState )
|
||||||
|
{
|
||||||
|
case kWaitForHandshake_0_Id:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kWaitForHandshake_Tick_Id:
|
||||||
|
printf("HS Tick");
|
||||||
|
_send_heartbeat();
|
||||||
|
_protoState = kWaitForHandshake_1_Id;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kWaitForHandshake_1_Id:
|
||||||
|
break;
|
||||||
|
case kWaitForHeartBeat_Id:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
fader::rc_t fader::physical_fader_touched( uint16_t chanIdx )
|
||||||
|
{
|
||||||
|
return kOkRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
fader::rc_t fader::physical_fader_moved( uint16_t chanIdx, uint16_t value )
|
||||||
|
{
|
||||||
|
return kOkRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
fader::rc_t fader::physical_mute_switched( uint16_t chanIdx, bool value )
|
||||||
|
{
|
||||||
|
return kOkRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fader::_send_response_0()
|
||||||
|
{
|
||||||
|
unsigned char buf[] =
|
||||||
|
{ 0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x00,0x02,0x03,0xfc,0x01,0x05,
|
||||||
|
0x06,0x00,
|
||||||
|
0x38,0xc9,0x86,0x37,0x44,0xe7, // mac: 16
|
||||||
|
0x01,0x00,
|
||||||
|
0xc0,0xa8,0x00,0x44, // ip: 24
|
||||||
|
0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||||
|
0x03,0xff,0x00,0x30,0x08,0x00,0x00,0x80,0x00,0x40,0x01,0x01,0x00,0x00,0x00,0x00,
|
||||||
|
0x00,0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
memcpy(buf+16,_mac,6);
|
||||||
|
memcpy((unsigned char *)(buf+24),(unsigned char*)&_inetAddr, 4);
|
||||||
|
|
||||||
|
_send(buf,sizeof(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
void fader::_send_heartbeat()
|
||||||
|
{
|
||||||
|
const unsigned char buf[] = { 0x03, 0x00, 0x00, 0x00 };
|
||||||
|
_send(buf,sizeof(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
void fader::_send( const void* buf, unsigned bufByteN )
|
||||||
|
{
|
||||||
|
return _hostCbFunc(_hostCbArg,buf,bufByteN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fader::_on_fader_receive( uint16_t chanIdx, uint16_t value )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void fader::_on_mute_receive( uint16_t chanIdx, bool value )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
70
dns_sd/fader.h
Normal file
70
dns_sd/fader.h
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#ifndef fader_h
|
||||||
|
#define fader_h
|
||||||
|
|
||||||
|
|
||||||
|
class fader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
kOkRC,
|
||||||
|
kTimeOutRC,
|
||||||
|
kUnknownMsgRC
|
||||||
|
} rc_t;
|
||||||
|
|
||||||
|
// Function to send TCP messages to the host.
|
||||||
|
typedef void (*hostCallback_t)( void* arg, const void* buf, unsigned bufByteN );
|
||||||
|
|
||||||
|
fader( const unsigned char faderMac[6], uint32_t faderInetAddr, hostCallback_t hostCbFunc, void* cbArg, unsigned chN = 8 );
|
||||||
|
virtual ~fader();
|
||||||
|
|
||||||
|
// Called by the TCP receive function to update the faders state
|
||||||
|
// based on host state changes.
|
||||||
|
// Return kUnknownMsgRC if the received msg is not recognized.
|
||||||
|
rc_t host_receive( const void* buf, unsigned bufByteN );
|
||||||
|
|
||||||
|
// Called by the application to drive time dependent functions.
|
||||||
|
// Return kTimeOut if the protocol state machine has timed out.
|
||||||
|
rc_t tick();
|
||||||
|
|
||||||
|
// Call these function to generate messages to the host when
|
||||||
|
// the controls physical state changes.
|
||||||
|
rc_t physical_fader_touched( uint16_t chIdx );
|
||||||
|
rc_t physical_fader_moved( uint16_t chIdx, uint16_t newPosition );
|
||||||
|
rc_t physical_mute_switched( uint16_t chIdx, bool newMuteFl );
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
kWaitForHandshake_0_Id,
|
||||||
|
kWaitForHandshake_Tick_Id,
|
||||||
|
kWaitForHandshake_1_Id,
|
||||||
|
kWaitForHeartBeat_Id
|
||||||
|
} protoState_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint16_t position;
|
||||||
|
bool muteFl;
|
||||||
|
} ch_t;
|
||||||
|
|
||||||
|
uint32_t _inetAddr;
|
||||||
|
unsigned _lastTickSeconds;
|
||||||
|
ch_t* _chArray;
|
||||||
|
unsigned _chN;
|
||||||
|
hostCallback_t _hostCbFunc;
|
||||||
|
void* _hostCbArg;
|
||||||
|
protoState_t _protoState;
|
||||||
|
unsigned char _mac[6];
|
||||||
|
|
||||||
|
void _send_response_0();
|
||||||
|
void _send_heartbeat();
|
||||||
|
void _send( const void* buf, unsigned bufByteN );
|
||||||
|
void _on_fader_receive( uint16_t chanIdx, uint16_t position );
|
||||||
|
void _on_mute_receive( uint16_t chanIdx, bool muteFl );
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user