DummyPlayer indicate there is no available players. For AVRCP 1.4 devices use NoAvailblePlayers status code, on the other side, for AVRCP 1.3 devices use InternalError. --- audio/avrcp.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- audio/avrcp.h | 1 + audio/media.c | 13 ++++++++++++- 3 files changed, 66 insertions(+), 5 deletions(-) diff --git a/audio/avrcp.c b/audio/avrcp.c index 710bb16..93d9c42 100644 --- a/audio/avrcp.c +++ b/audio/avrcp.c @@ -1150,6 +1150,41 @@ err_metadata: return AVRCP_HEADER_LENGTH + 1; } +static size_t handle_dummy_player(struct avctp *session, uint8_t transaction, + uint8_t *code, uint8_t *subunit, + uint8_t *operands, size_t operand_count, + void *user_data) +{ + struct avrcp_player *player = user_data; + struct avrcp_header *pdu = (void *) operands; + uint32_t company_id = get_company_id(pdu->company_id); + + if (player->server->session.version_ct < VERSION_1_4) + goto ignoring; + + if (pdu->pdu_id == PDU_GET_CAPABILITIES || + pdu->pdu_id == PDU_REGISTER_NOTIFICATION) + goto pass; + + *code = AVC_CTYPE_REJECTED; + pdu->params_len = htons(1); + + pdu->params[0] = STATUS_NO_AVAILABLE_PLAYERS; + + DBG("cannot handle regard to no available players " + "AVRCP PDU 0x%02X, company 0x%06X len 0x%04X", + pdu->pdu_id, company_id, pdu->params_len); + + return AVRCP_HEADER_LENGTH + 1; + +ignoring: + DBG("ignoring AVRCP PDU 0x%02X, company 0x%06X len 0x%04X", + pdu->pdu_id, company_id, pdu->params_len); +pass: + return handle_vendordep_pdu(session, transaction, code, subunit, + operands, operand_count, user_data); +} + size_t avrcp_handle_vendor_reject(uint8_t *code, uint8_t *operands) { struct avrcp_header *pdu = (void *) operands; @@ -1157,6 +1192,7 @@ size_t avrcp_handle_vendor_reject(uint8_t *code, uint8_t *operands) *code = AVC_CTYPE_REJECTED; pdu->params_len = htons(1); + pdu->params[0] = STATUS_INTERNAL_ERROR; DBG("rejecting AVRCP PDU 0x%02X, company 0x%06X len 0x%04X", @@ -1260,11 +1296,19 @@ static void state_changed(struct audio_device *dev, avctp_state_t old_state, player->dev = dev; - if (!player->handler) - player->handler = avctp_register_pdu_handler( + if (!player->handler) { + if (player->cb->is_dummy_player(player->user_data)) + player->handler = avctp_register_pdu_handler( + AVC_OP_VENDORDEP, + handle_dummy_player, + player); + else + player->handler = avctp_register_pdu_handler( AVC_OP_VENDORDEP, handle_vendordep_pdu, player); + } + break; case AVCTP_STATE_CONNECTED: rec_tg = btd_device_get_record(dev->btd_dev, AVRCP_TARGET_UUID); @@ -1602,8 +1646,13 @@ gboolean avrcp_set_addressed_player(struct avrcp_player *player, gboolean local) avctp_unregister_pdu_handler(server->addressed_player->handler); server->addressed_player->handler = 0; } - player->handler = avctp_register_pdu_handler(AVC_OP_VENDORDEP, - handle_vendordep_pdu, player); + + if (player->cb->is_dummy_player(player->user_data)) + player->handler = avctp_register_pdu_handler(AVC_OP_VENDORDEP, + handle_dummy_player, player); + else + player->handler = avctp_register_pdu_handler(AVC_OP_VENDORDEP, + handle_vendordep_pdu, player); server->addressed_player = player; diff --git a/audio/avrcp.h b/audio/avrcp.h index 5c31665..ec56b40 100644 --- a/audio/avrcp.h +++ b/audio/avrcp.h @@ -91,6 +91,7 @@ struct avrcp_player_cb { uint32_t (*get_position) (void *user_data); void (*set_volume) (uint8_t volume, struct audio_device *dev, void *user_data); + gboolean (*is_dummy_player) (void *user_data); }; struct avrcp_player *player; diff --git a/audio/media.c b/audio/media.c index 97bf7df..0c11cf0 100644 --- a/audio/media.c +++ b/audio/media.c @@ -1393,6 +1393,16 @@ static void set_volume(uint8_t volume, struct audio_device *dev, void *user_data } } +static gboolean is_dummy_player(void *user_data) +{ + struct media_player *mp = user_data; + + if (strcmp(mp->path, DUMMY_PLAYER) == 0) + return TRUE; + + return FALSE; +} + static struct avrcp_player_cb player_cb = { .get_setting = get_setting, .set_setting = set_setting, @@ -1401,7 +1411,8 @@ static struct avrcp_player_cb player_cb = { .get_metadata = get_metadata, .get_position = get_position, .get_status = get_status, - .set_volume = set_volume + .set_volume = set_volume, + .is_dummy_player = is_dummy_player }; static void media_player_exit(DBusConnection *connection, void *user_data) -- on behalf of ST-Ericsson -- To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html