diff --git a/main.c b/main.c index 558ccc2..0827dde 100644 --- a/main.c +++ b/main.c @@ -51,6 +51,7 @@ " -f \t\tWrite debug to logfile\n" " -m \t\tSet mac address, format: ab:cd:ef:12:34:56\n" " -n \t\tSet the player name\n" + " -N \t\tStore player name in filename to allow server defined name changes to be shared between servers (not suppored with -n)\n" #if ALSA " -p \t\tSet real time priority of output thread (1-99)\n" #endif @@ -138,6 +139,7 @@ char *output_device = "default"; char *codecs = NULL; char *name = NULL; + char *namefile = NULL; char *logfile = NULL; u8_t mac[6]; unsigned stream_buf_size = STREAMBUF_SIZE; @@ -174,7 +176,7 @@ while (optind < argc && strlen(argv[optind]) >= 2 && argv[optind][0] == '-') { char *opt = argv[optind] + 1; - if (strstr("oabcdfmnprs", opt) && optind < argc - 1) { + if (strstr("oabcdfmnNprs", opt) && optind < argc - 1) { optarg = argv[optind + 1]; optind += 2; } else if (strstr("ltz" @@ -269,6 +271,9 @@ case 'n': name = optarg; break; + case 'N': + namefile = optarg; + break; #if ALSA case 'p': rt_priority = atoi(optarg); @@ -368,7 +373,12 @@ } #endif - slimproto(log_slimproto, server, mac, name); + if (name && namefile) { + printf("-n and -N option should not be used at same time\n"); + exit(0); + } + + slimproto(log_slimproto, server, mac, name, namefile); decode_close(); stream_close(); diff --git a/slimproto.c b/slimproto.c index e0774d5..f044c34 100644 --- a/slimproto.c +++ b/slimproto.c @@ -75,6 +75,9 @@ bool sentSTMu, sentSTMo, sentSTMl; u32_t new_server; char *new_server_cap; +#define PLAYER_NAME_LEN 64 +char player_name[PLAYER_NAME_LEN + 1] = ""; +const char *name_file = NULL; void send_packet(u8_t *packet, size_t len) { u8_t *ptr = packet; @@ -382,6 +385,36 @@ UNLOCK_O; } +static void process_setd(u8_t *pkt, int len) { + struct setd_packet *setd = (struct setd_packet *)pkt; + + // handle player name query and change + if (setd->id == 0) { + if (len == 5) { + if (strlen(player_name)) { + sendSETDName(player_name); + } + } else if (len > 5) { + strncpy(player_name, setd->data, PLAYER_NAME_LEN); + player_name[PLAYER_NAME_LEN] = '\0'; + LOG_INFO("set name: %s", setd->data); + // confirm change to server + sendSETDName(setd->data); + // write name to name_file if -N option set + if (name_file) { + FILE *fp = fopen(name_file, "w"); + if (fp) { + LOG_INFO("storing name in %s", name_file); + fputs(player_name, fp); + fclose(fp); + } else { + LOG_WARN("unable to store new name in %s", name_file); + } + } + } + } +} + #define SYNC_CAP ",SyncgroupID=" #define SYNC_CAP_LEN 13 @@ -418,6 +451,7 @@ { "codc", process_codc }, { "aude", process_aude }, { "audg", process_audg }, + { "setd", process_setd }, { "serv", process_serv }, { "", NULL }, }; @@ -678,7 +712,7 @@ return s.sin_addr.s_addr; } -void slimproto(log_level level, char *server, u8_t mac[6], const char *name) { +void slimproto(log_level level, char *server, u8_t mac[6], const char *name, const char *namefile) { struct sockaddr_in serv_addr; static char fixed_cap[128], var_cap[128] = ""; bool reconnect = false; @@ -701,6 +735,25 @@ if (!slimproto_port) { slimproto_port = PORT; + } + + if (name) { + strncpy(player_name, name, PLAYER_NAME_LEN); + player_name[PLAYER_NAME_LEN] = '\0'; + } + + if (namefile) { + FILE *fp; + name_file = namefile; + fp = fopen(namefile, "r"); + if (fp) { + if (!fgets(player_name, PLAYER_NAME_LEN, fp)) { + player_name[PLAYER_NAME_LEN] = '\0'; + } else { + LOG_INFO("retrived name %s from %s", player_name, name_file); + } + fclose(fp); + } } if (!running) return; @@ -781,10 +834,6 @@ sendHELO(reconnect, fixed_cap, var_cap, mac); - if (name) { - sendSETDName(name); - } - slimproto_run(); if (!reconnect) { diff --git a/slimproto.h b/slimproto.h index e6bb135..7133dff 100644 --- a/slimproto.h +++ b/slimproto.h @@ -145,6 +145,13 @@ // possible sync group }; +// S:P:Squeezebox2 +struct setd_packet { + char opcode[4]; + u8_t id; + char data[]; +}; + // codec open - this is an extension to slimproto to allow the server to read the header and then return decode params struct codc_packet { char opcode[4]; diff --git a/squeezelite.h b/squeezelite.h index 13c6fea..77a66a8 100644 --- a/squeezelite.h +++ b/squeezelite.h @@ -369,7 +369,7 @@ void buf_destroy(struct buffer *buf); // slimproto.c -void slimproto(log_level level, char *server, u8_t mac[6], const char *name); +void slimproto(log_level level, char *server, u8_t mac[6], const char *name, const char *namefile); void slimproto_stop(void); void wake_controller(void);