Skip to content

Commit

Permalink
Change bonjour advertisement if metadata sought, add sender name meta…
Browse files Browse the repository at this point in the history
…data, use own base64 encoder
  • Loading branch information
mikebrady committed Feb 25, 2015
1 parent 1cf0de4 commit 7d339b1
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 19 deletions.
1 change: 1 addition & 0 deletions common.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ double vol2attn(double vol, long max_db, long min_db);
uint64_t get_absolute_time_in_fp(void);

shairport_cfg config;
char sender_name[1024];

void command_start(void);
void command_stop(void);
Expand Down
6 changes: 5 additions & 1 deletion mdns.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ typedef struct {
void (*mdns_unregister)(void);
} mdns_backend;

#define MDNS_RECORD "tp=UDP", "sm=false", "ek=1", "et=0,1", "cn=0,1", "ch=2", "md=0,1", \
#define MDNS_RECORD_WITH_METADATA "tp=UDP", "sm=false", "ek=1", "et=0,1", "cn=0,1", "ch=2", "md=0,1", \
"ss=16", "sr=44100", "vn=3", "txtvers=1", \
config.password ? "pw=true" : "pw=false"

#define MDNS_RECORD_WITHOUT_METADATA "tp=UDP", "sm=false", "ek=1", "et=0,1", "cn=0,1", "ch=2", \
"ss=16", "sr=44100", "vn=3", "txtvers=1", \
config.password ? "pw=true" : "pw=false"

Expand Down
17 changes: 16 additions & 1 deletion mdns_avahi.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ static void register_service(AvahiClient *c) {
return;

int ret;
if (config.meta_dir) {
ret = avahi_entry_group_add_service(group,
AVAHI_IF_UNSPEC,
AVAHI_PROTO_UNSPEC,
Expand All @@ -71,8 +72,22 @@ static void register_service(AvahiClient *c) {
NULL,
NULL,
port,
MDNS_RECORD,
MDNS_RECORD_WITH_METADATA,
NULL);
} else {
ret = avahi_entry_group_add_service(group,
AVAHI_IF_UNSPEC,
AVAHI_PROTO_UNSPEC,
0,
name,
"_raop._tcp",
NULL,
NULL,
port,
MDNS_RECORD_WITHOUT_METADATA,
NULL);
}

if (ret < 0)
die("avahi_entry_group_add_service failed");

Expand Down
10 changes: 9 additions & 1 deletion mdns_dns_sd.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,15 @@
static DNSServiceRef service;

static int mdns_dns_sd_register(char *apname, int port) {
const char *record[] = { MDNS_RECORD, NULL };
const char *recordwithoutmetadata[] = { MDNS_RECORD_WITHOUT_METADATA, NULL };
const char *recordwithmetadata[] = { MDNS_RECORD_WITH_METADATA, NULL };

char **record;
if (config.meta_dir)
record = recordwithmetadata;
else
record = recordwithoutmetadata;

uint16_t length = 0;
const char **field;

Expand Down
29 changes: 25 additions & 4 deletions mdns_external.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,20 @@ static int mdns_external_avahi_register(char *apname, int port) {
char mdns_port[6];
sprintf(mdns_port, "%d", config.port);

char *argv[] = {
NULL, apname, "_raop._tcp", mdns_port, MDNS_RECORD, NULL
char *argvwithoutmetadata[] = {
NULL, apname, "_raop._tcp", mdns_port, MDNS_RECORD_WITHOUT_METADATA, NULL
};

char *argvwithmetadata[] = {
NULL, apname, "_raop._tcp", mdns_port, MDNS_RECORD_WITH_METADATA, NULL
};

char **argv;
if (config.meta_dir)
argv=argvwithmetadata;
else
argv=argvwithoutmetadata;

argv[0] = "avahi-publish-service";
int pid = fork_execvp(argv[0], argv);
if (pid >= 0)
Expand Down Expand Up @@ -121,8 +131,19 @@ static int mdns_external_dns_sd_register(char *apname, int port) {
char mdns_port[6];
sprintf(mdns_port, "%d", config.port);

char *argv[] = {"dns-sd", "-R", apname, "_raop._tcp", ".",
mdns_port, MDNS_RECORD, NULL};
char *argvwithoutmetadata[] = {
NULL, apname, "_raop._tcp", mdns_port, MDNS_RECORD_WITHOUT_METADATA, NULL
};

char *argvwithmetadata[] = {
NULL, apname, "_raop._tcp", mdns_port, MDNS_RECORD_WITH_METADATA, NULL
};

char **argv;
if (config.meta_dir)
argv=argvwithmetadata;
else
argv=argvwithoutmetadata;

int pid = fork_execvp(argv[0], argv);
if (pid >= 0)
Expand Down
15 changes: 13 additions & 2 deletions mdns_tinysvcmdns.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,24 @@ static int mdns_tinysvcmdns_register(char *apname, int port) {

freeifaddrs(ifa);

const char *txt[] = { MDNS_RECORD, NULL };
char *txtwithoutmetadata[] = { MDNS_RECORD_WITHOUT_METADATA, NULL };
char *txtwithmetadata[] = { MDNS_RECORD_WITH_METADATA, NULL };

char **txt;

if (config.meta_dir)
txt = txtwithmetadata;
else
txt = txtwithoutmetadata;



struct mdns_service *svc = mdnsd_register_svc(svr,
apname,
"_raop._tcp.local",
port,
NULL,
txt); // TTL should be 75 minutes, i.e. 4500 seconds
(const char **)txt); // TTL should be 75 minutes, i.e. 4500 seconds

mdns_service_destroy(svc);

Expand Down
88 changes: 82 additions & 6 deletions metadata.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,63 @@
#include "common.h"
#include "metadata.h"


// including a simple base64 encoder to minimise malloc/free activity

// From Stack Overflow, with thanks:
// http://stackoverflow.com/questions/342409/how-do-i-base64-encode-decode-in-c
// minor mods to make independent of C99.
// more significant changes make it not malloc memory
// needs to initialise the docoding table first

static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'};

static int mod_table[] = {0, 2, 1};

// pass in a pointer to the data, its length, a pointer to the output buffer and a pointer to an int containing its maximum length
// the actual length will be returned.

char *base64_encode(const unsigned char *data,
size_t input_length,
char *encoded_data,
size_t *output_length) {

size_t calculated_output_length = 4 * ((input_length + 2) / 3);
if (calculated_output_length> *output_length)
return(NULL);
*output_length = calculated_output_length;

int i,j;
for (i = 0, j = 0; i < input_length;) {

uint32_t octet_a = i < input_length ? (unsigned char)data[i++] : 0;
uint32_t octet_b = i < input_length ? (unsigned char)data[i++] : 0;
uint32_t octet_c = i < input_length ? (unsigned char)data[i++] : 0;

uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;

encoded_data[j++] = encoding_table[(triple >> 3 * 6) & 0x3F];
encoded_data[j++] = encoding_table[(triple >> 2 * 6) & 0x3F];
encoded_data[j++] = encoding_table[(triple >> 1 * 6) & 0x3F];
encoded_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F];
}

for (i = 0; i < mod_table[input_length % 3]; i++)
encoded_data[*output_length - 1 - i] = '=';

return encoded_data;
}

// with thanks!
//

metadata player_meta;
static int fd = -1;
static int dirty = 0;
Expand Down Expand Up @@ -224,14 +281,33 @@ void metadata_process(uint32_t type,uint32_t code,char *data,uint32_t length) {
ret = write(fd, thestring, strlen(thestring));
if (ret < 1) // no reader
metadata_close();

char *b64 = base64_enc(data,length);
ret = write(fd,b64,strlen(b64));
free(b64);

// here, we write the data in base64 form using the crappy base64 encoder provided
// but, we break it into lines of 76 output characters, except for the last one.
// thus, we send groups of (76/4)*3 = 57 bytes to the eoncoder at a time
size_t remaining_count = length;
char *remaining_data = data;
size_t towrite_count;
char outbuf[76];
while ((remaining_count) && (ret>=0)) {
size_t towrite_count = remaining_count;
if (towrite_count>57)
towrite_count = 57;
size_t outbuf_size = 76; // size of output buffer on entry, length of result on exit
if (base64_encode(remaining_data, towrite_count, outbuf, &outbuf_size)==NULL)
debug(1,"Error encoding...");
//debug(1,"Remaining count: %d ret: %d, outbuf_size: %d.",remaining_count,ret,outbuf_size);
ret = write(fd,outbuf,outbuf_size);
if (ret<0)
perror("Error writing metadata");
remaining_data+=towrite_count;
remaining_count-=towrite_count;
//if (ret>=0)
// ret = write(fd,"\r\n",2);
}
debug(1,"ret: %d",ret);
if (ret < 1) // no reader
metadata_close();
snprintf(thestring,1024,"\n</data>\n");
snprintf(thestring,1024,"</data>\n");
ret = write(fd, thestring, strlen(thestring));
if (ret < 1) // no reader
metadata_close();
Expand Down
15 changes: 11 additions & 4 deletions rtsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,9 @@ static void handle_set_parameter_metadata(rtsp_conn_info *conn,

// inform the listener that a set of metadata is ending
metadata_process('ssnc','stop',NULL,0);
// send the user some shairport-originated metadata
// send the name of the player, e.g. "Joe's iPhone" or "iTunes"
metadata_process('ssnc','sndr',sender_name,strlen(sender_name));
}

static void handle_set_parameter(rtsp_conn_info *conn,
Expand Down Expand Up @@ -721,13 +724,17 @@ static void handle_announce(rtsp_conn_info *conn,
conn->stream.fmtp[i] = atoi(strsep(&pfmtp, " \t"));

char *hdr = msg_get_header(req, "X-Apple-Client-Name");
if (hdr)
if (hdr) {
strncpy(sender_name,hdr,1024);
debug(1,"Play connection from \"%s\".",hdr);
else {
} else {
hdr = msg_get_header(req, "User-Agent");
if (hdr)
if (hdr) {
debug(1,"Play connection from \"%s\".",hdr);
}
strncpy(sender_name,hdr,1024);
} else
sender_name[0]=0;
}
resp->respcode = 200;
} else {
resp->respcode = 453;
Expand Down

0 comments on commit 7d339b1

Please sign in to comment.