I'm trying to retrieve track details from a connected Bluetooth device using the org.bluez.MediaPlayer1 interface in the object "/org/bluez/hci0/dev_3C_19_5E_F9_26_60/player0" of org.bluez.
Firstly, I successfully retrieved the status of the currently playing track using the property "Status". Below is the working code snippet:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <systemd/sd-bus.h>
int main(int argc, char *argv[]) {
sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus_message *m = NULL;
sd_bus *bus = NULL;
int r;
const char *path = NULL;
/* Connect to the system bus */
r = sd_bus_open_system(&bus);
if (r < 0) {
fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-r));
goto finish;
}
printf("Connected to system bus\n");
/* Get the property value */
r = sd_bus_get_property(bus,
"org.bluez", /* service to contact */
"/org/bluez/hci0/dev_3C_19_5E_F9_26_60/player0", /* object path */
"org.bluez.MediaPlayer1",/* interface name */
"Status", /* property name */
&error, /* object to return error in */
&m, /* return message on success */
"s" /* type */
);
if (r < 0) {
fprintf(stderr, "Failed to get property: %s\n", error.message);
goto finish;
}
printf("Successfully got property\n");
/* Parse the response message */
r = sd_bus_message_read(m, "s", &path);
if (r < 0) {
fprintf(stderr, "Failed to parse response message: %s\n", strerror(-r));
goto finish;
}
printf("Successfully parsed response message\n");
if (path != NULL)
printf("Track status is: %s\n", path);
else
printf("Track status not found\n");
finish:
sd_bus_error_free(&error);
sd_bus_message_unref(m);
sd_bus_unref(bus);
return 0;
}
Then, I extended the code to retrieve properties like track name, duration, artist name, etc., using the property name "Track". Here's the relevant code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <systemd/sd-bus.h>
int main(int argc, char *argv[]) {
sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus_message *m = NULL;
sd_bus *bus = NULL;
int r;
const char *title = NULL;
uint32_t track_number = 0;
uint32_t num_tracks = 0;
uint32_t duration = 0;
const char *album = NULL;
const char *artist = NULL;
const char *genre = NULL;
/* Connect to the system bus */
r = sd_bus_open_system(&bus);
if (r < 0) {
fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-r));
goto finish;
}
printf("Connected to system bus\n");
/* Get the property value */
r = sd_bus_get_property(bus,
"org.bluez", /* service to contact */
"/org/bluez/hci0/dev_3C_19_5E_F9_26_60/player0", /* object path */
"org.bluez.MediaPlayer1",/* interface name */
"Track", /* property name */
&error, /* object to return error in */
&m, /* return message on success */
"a{sv}" /* type */
);
if (r < 0) {
fprintf(stderr, "Failed to get property: %s\n", error.message);
goto finish;
}
printf("Successfully got property\n");
/* Parse the response message */
const char *s1, *s2, *s3, *s4, *s5, *s6, *s7;
r = sd_bus_message_read(m, "a{sv}", 7, &s1, &title, &s2, &track_number, &s3, &num_tracks, &s4, &duration, &s5, &album, &s6, &artist, &s7, &genre);
if (r < 0) {
fprintf(stderr, "Failed to parse response message: %s\n", strerror(-r));
goto finish;
}
printf("Successfully parsed response message\n");
printf("Title: %s\n", title);
printf("Track Number: %u\n", track_number);
printf("Number of Tracks: %u\n", num_tracks);
printf("Duration: %u milliseconds\n", duration);
printf("Album: %s\n", album);
printf("Artist: %s\n", artist);
printf("Genre: %s\n", genre);
finish:
sd_bus_error_free(&error);
sd_bus_message_unref(m);
sd_bus_unref(bus);
return 0;
}
According to the output from the busctl command,
busctl get-property org.bluez /org/bluez/hci0/dev_3C_19_5E_F9_26_60/player0 org.bluez.MediaPlayer1 Track
the dictionary response contains 7 pairs of type {variant=>string}. Here's the output from command line:
a{sv} 7 "Title" s "Tere Naina" "TrackNumber" u 1 "NumberOfTracks" u 1 "Duration" u 278546 "Album" s "My Name Is Khan (Original Motion Picture Soundtrack)" "Artist" s "From Smart Shuffle \342\200\242 Shankar-Ehsaan-Loy, Shafqat Amanat Ali" "Genre" s ""
I referred to the documentation on sd_bus_message_read() and the example provided there, but couldn't find a solution. What am I doing wrong here? Any assistance would be greatly appreciated.