Diff between b8bf7a40a26b23f79c174c75e6869cfa723bcbb7 and d9f9f2e26d2fbc0f07046063b3a74c4e07d1a6d8

Changed Files

File Additions Deletions Status
audio/avctp.c +34 -49 modified

Full Patch

diff --git a/audio/avctp.c b/audio/avctp.c
index 228d5b7..9a62bc0 100644
--- a/audio/avctp.c
+++ b/audio/avctp.c
@@ -1066,51 +1066,11 @@ void avctp_unregister(const bdaddr_t *src)
 	g_free(server);
 }
 
-int avctp_send_passthrough(struct avctp *session, uint8_t op)
-{
-	unsigned char buf[AVCTP_HEADER_LENGTH + AVC_HEADER_LENGTH + 2];
-	struct avctp_header *avctp = (void *) buf;
-	struct avc_header *avc = (void *) &buf[AVCTP_HEADER_LENGTH];
-	uint8_t *operands = &buf[AVCTP_HEADER_LENGTH + AVC_HEADER_LENGTH];
-	int sk;
-
-	if (session->state != AVCTP_STATE_CONNECTED)
-		return -ENOTCONN;
-
-	memset(buf, 0, sizeof(buf));
-
-	avctp->transaction = id++;
-	avctp->packet_type = AVCTP_PACKET_SINGLE;
-	avctp->cr = AVCTP_COMMAND;
-	avctp->pid = htons(AV_REMOTE_SVCLASS_ID);
-
-	avc->code = AVC_CTYPE_CONTROL;
-	avc->subunit_type = AVC_SUBUNIT_PANEL;
-	avc->opcode = AVC_OP_PASSTHROUGH;
-
-	operands[0] = op & 0x7f;
-	operands[1] = 0;
-
-	sk = g_io_channel_unix_get_fd(session->control->io);
-
-	if (write(sk, buf, sizeof(buf)) < 0)
-		return -errno;
-
-	/* Button release */
-	avctp->transaction = id++;
-	operands[0] |= 0x80;
-
-	if (write(sk, buf, sizeof(buf)) < 0)
-		return -errno;
-
-	return 0;
-}
-
 static int avctp_send(struct avctp *session, uint8_t transaction, uint8_t cr,
 				uint8_t code, uint8_t subunit, uint8_t opcode,
 				uint8_t *operands, size_t operand_count)
 {
-	uint8_t buf[AVCTP_HEADER_LENGTH + AVC_HEADER_LENGTH];
+	struct avctp_channel *control = session->control;
 	struct avctp_header *avctp;
 	struct avc_header *avc;
 	struct msghdr msg;
@@ -1120,12 +1080,20 @@ static int avctp_send(struct avctp *session, uint8_t transaction, uint8_t cr,
 	if (session->state != AVCTP_STATE_CONNECTED)
 		return -ENOTCONN;
 
+	iov[0].iov_base = control->buffer;
+	iov[0].iov_len  = sizeof(*avctp) + sizeof(*avc);
+	iov[1].iov_base = operands;
+	iov[1].iov_len  = operand_count;
+
+	if (control->omtu < (iov[0].iov_len + iov[1].iov_len))
+		return -EOVERFLOW;
+
 	sk = g_io_channel_unix_get_fd(session->control->io);
 
-	memset(buf, 0, sizeof(buf));
+	memset(control->buffer, 0, iov[0].iov_len);
 
-	avctp = (void *) buf;
-	avc = (void *) &buf[AVCTP_HEADER_LENGTH];
+	avctp = (void *) control->buffer;
+	avc = (void *) avctp + sizeof(*avctp);
 
 	avctp->transaction = transaction;
 	avctp->packet_type = AVCTP_PACKET_SINGLE;
@@ -1136,11 +1104,6 @@ static int avctp_send(struct avctp *session, uint8_t transaction, uint8_t cr,
 	avc->subunit_type = subunit;
 	avc->opcode = opcode;
 
-	iov[0].iov_base = buf;
-	iov[0].iov_len  = sizeof(buf);
-	iov[1].iov_base = operands;
-	iov[1].iov_len  = operand_count;
-
 	memset(&msg, 0, sizeof(msg));
 	msg.msg_iov = iov;
 	msg.msg_iovlen = 2;
@@ -1151,6 +1114,28 @@ static int avctp_send(struct avctp *session, uint8_t transaction, uint8_t cr,
 	return err;
 }
 
+int avctp_send_passthrough(struct avctp *session, uint8_t op)
+{
+	uint8_t operands[2];
+	int ret;
+
+	operands[0] = op & 0x7f;
+	operands[1] = 0;
+
+	ret = avctp_send(session, id, AVCTP_COMMAND, AVC_CTYPE_CONTROL,
+					AVC_SUBUNIT_PANEL, AVC_OP_PASSTHROUGH,
+					operands, sizeof(operands));
+	if (ret < 0)
+		return ret;
+
+	/* Button release */
+	operands[0] |= 0x80;
+
+	return avctp_send(session, id, AVCTP_COMMAND, AVC_CTYPE_CONTROL,
+					AVC_SUBUNIT_PANEL, AVC_OP_PASSTHROUGH,
+					operands, sizeof(operands));
+}
+
 int avctp_send_vendordep(struct avctp *session, uint8_t transaction,
 				uint8_t code, uint8_t subunit,
 				uint8_t *operands, size_t operand_count)