Skip to content

Commit

Permalink
Add some more D-Bus facilities. Countermand faulty D-Bus commands.
Browse files Browse the repository at this point in the history
  • Loading branch information
mikebrady committed Mar 24, 2018
1 parent 89d4712 commit cbbe84d
Show file tree
Hide file tree
Showing 8 changed files with 299 additions and 68 deletions.
32 changes: 21 additions & 11 deletions dacp.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,8 @@ void *dacp_monitor_thread_code(__attribute__((unused)) void *na) {
pthread_cond_wait(&dacp_server_information_cv, &dacp_server_information_lock);
}
scan_index++;
result = dacp_get_volume(NULL); // just want the http code
int32_t the_volume;
result = dacp_get_volume(&the_volume); // just want the http code
if ((result == 496) || (result == 403) || (result == 501)) {
// debug(1,"Stopping scan because the response to \"dacp_get_volume(NULL)\" is %d.",result);
dacp_server.scan_enable = 0;
Expand All @@ -351,6 +352,13 @@ void *dacp_monitor_thread_code(__attribute__((unused)) void *na) {
metadata_hub_modify_epilog(diff);

if (result == 200) {

metadata_hub_modify_prolog();
int diff = metadata_store.speaker_volume != the_volume;
if (diff)
metadata_store.speaker_volume = the_volume;
metadata_hub_modify_epilog(diff);

ssize_t le;
char *response = NULL;
int32_t item_size;
Expand All @@ -360,17 +368,17 @@ void *dacp_monitor_thread_code(__attribute__((unused)) void *na) {
// debug(1,"Command: \"%s\"",command);
result = dacp_send_command(command, &response, &le);
// debug(1,"Response to \"%s\" is %d.",command,result);
// if (result == 200) {
if (0) {
if (result == 200) {
// if (0) {
char *sp = response;
if (le >= 8) {
// here start looking for the contents of the status update
if (dacp_tlv_crawl(&sp, &item_size) == 'cmst') { // status
// here, we know that we are receiving playerstatusupdates, so set a flag
metadata_hub_modify_prolog();
debug(1, "playstatusupdate release track metadata");
metadata_hub_reset_track_metadata();
metadata_store.playerstatusupdates_are_received = 1;
// debug(1, "playstatusupdate release track metadata");
// metadata_hub_reset_track_metadata();
// metadata_store.playerstatusupdates_are_received = 1;
sp -= item_size; // drop down into the array -- don't skip over it
le -= 8;
// char typestring[5];
Expand Down Expand Up @@ -454,18 +462,18 @@ void *dacp_monitor_thread_code(__attribute__((unused)) void *na) {
r = *(unsigned char *)(t);
switch (r) {
case 0:
if (metadata_store.repeat_status != RS_NONE) {
metadata_store.repeat_status = RS_NONE;
if (metadata_store.repeat_status != RS_OFF) {
metadata_store.repeat_status = RS_OFF;
metadata_store.repeat_status_changed = 1;
debug(1, "Repeat status changed to \"none\".");
metadata_store.changed = 1;
}
break;
case 1:
if (metadata_store.repeat_status != RS_SINGLE) {
metadata_store.repeat_status = RS_SINGLE;
if (metadata_store.repeat_status != RS_ONE) {
metadata_store.repeat_status = RS_ONE;
metadata_store.repeat_status_changed = 1;
debug(1, "Repeat status changed to \"single\".");
debug(1, "Repeat status changed to \"one\".");
metadata_store.changed = 1;
}
break;
Expand All @@ -482,6 +490,7 @@ void *dacp_monitor_thread_code(__attribute__((unused)) void *na) {
break;
}
break;
/*
case 'cann': // track name
t = sp - item_size;
if ((metadata_store.track_name == NULL) ||
Expand Down Expand Up @@ -551,6 +560,7 @@ void *dacp_monitor_thread_code(__attribute__((unused)) void *na) {
metadata_store.changed = 1;
}
break;
*/
case 'astm':
t = sp - item_size;
r = ntohl(*(uint32_t *)(t));
Expand Down
211 changes: 187 additions & 24 deletions dbus-service.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,10 @@ ShairportSyncRemoteControl *shairportSyncRemoteControlSkeleton;
ShairportSyncAdvancedRemoteControl *shairportSyncAdvancedRemoteControlSkeleton;

void dbus_metadata_watcher(struct metadata_bundle *argc, __attribute__((unused)) void *userdata) {
// debug(1, "DBUS metadata watcher called");

shairport_sync_advanced_remote_control_set_volume(shairportSyncAdvancedRemoteControlSkeleton,
argc->speaker_volume);

// debug(1, "No diagnostics watcher required");

// debug(1, "DBUS remote control watcher called");

shairport_sync_remote_control_set_airplay_volume(shairportSyncRemoteControlSkeleton,
argc->airplay_volume);

Expand All @@ -47,6 +43,81 @@ void dbus_metadata_watcher(struct metadata_bundle *argc, __attribute__((unused))
FALSE);
}

switch (argc->player_state) {
case PS_NOT_AVAILABLE:
shairport_sync_remote_control_set_player_state(shairportSyncRemoteControlSkeleton,
"Not Available");
case PS_STOPPED:
shairport_sync_remote_control_set_player_state(shairportSyncRemoteControlSkeleton, "Stopped");
break;
case PS_PAUSED:
shairport_sync_remote_control_set_player_state(shairportSyncRemoteControlSkeleton, "Paused");
break;
case PS_PLAYING:
shairport_sync_remote_control_set_player_state(shairportSyncRemoteControlSkeleton, "Playing");
break;
default:
debug(1, "This should never happen.");
}

switch (argc->play_status) {
case PS_NOT_AVAILABLE:
shairport_sync_advanced_remote_control_set_playback_status(
shairportSyncAdvancedRemoteControlSkeleton, "Not Available");
case PS_STOPPED:
shairport_sync_advanced_remote_control_set_playback_status(
shairportSyncAdvancedRemoteControlSkeleton, "Stopped");
break;
case PS_PAUSED:
shairport_sync_advanced_remote_control_set_playback_status(
shairportSyncAdvancedRemoteControlSkeleton, "Paused");
break;
case PS_PLAYING:
shairport_sync_advanced_remote_control_set_playback_status(
shairportSyncAdvancedRemoteControlSkeleton, "Playing");
break;
default:
debug(1, "This should never happen.");
}

switch (argc->repeat_status) {
case RS_NOT_AVAILABLE:
shairport_sync_advanced_remote_control_set_loop_status(
shairportSyncAdvancedRemoteControlSkeleton, "Not Available");
break;
case RS_OFF:
shairport_sync_advanced_remote_control_set_loop_status(
shairportSyncAdvancedRemoteControlSkeleton, "Off");
break;
case RS_ONE:
shairport_sync_advanced_remote_control_set_loop_status(
shairportSyncAdvancedRemoteControlSkeleton, "One");
break;
case RS_ALL:
shairport_sync_advanced_remote_control_set_loop_status(
shairportSyncAdvancedRemoteControlSkeleton, "All");
break;
default:
debug(1, "This should never happen.");
}

switch (argc->shuffle_status) {
case SS_NOT_AVAILABLE:
shairport_sync_advanced_remote_control_set_shuffle(shairportSyncAdvancedRemoteControlSkeleton,
FALSE);
break;
case SS_OFF:
shairport_sync_advanced_remote_control_set_shuffle(shairportSyncAdvancedRemoteControlSkeleton,
FALSE);
break;
case SS_ON:
shairport_sync_advanced_remote_control_set_shuffle(shairportSyncAdvancedRemoteControlSkeleton,
TRUE);
break;
default:
debug(1, "This should never happen.");
}

GVariantBuilder *dict_builder, *aa;

/* Build the metadata array */
Expand Down Expand Up @@ -276,6 +347,7 @@ gboolean notify_verbosity_callback(ShairportSyncDiagnostics *skeleton,
debug(1, ">> log verbosity set to %d.", th);
} else {
debug(1, ">> invalid log verbosity: %d. Ignored.", th);
shairport_sync_diagnostics_set_verbosity(skeleton, debuglev);
}
return TRUE;
}
Expand All @@ -301,6 +373,7 @@ gboolean notify_loudness_threshold_callback(ShairportSync *skeleton,
config.loudness_reference_volume_db = th;
} else {
debug(1, "Invalid loudness threshhold: %f. Ignored.", th);
shairport_sync_set_loudness_threshold(skeleton, config.loudness_reference_volume_db);
}
return TRUE;
}
Expand All @@ -313,17 +386,25 @@ gboolean notify_alacdecoder_callback(ShairportSync *skeleton,
config.use_apple_decoder = 0;
else if (strcasecmp(th, "apple") == 0)
config.use_apple_decoder = 1;
else
warn("Unrecognised ALAC decoder: \"%s\".", th);
else {
warn("An unrecognised ALAC decoder: \"%s\" was requested via D-Bus interface.", th);
if (config.use_apple_decoder == 0)
shairport_sync_set_alacdecoder(skeleton, "hammerton");
else
shairport_sync_set_alacdecoder(skeleton, "apple");
}
// debug(1,"Using the %s ALAC decoder.", ((config.use_apple_decoder==0) ? "Hammerton" : "Apple"));
#else
if (strcasecmp(th, "hammerton") == 0) {
config.use_apple_decoder = 0;
// debug(1,"Using the Hammerton ALAC decoder.");
} else
warn("Unrecognised ALAC decoder: \"%s\" (or else support for this decoder was not compiled "
"into this version of Shairport Sync).",
} else {
warn("An unrecognised ALAC decoder: \"%s\" was requested via D-Bus interface. (Possibly "
"support for this decoder was not compiled "
"into this version of Shairport Sync.)",
th);
shairport_sync_set_alacdecoder(skeleton, "hammerton");
}
#endif
return TRUE;
}
Expand All @@ -336,35 +417,106 @@ gboolean notify_interpolation_callback(ShairportSync *skeleton,
config.packet_stuffing = ST_basic;
else if (strcasecmp(th, "soxr") == 0)
config.packet_stuffing = ST_soxr;
else
warn("Unrecognised interpolation: \"%s\".", th);
else {
warn("An unrecognised interpolation method: \"%s\" was requested via the D-Bus interface.", th);
switch (config.packet_stuffing) {
case ST_basic:
shairport_sync_set_interpolation(skeleton, "basic");
break;
case ST_soxr:
shairport_sync_set_interpolation(skeleton, "soxr");
break;
default:
debug(1, "This should never happen!");
shairport_sync_set_interpolation(skeleton, "basic");
break;
}
}
#else
if (strcasecmp(th, "basic") == 0)
config.packet_stuffing = ST_basic;
}
else warn("Unrecognised interpolation method: \"%s\" (or else support for this interolation method "
"was not compiled into this version of Shairport Sync).",
th);
else {
warn("An unrecognised interpolation method: \"%s\" was requested via the D-Bus interface. "
"(Possibly support for this method was not compiled "
"into this version of Shairport Sync.)",
th);
shairport_sync_set_interpolation(skeleton, "basic");
}
#endif
debug(1, "Using %s interpolation (aka \"stuffing\").",
((config.packet_stuffing == ST_basic) ? "basic" : "soxr"));
return TRUE;
}

gboolean notify_volume_control_profile_callback(ShairportSync *skeleton,
__attribute__((unused)) gpointer user_data) {
char *th = (char *)shairport_sync_get_volume_control_profile(skeleton);
enum volume_control_profile_type previous_volume_control_profile = config.volume_control_profile;
// enum volume_control_profile_type previous_volume_control_profile =
// config.volume_control_profile;
if (strcasecmp(th, "standard") == 0)
config.volume_control_profile = VCP_standard;
else if (strcasecmp(th, "flat") == 0)
config.volume_control_profile = VCP_flat;
else
else {
warn("Unrecognised Volume Control Profile: \"%s\".", th);
debug(1, "Using the %s Volume Control Profile.",
((config.volume_control_profile == VCP_standard) ? "Standard" : "Flat"));
if (previous_volume_control_profile != config.volume_control_profile)
debug(1, "Should really reset volume now, maybe?");
switch (config.volume_control_profile) {
case VCP_standard:
shairport_sync_set_volume_control_profile(skeleton, "standard");
break;
case VCP_flat:
shairport_sync_set_volume_control_profile(skeleton, "flat");
break;
default:
debug(1, "This should never happen!");
shairport_sync_set_volume_control_profile(skeleton, "standard");
break;
}
}
return TRUE;
}

gboolean notify_shuffle_callback(ShairportSyncAdvancedRemoteControl *skeleton,
__attribute__((unused)) gpointer user_data) {
// debug(1,"notify_shuffle_callback called");
if (shairport_sync_advanced_remote_control_get_shuffle(skeleton))
send_simple_dacp_command("setproperty?dacp.shufflestate=1");
else
send_simple_dacp_command("setproperty?dacp.shufflestate=0");
;
return TRUE;
}

gboolean notify_loop_status_callback(ShairportSyncAdvancedRemoteControl *skeleton,
__attribute__((unused)) gpointer user_data) {
// debug(1,"notify_loop_status_callback called");
char *th = (char *)shairport_sync_advanced_remote_control_get_loop_status(skeleton);
// enum volume_control_profile_type previous_volume_control_profile =
// config.volume_control_profile;
if (strcasecmp(th, "off") == 0)
send_simple_dacp_command("setproperty?dacp.repeatstate=0");
else if (strcasecmp(th, "one") == 0)
send_simple_dacp_command("setproperty?dacp.repeatstate=1");
else if (strcasecmp(th, "all") == 0)
send_simple_dacp_command("setproperty?dacp.repeatstate=2");
else if (strcasecmp(th, "not available") != 0) {
warn("Illegal Loop Request: \"%s\".", th);
switch (metadata_store.repeat_status) {
case RS_NOT_AVAILABLE:
shairport_sync_advanced_remote_control_set_loop_status(skeleton, "Not Available");
break;
case RS_OFF:
shairport_sync_advanced_remote_control_set_loop_status(skeleton, "Off");
break;
case RS_ONE:
shairport_sync_advanced_remote_control_set_loop_status(skeleton, "One");
break;
case RS_ALL:
shairport_sync_advanced_remote_control_set_loop_status(skeleton, "All");
break;
default:
debug(1, "This should never happen!");
shairport_sync_advanced_remote_control_set_loop_status(skeleton, "Off");
break;
}
}
return TRUE;
}

Expand Down Expand Up @@ -457,6 +609,12 @@ static void on_dbus_name_acquired(GDBusConnection *connection, const gchar *name
g_signal_connect(shairportSyncAdvancedRemoteControlSkeleton, "handle-set-volume",
G_CALLBACK(on_handle_set_volume), NULL);

g_signal_connect(shairportSyncAdvancedRemoteControlSkeleton, "notify::shuffle",
G_CALLBACK(notify_shuffle_callback), NULL);

g_signal_connect(shairportSyncAdvancedRemoteControlSkeleton, "notify::loop-status",
G_CALLBACK(notify_loop_status_callback), NULL);

add_metadata_watcher(dbus_metadata_watcher, NULL);

shairport_sync_set_loudness_threshold(SHAIRPORT_SYNC(shairportSyncSkeleton),
Expand Down Expand Up @@ -532,6 +690,11 @@ static void on_dbus_name_acquired(GDBusConnection *connection, const gchar *name
// debug(1, ">> delta time is not included in log entries");
}

shairport_sync_remote_control_set_player_state(shairportSyncRemoteControlSkeleton,
"Not Available");
shairport_sync_advanced_remote_control_set_playback_status(
shairportSyncAdvancedRemoteControlSkeleton, "Not Available");

debug(1, "Shairport Sync native D-Bus service started at \"%s\" on the %s bus.", name,
(config.dbus_service_bus_type == DBT_session) ? "session" : "system");
}
Expand Down
2 changes: 2 additions & 0 deletions metadata_hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,8 @@ void metadata_hub_process_metadata(uint32_t type, uint32_t code, char *data, uin
metadata_hub_modify_epilog(1);
}
break;
// these could tell us about play / pause etc. but will only occur if metadata is enabled, so
// we'll just ignore them
case 'pbeg':
case 'pend':
case 'pfls':
Expand Down
Loading

0 comments on commit cbbe84d

Please sign in to comment.