add ability to store player name changes from the server to allow them to transfered between servers
Adrian Smith
10 years ago
50 | 50 | " -f <logfile>\t\tWrite debug to logfile\n" |
51 | 51 | " -m <mac addr>\t\tSet mac address, format: ab:cd:ef:12:34:56\n" |
52 | 52 | " -n <name>\t\tSet the player name\n" |
53 | " -N <filename>\t\tStore player name in filename to allow server defined name changes to be shared between servers (not suppored with -n)\n" | |
53 | 54 | #if ALSA |
54 | 55 | " -p <priority>\t\tSet real time priority of output thread (1-99)\n" |
55 | 56 | #endif |
137 | 138 | char *output_device = "default"; |
138 | 139 | char *codecs = NULL; |
139 | 140 | char *name = NULL; |
141 | char *namefile = NULL; | |
140 | 142 | char *logfile = NULL; |
141 | 143 | u8_t mac[6]; |
142 | 144 | unsigned stream_buf_size = STREAMBUF_SIZE; |
173 | 175 | |
174 | 176 | while (optind < argc && strlen(argv[optind]) >= 2 && argv[optind][0] == '-') { |
175 | 177 | char *opt = argv[optind] + 1; |
176 | if (strstr("oabcdfmnprs", opt) && optind < argc - 1) { | |
178 | if (strstr("oabcdfmnNprs", opt) && optind < argc - 1) { | |
177 | 179 | optarg = argv[optind + 1]; |
178 | 180 | optind += 2; |
179 | 181 | } else if (strstr("ltz" |
268 | 270 | case 'n': |
269 | 271 | name = optarg; |
270 | 272 | break; |
273 | case 'N': | |
274 | namefile = optarg; | |
275 | break; | |
271 | 276 | #if ALSA |
272 | 277 | case 'p': |
273 | 278 | rt_priority = atoi(optarg); |
367 | 372 | } |
368 | 373 | #endif |
369 | 374 | |
370 | slimproto(log_slimproto, server, mac, name); | |
375 | if (name && namefile) { | |
376 | printf("-n and -N option should not be used at same time\n"); | |
377 | exit(0); | |
378 | } | |
379 | ||
380 | slimproto(log_slimproto, server, mac, name, namefile); | |
371 | 381 | |
372 | 382 | decode_close(); |
373 | 383 | stream_close(); |
74 | 74 | bool sentSTMu, sentSTMo, sentSTMl; |
75 | 75 | u32_t new_server; |
76 | 76 | char *new_server_cap; |
77 | #define PLAYER_NAME_LEN 64 | |
78 | char player_name[PLAYER_NAME_LEN + 1] = ""; | |
79 | const char *name_file = NULL; | |
77 | 80 | |
78 | 81 | void send_packet(u8_t *packet, size_t len) { |
79 | 82 | u8_t *ptr = packet; |
381 | 384 | UNLOCK_O; |
382 | 385 | } |
383 | 386 | |
387 | static void process_setd(u8_t *pkt, int len) { | |
388 | struct setd_packet *setd = (struct setd_packet *)pkt; | |
389 | ||
390 | // handle player name query and change | |
391 | if (setd->id == 0) { | |
392 | if (len == 5) { | |
393 | if (strlen(player_name)) { | |
394 | sendSETDName(player_name); | |
395 | } | |
396 | } else if (len > 5) { | |
397 | strncpy(player_name, setd->data, PLAYER_NAME_LEN); | |
398 | player_name[PLAYER_NAME_LEN] = '\0'; | |
399 | LOG_INFO("set name: %s", setd->data); | |
400 | // confirm change to server | |
401 | sendSETDName(setd->data); | |
402 | // write name to name_file if -N option set | |
403 | if (name_file) { | |
404 | FILE *fp = fopen(name_file, "w"); | |
405 | if (fp) { | |
406 | LOG_INFO("storing name in %s", name_file); | |
407 | fputs(player_name, fp); | |
408 | fclose(fp); | |
409 | } else { | |
410 | LOG_WARN("unable to store new name in %s", name_file); | |
411 | } | |
412 | } | |
413 | } | |
414 | } | |
415 | } | |
416 | ||
384 | 417 | #define SYNC_CAP ",SyncgroupID=" |
385 | 418 | #define SYNC_CAP_LEN 13 |
386 | 419 | |
417 | 450 | { "codc", process_codc }, |
418 | 451 | { "aude", process_aude }, |
419 | 452 | { "audg", process_audg }, |
453 | { "setd", process_setd }, | |
420 | 454 | { "serv", process_serv }, |
421 | 455 | { "", NULL }, |
422 | 456 | }; |
677 | 711 | return s.sin_addr.s_addr; |
678 | 712 | } |
679 | 713 | |
680 | void slimproto(log_level level, char *server, u8_t mac[6], const char *name) { | |
714 | void slimproto(log_level level, char *server, u8_t mac[6], const char *name, const char *namefile) { | |
681 | 715 | struct sockaddr_in serv_addr; |
682 | 716 | static char fixed_cap[128], var_cap[128] = ""; |
683 | 717 | bool reconnect = false; |
700 | 734 | |
701 | 735 | if (!slimproto_port) { |
702 | 736 | slimproto_port = PORT; |
737 | } | |
738 | ||
739 | if (name) { | |
740 | strncpy(player_name, name, PLAYER_NAME_LEN); | |
741 | player_name[PLAYER_NAME_LEN] = '\0'; | |
742 | } | |
743 | ||
744 | if (namefile) { | |
745 | FILE *fp; | |
746 | name_file = namefile; | |
747 | fp = fopen(namefile, "r"); | |
748 | if (fp) { | |
749 | if (!fgets(player_name, PLAYER_NAME_LEN, fp)) { | |
750 | player_name[PLAYER_NAME_LEN] = '\0'; | |
751 | } else { | |
752 | LOG_INFO("retrived name %s from %s", player_name, name_file); | |
753 | } | |
754 | fclose(fp); | |
755 | } | |
703 | 756 | } |
704 | 757 | |
705 | 758 | if (!running) return; |
780 | 833 | |
781 | 834 | sendHELO(reconnect, fixed_cap, var_cap, mac); |
782 | 835 | |
783 | if (name) { | |
784 | sendSETDName(name); | |
785 | } | |
786 | ||
787 | 836 | slimproto_run(); |
788 | 837 | |
789 | 838 | if (!reconnect) { |
144 | 144 | // possible sync group |
145 | 145 | }; |
146 | 146 | |
147 | // S:P:Squeezebox2 | |
148 | struct setd_packet { | |
149 | char opcode[4]; | |
150 | u8_t id; | |
151 | char data[]; | |
152 | }; | |
153 | ||
147 | 154 | // codec open - this is an extension to slimproto to allow the server to read the header and then return decode params |
148 | 155 | struct codc_packet { |
149 | 156 | char opcode[4]; |
368 | 368 | void buf_destroy(struct buffer *buf); |
369 | 369 | |
370 | 370 | // slimproto.c |
371 | void slimproto(log_level level, char *server, u8_t mac[6], const char *name); | |
371 | void slimproto(log_level level, char *server, u8_t mac[6], const char *name, const char *namefile); | |
372 | 372 | void slimproto_stop(void); |
373 | 373 | void wake_controller(void); |
374 | 374 |