diff --git a/audio/avrcp.c b/audio/avrcp.c
index 2f5df21..fe304d1 100644
--- a/audio/avrcp.c
+++ b/audio/avrcp.c
{
uint16_t len;
uint16_t attr_len;
- char valstr[20];
- void *value;
+ const char *value = NULL;
DBG("%u", id);
return 0;
}
- switch (id) {
- case AVRCP_MEDIA_ATTRIBUTE_TRACK:
- case AVRCP_MEDIA_ATTRIBUTE_N_TRACKS:
- case AVRCP_MEDIA_ATTRIBUTE_DURATION:
- snprintf(valstr, 20, "%u", GPOINTER_TO_UINT(value));
- value = valstr;
- break;
- }
-
attr_len = strlen(value);
value = ((char *) value) + *offset;
len = attr_len - *offset;
uint16_t len = ntohs(pdu->params_len);
uint32_t position;
uint32_t duration;
- void *pduration;
if (len != 0 || player == NULL) {
pdu->params_len = htons(1);
}
position = player->cb->get_position(player->user_data);
- pduration = player->cb->get_metadata(AVRCP_MEDIA_ATTRIBUTE_DURATION,
- player->user_data);
- if (pduration != NULL)
- duration = htonl(GPOINTER_TO_UINT(pduration));
- else
- duration = htonl(UINT32_MAX);
+ duration = player->cb->get_duration(player->user_data);
+ if (duration == 0)
+ duration = UINT32_MAX;
position = htonl(position);
+ duration = htonl(duration);
memcpy(&pdu->params[0], &duration, 4);
memcpy(&pdu->params[4], &position, 4);
diff --git a/audio/avrcp.h b/audio/avrcp.h
index 6c651dd..31fdf8d 100644
--- a/audio/avrcp.h
+++ b/audio/avrcp.h
int (*get_setting) (uint8_t attr, void *user_data);
int (*set_setting) (uint8_t attr, uint8_t value, void *user_data);
uint64_t (*get_uid) (void *user_data);
- void *(*get_metadata) (uint32_t id, void *user_data);
+ const char *(*get_metadata) (uint32_t id, void *user_data);
GList *(*list_metadata) (void *user_data);
uint8_t (*get_status) (void *user_data);
uint32_t (*get_position) (void *user_data);
+ uint32_t (*get_duration) (void *user_data);
void (*set_volume) (uint8_t volume, struct audio_device *dev,
void *user_data);
};
diff --git a/audio/media.c b/audio/media.c
index 1b811bd..ca08356 100644
--- a/audio/media.c
+++ b/audio/media.c
guint track_watch;
uint8_t status;
uint32_t position;
+ uint32_t duration;
uint8_t volume;
GTimer *timer;
};
-struct metadata_value {
- int type;
- union {
- char *str;
- uint32_t num;
- } value;
-};
-
static GSList *adapters = NULL;
static void endpoint_request_free(struct endpoint_request *request)
return 0;
}
-static void *get_metadata(uint32_t id, void *user_data)
+static const char *get_metadata(uint32_t id, void *user_data)
{
struct media_player *mp = user_data;
- struct metadata_value *value;
DBG("%s", metadata_to_str(id));
if (mp->track == NULL)
return NULL;
- value = g_hash_table_lookup(mp->track, GUINT_TO_POINTER(id));
- if (!value)
- return NULL;
-
- switch (value->type) {
- case DBUS_TYPE_STRING:
- return value->value.str;
- case DBUS_TYPE_UINT32:
- return GUINT_TO_POINTER(value->value.num);
- }
-
- return NULL;
+ return g_hash_table_lookup(mp->track, GUINT_TO_POINTER(id));
}
static uint8_t get_status(void *user_data)
return mp->position + sec * 1000 + msec;
}
+static uint32_t get_duration(void *user_data)
+{
+ struct media_player *mp = user_data;
+
+ return mp->duration;
+}
+
static void set_volume(uint8_t volume, struct audio_device *dev, void *user_data)
{
struct media_player *mp = user_data;
.get_uid = get_uid,
.get_metadata = get_metadata,
.get_position = get_position,
+ .get_duration = get_duration,
.get_status = get_status,
.set_volume = set_volume
};
static gboolean set_position(struct media_player *mp, DBusMessageIter *iter)
{
uint32_t value;
- struct metadata_value *duration;
if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_UINT32)
return FALSE;
return TRUE;
}
- duration = g_hash_table_lookup(mp->track, GUINT_TO_POINTER(
- AVRCP_MEDIA_ATTRIBUTE_DURATION));
-
/*
* If position is the maximum value allowed or greater than track's
* duration, we send a track-reached-end event.
*/
- if (mp->position == UINT32_MAX ||
- (duration && mp->position >= duration->value.num))
+ if (mp->position == UINT32_MAX || mp->position >= mp->duration)
avrcp_player_event(mp->player, AVRCP_EVENT_TRACK_REACHED_END,
NULL);
return TRUE;
}
-static void metadata_value_free(gpointer data)
-{
- struct metadata_value *value = data;
-
- switch (value->type) {
- case DBUS_TYPE_STRING:
- g_free(value->value.str);
- break;
- }
-
- g_free(value);
-}
-
static gboolean parse_player_metadata(struct media_player *mp,
DBusMessageIter *iter)
{
dbus_message_iter_recurse(iter, &dict);
track = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
- metadata_value_free);
+ g_free);
while ((ctype = dbus_message_iter_get_arg_type(&dict)) !=
DBUS_TYPE_INVALID) {
DBusMessageIter entry;
const char *key;
- struct metadata_value *value;
+ const char *string;
+ char valstr[20];
+ char *value;
+ uint32_t num;
int id;
+ int type;
if (ctype != DBUS_TYPE_DICT_ENTRY)
goto parse_error;
dbus_message_iter_recurse(&entry, &var);
- value = g_new0(struct metadata_value, 1);
- value->type = dbus_message_iter_get_arg_type(&var);
+ type = dbus_message_iter_get_arg_type(&var);
switch (id) {
case AVRCP_MEDIA_ATTRIBUTE_TITLE:
case AVRCP_MEDIA_ATTRIBUTE_ARTIST:
case AVRCP_MEDIA_ATTRIBUTE_ALBUM:
case AVRCP_MEDIA_ATTRIBUTE_GENRE:
- if (value->type != DBUS_TYPE_STRING) {
- g_free(value);
+ if (type != DBUS_TYPE_STRING)
goto parse_error;
- }
- dbus_message_iter_get_basic(&var, &value->value.str);
+ dbus_message_iter_get_basic(&var, &string);
break;
case AVRCP_MEDIA_ATTRIBUTE_TRACK:
case AVRCP_MEDIA_ATTRIBUTE_N_TRACKS:
+ if (type != DBUS_TYPE_UINT32)
+ goto parse_error;
+
+ dbus_message_iter_get_basic(&var, &num);
+ break;
case AVRCP_MEDIA_ATTRIBUTE_DURATION:
- if (value->type != DBUS_TYPE_UINT32) {
- g_free(value);
+ if (type != DBUS_TYPE_UINT32)
goto parse_error;
- }
- dbus_message_iter_get_basic(&var, &value->value.num);
+ dbus_message_iter_get_basic(&var, &num);
+ mp->duration = num;
break;
default:
goto parse_error;
}
- switch (value->type) {
+ switch (dbus_message_iter_get_arg_type(&var)) {
case DBUS_TYPE_STRING:
- value->value.str = g_strdup(value->value.str);
- DBG("%s=%s", key, value->value.str);
+ value = g_strdup(string);
break;
default:
- DBG("%s=%u", key, value->value.num);
+ snprintf(valstr, 20, "%u", num);
+ value = g_strdup(valstr);
}
+ DBG("%s=%s", key, value);
g_hash_table_replace(track, GUINT_TO_POINTER(id), value);
dbus_message_iter_next(&dict);
}
g_hash_table_unref(track);
track = NULL;
} else if (title == FALSE) {
- struct metadata_value *value = g_new(struct metadata_value, 1);
uint32_t id = AVRCP_MEDIA_ATTRIBUTE_TITLE;
- value->type = DBUS_TYPE_STRING;
- value->value.str = g_strdup("");
- g_hash_table_insert(track, GUINT_TO_POINTER(id), value);
+ g_hash_table_insert(track, GUINT_TO_POINTER(id), g_strdup(""));
}
if (mp->track != NULL)