[PATCH v3 12/14] AVRCP: Use NoAvailablePlayers status code for AVRCP 1.4 devices

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux