1/*
2 * Copyright (C) 2010-2011 Julien BLACHE <jb@jblache.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 */
18
19#ifdef HAVE_CONFIG_H
20# include <config.h>
21#endif
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <unistd.h>
26#include <fcntl.h>
27#include <string.h>
28#include <inttypes.h>
29#include <stdint.h>
30#include <errno.h>
31#include <time.h>
32#include <pthread.h>
33
34#if defined(__linux__)
35# include <sys/timerfd.h>
36#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
37# include <sys/time.h>
38# include <sys/event.h>
39#endif
40
41#if defined(HAVE_SYS_EVENTFD_H) && defined(HAVE_EVENTFD)
42# define USE_EVENTFD
43# include <sys/eventfd.h>
44#endif
45
46#include <event.h>
47
48#include <gcrypt.h>
49
50#include "db.h"
51#include "daap_query.h"
52#include "logger.h"
53#include "mdns.h"
54#include "conffile.h"
55#include "misc.h"
56#include "rng.h"
57#include "transcode.h"
58#include "player.h"
59#include "raop.h"
60#include "laudio.h"
61
62
63#ifndef MIN
64# define MIN(a, b) ((a < b) ? a : b)
65#endif
66
67enum player_sync_source
68  {
69    PLAYER_SYNC_CLOCK,
70    PLAYER_SYNC_LAUDIO,
71  };
72
73struct volume_param {
74  int volume;
75  uint64_t spk_id;
76};
77
78struct player_command;
79typedef int (*cmd_func)(struct player_command *cmd);
80
81struct spk_enum
82{
83  spk_enum_cb cb;
84  void *arg;
85};
86
87struct player_command
88{
89  pthread_mutex_t lck;
90  pthread_cond_t cond;
91
92  cmd_func func;
93  cmd_func func_bh;
94
95  int nonblock;
96
97  union {
98    struct volume_param vol_param;
99    void *noarg;
100    struct spk_enum *spk_enum;
101    struct raop_device *rd;
102    struct player_status *status;
103    struct player_source *ps;
104    player_status_handler status_handler;
105    uint32_t *id_ptr;
106    uint64_t *raop_ids;
107    enum repeat_mode mode;
108    uint32_t id;
109    int intval;
110  } arg;
111
112  int ret;
113
114  int raop_pending;
115};
116
117struct player_source
118{
119  uint32_t id;
120
121  uint64_t stream_start;
122  uint64_t output_start;
123  uint64_t end;
124
125  struct transcode_ctx *ctx;
126
127  struct player_source *pl_next;
128  struct player_source *pl_prev;
129
130  struct player_source *shuffle_next;
131  struct player_source *shuffle_prev;
132
133  struct player_source *play_next;
134};
135
136
137/* Keep in sync with enum raop_devtype */
138static const char *raop_devtype[] =
139  {
140    "AirPort Express 802.11g",
141    "AirPort Express 802.11n",
142    "AppleTV",
143  };
144
145
146struct event_base *evbase_player;
147
148#ifdef USE_EVENTFD
149static int exit_efd;
150#else
151static int exit_pipe[2];
152#endif
153static int cmd_pipe[2];
154static int player_exit;
155static struct event exitev;
156static struct event cmdev;
157static pthread_t tid_player;
158
159/* Player status */
160static enum play_status player_state;
161static enum repeat_mode repeat;
162static char shuffle;
163
164/* Status updates (for DACP) */
165static player_status_handler update_handler;
166
167/* Playback timer */
168static int pb_timer_fd;
169static struct event pb_timer_ev;
170#if defined(__linux__)
171static struct timespec pb_timer_last;
172#endif
173
174/* Sync source */
175static enum player_sync_source pb_sync_source;
176
177/* Sync values */
178static struct timespec pb_pos_stamp;
179static uint64_t pb_pos;
180
181/* Stream position (packets) */
182static uint64_t last_rtptime;
183
184/* AirTunes devices */
185static int dev_autoselect;
186static struct raop_device *dev_list;
187static uint8_t laudio_enabled;
188
189/* Device status */
190static enum laudio_state laudio_status;
191static int laudio_selected;
192static int laudio_volume;
193static int laudio_relvol;
194static int raop_sessions;
195
196/* Commands */
197static struct player_command *cur_cmd;
198
199/* Last commanded volume */
200static int master_volume;
201
202/* Shuffle RNG state */
203struct rng_ctx shuffle_rng;
204
205/* Audio source */
206static struct player_source *source_head;
207static struct player_source *shuffle_head;
208static struct player_source *cur_playing;
209static struct player_source *cur_streaming;
210static uint32_t cur_plid;
211static struct evbuffer *audio_buf;
212
213
214/* Command helpers */
215static void
216command_async_end(struct player_command *cmd)
217{
218  cur_cmd = NULL;
219
220  pthread_cond_signal(&cmd->cond);
221  pthread_mutex_unlock(&cmd->lck);
222
223  /* Process commands again */
224  event_add(&cmdev, NULL);
225}
226
227static void
228command_init(struct player_command *cmd)
229{
230  memset(cmd, 0, sizeof(struct player_command));
231
232  pthread_mutex_init(&cmd->lck, NULL);
233  pthread_cond_init(&cmd->cond, NULL);
234}
235
236static void
237command_deinit(struct player_command *cmd)
238{
239  pthread_cond_destroy(&cmd->cond);
240  pthread_mutex_destroy(&cmd->lck);
241}
242
243
244static void
245status_update(enum play_status status)
246{
247  player_state = status;
248
249  if (update_handler)
250    update_handler();
251
252  if (status == PLAY_PLAYING)
253    dev_autoselect = 0;
254}
255
256
257/* Volume helpers */
258static int
259rel_to_vol(int relvol)
260{
261  float vol;
262
263  if (relvol == 100)
264    return master_volume;
265
266  vol = ((float)relvol * (float)master_volume) / 100.0;
267
268  return (int)vol;
269}
270
271static int
272vol_to_rel(int volume)
273{
274  float rel;
275
276  if (volume == master_volume)
277    return 100;
278
279  rel = ((float)volume / (float)master_volume) * 100.0;
280
281  return (int)rel;
282}
283
284/* Master volume helpers */
285static void
286volume_master_update(int newvol)
287{
288  struct raop_device *rd;
289
290  master_volume = newvol;
291
292//  if (laudio_selected)
293  if (laudio_enabled & laudio_selected)
294    laudio_relvol = vol_to_rel(laudio_volume);
295
296  for (rd = dev_list; rd; rd = rd->next)
297    {
298      if (rd->selected)
299	rd->relvol = vol_to_rel(rd->volume);
300    }
301}
302
303static void
304volume_master_find(void)
305{
306  struct raop_device *rd;
307  int newmaster;
308
309  newmaster = -1;
310
311//  if (laudio_selected)
312  if (laudio_enabled & laudio_selected)
313    newmaster = laudio_volume;
314
315  for (rd = dev_list; rd; rd = rd->next)
316    {
317      if (rd->selected && (rd->volume > newmaster))
318	newmaster = rd->volume;
319    }
320
321  volume_master_update(newmaster);
322}
323
324
325/* Device select/deselect hooks */
326static void
327speaker_select_laudio(void)
328{
329  laudio_selected = 1;
330
331  if (laudio_volume > master_volume)
332    {
333      if (player_state == PLAY_STOPPED)
334	volume_master_update(laudio_volume);
335      else
336	laudio_volume = master_volume;
337    }
338
339  laudio_relvol = vol_to_rel(laudio_volume);
340}
341
342static void
343speaker_select_raop(struct raop_device *rd)
344{
345  rd->selected = 1;
346
347  if (rd->volume > master_volume)
348    {
349      if (player_state == PLAY_STOPPED)
350	volume_master_update(rd->volume);
351      else
352	rd->volume = master_volume;
353    }
354
355  rd->relvol = vol_to_rel(rd->volume);
356}
357
358static void
359speaker_deselect_laudio(void)
360{
361  laudio_selected = 0;
362
363  if (laudio_volume == master_volume)
364    volume_master_find();
365}
366
367static void
368speaker_deselect_raop(struct raop_device *rd)
369{
370  rd->selected = 0;
371
372  if (rd->volume == master_volume)
373    volume_master_find();
374}
375
376int
377player_is_playing(void)
378{
379  return player_state == PLAY_PLAYING ? 1 : 0;
380}
381
382static int
383player_get_current_pos_clock(uint64_t *pos, struct timespec *ts, int commit)
384{
385  uint64_t delta;
386  int ret;
387
388  ret = clock_gettime(CLOCK_MONOTONIC, ts);
389  if (ret < 0)
390    {
391      DPRINTF(E_LOG, L_PLAYER, "Couldn't get clock: %s\n", strerror(errno));
392
393      return -1;
394    }
395
396  delta = (ts->tv_sec - pb_pos_stamp.tv_sec) * 1000000 + (ts->tv_nsec - pb_pos_stamp.tv_nsec) / 1000;
397
398#ifdef DEBUG_SYNC
399  DPRINTF(E_DBG, L_PLAYER, "Delta is %" PRIu64 " usec\n", delta);
400#endif
401
402  delta = (delta * 44100) / 1000000;
403
404#ifdef DEBUG_SYNC
405  DPRINTF(E_DBG, L_PLAYER, "Delta is %" PRIu64 " samples\n", delta);
406#endif
407
408  *pos = pb_pos + delta;
409
410  if (commit)
411    {
412      pb_pos = *pos;
413
414      pb_pos_stamp.tv_sec = ts->tv_sec;
415      pb_pos_stamp.tv_nsec = ts->tv_nsec;
416
417#ifdef DEBUG_SYNC
418      DPRINTF(E_DBG, L_PLAYER, "Pos: %" PRIu64 " (clock)\n", *pos);
419#endif
420    }
421
422  return 0;
423}
424
425static int
426player_get_current_pos_laudio(uint64_t *pos, struct timespec *ts, int commit)
427{
428  int ret;
429
430  *pos = laudio_get_pos();
431
432  ret = clock_gettime(CLOCK_MONOTONIC, ts);
433  if (ret < 0)
434    {
435      DPRINTF(E_LOG, L_PLAYER, "Couldn't get clock: %s\n", strerror(errno));
436
437      return -1;
438    }
439
440  if (commit)
441    {
442      pb_pos = *pos;
443
444      pb_pos_stamp.tv_sec = ts->tv_sec;
445      pb_pos_stamp.tv_nsec = ts->tv_nsec;
446
447#ifdef DEBUG_SYNC
448      DPRINTF(E_DBG, L_PLAYER, "Pos: %" PRIu64 " (laudio)\n", *pos);
449#endif
450    }
451
452  return 0;
453}
454
455int
456player_get_current_pos(uint64_t *pos, struct timespec *ts, int commit)
457{
458  switch (pb_sync_source)
459    {
460      case PLAYER_SYNC_CLOCK:
461	return player_get_current_pos_clock(pos, ts, commit);
462
463      case PLAYER_SYNC_LAUDIO:
464	return player_get_current_pos_laudio(pos, ts, commit);
465    }
466
467  return -1;
468}
469
470/* Forward */
471static void
472playback_abort(void);
473
474static void
475player_laudio_status_cb(enum laudio_state status)
476{
477  struct timespec ts;
478  uint64_t pos;
479
480  switch (status)
481    {
482      /* Switch sync to clock sync */
483      case LAUDIO_STOPPING:
484	DPRINTF(E_DBG, L_PLAYER, "Local audio stopping\n");
485
486	laudio_status = status;
487
488	/* Synchronize pb_pos and pb_pos_stamp before laudio stops entirely */
489	player_get_current_pos_laudio(&pos, &ts, 1);
490
491	pb_sync_source = PLAYER_SYNC_CLOCK;
492	break;
493
494      /* Switch sync to laudio sync */
495      case LAUDIO_RUNNING:
496	DPRINTF(E_DBG, L_PLAYER, "Local audio running\n");
497
498	laudio_status = status;
499
500	pb_sync_source = PLAYER_SYNC_LAUDIO;
501	break;
502
503      case LAUDIO_FAILED:
504	DPRINTF(E_DBG, L_PLAYER, "Local audio failed\n");
505
506	pb_sync_source = PLAYER_SYNC_CLOCK;
507
508	laudio_close();
509
510	if (raop_sessions == 0)
511	  playback_abort();
512
513	speaker_deselect_laudio();
514	break;
515
516      default:
517      	laudio_status = status;
518	break;
519    }
520}
521
522
523/* Metadata */
524static void
525metadata_prune(uint64_t pos)
526{
527  raop_metadata_prune(pos);
528}
529
530static void
531metadata_purge(void)
532{
533  raop_metadata_purge();
534}
535
536static void
537metadata_send(struct player_source *ps, int startup)
538{
539  uint64_t offset;
540  uint64_t rtptime;
541
542  offset = 0;
543
544  /* Determine song boundaries, dependent on context */
545
546  /* Restart after pause/seek */
547  if (ps->stream_start)
548    {
549      offset = ps->output_start - ps->stream_start;
550      rtptime = ps->stream_start;
551    }
552  else if (startup)
553    {
554      rtptime = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES;
555    }
556  /* Generic case */
557  else if (cur_streaming && (cur_streaming->end))
558    {
559      rtptime = cur_streaming->end + 1;
560    }
561  else
562    {
563      rtptime = 0;
564      DPRINTF(E_LOG, L_PLAYER, "PTOH! Unhandled song boundary case in metadata_send()\n");
565    }
566
567  raop_metadata_send(ps->id, rtptime, offset, startup);
568}
569
570
571/* Audio sources */
572/* Thread: httpd (DACP) */
573static struct player_source *
574player_queue_make(struct query_params *qp, const char *sort)
575{
576  struct db_media_file_info dbmfi;
577  struct player_source *q_head;
578  struct player_source *q_tail;
579  struct player_source *ps;
580  uint32_t id;
581  int ret;
582
583  qp->idx_type = I_NONE;
584  qp->sort = S_NONE;
585
586  if (sort)
587    {
588      if (strcmp(sort, "name") == 0)
589	qp->sort = S_NAME;
590      else if (strcmp(sort, "album") == 0)
591	qp->sort = S_ALBUM;
592      else if (strcmp(sort, "artist") == 0)
593	qp->sort = S_ARTIST;
594    }
595
596  ret = db_query_start(qp);
597  if (ret < 0)
598    {
599      DPRINTF(E_LOG, L_PLAYER, "Could not start query\n");
600
601      return NULL;
602    }
603
604  DPRINTF(E_DBG, L_PLAYER, "Player queue query returned %d items\n", qp->results);
605
606  q_head = NULL;
607  q_tail = NULL;
608  while (((ret = db_query_fetch_file(qp, &dbmfi)) == 0) && (dbmfi.id))
609    {
610      ret = safe_atou32(dbmfi.id, &id);
611      if (ret < 0)
612	{
613	  DPRINTF(E_LOG, L_PLAYER, "Invalid song id in query result!\n");
614
615	  continue;
616	}
617
618      ps = (struct player_source *)malloc(sizeof(struct player_source));
619      if (!ps)
620	{
621	  DPRINTF(E_LOG, L_PLAYER, "Out of memory for struct player_source\n");
622
623	  ret = -1;
624	  break;
625	}
626
627      memset(ps, 0, sizeof(struct player_source));
628
629      ps->id = id;
630
631      if (!q_head)
632	q_head = ps;
633
634      if (q_tail)
635	{
636	  q_tail->pl_next = ps;
637	  ps->pl_prev = q_tail;
638
639	  q_tail->shuffle_next = ps;
640	  ps->shuffle_prev = q_tail;
641	}
642
643      q_tail = ps;
644
645      DPRINTF(E_DBG, L_PLAYER, "Added song id %d (%s)\n", id, dbmfi.title);
646    }
647
648  db_query_end(qp);
649
650  if (ret < 0)
651    {
652      DPRINTF(E_LOG, L_PLAYER, "Error fetching results\n");
653
654      return NULL;
655    }
656
657  if (!q_head)
658    return NULL;
659
660  q_head->pl_prev = q_tail;
661  q_tail->pl_next = q_head;
662
663  return q_head;
664}
665
666/* Thread: httpd (DACP) */
667struct player_source *
668player_queue_make_daap(const char *query, const char *sort)
669{
670  struct query_params qp;
671  struct player_source *ps;
672
673  memset(&qp, 0, sizeof(struct query_params));
674
675  qp.type = Q_ITEMS;
676  qp.offset = 0;
677  qp.limit = 0;
678
679  qp.filter = daap_query_parse_sql(query);
680  if (!qp.filter)
681    {
682      DPRINTF(E_LOG, L_PLAYER, "Improper DAAP query!\n");
683
684      return NULL;
685    }
686
687  ps = player_queue_make(&qp, sort);
688
689  free(qp.filter);
690
691  return ps;
692}
693
694struct player_source *
695player_queue_make_pl(int plid, uint32_t *id)
696{
697  struct query_params qp;
698  struct player_source *ps;
699  struct player_source *p;
700  uint32_t i;
701
702  memset(&qp, 0, sizeof(struct query_params));
703
704  qp.id = plid;
705  qp.type = Q_PLITEMS;
706  qp.offset = 0;
707  qp.limit = 0;
708
709  ps = player_queue_make(&qp, NULL);
710
711  /* Shortcut for shuffled playlist */
712  if (*id == 0)
713    return ps;
714
715  p = ps;
716  i = 0;
717  do
718    {
719      if (p->id == *id)
720	{
721	  *id = i;
722	  break;
723	}
724
725      p = p->pl_next;
726      i++;
727    }
728  while (p != ps);
729
730  return ps;
731}
732
733static void
734source_free(struct player_source *ps)
735{
736  if (ps->ctx)
737    transcode_cleanup(ps->ctx);
738
739  free(ps);
740}
741
742static void
743source_stop(struct player_source *ps)
744{
745  struct player_source *tmp;
746
747  while (ps)
748    {
749      if (ps->ctx)
750	{
751	  transcode_cleanup(ps->ctx);
752	  ps->ctx = NULL;
753	}
754
755      tmp = ps;
756      ps = ps->play_next;
757
758      tmp->play_next = NULL;
759    }
760}
761
762static struct player_source *
763source_shuffle(struct player_source *head)
764{
765  struct player_source *ps;
766  struct player_source **ps_array;
767  int nitems;
768  int i;
769
770  if (!head)
771    return NULL;
772
773  ps = head;
774  nitems = 0;
775  do
776    {
777      nitems++;
778      ps = ps->pl_next;
779    }
780  while (ps != head);
781
782  ps_array = (struct player_source **)malloc(nitems * sizeof(struct player_source *));
783  if (!ps_array)
784    {
785      DPRINTF(E_LOG, L_PLAYER, "Could not allocate memory for shuffle array\n");
786      return NULL;
787    }
788
789  ps = head;
790  i = 0;
791  do
792    {
793      ps_array[i] = ps;
794
795      ps = ps->pl_next;
796      i++;
797    }
798  while (ps != head);
799
800  shuffle_ptr(&shuffle_rng, (void **)ps_array, nitems);
801
802  for (i = 0; i < nitems; i++)
803    {
804      ps = ps_array[i];
805
806      if (i > 0)
807	ps->shuffle_prev = ps_array[i - 1];
808
809      if (i < (nitems - 1))
810	ps->shuffle_next = ps_array[i + 1];
811    }
812
813  ps_array[0]->shuffle_prev = ps_array[nitems - 1];
814  ps_array[nitems - 1]->shuffle_next = ps_array[0];
815
816  ps = ps_array[0];
817
818  free(ps_array);
819
820  return ps;
821}
822
823static void
824source_reshuffle(void)
825{
826  struct player_source *ps;
827
828  ps = source_shuffle(source_head);
829  if (!ps)
830    return;
831
832  if (cur_streaming)
833    shuffle_head = cur_streaming;
834  else
835    shuffle_head = ps;
836}
837
838/* Helper */
839static int
840source_open(struct player_source *ps, int no_md)
841{
842  struct media_file_info *mfi;
843
844  ps->stream_start = 0;
845  ps->output_start = 0;
846  ps->end = 0;
847  ps->play_next = NULL;
848
849  mfi = db_file_fetch_byid(ps->id);
850  if (!mfi)
851    {
852      DPRINTF(E_LOG, L_PLAYER, "Couldn't fetch file id %d\n", ps->id);
853
854      return -1;
855    }
856
857  if (mfi->disabled)
858    {
859      DPRINTF(E_DBG, L_PLAYER, "File id %d is disabled, skipping\n", ps->id);
860
861      free_mfi(mfi, 0);
862      return -1;
863    }
864
865  DPRINTF(E_DBG, L_PLAYER, "Opening %s\n", mfi->path);
866
867  ps->ctx = transcode_setup(mfi, NULL, 0);
868
869  free_mfi(mfi, 0);
870
871  if (!ps->ctx)
872    {
873      DPRINTF(E_LOG, L_PLAYER, "Could not open file id %d\n", ps->id);
874
875      return -1;
876    }
877
878  if (!no_md)
879    metadata_send(ps, (player_state == PLAY_PLAYING) ? 0 : 1);
880
881  return 0;
882}
883
884static int
885source_next(int force)
886{
887  struct player_source *ps;
888  struct player_source *head;
889  struct player_source *limit;
890  enum repeat_mode r_mode;
891  int ret;
892
893  head = (shuffle) ? shuffle_head : source_head;
894  limit = head;
895  r_mode = repeat;
896
897  /* Force repeat mode at user request */
898  if (force && (r_mode == REPEAT_SONG))
899    r_mode = REPEAT_ALL;
900
901  /* Playlist has only one file, treat REPEAT_ALL as REPEAT_SONG */
902  if ((r_mode == REPEAT_ALL) && (source_head == source_head->pl_next))
903    r_mode = REPEAT_SONG;
904  /* Playlist has only one file, not a user action, treat as REPEAT_ALL
905   * and source_check() will stop playback
906   */
907  else if (!force && (r_mode == REPEAT_OFF) && (source_head == source_head->pl_next))
908    r_mode = REPEAT_SONG;
909
910  if (!cur_streaming)
911    ps = head;
912  else
913    ps = (shuffle) ? cur_streaming->shuffle_next : cur_streaming->pl_next;
914
915  switch (r_mode)
916    {
917      case REPEAT_SONG:
918	if (cur_streaming->ctx)
919	  {
920	    ret = transcode_seek(cur_streaming->ctx, 0);
921
922	    /* source_open() takes care of sending metadata, but we don't
923	     * call it when repeating a song as we just seek back to 0
924	     * so we have to handle metadata ourselves here
925	     */
926	    if (ret >= 0)
927	      metadata_send(cur_streaming, 0);
928	  }
929	else
930	  ret = source_open(cur_streaming, force);
931
932	if (ret < 0)
933	  {
934	    DPRINTF(E_LOG, L_PLAYER, "Failed to restart song for song repeat\n");
935
936	    return -1;
937	  }
938
939	return 0;
940
941      case REPEAT_ALL:
942	if (!shuffle)
943	  {
944	    limit = ps;
945	    break;
946	  }
947
948	/* Reshuffle before repeating playlist */
949	if (cur_streaming && (ps == shuffle_head))
950	  {
951	    source_reshuffle();
952	    ps = shuffle_head;
953	  }
954
955	limit = shuffle_head;
956
957	break;
958
959      case REPEAT_OFF:
960	limit = head;
961
962	if (force && (ps == limit))
963	  {
964	    DPRINTF(E_DBG, L_PLAYER, "End of playlist reached and repeat is OFF\n");
965
966	    playback_abort();
967	    return 0;
968	  }
969	break;
970    }
971
972  do
973    {
974      ret = source_open(ps, force);
975      if (ret < 0)
976	{
977	  if (shuffle)
978	    ps = ps->shuffle_next;
979	  else
980	    ps = ps->pl_next;
981
982	  continue;
983	}
984
985      break;
986    }
987  while (ps != limit);
988
989  /* Couldn't open any of the files in our queue */
990  if (ret < 0)
991    {
992      DPRINTF(E_WARN, L_PLAYER, "Could not open any file in the queue (next)\n");
993
994      return -1;
995    }
996
997  if (!force && cur_streaming)
998    cur_streaming->play_next = ps;
999
1000  cur_streaming = ps;
1001
1002  return 0;
1003}
1004
1005static int
1006source_prev(void)
1007{
1008  struct player_source *ps;
1009  struct player_source *head;
1010  struct player_source *limit;
1011  int ret;
1012
1013  if (!cur_streaming)
1014    return -1;
1015
1016  head = (shuffle) ? shuffle_head : source_head;
1017  ps = (shuffle) ? cur_streaming->shuffle_prev : cur_streaming->pl_prev;
1018  limit = ps;
1019
1020  if ((repeat == REPEAT_OFF) && (cur_streaming == head))
1021    {
1022      DPRINTF(E_DBG, L_PLAYER, "Start of playlist reached and repeat is OFF\n");
1023
1024      playback_abort();
1025      return 0;
1026    }
1027
1028  /* We are not reshuffling on prev calls in the shuffle case - should we? */
1029
1030  do
1031    {
1032      ret = source_open(ps, 1);
1033      if (ret < 0)
1034	{
1035	  if (shuffle)
1036	    ps = ps->shuffle_prev;
1037	  else
1038	    ps = ps->pl_prev;
1039
1040	  continue;
1041	}
1042
1043      break;
1044    }
1045  while (ps != limit);
1046
1047  /* Couldn't open any of the files in our queue */
1048  if (ret < 0)
1049    {
1050      DPRINTF(E_WARN, L_PLAYER, "Could not open any file in the queue (prev)\n");
1051
1052      return -1;
1053    }
1054
1055  cur_streaming = ps;
1056
1057  return 0;
1058}
1059
1060static int
1061source_position(struct player_source *ps)
1062{
1063  struct player_source *p;
1064  int ret;
1065
1066  ret = 0;
1067  for (p = source_head; p != ps; p = p->pl_next)
1068    ret++;
1069
1070  return ret;
1071}
1072
1073static uint64_t
1074source_check(void)
1075{
1076  struct timespec ts;
1077  struct player_source *ps;
1078  struct player_source *head;
1079  uint64_t pos;
1080  enum repeat_mode r_mode;
1081  int i;
1082  int ret;
1083
1084  if (!cur_streaming)
1085    return 0;
1086
1087  ret = player_get_current_pos(&pos, &ts, 0);
1088  if (ret < 0)
1089    {
1090      DPRINTF(E_LOG, L_PLAYER, "Couldn't get current playback position\n");
1091
1092      return 0;
1093    }
1094
1095  if (!cur_playing)
1096    {
1097      if (pos >= cur_streaming->output_start)
1098	{
1099	  cur_playing = cur_streaming;
1100	  status_update(PLAY_PLAYING);
1101
1102	  /* Start of streaming, no metadata to prune yet */
1103	}
1104
1105      return pos;
1106    }
1107
1108  if ((cur_playing->end == 0) || (pos < cur_playing->end))
1109    return pos;
1110
1111  r_mode = repeat;
1112  /* Playlist has only one file, treat REPEAT_ALL as REPEAT_SONG */
1113  if ((r_mode == REPEAT_ALL) && (source_head == source_head->pl_next))
1114    r_mode = REPEAT_SONG;
1115
1116  if (r_mode == REPEAT_SONG)
1117    {
1118      ps = cur_playing;
1119
1120      /* Check that we haven't gone to the next file already
1121       * (repeat song toggled in the last 2 seconds of a song)
1122       */
1123      if (cur_playing->play_next)
1124	{
1125	  cur_playing = cur_playing->play_next;
1126
1127	  if (ps->ctx)
1128	    {
1129	      transcode_cleanup(ps->ctx);
1130	      ps->ctx = NULL;
1131	      ps->play_next = NULL;
1132	    }
1133        }
1134
1135      cur_playing->stream_start = ps->end + 1;
1136      cur_playing->output_start = cur_playing->stream_start;
1137
1138      /* Do not use cur_playing to reset the end position, it may have changed */
1139      ps->end = 0;
1140
1141      status_update(PLAY_PLAYING);
1142
1143      metadata_prune(pos);
1144
1145      return pos;
1146    }
1147
1148  head = (shuffle) ? shuffle_head : source_head;
1149
1150  i = 0;
1151  while (cur_playing && (cur_playing->end != 0) && (pos > cur_playing->end))
1152    {
1153      i++;
1154
1155      /* Stop playback if:
1156       * - at end of playlist (NULL)
1157       * - repeat OFF and at end of playlist (wraparound)
1158       */
1159      if (!cur_playing->play_next
1160	  || ((r_mode == REPEAT_OFF) && (cur_playing->play_next == head)))
1161	{
1162	  playback_abort();
1163
1164	  return pos;
1165        }
1166
1167      ps = cur_playing;
1168      cur_playing = cur_playing->play_next;
1169
1170      cur_playing->stream_start = ps->end + 1;
1171      cur_playing->output_start = cur_playing->stream_start;
1172
1173      if (ps->ctx)
1174	{
1175	  transcode_cleanup(ps->ctx);
1176	  ps->ctx = NULL;
1177	  ps->play_next = NULL;
1178	}
1179    }
1180
1181  if (i > 0)
1182    {
1183      DPRINTF(E_DBG, L_PLAYER, "Playback switched to next song\n");
1184
1185      status_update(PLAY_PLAYING);
1186
1187      metadata_prune(pos);
1188    }
1189
1190  return pos;
1191}
1192
1193static int
1194source_read(uint8_t *buf, int len, uint64_t rtptime)
1195{
1196  int new;
1197  int ret;
1198  int nbytes;
1199
1200  if (!cur_streaming)
1201    return 0;
1202
1203  nbytes = 0;
1204  new = 0;
1205  while (nbytes < len)
1206    {
1207      if (new)
1208	{
1209	  DPRINTF(E_DBG, L_PLAYER, "New file\n");
1210
1211	  new = 0;
1212
1213	  ret = source_next(0);
1214	  if (ret < 0)
1215	    return -1;
1216	}
1217
1218      if (EVBUFFER_LENGTH(audio_buf) == 0)
1219	{
1220	  ret = transcode(cur_streaming->ctx, audio_buf, len - nbytes);
1221	  if (ret <= 0)
1222	    {
1223	      /* EOF or error */
1224	      cur_streaming->end = rtptime + BTOS(nbytes) - 1;
1225
1226	      new = 1;
1227	      continue;
1228	    }
1229	}
1230
1231      nbytes += evbuffer_remove(audio_buf, buf + nbytes, len - nbytes);
1232    }
1233
1234  return nbytes;
1235}
1236
1237
1238static void
1239playback_write(void)
1240{
1241  uint8_t rawbuf[AIRTUNES_V2_PACKET_SAMPLES * 2 * 2];
1242  int ret;
1243
1244  source_check();
1245  /* Make sure playback is still running after source_check() */
1246  if (player_state == PLAY_STOPPED)
1247    return;
1248
1249  last_rtptime += AIRTUNES_V2_PACKET_SAMPLES;
1250
1251  memset(rawbuf, 0, sizeof(rawbuf));
1252
1253  ret = source_read(rawbuf, sizeof(rawbuf), last_rtptime);
1254  if (ret < 0)
1255    {
1256      DPRINTF(E_DBG, L_PLAYER, "Error reading from source, aborting playback\n");
1257
1258      playback_abort();
1259      return;
1260    }
1261
1262  if (laudio_enabled & laudio_status & LAUDIO_F_STARTED)
1263//  if (laudio_status & LAUDIO_F_STARTED)
1264    laudio_write(rawbuf, last_rtptime);
1265
1266  if (raop_sessions > 0)
1267    raop_v2_write(rawbuf, last_rtptime);
1268}
1269
1270#if defined(__linux__)
1271static void
1272player_playback_cb(int fd, short what, void *arg)
1273{
1274  struct itimerspec next;
1275  uint64_t ticks;
1276  int ret;
1277
1278  /* Acknowledge timer */
1279  read(fd, &ticks, sizeof(ticks));
1280
1281  playback_write();
1282
1283  /* Make sure playback is still running */
1284  if (player_state == PLAY_STOPPED)
1285    return;
1286
1287  pb_timer_last.tv_nsec += AIRTUNES_V2_STREAM_PERIOD;
1288  if (pb_timer_last.tv_nsec >= 1000000000)
1289    {
1290      pb_timer_last.tv_sec++;
1291      pb_timer_last.tv_nsec -= 1000000000;
1292    }
1293
1294  next.it_interval.tv_sec = 0;
1295  next.it_interval.tv_nsec = 0;
1296  next.it_value.tv_sec = pb_timer_last.tv_sec;
1297  next.it_value.tv_nsec = pb_timer_last.tv_nsec;
1298
1299  ret = timerfd_settime(pb_timer_fd, TFD_TIMER_ABSTIME, &next, NULL);
1300  if (ret < 0)
1301    {
1302      DPRINTF(E_LOG, L_PLAYER, "Could not set playback timer: %s\n", strerror(errno));
1303
1304      playback_abort();
1305      return;
1306    }
1307
1308  ret = event_add(&pb_timer_ev, NULL);
1309  if (ret < 0)
1310    {
1311      DPRINTF(E_LOG, L_PLAYER, "Could not re-add playback timer event\n");
1312
1313      playback_abort();
1314      return;
1315    }
1316}
1317#endif /* __linux__ */
1318
1319
1320#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1321static void
1322player_playback_cb(int fd, short what, void *arg)
1323{
1324  struct timespec ts;
1325  struct kevent kev;
1326  int ret;
1327
1328  ts.tv_sec = 0;
1329  ts.tv_nsec = 0;
1330
1331  while (kevent(pb_timer_fd, NULL, 0, &kev, 1, &ts) > 0)
1332    {
1333      if (kev.filter != EVFILT_TIMER)
1334        continue;
1335
1336      playback_write();
1337
1338      /* Make sure playback is still running */
1339      if (player_state == PLAY_STOPPED)
1340	return;
1341    }
1342
1343  ret = event_add(&pb_timer_ev, NULL);
1344  if (ret < 0)
1345    {
1346      DPRINTF(E_LOG, L_PLAYER, "Could not re-add playback timer event\n");
1347
1348      playback_abort();
1349      return;
1350    }
1351}
1352#endif /* __FreeBSD__ || __FreeBSD_kernel__ */
1353
1354
1355static void
1356device_free(struct raop_device *dev)
1357{
1358  free(dev->name);
1359
1360  if (dev->v4_address)
1361    free(dev->v4_address);
1362
1363  if (dev->v6_address)
1364    free(dev->v6_address);
1365
1366  free(dev);
1367}
1368
1369/* Helpers */
1370static void
1371device_remove(struct raop_device *dev)
1372{
1373  struct raop_device *rd;
1374  struct raop_device *prev;
1375  int ret;
1376
1377  prev = NULL;
1378  for (rd = dev_list; rd; rd = rd->next)
1379    {
1380      if (rd == dev)
1381	break;
1382
1383      prev = rd;
1384    }
1385
1386  if (!rd)
1387    return;
1388
1389  DPRINTF(E_DBG, L_PLAYER, "Removing AirTunes device %s; stopped advertising\n", dev->name);
1390
1391  /* Make sure device isn't selected anymore */
1392  if (dev->selected)
1393    speaker_deselect_raop(dev);
1394
1395  /* Save device volume */
1396  ret = db_speaker_save(dev->id, 0, dev->volume);
1397  if (ret < 0)
1398    DPRINTF(E_LOG, L_PLAYER, "Could not save state for speaker %s\n", dev->name);
1399
1400  if (!prev)
1401    dev_list = dev->next;
1402  else
1403    prev->next = dev->next;
1404
1405  device_free(dev);
1406}
1407
1408static int
1409device_check(struct raop_device *dev)
1410{
1411  struct raop_device *rd;
1412
1413  for (rd = dev_list; rd; rd = rd->next)
1414    {
1415      if (rd == dev)
1416	break;
1417    }
1418
1419  return (rd) ? 0 : -1;
1420}
1421
1422static int
1423device_add(struct player_command *cmd)
1424{
1425  struct raop_device *dev;
1426  struct raop_device *rd;
1427  int selected;
1428  int ret;
1429
1430  dev = cmd->arg.rd;
1431
1432  for (rd = dev_list; rd; rd = rd->next)
1433    {
1434      if (rd->id == dev->id)
1435	break;
1436    }
1437
1438  /* New device */
1439  if (!rd)
1440    {
1441      rd = dev;
1442
1443      ret = db_speaker_get(rd->id, &selected, &rd->volume);
1444      if (ret < 0)
1445	{
1446	  selected = 0;
1447	  rd->volume = (master_volume >= 0) ? master_volume : 75;
1448	}
1449
1450//      if (dev_autoselect && selected)
1451	speaker_select_raop(rd);
1452
1453      rd->next = dev_list;
1454      dev_list = rd;
1455    }
1456  else
1457    {
1458      rd->advertised = 1;
1459
1460      if (dev->v4_address)
1461	{
1462	  if (rd->v4_address)
1463	    free(rd->v4_address);
1464
1465	  rd->v4_address = dev->v4_address;
1466	  rd->v4_port = dev->v4_port;
1467
1468	  /* Address is ours now */
1469	  dev->v4_address = NULL;
1470	}
1471
1472      if (dev->v6_address)
1473	{
1474	  if (rd->v6_address)
1475	    free(rd->v6_address);
1476
1477	  rd->v6_address = dev->v6_address;
1478	  rd->v6_port = dev->v6_port;
1479
1480	  /* Address is ours now */
1481	  dev->v6_address = NULL;
1482	}
1483
1484      if (rd->name)
1485	free(rd->name);
1486      rd->name = dev->name;
1487      dev->name = NULL;
1488
1489      rd->devtype = dev->devtype;
1490
1491      rd->has_password = dev->has_password;
1492      rd->password = dev->password;
1493
1494      device_free(dev);
1495    }
1496
1497  return 0;
1498}
1499
1500static int
1501device_remove_family(struct player_command *cmd)
1502{
1503  struct raop_device *dev;
1504  struct raop_device *rd;
1505
1506  dev = cmd->arg.rd;
1507
1508  for (rd = dev_list; rd; rd = rd->next)
1509    {
1510      if (rd->id == dev->id)
1511        break;
1512    }
1513
1514  if (!rd)
1515    {
1516      DPRINTF(E_WARN, L_PLAYER, "AirTunes device %s stopped advertising, but not in our list\n", dev->name);
1517
1518      device_free(dev);
1519      return 0;
1520    }
1521
1522  /* v{4,6}_port non-zero indicates the address family stopped advertising */
1523  if (dev->v4_port && rd->v4_address)
1524    {
1525      free(rd->v4_address);
1526      rd->v4_address = NULL;
1527      rd->v4_port = 0;
1528    }
1529
1530  if (dev->v6_port && rd->v6_address)
1531    {
1532      free(rd->v6_address);
1533      rd->v6_address = NULL;
1534      rd->v6_port = 0;
1535    }
1536
1537  if (!rd->v4_address && !rd->v6_address)
1538    {
1539      rd->advertised = 0;
1540
1541      if (!rd->session)
1542	device_remove(rd);
1543    }
1544
1545  device_free(dev);
1546
1547  return 0;
1548}
1549
1550/* RAOP callbacks executed in the player thread */
1551static void
1552device_streaming_cb(struct raop_device *dev, struct raop_session *rs, enum raop_session_state status)
1553{
1554  int ret;
1555
1556  if (status == RAOP_FAILED)
1557    {
1558      raop_sessions--;
1559
1560      ret = device_check(dev);
1561      if (ret < 0)
1562	{
1563	  DPRINTF(E_WARN, L_PLAYER, "AirTunes device disappeared during streaming!\n");
1564
1565	  return;
1566	}
1567
1568      DPRINTF(E_LOG, L_PLAYER, "AirTunes device %s FAILED\n", dev->name);
1569
1570      if (player_state == PLAY_PLAYING)
1571	speaker_deselect_raop(dev);
1572
1573      dev->session = NULL;
1574
1575      if (!dev->advertised)
1576	device_remove(dev);
1577    }
1578  else if (status == RAOP_STOPPED)
1579    {
1580      raop_sessions--;
1581
1582      ret = device_check(dev);
1583      if (ret < 0)
1584	{
1585	  DPRINTF(E_WARN, L_PLAYER, "AirTunes device disappeared during streaming!\n");
1586
1587	  return;
1588	}
1589
1590      DPRINTF(E_LOG, L_PLAYER, "AirTunes device %s stopped\n", dev->name);
1591
1592      dev->session = NULL;
1593
1594      if (!dev->advertised)
1595	device_remove(dev);
1596    }
1597}
1598
1599static void
1600device_command_cb(struct raop_device *dev, struct raop_session *rs, enum raop_session_state status)
1601{
1602  cur_cmd->raop_pending--;
1603
1604  raop_set_status_cb(rs, device_streaming_cb);
1605
1606  if (status == RAOP_FAILED)
1607    device_streaming_cb(dev, rs, status);
1608
1609  if (cur_cmd->raop_pending == 0)
1610    {
1611      if (cur_cmd->func_bh)
1612	cur_cmd->ret = cur_cmd->func_bh(cur_cmd);
1613      else
1614	cur_cmd->ret = 0;
1615
1616      command_async_end(cur_cmd);
1617    }
1618}
1619
1620static void
1621device_shutdown_cb(struct raop_device *dev, struct raop_session *rs, enum raop_session_state status)
1622{
1623  int ret;
1624
1625  cur_cmd->raop_pending--;
1626
1627  if (raop_sessions)
1628    raop_sessions--;
1629
1630  ret = device_check(dev);
1631  if (ret < 0)
1632    {
1633      DPRINTF(E_WARN, L_PLAYER, "AirTunes device disappeared before shutdown completion!\n");
1634
1635      if (cur_cmd->ret != -2)
1636	cur_cmd->ret = -1;
1637      goto out;
1638    }
1639
1640  dev->session = NULL;
1641
1642  if (!dev->advertised)
1643    device_remove(dev);
1644
1645 out:
1646  if (cur_cmd->raop_pending == 0)
1647    {
1648      /* cur_cmd->ret already set
1649       *  - to 0 (or -2 if password issue) in speaker_set()
1650       *  - to -1 above on error
1651       */
1652      command_async_end(cur_cmd);
1653    }
1654}
1655
1656static void
1657device_lost_cb(struct raop_device *dev, struct raop_session *rs, enum raop_session_state status)
1658{
1659  /* We lost that device during startup for some reason, not much we can do here */
1660  if (status == RAOP_FAILED)
1661    DPRINTF(E_WARN, L_PLAYER, "Failed to stop lost device\n");
1662  else
1663    DPRINTF(E_INFO, L_PLAYER, "Lost device stopped properly\n");
1664}
1665
1666static void
1667device_activate_cb(struct raop_device *dev, struct raop_session *rs, enum raop_session_state status)
1668{
1669  struct timespec ts;
1670  int ret;
1671
1672  cur_cmd->raop_pending--;
1673
1674  ret = device_check(dev);
1675  if (ret < 0)
1676    {
1677      DPRINTF(E_WARN, L_PLAYER, "AirTunes device disappeared during startup!\n");
1678
1679      raop_set_status_cb(rs, device_lost_cb);
1680      raop_device_stop(rs);
1681
1682      if (cur_cmd->ret != -2)
1683	cur_cmd->ret = -1;
1684      goto out;
1685    }
1686
1687  if (status == RAOP_PASSWORD)
1688    {
1689      status = RAOP_FAILED;
1690      cur_cmd->ret = -2;
1691    }
1692
1693  if (status == RAOP_FAILED)
1694    {
1695      speaker_deselect_raop(dev);
1696
1697      if (!dev->advertised)
1698	device_remove(dev);
1699
1700      if (cur_cmd->ret != -2)
1701	cur_cmd->ret = -1;
1702      goto out;
1703    }
1704
1705  dev->session = rs;
1706
1707  raop_sessions++;
1708
1709  if ((player_state == PLAY_PLAYING) && (raop_sessions == 1))
1710    {
1711      ret = clock_gettime(CLOCK_MONOTONIC, &ts);
1712      if (ret < 0)
1713	{
1714	  DPRINTF(E_LOG, L_PLAYER, "Could not get current time: %s\n", strerror(errno));
1715
1716#if defined(__linux__)
1717	  /* Fallback to nearest timer expiration time */
1718	  ts.tv_sec = pb_timer_last.tv_sec;
1719	  ts.tv_nsec = pb_timer_last.tv_nsec;
1720#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1721	  if (cur_cmd->ret != -2)
1722	    cur_cmd->ret = -1;
1723	  goto out;
1724#endif
1725	}
1726
1727      raop_playback_start(last_rtptime + AIRTUNES_V2_PACKET_SAMPLES, &ts);
1728    }
1729
1730  raop_set_status_cb(rs, device_streaming_cb);
1731
1732 out:
1733  if (cur_cmd->raop_pending == 0)
1734    {
1735      /* cur_cmd->ret already set
1736       *  - to 0 in speaker_set() (default)
1737       *  - to -2 above if password issue
1738       *  - to -1 above on error
1739       */
1740      command_async_end(cur_cmd);
1741    }
1742}
1743
1744static void
1745device_probe_cb(struct raop_device *dev, struct raop_session *rs, enum raop_session_state status)
1746{
1747  int ret;
1748
1749  cur_cmd->raop_pending--;
1750
1751  ret = device_check(dev);
1752  if (ret < 0)
1753    {
1754      DPRINTF(E_WARN, L_PLAYER, "AirTunes device disappeared during probe!\n");
1755
1756      if (cur_cmd->ret != -2)
1757	cur_cmd->ret = -1;
1758      goto out;
1759    }
1760
1761  if (status == RAOP_PASSWORD)
1762    {
1763      status = RAOP_FAILED;
1764      cur_cmd->ret = -2;
1765    }
1766
1767  if (status == RAOP_FAILED)
1768    {
1769      speaker_deselect_raop(dev);
1770
1771      if (!dev->advertised)
1772	device_remove(dev);
1773
1774      if (cur_cmd->ret != -2)
1775	cur_cmd->ret = -1;
1776      goto out;
1777    }
1778
1779 out:
1780  if (cur_cmd->raop_pending == 0)
1781    {
1782      /* cur_cmd->ret already set
1783       *  - to 0 in speaker_set() (default)
1784       *  - to -2 above if password issue
1785       *  - to -1 above on error
1786       */
1787      command_async_end(cur_cmd);
1788    }
1789}
1790
1791static void
1792device_restart_cb(struct raop_device *dev, struct raop_session *rs, enum raop_session_state status)
1793{
1794  int ret;
1795
1796  cur_cmd->raop_pending--;
1797
1798  ret = device_check(dev);
1799  if (ret < 0)
1800    {
1801      DPRINTF(E_WARN, L_PLAYER, "AirTunes device disappeared during restart!\n");
1802
1803      raop_set_status_cb(rs, device_lost_cb);
1804      raop_device_stop(rs);
1805
1806      goto out;
1807    }
1808
1809  if (status == RAOP_FAILED)
1810    {
1811      speaker_deselect_raop(dev);
1812
1813      if (!dev->advertised)
1814	device_remove(dev);
1815
1816      goto out;
1817    }
1818
1819  dev->session = rs;
1820
1821  raop_sessions++;
1822  raop_set_status_cb(rs, device_streaming_cb);
1823
1824 out:
1825  if (cur_cmd->raop_pending == 0)
1826    {
1827      cur_cmd->ret = cur_cmd->func_bh(cur_cmd);
1828
1829      command_async_end(cur_cmd);
1830    }
1831}
1832
1833
1834/* Internal abort routine */
1835static void
1836playback_abort(void)
1837{
1838  if (laudio_enabled && laudio_status != LAUDIO_CLOSED)
1839//  if (laudio_status != LAUDIO_CLOSED)
1840    laudio_close();
1841
1842  if (raop_sessions > 0)
1843    raop_playback_stop();
1844
1845  if (event_initialized(&pb_timer_ev))
1846    event_del(&pb_timer_ev);
1847
1848  close(pb_timer_fd);
1849  pb_timer_fd = -1;
1850
1851  if (cur_playing)
1852    source_stop(cur_playing);
1853  else
1854    source_stop(cur_streaming);
1855
1856  cur_playing = NULL;
1857  cur_streaming = NULL;
1858
1859  evbuffer_drain(audio_buf, EVBUFFER_LENGTH(audio_buf));
1860
1861  status_update(PLAY_STOPPED);
1862
1863  metadata_purge();
1864}
1865
1866
1867/* Actual commands, executed in the player thread */
1868static int
1869get_status(struct player_command *cmd)
1870{
1871  struct timespec ts;
1872  struct player_source *ps;
1873  struct player_status *status;
1874  uint64_t pos;
1875  int ret;
1876
1877  status = cmd->arg.status;
1878
1879  status->shuffle = shuffle;
1880  status->repeat = repeat;
1881
1882  /* No devices selected, autoselect local audio */
1883  if (laudio_enabled && master_volume < 0)
1884//  if (master_volume < 0)
1885    speaker_select_laudio();
1886
1887  status->volume = master_volume;
1888
1889  status->plid = cur_plid;
1890
1891  switch (player_state)
1892    {
1893      case PLAY_STOPPED:
1894	DPRINTF(E_DBG, L_PLAYER, "Player status: stopped\n");
1895
1896	status->status = PLAY_STOPPED;
1897	break;
1898
1899      case PLAY_PAUSED:
1900	DPRINTF(E_DBG, L_PLAYER, "Player status: paused\n");
1901
1902	status->status = PLAY_PAUSED;
1903	status->id = cur_streaming->id;
1904
1905	pos = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES - cur_streaming->stream_start;
1906	status->pos_ms = (pos * 1000) / 44100;
1907
1908	status->pos_pl = source_position(cur_streaming);
1909	break;
1910
1911      case PLAY_PLAYING:
1912	if (!cur_playing)
1913	  {
1914	    DPRINTF(E_DBG, L_PLAYER, "Player status: playing (buffering)\n");
1915
1916	    status->status = PLAY_PAUSED;
1917	    ps = cur_streaming;
1918
1919	    /* Avoid a visible 2-second jump backward for the client */
1920	    pos = ps->output_start - ps->stream_start;
1921	  }
1922	else
1923	  {
1924	    DPRINTF(E_DBG, L_PLAYER, "Player status: playing\n");
1925
1926	    status->status = PLAY_PLAYING;
1927	    ps = cur_playing;
1928
1929	    ret = player_get_current_pos(&pos, &ts, 0);
1930	    if (ret < 0)
1931	      {
1932		DPRINTF(E_LOG, L_PLAYER, "Could not get current stream position for playstatus\n");
1933
1934		pos = 0;
1935	      }
1936
1937	    if (pos < ps->stream_start)
1938	      pos = 0;
1939	    else
1940	      pos -= ps->stream_start;
1941	  }
1942
1943	status->pos_ms = (pos * 1000) / 44100;
1944
1945	status->id = ps->id;
1946	status->pos_pl = source_position(ps);
1947	break;
1948    }
1949
1950  return 0;
1951}
1952
1953static int
1954now_playing(struct player_command *cmd)
1955{
1956  uint32_t *id;
1957
1958  id = cmd->arg.id_ptr;
1959
1960  if (cur_playing)
1961    *id = cur_playing->id;
1962  else if (cur_streaming)
1963    *id = cur_streaming->id;
1964  else
1965    return -1;
1966
1967  return 0;
1968}
1969
1970static int
1971playback_stop(struct player_command *cmd)
1972{
1973//  if (laudio_status != LAUDIO_CLOSED)
1974  if (laudio_enabled && laudio_status != LAUDIO_CLOSED)
1975    laudio_close();
1976
1977  /* We may be restarting very soon, so we don't bring the devices to a
1978   * full stop just yet; this saves time when restarting, which is nicer
1979   * for the user.
1980   */
1981  cmd->raop_pending = raop_flush(device_command_cb, last_rtptime + AIRTUNES_V2_PACKET_SAMPLES);
1982
1983  if (event_initialized(&pb_timer_ev))
1984    event_del(&pb_timer_ev);
1985
1986  close(pb_timer_fd);
1987  pb_timer_fd = -1;
1988
1989  if (cur_playing)
1990    source_stop(cur_playing);
1991  else
1992    source_stop(cur_streaming);
1993
1994  cur_playing = NULL;
1995  cur_streaming = NULL;
1996
1997  evbuffer_drain(audio_buf, EVBUFFER_LENGTH(audio_buf));
1998
1999  status_update(PLAY_STOPPED);
2000
2001  metadata_purge();
2002
2003  /* We're async if we need to flush RAOP devices */
2004  if (cmd->raop_pending > 0)
2005    return 1; /* async */
2006
2007  return 0;
2008}
2009
2010/* Playback startup bottom half */
2011static int
2012playback_start_bh(struct player_command *cmd)
2013{
2014#if defined(__linux__)
2015  struct itimerspec next;
2016#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2017  struct kevent kev;
2018#endif
2019  int ret;
2020
2021  if ((laudio_status == LAUDIO_CLOSED) && (raop_sessions == 0))
2022    {
2023      DPRINTF(E_LOG, L_PLAYER, "Cannot start playback: no output started\n");
2024
2025      goto out_fail;
2026    }
2027
2028  /* Start laudio first as it can fail, but can be stopped easily if needed */
2029  if (laudio_status == LAUDIO_OPEN)
2030    {
2031      laudio_set_volume(laudio_volume);
2032
2033      ret = laudio_start(pb_pos, last_rtptime + AIRTUNES_V2_PACKET_SAMPLES);
2034      if (ret < 0)
2035	{
2036	  DPRINTF(E_LOG, L_PLAYER, "Local audio failed to start\n");
2037
2038	  goto out_fail;
2039	}
2040    }
2041
2042  ret = clock_gettime(CLOCK_MONOTONIC, &pb_pos_stamp);
2043  if (ret < 0)
2044    {
2045      DPRINTF(E_LOG, L_PLAYER, "Couldn't get current clock: %s\n", strerror(errno));
2046
2047      goto out_fail;
2048    }
2049
2050  memset(&pb_timer_ev, 0, sizeof(struct event));
2051
2052#if defined(__linux__)
2053  pb_timer_last.tv_sec = pb_pos_stamp.tv_sec;
2054  pb_timer_last.tv_nsec = pb_pos_stamp.tv_nsec;
2055
2056  pb_timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
2057  if (pb_timer_fd < 0)
2058    {
2059      DPRINTF(E_LOG, L_PLAYER, "Could not create playback timer: %s\n", strerror(errno));
2060
2061      goto out_fail;
2062    }
2063
2064  next.it_interval.tv_sec = 0;
2065  next.it_interval.tv_nsec = 0;
2066  next.it_value.tv_sec = pb_timer_last.tv_sec;
2067  next.it_value.tv_nsec = pb_timer_last.tv_nsec;
2068
2069  ret = timerfd_settime(pb_timer_fd, TFD_TIMER_ABSTIME, &next, NULL);
2070  if (ret < 0)
2071    {
2072      DPRINTF(E_LOG, L_PLAYER, "Could not set playback timer: %s\n", strerror(errno));
2073
2074      goto out_fail;
2075    }
2076#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2077  pb_timer_fd = kqueue();
2078  if (pb_timer_fd < 0)
2079    {
2080      DPRINTF(E_LOG, L_PLAYER, "Could not create kqueue: %s\n", strerror(errno));
2081
2082      goto out_fail;
2083    }
2084
2085  memset(&kev, 0, sizeof(struct kevent));
2086
2087  EV_SET(&kev, 1, EVFILT_TIMER, EV_ADD | EV_ENABLE, 0, AIRTUNES_V2_STREAM_PERIOD, 0);
2088
2089  ret = kevent(pb_timer_fd, &kev, 1, NULL, 0, NULL);
2090  if (ret < 0)
2091    {
2092      DPRINTF(E_LOG, L_PLAYER, "Could not add kevent timer: %s\n", strerror(errno));
2093
2094      goto out_fail;
2095    }
2096#endif
2097
2098  event_set(&pb_timer_ev, pb_timer_fd, EV_READ, player_playback_cb, NULL);
2099  event_base_set(evbase_player, &pb_timer_ev);
2100
2101  ret = event_add(&pb_timer_ev, NULL);
2102  if (ret < 0)
2103    {
2104      DPRINTF(E_LOG, L_PLAYER, "Could not set up playback timer event\n");
2105
2106      goto out_fail;
2107    }
2108
2109  /* Everything OK, start RAOP */
2110  if (raop_sessions > 0)
2111    raop_playback_start(last_rtptime + AIRTUNES_V2_PACKET_SAMPLES, &pb_pos_stamp);
2112
2113  status_update(PLAY_PLAYING);
2114
2115  return 0;
2116
2117 out_fail:
2118  close(pb_timer_fd);
2119  pb_timer_fd = -1;
2120  playback_abort();
2121
2122  return -1;
2123}
2124
2125static int
2126playback_start(struct player_command *cmd)
2127{
2128  struct raop_device *rd;
2129  uint32_t *idx_id;
2130  int ret;
2131
2132  if (!source_head)
2133    {
2134      DPRINTF(E_LOG, L_PLAYER, "Nothing to play!\n");
2135
2136      return -1;
2137    }
2138
2139  idx_id = cmd->arg.id_ptr;
2140
2141  if (player_state == PLAY_PLAYING)
2142    {
2143      if (idx_id)
2144	{
2145	  if (cur_playing)
2146	    *idx_id = cur_playing->id;
2147	  else
2148	    *idx_id = cur_streaming->id;
2149	}
2150
2151      status_update(player_state);
2152
2153      return 0;
2154    }
2155
2156  pb_pos = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES - 88200;
2157
2158  if (idx_id)
2159    {
2160      if (cur_playing)
2161	source_stop(cur_playing);
2162      else if (cur_streaming)
2163	source_stop(cur_streaming);
2164
2165      cur_playing = NULL;
2166      cur_streaming = NULL;
2167
2168      if (shuffle)
2169	{
2170	  source_reshuffle();
2171	  cur_streaming = shuffle_head;
2172	}
2173      else
2174	cur_streaming = source_head;
2175
2176      if (*idx_id > 0)
2177	{
2178	  cur_streaming = source_head;
2179	  for (; *idx_id > 0; (*idx_id)--)
2180	    cur_streaming = cur_streaming->pl_next;
2181
2182	  if (shuffle)
2183	    shuffle_head = cur_streaming;
2184	}
2185
2186      ret = source_open(cur_streaming, 0);
2187      if (ret < 0)
2188	{
2189	  DPRINTF(E_LOG, L_PLAYER, "Couldn't jump to queue position %d\n", *idx_id);
2190
2191	  playback_abort();
2192	  return -1;
2193	}
2194
2195      *idx_id = cur_streaming->id;
2196      cur_streaming->stream_start = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES;
2197      cur_streaming->output_start = cur_streaming->stream_start;
2198    }
2199  else if (!cur_streaming)
2200    {
2201      if (shuffle)
2202	source_reshuffle();
2203
2204      ret = source_next(0);
2205      if (ret < 0)
2206	{
2207	  DPRINTF(E_LOG, L_PLAYER, "Couldn't find anything to play!\n");
2208
2209	  playback_abort();
2210	  return -1;
2211	}
2212
2213      cur_streaming->stream_start = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES;
2214      cur_streaming->output_start = cur_streaming->stream_start;
2215    }
2216  else
2217    {
2218      /* After a pause, the source is still open so source_open() doesn't get
2219       * called and we have to handle metadata ourselves.
2220       */
2221      metadata_send(cur_streaming, 1);
2222    }
2223
2224  /* Start local audio if needed */
2225  if (laudio_selected && (laudio_status == LAUDIO_CLOSED))
2226    {
2227      ret = laudio_open();
2228      if (ret < 0)
2229	{
2230	  DPRINTF(E_LOG, L_PLAYER, "Could not open local audio\n");
2231
2232	  playback_abort();
2233	  return -1;
2234	}
2235    }
2236
2237  /* Start RAOP sessions on selected devices if needed */
2238  cmd->raop_pending = 0;
2239
2240  for (rd = dev_list; rd; rd = rd->next)
2241    {
2242//      if (rd->selected && !rd->session)
2243      if ( !rd->session)
2244	{
2245	  ret = raop_device_start(rd, device_restart_cb, last_rtptime + AIRTUNES_V2_PACKET_SAMPLES);
2246	  if (ret < 0)
2247	    {
2248	      DPRINTF(E_LOG, L_PLAYER, "Could not start selected AirTunes device %s\n", rd->name);
2249	      continue;
2250	    }
2251
2252	  cmd->raop_pending++;
2253	}
2254    }
2255
2256  if ((laudio_status == LAUDIO_CLOSED) && (cmd->raop_pending == 0) && (raop_sessions == 0))
2257    {
2258      DPRINTF(E_LOG, L_PLAYER, "Could not start playback: no output selected or couldn't start any output\n");
2259
2260      playback_abort();
2261      return -1;
2262    }
2263
2264  /* We're async if we need to start RAOP devices */
2265  if (cmd->raop_pending > 0)
2266    return 1; /* async */
2267
2268  /* Otherwise, just run the bottom half */
2269  return playback_start_bh(cmd);
2270}
2271
2272static int
2273playback_prev_bh(struct player_command *cmd)
2274{
2275  int ret;
2276
2277  if (cur_playing)
2278    source_stop(cur_playing);
2279  else
2280    source_stop(cur_streaming);
2281
2282  ret = source_prev();
2283  if (ret < 0)
2284    {
2285      playback_abort();
2286
2287      return -1;
2288    }
2289
2290  if (player_state == PLAY_STOPPED)
2291    return -1;
2292
2293  cur_streaming->stream_start = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES;
2294  cur_streaming->output_start = cur_streaming->stream_start;
2295
2296  cur_playing = NULL;
2297
2298  /* Silent status change - playback_start() sends the real status update */
2299  player_state = PLAY_PAUSED;
2300
2301  return 0;
2302}
2303
2304static int
2305playback_next_bh(struct player_command *cmd)
2306{
2307  int ret;
2308
2309  if (cur_playing)
2310    source_stop(cur_playing);
2311  else
2312    source_stop(cur_streaming);
2313
2314  ret = source_next(1);
2315  if (ret < 0)
2316    {
2317      playback_abort();
2318
2319      return -1;
2320    }
2321
2322  if (player_state == PLAY_STOPPED)
2323    return -1;
2324
2325  cur_streaming->stream_start = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES;
2326  cur_streaming->output_start = cur_streaming->stream_start;
2327
2328  cur_playing = NULL;
2329
2330  /* Silent status change - playback_start() sends the real status update */
2331  player_state = PLAY_PAUSED;
2332
2333  return 0;
2334}
2335
2336static int
2337playback_seek_bh(struct player_command *cmd)
2338{
2339  struct player_source *ps;
2340  int ms;
2341  int ret;
2342
2343  ms = cmd->arg.intval;
2344
2345  if (cur_playing)
2346    ps = cur_playing;
2347  else
2348    ps = cur_streaming;
2349
2350  ps->end = 0;
2351
2352  /* Seek to commanded position */
2353  ret = transcode_seek(ps->ctx, ms);
2354  if (ret < 0)
2355    {
2356      playback_abort();
2357
2358      return -1;
2359    }
2360
2361  /* Adjust start_pos for the new position */
2362  ps->stream_start = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES - ((uint64_t)ret * 44100) / 1000;
2363  ps->output_start = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES;
2364
2365  cur_streaming = ps;
2366  cur_playing = NULL;
2367
2368  /* Silent status change - playback_start() sends the real status update */
2369  player_state = PLAY_PAUSED;
2370
2371  return 0;
2372}
2373
2374static int
2375playback_pause_bh(struct player_command *cmd)
2376{
2377  struct player_source *ps;
2378  uint64_t pos;
2379  int ms;
2380  int ret;
2381
2382  if (cur_playing)
2383    ps = cur_playing;
2384  else
2385    ps = cur_streaming;
2386
2387  pos = ps->end;
2388  ps->end = 0;
2389
2390  /* Seek back to current playback position */
2391  pos -= ps->stream_start;
2392  ms = (int)((pos * 1000) / 44100);
2393
2394  ret = transcode_seek(ps->ctx, ms);
2395  if (ret < 0)
2396    {
2397      playback_abort();
2398
2399      return -1;
2400    }
2401
2402  /* Adjust start_pos to take into account the pause and seek back */
2403  ps->stream_start = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES - ((uint64_t)ret * 44100) / 1000;
2404  ps->output_start = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES;
2405
2406  cur_streaming = ps;
2407  cur_playing = NULL;
2408
2409  status_update(PLAY_PAUSED);
2410
2411  return 0;
2412}
2413
2414static int
2415playback_pause(struct player_command *cmd)
2416{
2417  struct player_source *ps;
2418  uint64_t pos;
2419
2420  pos = source_check();
2421  if (pos == 0)
2422    {
2423      DPRINTF(E_LOG, L_PLAYER, "Could not retrieve current position for pause\n");
2424
2425      playback_abort();
2426      return -1;
2427    }
2428
2429  /* Make sure playback is still running after source_check() */
2430  if (player_state == PLAY_STOPPED)
2431    return -1;
2432
2433  if (cur_playing)
2434    ps = cur_playing;
2435  else
2436    ps = cur_streaming;
2437
2438  /* Store pause position */
2439  ps->end = pos;
2440
2441  cmd->raop_pending = raop_flush(device_command_cb, last_rtptime + AIRTUNES_V2_PACKET_SAMPLES);
2442
2443  if (laudio_status != LAUDIO_CLOSED)
2444    laudio_stop();
2445
2446  if (event_initialized(&pb_timer_ev))
2447    event_del(&pb_timer_ev);
2448
2449  close(pb_timer_fd);
2450  pb_timer_fd = -1;
2451
2452  if (ps->play_next)
2453    source_stop(ps->play_next);
2454
2455  cur_playing = NULL;
2456  cur_streaming = ps;
2457  cur_streaming->play_next = NULL;
2458
2459  evbuffer_drain(audio_buf, EVBUFFER_LENGTH(audio_buf));
2460
2461  metadata_purge();
2462
2463  /* We're async if we need to flush RAOP devices */
2464  if (cmd->raop_pending > 0)
2465    return 1; /* async */
2466
2467  /* Otherwise, just run the bottom half */
2468  return cmd->func_bh(cmd);
2469}
2470
2471static int
2472speaker_enumerate(struct player_command *cmd)
2473{
2474  struct raop_device *rd;
2475  struct spk_enum *spk_enum;
2476  struct spk_flags flags;
2477  char *laudio_name;
2478
2479  spk_enum = cmd->arg.spk_enum;
2480
2481  laudio_name = cfg_getstr(cfg_getsec(cfg, "audio"), "nickname");
2482
2483  /* Auto-select local audio if there are no AirTunes devices */
2484//  if (!dev_list && !laudio_selected)
2485  if (laudio_enabled && !dev_list && !laudio_selected)
2486    speaker_select_laudio();
2487
2488  flags.selected = laudio_selected;
2489  flags.has_password = 0;
2490  flags.has_video = 0;
2491
2492  if (laudio_enabled)
2493    spk_enum->cb(0, laudio_name, laudio_relvol, flags, spk_enum->arg);
2494//  spk_enum->cb(0, laudio_name, laudio_relvol, flags, spk_enum->arg);
2495
2496#ifdef DEBUG_RELVOL
2497  DPRINTF(E_DBG, L_PLAYER, "*** master: %d\n", master_volume);
2498  if (laudio_enabled)
2499    DPRINTF(E_DBG, L_PLAYER, "*** laudio: abs %d rel %d\n", laudio_volume, laudio_relvol);
2500//  DPRINTF(E_DBG, L_PLAYER, "*** laudio: abs %d rel %d\n", laudio_volume, laudio_relvol);
2501#endif
2502
2503  for (rd = dev_list; rd; rd = rd->next)
2504    {
2505      if (rd->advertised || rd->selected)
2506	{
2507	  flags.selected = rd->selected;
2508	  flags.has_password = rd->has_password;
2509	  flags.has_video = (rd->devtype == RAOP_DEV_APPLETV);
2510
2511	  spk_enum->cb(rd->id, rd->name, rd->relvol, flags, spk_enum->arg);
2512
2513#ifdef DEBUG_RELVOL
2514	  DPRINTF(E_DBG, L_PLAYER, "*** %s: abs %d rel %d\n", rd->name, rd->volume, rd->relvol);
2515#endif
2516	}
2517    }
2518
2519  return 0;
2520}
2521
2522static int
2523speaker_activate(struct raop_device *rd)
2524{
2525  struct timespec ts;
2526  uint64_t pos;
2527  int ret;
2528
2529//  if (!rd)
2530  if (!rd && laudio_enabled)
2531    {
2532      /* Local */
2533      DPRINTF(E_DBG, L_PLAYER, "Activating local audio\n");
2534
2535      if (laudio_status == LAUDIO_CLOSED)
2536	{
2537	  ret = laudio_open();
2538	  if (ret < 0)
2539	    {
2540	      DPRINTF(E_LOG, L_PLAYER, "Could not open local audio\n");
2541
2542	      return -1;
2543	    }
2544	}
2545
2546      if (player_state == PLAY_PLAYING)
2547	{
2548	  laudio_set_volume(laudio_volume);
2549
2550	  ret = player_get_current_pos(&pos, &ts, 0);
2551	  if (ret < 0)
2552	    {
2553	      DPRINTF(E_LOG, L_PLAYER, "Could not get current stream position for local audio start\n");
2554
2555	      laudio_close();
2556	      return -1;
2557	    }
2558
2559	  ret = laudio_start(pos, last_rtptime + AIRTUNES_V2_PACKET_SAMPLES);
2560	  if (ret < 0)
2561	    {
2562	      DPRINTF(E_LOG, L_PLAYER, "Local playback failed to start\n");
2563
2564	      laudio_close();
2565	      return -1;
2566	    }
2567	}
2568
2569      return 0;
2570    }
2571  else
2572    {
2573      /* RAOP */
2574      if (player_state == PLAY_PLAYING)
2575	{
2576	  DPRINTF(E_DBG, L_PLAYER, "Activating RAOP device %s\n", rd->name);
2577
2578	  ret = raop_device_start(rd, device_activate_cb, last_rtptime + AIRTUNES_V2_PACKET_SAMPLES);
2579	  if (ret < 0)
2580	    {
2581	      DPRINTF(E_LOG, L_PLAYER, "Could not start device %s\n", rd->name);
2582
2583	      return -1;
2584	    }
2585	}
2586      else
2587	{
2588	  DPRINTF(E_DBG, L_PLAYER, "Probing RAOP device %s\n", rd->name);
2589
2590	  ret = raop_device_probe(rd, device_probe_cb);
2591	  if (ret < 0)
2592	    {
2593	      DPRINTF(E_LOG, L_PLAYER, "Could not probe device %s\n", rd->name);
2594
2595	      return -1;
2596	    }
2597	}
2598
2599      return 1;
2600    }
2601
2602  return -1;
2603}
2604
2605static int
2606speaker_deactivate(struct raop_device *rd)
2607{
2608//  if (!rd)
2609  if (!rd && laudio_enabled)
2610    {
2611      /* Local */
2612      DPRINTF(E_DBG, L_PLAYER, "Deactivating local audio\n");
2613
2614      if (laudio_status == LAUDIO_CLOSED)
2615	return 0;
2616
2617      if (laudio_status & LAUDIO_F_STARTED)
2618	laudio_stop();
2619
2620      laudio_close();
2621
2622      return 0;
2623    }
2624  else
2625    {
2626      /* RAOP */
2627      DPRINTF(E_DBG, L_PLAYER, "Deactivating RAOP device %s\n", rd->name);
2628
2629      raop_set_status_cb(rd->session, device_shutdown_cb);
2630      raop_device_stop(rd->session);
2631
2632      return 1;
2633    }
2634
2635  return -1;
2636}
2637
2638static int
2639speaker_set(struct player_command *cmd)
2640{
2641  struct raop_device *rd;
2642  uint64_t *ids;
2643  int nspk;
2644  int i;
2645  int ret;
2646
2647  ids = cmd->arg.raop_ids;
2648
2649  if (ids)
2650    nspk = ids[0];
2651  else
2652    nspk = 0;
2653
2654  DPRINTF(E_DBG, L_PLAYER, "Speaker set: %d speakers\n", nspk);
2655
2656  cmd->raop_pending = 0;
2657  cmd->ret = 0;
2658
2659  /* RAOP devices */
2660  for (rd = dev_list; rd; rd = rd->next)
2661    {
2662      for (i = 1; i <= nspk; i++)
2663	{
2664	  DPRINTF(E_DBG, L_PLAYER, "Set %" PRIu64 " device %" PRIu64 "\n", ids[i], rd->id);
2665
2666	  if (ids[i] == rd->id)
2667	    break;
2668	}
2669
2670      if (i <= nspk)
2671	{
2672	  if (rd->has_password && !rd->password)
2673	    {
2674	      DPRINTF(E_INFO, L_PLAYER, "RAOP device %s is password-protected, but we don't have it\n", rd->name);
2675
2676	      cmd->ret = -2;
2677	      continue;
2678	    }
2679
2680	  DPRINTF(E_DBG, L_PLAYER, "RAOP device %s selected\n", rd->name);
2681
2682	  if (!rd->selected)
2683	    speaker_select_raop(rd);
2684
2685	  if (!rd->session)
2686	    {
2687	      ret = speaker_activate(rd);
2688	      if (ret < 0)
2689		{
2690		  DPRINTF(E_LOG, L_PLAYER, "Could not activate RAOP device %s\n", rd->name);
2691
2692		  speaker_deselect_raop(rd);
2693
2694		  if (cmd->ret != -2)
2695		    cmd->ret = -1;
2696		}
2697
2698	      /* ret = 1 if RAOP needs to take action */
2699	      cmd->raop_pending += ret;
2700	    }
2701	}
2702      else
2703	{
2704	  DPRINTF(E_DBG, L_PLAYER, "RAOP device %s NOT selected\n", rd->name);
2705
2706	  if (rd->selected)
2707	    speaker_deselect_raop(rd);
2708
2709	  if (rd->session)
2710	    {
2711	      ret = speaker_deactivate(rd);
2712	      if (ret < 0)
2713		{
2714		  DPRINTF(E_LOG, L_PLAYER, "Could not deactivate RAOP device %s\n", rd->name);
2715
2716		  if (cmd->ret != -2)
2717		    cmd->ret = -1;
2718		}
2719
2720	      /* ret = 1 if RAOP needs to take action */
2721	      cmd->raop_pending += ret;
2722	    }
2723	}
2724    }
2725
2726  /* Local audio */
2727  if(laudio_enabled)
2728     {
2729      for (i = 1; i <= nspk; i++)
2730        {
2731          if (ids[i] == 0)
2732          break;
2733        }
2734
2735      if (i <= nspk)
2736        {
2737          DPRINTF(E_DBG, L_PLAYER, "Local audio selected\n");
2738
2739          if (!laudio_selected)
2740            speaker_select_laudio();
2741
2742          if (!(laudio_status & LAUDIO_F_STARTED))
2743            {
2744              ret = speaker_activate(NULL);
2745              if (ret < 0)
2746                {
2747                  DPRINTF(E_LOG, L_PLAYER, "Could not activate local audio output\n");
2748
2749                  speaker_deselect_laudio();
2750
2751                  if (cmd->ret != -2)
2752                    cmd->ret = -1;
2753                }
2754            }
2755        }
2756      else
2757        {
2758          DPRINTF(E_DBG, L_PLAYER, "Local audio NOT selected\n");
2759
2760      if (laudio_selected)
2761	speaker_deselect_laudio();
2762
2763      if (laudio_status != LAUDIO_CLOSED)
2764	{
2765	  ret = speaker_deactivate(NULL);
2766	  if (ret < 0)
2767	    {
2768	      DPRINTF(E_LOG, L_PLAYER, "Could not deactivate local audio output\n");
2769
2770	      if (cmd->ret != -2)
2771		cmd->ret = -1;
2772                }
2773	    }
2774	}
2775    }
2776
2777  if (cmd->raop_pending > 0)
2778    return 1; /* async */
2779
2780  return cmd->ret;
2781}
2782
2783static int
2784volume_set(struct player_command *cmd)
2785{
2786  struct raop_device *rd;
2787  int volume;
2788
2789  volume = cmd->arg.intval;
2790
2791  if (master_volume == volume)
2792    return 0;
2793
2794  master_volume = volume;
2795
2796  if (laudio_selected)
2797    {
2798      laudio_volume = rel_to_vol(laudio_relvol);
2799      laudio_set_volume(laudio_volume);
2800
2801#ifdef DEBUG_RELVOL
2802      DPRINTF(E_DBG, L_PLAYER, "*** laudio: abs %d rel %d\n", laudio_volume, laudio_relvol);
2803#endif
2804    }
2805
2806  cmd->raop_pending = 0;
2807
2808  for (rd = dev_list; rd; rd = rd->next)
2809    {
2810/*
2811      if (!rd->selected)
2812	continue;
2813*/
2814      rd->volume = rel_to_vol(rd->relvol);
2815
2816#ifdef DEBUG_RELVOL
2817      DPRINTF(E_DBG, L_PLAYER, "*** %s: abs %d rel %d\n", rd->name, rd->volume, rd->relvol);
2818#endif
2819
2820      if (rd->session)
2821	cmd->raop_pending += raop_set_volume_one(rd->session, rd->volume, device_command_cb);
2822    }
2823
2824  if (cmd->raop_pending > 0)
2825    return 1; /* async */
2826
2827  return 0;
2828}
2829
2830static int
2831volume_setrel_speaker(struct player_command *cmd)
2832{
2833  struct raop_device *rd;
2834  uint64_t id;
2835  int relvol;
2836
2837  id = cmd->arg.vol_param.spk_id;
2838  relvol = cmd->arg.vol_param.volume;
2839
2840  if (id == 0)
2841    {
2842      laudio_relvol = relvol;
2843      laudio_volume = rel_to_vol(relvol);
2844      laudio_set_volume(laudio_volume);
2845
2846#ifdef DEBUG_RELVOL
2847      DPRINTF(E_DBG, L_PLAYER, "*** laudio: abs %d rel %d\n", laudio_volume, laudio_relvol);
2848#endif
2849    }
2850  else
2851    {
2852      for (rd = dev_list; rd; rd = rd->next)
2853        {
2854	  if (rd->id != id)
2855	    continue;
2856
2857	  if (!rd->selected)
2858	    return 0;
2859
2860	  rd->relvol = relvol;
2861	  rd->volume = rel_to_vol(relvol);
2862
2863#ifdef DEBUG_RELVOL
2864	  DPRINTF(E_DBG, L_PLAYER, "*** %s: abs %d rel %d\n", rd->name, rd->volume, rd->relvol);
2865#endif
2866
2867	  if (rd->session)
2868	    cmd->raop_pending = raop_set_volume_one(rd->session, rd->volume, device_command_cb);
2869
2870	  break;
2871        }
2872    }
2873
2874  if (cmd->raop_pending > 0)
2875    return 1; /* async */
2876
2877  return 0;
2878}
2879
2880static int
2881volume_setabs_speaker(struct player_command *cmd)
2882{
2883  struct raop_device *rd;
2884  uint64_t id;
2885  int volume;
2886
2887  id = cmd->arg.vol_param.spk_id;
2888  volume = cmd->arg.vol_param.volume;
2889
2890  master_volume = volume;
2891
2892  if (id == 0)
2893    {
2894      laudio_relvol = 100;
2895      laudio_volume = volume;
2896      laudio_set_volume(laudio_volume);
2897    }
2898  else
2899    laudio_relvol = vol_to_rel(laudio_volume);
2900
2901#ifdef DEBUG_RELVOL
2902  DPRINTF(E_DBG, L_PLAYER, "*** laudio: abs %d rel %d\n", laudio_volume, laudio_relvol);
2903#endif
2904
2905  for (rd = dev_list; rd; rd = rd->next)
2906    {
2907      if (!rd->selected)
2908	continue;
2909
2910      if (rd->id != id)
2911	{
2912	  rd->relvol = vol_to_rel(rd->volume);
2913
2914#ifdef DEBUG_RELVOL
2915	  DPRINTF(E_DBG, L_PLAYER, "*** %s: abs %d rel %d\n", rd->name, rd->volume, rd->relvol);
2916#endif
2917	  continue;
2918	}
2919      else
2920	{
2921	  rd->relvol = 100;
2922	  rd->volume = master_volume;
2923
2924#ifdef DEBUG_RELVOL
2925	  DPRINTF(E_DBG, L_PLAYER, "*** %s: abs %d rel %d\n", rd->name, rd->volume, rd->relvol);
2926#endif
2927
2928	  if (rd->session)
2929	    cmd->raop_pending = raop_set_volume_one(rd->session, rd->volume, device_command_cb);
2930	}
2931    }
2932
2933  if (cmd->raop_pending > 0)
2934    return 1; /* async */
2935
2936  return 0;
2937}
2938
2939static int
2940repeat_set(struct player_command *cmd)
2941{
2942  switch (cmd->arg.mode)
2943    {
2944      case REPEAT_OFF:
2945      case REPEAT_SONG:
2946      case REPEAT_ALL:
2947	repeat = cmd->arg.mode;
2948	break;
2949
2950      default:
2951	DPRINTF(E_LOG, L_PLAYER, "Invalid repeat mode: %d\n", cmd->arg.mode);
2952	return -1;
2953    }
2954
2955  return 0;
2956}
2957
2958static int
2959shuffle_set(struct player_command *cmd)
2960{
2961  switch (cmd->arg.intval)
2962    {
2963      case 1:
2964	if (!shuffle)
2965	  source_reshuffle();
2966	/* FALLTHROUGH*/
2967      case 0:
2968	shuffle = cmd->arg.intval;
2969	break;
2970
2971      default:
2972	DPRINTF(E_LOG, L_PLAYER, "Invalid shuffle mode: %d\n", cmd->arg.intval);
2973	return -1;
2974    }
2975
2976  return 0;
2977}
2978
2979static int
2980queue_add(struct player_command *cmd)
2981{
2982  struct player_source *ps;
2983  struct player_source *ps_shuffle;
2984  struct player_source *source_tail;
2985  struct player_source *ps_tail;
2986
2987  ps = cmd->arg.ps;
2988
2989  ps_shuffle = source_shuffle(ps);
2990  if (!ps_shuffle)
2991    ps_shuffle = ps;
2992
2993  if (source_head)
2994    {
2995      /* Playlist order */
2996      source_tail = source_head->pl_prev;
2997      ps_tail = ps->pl_prev;
2998
2999      source_tail->pl_next = ps;
3000      ps_tail->pl_next = source_head;
3001
3002      source_head->pl_prev = ps_tail;
3003      ps->pl_prev = source_tail;
3004
3005      /* Shuffle */
3006      source_tail = shuffle_head->shuffle_prev;
3007      ps_tail = ps_shuffle->shuffle_prev;
3008
3009      source_tail->shuffle_next = ps_shuffle;
3010      ps_tail->shuffle_next = shuffle_head;
3011
3012      shuffle_head->shuffle_prev = ps_tail;
3013      ps_shuffle->shuffle_prev = source_tail;
3014    }
3015  else
3016    {
3017      source_head = ps;
3018      shuffle_head = ps_shuffle;
3019    }
3020
3021  if (cur_plid != 0)
3022    cur_plid = 0;
3023
3024  return 0;
3025}
3026
3027static int
3028queue_clear(struct player_command *cmd)
3029{
3030  struct player_source *ps;
3031
3032  if (!source_head)
3033    return 0;
3034
3035  shuffle_head = NULL;
3036  source_head->pl_prev->pl_next = NULL;
3037
3038  for (ps = source_head; ps; ps = source_head)
3039    {
3040      source_head = ps->pl_next;
3041
3042      source_free(ps);
3043    }
3044
3045  cur_plid = 0;
3046
3047  return 0;
3048}
3049
3050static int
3051queue_plid(struct player_command *cmd)
3052{
3053  if (!source_head)
3054    return 0;
3055
3056  cur_plid = cmd->arg.id;
3057
3058  return 0;
3059}
3060
3061static int
3062set_update_handler(struct player_command *cmd)
3063{
3064  update_handler = cmd->arg.status_handler;
3065
3066  return 0;
3067}
3068
3069/* Command processing */
3070/* Thread: player */
3071static void
3072command_cb(int fd, short what, void *arg)
3073{
3074  struct player_command *cmd;
3075  int ret;
3076
3077  ret = read(cmd_pipe[0], &cmd, sizeof(cmd));
3078  if (ret != sizeof(cmd))
3079    {
3080      DPRINTF(E_LOG, L_PLAYER, "Could not read command! (read %d): %s\n", ret, (ret < 0) ? strerror(errno) : "-no error-");
3081
3082      goto readd;
3083    }
3084
3085  if (cmd->nonblock)
3086    {
3087      cmd->func(cmd);
3088
3089      free(cmd);
3090      goto readd;
3091    }
3092
3093  pthread_mutex_lock(&cmd->lck);
3094
3095  cur_cmd = cmd;
3096
3097  ret = cmd->func(cmd);
3098
3099  if (ret <= 0)
3100    {
3101      cmd->ret = ret;
3102
3103      cur_cmd = NULL;
3104
3105      pthread_cond_signal(&cmd->cond);
3106      pthread_mutex_unlock(&cmd->lck);
3107    }
3108  else
3109    {
3110      /* Command is asynchronous, we don't want to process another command
3111       * before we're done with this one. See command_async_end().
3112       */
3113
3114      return;
3115    }
3116
3117 readd:
3118  event_add(&cmdev, NULL);
3119}
3120
3121
3122/* Thread: httpd (DACP) - mDNS */
3123static int
3124send_command(struct player_command *cmd)
3125{
3126  int ret;
3127
3128  if (!cmd->func)
3129    {
3130      DPRINTF(E_LOG, L_PLAYER, "BUG: cmd->func is NULL!\n");
3131
3132      return -1;
3133    }
3134
3135  ret = write(cmd_pipe[1], &cmd, sizeof(cmd));
3136  if (ret != sizeof(cmd))
3137    {
3138      DPRINTF(E_LOG, L_PLAYER, "Could not send command: %s\n", strerror(errno));
3139
3140      return -1;
3141    }
3142
3143  return 0;
3144}
3145
3146/* Thread: mDNS */
3147static int
3148nonblock_command(struct player_command *cmd)
3149{
3150  int ret;
3151
3152  ret = send_command(cmd);
3153  if (ret < 0)
3154    return -1;
3155
3156  return 0;
3157}
3158
3159/* Thread: httpd (DACP) */
3160static int
3161sync_command(struct player_command *cmd)
3162{
3163  int ret;
3164
3165  pthread_mutex_lock(&cmd->lck);
3166
3167  ret = send_command(cmd);
3168  if (ret < 0)
3169    {
3170      pthread_mutex_unlock(&cmd->lck);
3171
3172      return -1;
3173    }
3174
3175  pthread_cond_wait(&cmd->cond, &cmd->lck);
3176
3177  pthread_mutex_unlock(&cmd->lck);
3178
3179  ret = cmd->ret;
3180
3181  return ret;
3182}
3183
3184
3185/* Player API executed in the httpd (DACP) thread */
3186int
3187player_get_status(struct player_status *status)
3188{
3189  struct player_command cmd;
3190  int ret;
3191
3192  command_init(&cmd);
3193
3194  cmd.func = get_status;
3195  cmd.func_bh = NULL;
3196  cmd.arg.status = status;
3197
3198  ret = sync_command(&cmd);
3199
3200  command_deinit(&cmd);
3201
3202  return ret;
3203}
3204
3205int
3206player_now_playing(uint32_t *id)
3207{
3208  struct player_command cmd;
3209  int ret;
3210
3211  command_init(&cmd);
3212
3213  cmd.func = now_playing;
3214  cmd.func_bh = NULL;
3215  cmd.arg.id_ptr = id;
3216
3217  ret = sync_command(&cmd);
3218
3219  command_deinit(&cmd);
3220
3221  return ret;
3222}
3223
3224int
3225player_playback_start(uint32_t *idx_id)
3226{
3227  struct player_command cmd;
3228  int ret;
3229
3230  command_init(&cmd);
3231
3232  cmd.func = playback_start;
3233  cmd.func_bh = playback_start_bh;
3234  cmd.arg.id_ptr = idx_id;
3235
3236  ret = sync_command(&cmd);
3237
3238  command_deinit(&cmd);
3239
3240  return ret;
3241}
3242
3243int
3244player_playback_stop(void)
3245{
3246  struct player_command cmd;
3247  int ret;
3248
3249  command_init(&cmd);
3250
3251  cmd.func = playback_stop;
3252  cmd.arg.noarg = NULL;
3253
3254  ret = sync_command(&cmd);
3255
3256  command_deinit(&cmd);
3257
3258  return ret;
3259}
3260
3261int
3262player_playback_pause(void)
3263{
3264  struct player_command cmd;
3265  int ret;
3266
3267  command_init(&cmd);
3268
3269  cmd.func = playback_pause;
3270  cmd.func_bh = playback_pause_bh;
3271  cmd.arg.noarg = NULL;
3272
3273  ret = sync_command(&cmd);
3274
3275  command_deinit(&cmd);
3276
3277  return ret;
3278}
3279
3280int
3281player_playback_seek(int ms)
3282{
3283  struct player_command cmd;
3284  int ret;
3285
3286  command_init(&cmd);
3287
3288  cmd.func = playback_pause;
3289  cmd.func_bh = playback_seek_bh;
3290  cmd.arg.intval = ms;
3291
3292  ret = sync_command(&cmd);
3293
3294  command_deinit(&cmd);
3295
3296  return ret;
3297}
3298
3299int
3300player_playback_next(void)
3301{
3302  struct player_command cmd;
3303  int ret;
3304
3305  command_init(&cmd);
3306
3307  cmd.func = playback_pause;
3308  cmd.func_bh = playback_next_bh;
3309  cmd.arg.noarg = NULL;
3310
3311  ret = sync_command(&cmd);
3312
3313  command_deinit(&cmd);
3314
3315  return ret;
3316}
3317
3318int
3319player_playback_prev(void)
3320{
3321  struct player_command cmd;
3322  int ret;
3323
3324  command_init(&cmd);
3325
3326  cmd.func = playback_pause;
3327  cmd.func_bh = playback_prev_bh;
3328  cmd.arg.noarg = NULL;
3329
3330  ret = sync_command(&cmd);
3331
3332  command_deinit(&cmd);
3333
3334  return ret;
3335}
3336
3337void
3338player_speaker_enumerate(spk_enum_cb cb, void *arg)
3339{
3340  struct player_command cmd;
3341  struct spk_enum spk_enum;
3342
3343  command_init(&cmd);
3344
3345  spk_enum.cb = cb;
3346  spk_enum.arg = arg;
3347
3348  cmd.func = speaker_enumerate;
3349  cmd.func_bh = NULL;
3350  cmd.arg.spk_enum = &spk_enum;
3351
3352  sync_command(&cmd);
3353
3354  command_deinit(&cmd);
3355}
3356
3357int
3358player_speaker_set(uint64_t *ids)
3359{
3360  struct player_command cmd;
3361  int ret;
3362
3363  command_init(&cmd);
3364
3365  cmd.func = speaker_set;
3366  cmd.func_bh = NULL;
3367  cmd.arg.raop_ids = ids;
3368
3369  ret = sync_command(&cmd);
3370
3371  command_deinit(&cmd);
3372
3373  return ret;
3374}
3375
3376int
3377player_volume_set(int vol)
3378{
3379  struct player_command cmd;
3380  int ret;
3381
3382  command_init(&cmd);
3383
3384  cmd.func = volume_set;
3385  cmd.func_bh = NULL;
3386  cmd.arg.intval = vol;
3387
3388  ret = sync_command(&cmd);
3389
3390  command_deinit(&cmd);
3391
3392  return ret;
3393}
3394
3395int
3396player_volume_setrel_speaker(uint64_t id, int relvol)
3397{
3398  struct player_command cmd;
3399  int ret;
3400
3401  command_init(&cmd);
3402
3403  cmd.func = volume_setrel_speaker;
3404  cmd.func_bh = NULL;
3405  cmd.arg.vol_param.spk_id = id;
3406  cmd.arg.vol_param.volume = relvol;
3407
3408  ret = sync_command(&cmd);
3409
3410  command_deinit(&cmd);
3411
3412  return ret;
3413}
3414
3415int
3416player_volume_setabs_speaker(uint64_t id, int vol)
3417{
3418  struct player_command cmd;
3419  int ret;
3420
3421  command_init(&cmd);
3422
3423  cmd.func = volume_setabs_speaker;
3424  cmd.func_bh = NULL;
3425  cmd.arg.vol_param.spk_id = id;
3426  cmd.arg.vol_param.volume = vol;
3427
3428  ret = sync_command(&cmd);
3429
3430  command_deinit(&cmd);
3431
3432  return ret;
3433}
3434
3435int
3436player_repeat_set(enum repeat_mode mode)
3437{
3438  struct player_command cmd;
3439  int ret;
3440
3441  command_init(&cmd);
3442
3443  cmd.func = repeat_set;
3444  cmd.func_bh = NULL;
3445  cmd.arg.mode = mode;
3446
3447  ret = sync_command(&cmd);
3448
3449  command_deinit(&cmd);
3450
3451  return ret;
3452}
3453
3454int
3455player_shuffle_set(int enable)
3456{
3457  struct player_command cmd;
3458  int ret;
3459
3460  command_init(&cmd);
3461
3462  cmd.func = shuffle_set;
3463  cmd.func_bh = NULL;
3464  cmd.arg.intval = enable;
3465
3466  ret = sync_command(&cmd);
3467
3468  command_deinit(&cmd);
3469
3470  return ret;
3471}
3472
3473int
3474player_queue_add(struct player_source *ps)
3475{
3476  struct player_command cmd;
3477  int ret;
3478
3479  command_init(&cmd);
3480
3481  cmd.func = queue_add;
3482  cmd.func_bh = NULL;
3483  cmd.arg.ps = ps;
3484
3485  ret = sync_command(&cmd);
3486
3487  command_deinit(&cmd);
3488
3489  return ret;
3490}
3491
3492void
3493player_queue_clear(void)
3494{
3495  struct player_command cmd;
3496
3497  command_init(&cmd);
3498
3499  cmd.func = queue_clear;
3500  cmd.func_bh = NULL;
3501  cmd.arg.noarg = NULL;
3502
3503  sync_command(&cmd);
3504
3505  command_deinit(&cmd);
3506}
3507
3508void
3509player_queue_plid(uint32_t plid)
3510{
3511  struct player_command cmd;
3512
3513  command_init(&cmd);
3514
3515  cmd.func = queue_plid;
3516  cmd.func_bh = NULL;
3517  cmd.arg.id = plid;
3518
3519  sync_command(&cmd);
3520
3521  command_deinit(&cmd);
3522}
3523
3524void
3525player_set_update_handler(player_status_handler handler)
3526{
3527  struct player_command cmd;
3528
3529  command_init(&cmd);
3530
3531  cmd.func = set_update_handler;
3532  cmd.func_bh = NULL;
3533  cmd.arg.status_handler = handler;
3534
3535  sync_command(&cmd);
3536
3537  command_deinit(&cmd);
3538}
3539
3540/* Non-blocking commands used by mDNS */
3541static void
3542player_device_add(struct raop_device *rd)
3543{
3544  struct player_command *cmd;
3545  int ret;
3546
3547  cmd = (struct player_command *)malloc(sizeof(struct player_command));
3548  if (!cmd)
3549    {
3550      DPRINTF(E_LOG, L_PLAYER, "Could not allocate player_command\n");
3551
3552      device_free(rd);
3553      return;
3554    }
3555
3556  memset(cmd, 0, sizeof(struct player_command));
3557
3558  cmd->nonblock = 1;
3559
3560  cmd->func = device_add;
3561  cmd->arg.rd = rd;
3562
3563  ret = nonblock_command(cmd);
3564  if (ret < 0)
3565    {
3566      free(cmd);
3567      device_free(rd);
3568
3569      return;
3570    }
3571}
3572
3573static void
3574player_device_remove(struct raop_device *rd)
3575{
3576  struct player_command *cmd;
3577  int ret;
3578
3579  cmd = (struct player_command *)malloc(sizeof(struct player_command));
3580  if (!cmd)
3581    {
3582      DPRINTF(E_LOG, L_PLAYER, "Could not allocate player_command\n");
3583
3584      device_free(rd);
3585      return;
3586    }
3587
3588  memset(cmd, 0, sizeof(struct player_command));
3589
3590  cmd->nonblock = 1;
3591
3592  cmd->func = device_remove_family;
3593  cmd->arg.rd = rd;
3594
3595  ret = nonblock_command(cmd);
3596  if (ret < 0)
3597    {
3598      free(cmd);
3599      device_free(rd);
3600
3601      return;
3602    }
3603}
3604
3605
3606/* RAOP devices discovery - mDNS callback */
3607/* Thread: main (mdns) */
3608static void
3609raop_device_cb(const char *name, const char *type, const char *domain, const char *hostname, int family, const char *address, int port, struct keyval *txt)
3610{
3611  struct raop_device *rd;
3612  cfg_t *apex;
3613  const char *p;
3614  char *at_name;
3615  char *password;
3616  uint64_t id;
3617  char has_password;
3618  enum raop_devtype devtype;
3619  int ret;
3620
3621  ret = safe_hextou64(name, &id);
3622  if (ret < 0)
3623    {
3624      DPRINTF(E_LOG, L_PLAYER, "Could not extract AirTunes device ID (%s)\n", name);
3625
3626      return;
3627    }
3628
3629  at_name = strchr(name, '@');
3630  if (!at_name)
3631    {
3632      DPRINTF(E_LOG, L_PLAYER, "Could not extract AirTunes device name (%s)\n", name);
3633
3634      return;
3635    }
3636  at_name++;
3637
3638  DPRINTF(E_DBG, L_PLAYER, "Event for AirTunes device %" PRIx64 "/%s (%d)\n", id, at_name, port);
3639
3640  rd = (struct raop_device *)malloc(sizeof(struct raop_device));
3641  if (!rd)
3642    {
3643      DPRINTF(E_LOG, L_PLAYER, "Out of memory for new AirTunes device\n");
3644
3645      return;
3646    }
3647
3648  memset(rd, 0, sizeof(struct raop_device));
3649
3650  rd->id = id;
3651  rd->name = strdup(at_name);
3652
3653  if (port < 0)
3654    {
3655      /* Device stopped advertising */
3656      switch (family)
3657	{
3658	  case AF_INET:
3659	    rd->v4_port = 1;
3660	    break;
3661
3662	  case AF_INET6:
3663	    rd->v6_port = 1;
3664	    break;
3665	}
3666
3667      player_device_remove(rd);
3668
3669      return;
3670    }
3671
3672  p = keyval_get(txt, "tp");
3673  if (!p)
3674    {
3675      DPRINTF(E_LOG, L_PLAYER, "AirTunes %s: no tp field in TXT record!\n", name);
3676
3677      goto free_rd;
3678    }
3679
3680  if (*p == '\0')
3681    {
3682      DPRINTF(E_LOG, L_PLAYER, "AirTunes %s: tp has no value\n", name);
3683
3684      goto free_rd;
3685    }
3686
3687  if (!strstr(p, "UDP"))
3688    {
3689      DPRINTF(E_LOG, L_PLAYER, "AirTunes %s: device does not support AirTunes v2 (tp=%s), discarding\n", name, p);
3690
3691      goto free_rd;
3692    }
3693
3694  password = NULL;
3695  p = keyval_get(txt, "pw");
3696  if (!p)
3697    {
3698      DPRINTF(E_INFO, L_PLAYER, "AirTunes %s: no pw field in TXT record, assuming no password protection\n", name);
3699      has_password = 0;
3700    }
3701  else if (*p == '\0')
3702    {
3703      DPRINTF(E_LOG, L_PLAYER, "AirTunes %s: pw has no value\n", name);
3704
3705      goto free_rd;
3706    }
3707  else
3708    {
3709      has_password = (strcmp(p, "false") != 0);
3710    }
3711
3712  if (has_password)
3713    {
3714      DPRINTF(E_LOG, L_PLAYER, "AirTunes device %s is password-protected\n", name);
3715
3716      apex = cfg_gettsec(cfg, "apex", at_name);
3717      if (apex)
3718	password = cfg_getstr(apex, "password");
3719
3720      if (!password)
3721	DPRINTF(E_LOG, L_PLAYER, "No password given in config for AirTunes device %s\n", name);
3722    }
3723
3724  devtype = RAOP_DEV_APEX_80211N;
3725
3726  p = keyval_get(txt, "am");
3727  if (!p)
3728    {
3729      DPRINTF(E_LOG, L_PLAYER, "AirTunes %s: no am field in TXT record!\n", name);
3730
3731      /* Old AirPort Express */
3732      devtype = RAOP_DEV_APEX_80211G;
3733
3734      goto no_am;
3735    }
3736
3737  if (*p == '\0')
3738    {
3739      DPRINTF(E_LOG, L_PLAYER, "AirTunes %s: am has no value\n", name);
3740
3741      goto no_am;
3742    }
3743
3744  if (strncmp(p, "AppleTV", strlen("AppleTV")) == 0)
3745    devtype = RAOP_DEV_APPLETV;
3746  else if (strncmp(p, "AirPort4", strlen("AirPort4")) != 0)
3747    devtype = OTHER;
3748
3749 no_am:
3750  DPRINTF(E_DBG, L_PLAYER, "AirTunes device %s: password: %s, type %s\n", name, (password) ? "yes" : "no", raop_devtype[devtype]);
3751
3752  rd->advertised = 1;
3753
3754  switch (family)
3755    {
3756      case AF_INET:
3757	rd->v4_address = strdup(address);
3758	rd->v4_port = port;
3759	break;
3760
3761      case AF_INET6:
3762	rd->v6_address = strdup(address);
3763	rd->v6_port = port;
3764	break;
3765    }
3766
3767  rd->devtype = devtype;
3768
3769  rd->has_password = has_password;
3770  rd->password = password;
3771
3772  player_device_add(rd);
3773
3774  return;
3775
3776 free_rd:
3777  device_free(rd);
3778}
3779
3780/* Thread: player */
3781static void *
3782player(void *arg)
3783{
3784  struct raop_device *rd;
3785  int ret;
3786
3787  ret = db_perthread_init();
3788  if (ret < 0)
3789    {
3790      DPRINTF(E_LOG, L_PLAYER, "Error: DB init failed\n");
3791
3792      pthread_exit(NULL);
3793    }
3794
3795  event_base_dispatch(evbase_player);
3796
3797  if (!player_exit)
3798    DPRINTF(E_LOG, L_PLAYER, "Player event loop terminated ahead of time!\n");
3799
3800  /* Save selected devices */
3801  db_speaker_clear_all();
3802
3803  ret = db_speaker_save(0, laudio_selected, laudio_volume);
3804  if (ret < 0)
3805    DPRINTF(E_LOG, L_PLAYER, "Could not save state for local audio\n");
3806
3807  for (rd = dev_list; rd; rd = rd->next)
3808    {
3809      ret = db_speaker_save(rd->id, rd->selected, rd->volume);
3810      if (ret < 0)
3811	DPRINTF(E_LOG, L_PLAYER, "Could not save state for speaker %s\n", rd->name);
3812    }
3813
3814  db_perthread_deinit();
3815
3816  pthread_exit(NULL);
3817}
3818
3819/* Thread: player */
3820static void
3821exit_cb(int fd, short what, void *arg)
3822{
3823  event_base_loopbreak(evbase_player);
3824
3825  player_exit = 1;
3826}
3827
3828/* Thread: main */
3829int
3830player_init(void)
3831{
3832  uint32_t rnd;
3833  int raop_v6enabled;
3834  int mdns_flags;
3835  int ret;
3836
3837  player_exit = 0;
3838
3839  dev_autoselect = 1;
3840  dev_list = NULL;
3841
3842  master_volume = -1;
3843  laudio_enabled = 0;
3844
3845//  laudio_enabled = cfg_getbool(cfg_getsec(cfg, "general"), "laudio_enable");
3846//  laudio_enabled = 1;
3847  laudio_selected = 0;
3848  laudio_status = LAUDIO_CLOSED;
3849  raop_sessions = 0;
3850
3851  cur_cmd = NULL;
3852
3853  pb_timer_fd = -1;
3854
3855  source_head = NULL;
3856  shuffle_head = NULL;
3857  cur_playing = NULL;
3858  cur_streaming = NULL;
3859  cur_plid = 0;
3860
3861  player_state = PLAY_STOPPED;
3862  repeat = REPEAT_OFF;
3863  shuffle = 0;
3864
3865  update_handler = NULL;
3866
3867  /* Random RTP time start */
3868  gcry_randomize(&rnd, sizeof(rnd), GCRY_STRONG_RANDOM);
3869  last_rtptime = ((uint64_t)1 << 32) | rnd;
3870
3871  rng_init(&shuffle_rng);
3872
3873  ret = db_speaker_get(0, &laudio_selected, &laudio_volume);
3874  if (ret < 0)
3875    laudio_volume = 75;
3876  else if (laudio_selected)
3877    speaker_select_laudio(); /* Run the select helper */
3878
3879  audio_buf = evbuffer_new();
3880  if (!audio_buf)
3881    {
3882      DPRINTF(E_LOG, L_PLAYER, "Could not allocate evbuffer for audio buffer\n");
3883
3884      return -1;
3885    }
3886
3887  raop_v6enabled = cfg_getbool(cfg_getsec(cfg, "general"), "ipv6");
3888
3889
3890#ifdef USE_EVENTFD
3891  exit_efd = eventfd(0, EFD_CLOEXEC);
3892  if (exit_efd < 0)
3893    {
3894      DPRINTF(E_LOG, L_PLAYER, "Could not create eventfd: %s\n", strerror(errno));
3895
3896      goto exit_fail;
3897    }
3898#else
3899# if defined(__linux__)
3900  ret = pipe2(exit_pipe, O_CLOEXEC);
3901# else
3902  ret = pipe(exit_pipe);
3903# endif
3904  if (ret < 0)
3905    {
3906      DPRINTF(E_LOG, L_PLAYER, "Could not create pipe: %s\n", strerror(errno));
3907
3908      goto exit_fail;
3909    }
3910#endif /* USE_EVENTFD */
3911
3912# if defined(__linux__)
3913  ret = pipe2(cmd_pipe, O_CLOEXEC);
3914# else
3915  ret = pipe(cmd_pipe);
3916# endif
3917  if (ret < 0)
3918    {
3919      DPRINTF(E_LOG, L_PLAYER, "Could not create command pipe: %s\n", strerror(errno));
3920
3921      goto cmd_fail;
3922    }
3923
3924  evbase_player = event_base_new();
3925  if (!evbase_player)
3926    {
3927      DPRINTF(E_LOG, L_PLAYER, "Could not create an event base\n");
3928
3929      goto evbase_fail;
3930    }
3931
3932#ifdef USE_EVENTFD
3933  event_set(&exitev, exit_efd, EV_READ, exit_cb, NULL);
3934#else
3935  event_set(&exitev, exit_pipe[0], EV_READ, exit_cb, NULL);
3936#endif
3937  event_base_set(evbase_player, &exitev);
3938  event_add(&exitev, NULL);
3939
3940  event_set(&cmdev, cmd_pipe[0], EV_READ, command_cb, NULL);
3941  event_base_set(evbase_player, &cmdev);
3942  event_add(&cmdev, NULL);
3943
3944  ret = laudio_init(player_laudio_status_cb);
3945  if (ret < 0)
3946    {
3947      DPRINTF(E_LOG, L_PLAYER, "Local audio init failed\n");
3948
3949      goto laudio_fail;
3950    }
3951
3952  ret = raop_init(&raop_v6enabled);
3953  if (ret < 0)
3954    {
3955      DPRINTF(E_LOG, L_PLAYER, "RAOP init failed\n");
3956
3957      goto raop_fail;
3958    }
3959
3960  if (raop_v6enabled)
3961    mdns_flags = MDNS_WANT_V4 | MDNS_WANT_V6 | MDNS_WANT_V6LL;
3962  else
3963    mdns_flags = MDNS_WANT_V4;
3964
3965  ret = mdns_browse("_raop._tcp", mdns_flags, raop_device_cb);
3966  if (ret < 0)
3967    {
3968      DPRINTF(E_FATAL, L_PLAYER, "Could not add mDNS browser for AirTunes devices\n");
3969
3970      goto mdns_browse_fail;
3971    }
3972
3973  ret = pthread_create(&tid_player, NULL, player, NULL);
3974  if (ret < 0)
3975    {
3976      DPRINTF(E_LOG, L_PLAYER, "Could not spawn player thread: %s\n", strerror(errno));
3977
3978      goto thread_fail;
3979    }
3980
3981  return 0;
3982
3983 thread_fail:
3984 mdns_browse_fail:
3985  raop_deinit();
3986 raop_fail:
3987  laudio_deinit();
3988 laudio_fail:
3989  event_base_free(evbase_player);
3990 evbase_fail:
3991  close(cmd_pipe[0]);
3992  close(cmd_pipe[1]);
3993 cmd_fail:
3994#ifdef USE_EVENTFD
3995  close(exit_efd);
3996#else
3997  close(exit_pipe[0]);
3998  close(exit_pipe[1]);
3999#endif
4000 exit_fail:
4001  evbuffer_free(audio_buf);
4002
4003  return -1;
4004}
4005
4006/* Thread: main */
4007void
4008player_deinit(void)
4009{
4010  int ret;
4011
4012#ifdef USE_EVENTFD
4013  ret = eventfd_write(exit_efd, 1);
4014  if (ret < 0)
4015    {
4016      DPRINTF(E_LOG, L_PLAYER, "Could not send exit event: %s\n", strerror(errno));
4017
4018      return;
4019    }
4020#else
4021  int dummy = 42;
4022
4023  ret = write(exit_pipe[1], &dummy, sizeof(dummy));
4024  if (ret != sizeof(dummy))
4025    {
4026      DPRINTF(E_LOG, L_PLAYER, "Could not write to exit fd: %s\n", strerror(errno));
4027
4028      return;
4029    }
4030#endif
4031
4032  ret = pthread_join(tid_player, NULL);
4033  if (ret != 0)
4034    {
4035      DPRINTF(E_LOG, L_PLAYER, "Could not join HTTPd thread: %s\n", strerror(errno));
4036
4037      return;
4038    }
4039
4040  if (source_head)
4041    queue_clear(NULL);
4042
4043  evbuffer_free(audio_buf);
4044
4045  laudio_deinit();
4046  raop_deinit();
4047
4048  if (event_initialized(&pb_timer_ev))
4049    event_del(&pb_timer_ev);
4050
4051  event_del(&cmdev);
4052
4053#ifdef USE_EVENTFD
4054  close(exit_efd);
4055#else
4056  close(exit_pipe[0]);
4057  close(exit_pipe[1]);
4058#endif
4059  close(cmd_pipe[0]);
4060  close(cmd_pipe[1]);
4061  cmd_pipe[0] = -1;
4062  cmd_pipe[1] = -1;
4063  event_base_free(evbase_player);
4064}
4065