linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V2 1/2] midi: Fix SysEx parser in MIDI plugin
@ 2020-06-19 18:34 tedd.an
  2020-06-19 18:34 ` [PATCH V2 2/2] midi: Fix random empty timestamp_high value tedd.an
  2020-06-22 19:28 ` [PATCH V2 1/2] midi: Fix SysEx parser in MIDI plugin Luiz Augusto von Dentz
  0 siblings, 2 replies; 3+ messages in thread
From: tedd.an @ 2020-06-19 18:34 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Tedd Ho-Jeong An

From: Tedd Ho-Jeong An <tedd.an@intel.com>

The SysEx end of message parser didn't consider the fact that
timestampsLow are in the stream and it might have the EOX (F7)
byte as well.

Fix that by always assuming the first system message byte is
the timestampLow.

Future work would involve support other type of system message
bytes, such as real-time.
---
 profiles/midi/libmidi.c | 38 +++++++++++++++++++++++++++++++-------
 1 file changed, 31 insertions(+), 7 deletions(-)

diff --git a/profiles/midi/libmidi.c b/profiles/midi/libmidi.c
index 4b4df799f..7d57e7335 100644
--- a/profiles/midi/libmidi.c
+++ b/profiles/midi/libmidi.c
@@ -331,6 +331,30 @@ static size_t handle_end_of_sysex(struct midi_read_parser *parser,
 	return sysex_length + 1; /* +1 because of timestampLow */
 }
 
+/* Searches the end of a SysEx message that contains a timestampLow
+ * before the SysEx end byte. Returns the number of bytes of valid
+ * SysEx payload in the buffer.
+ */
+static size_t sysex_eox_len(const uint8_t *data, size_t size)
+{
+	size_t i = 0;
+
+	MIDI_ASSERT(size > 0);
+
+	if (data[i] == 0xF0)
+		i++;
+
+	/* Search for timestamp low */
+	while (i < size) {
+		if ((data[i] & 0x80)) {
+			i++;
+			break;
+		}
+		i++;
+	}
+
+	return (i < size && data[i] == 0xF7) ? i : 0;
+}
 
 
 size_t midi_read_raw(struct midi_read_parser *parser, const uint8_t *data,
@@ -368,14 +392,14 @@ size_t midi_read_raw(struct midi_read_parser *parser, const uint8_t *data,
 
 		/* System Common Messages */
 	case 0xF0: /* SysEx Start */ {
-		uint8_t *pos;
+		size_t sysex_length;
 
 		/* cleanup Running Status Message */
 		parser->rstatus = 0;
 
-		/* Avoid parsing if SysEx is contained in one BLE packet */
-		if ((pos = memchr(data + i, 0xF7, size - i))) {
-			const size_t sysex_length = pos - (data + i);
+		sysex_length = sysex_eox_len(data + i, size - i);
+		/* Search for End of SysEx message in one BLE message */
+		if (sysex_length > 0) {
 			midi_size = handle_end_of_sysex(parser, ev, data + i,
 			                                sysex_length);
 		} else {
@@ -424,10 +448,10 @@ size_t midi_read_raw(struct midi_read_parser *parser, const uint8_t *data,
 
 		/* Check for SysEx messages */
 		if (parser->sysex_stream.len > 0) {
-			uint8_t *pos;
+			size_t sysex_length;
 
-			if ((pos = memchr(data + i, 0xF7, size - i))) {
-				const size_t sysex_length = pos - (data + i);
+			sysex_length = sysex_eox_len(data + i, size - i);
+			if (sysex_length > 0) {
 				midi_size = handle_end_of_sysex(parser, ev, data + i,
 				                                sysex_length);
 			} else {
-- 
2.25.4


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH V2 2/2] midi: Fix random empty timestamp_high value
  2020-06-19 18:34 [PATCH V2 1/2] midi: Fix SysEx parser in MIDI plugin tedd.an
@ 2020-06-19 18:34 ` tedd.an
  2020-06-22 19:28 ` [PATCH V2 1/2] midi: Fix SysEx parser in MIDI plugin Luiz Augusto von Dentz
  1 sibling, 0 replies; 3+ messages in thread
From: tedd.an @ 2020-06-19 18:34 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Tedd Ho-Jeong An

From: Tedd Ho-Jeong An <tedd.an@intel.com>

The timestamp_high value is assigned from the monotonic time but there
is a chance that the value becomes zero because it reads the value
between bit8 and bit13.

This patch makes sure the timestamp_high value get a non-zero value.
---
 profiles/midi/libmidi.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/profiles/midi/libmidi.c b/profiles/midi/libmidi.c
index 7d57e7335..cb2787db1 100644
--- a/profiles/midi/libmidi.c
+++ b/profiles/midi/libmidi.c
@@ -77,8 +77,13 @@ inline static void append_timestamp_high_maybe(struct midi_write_parser *parser)
 	if (midi_write_has_data(parser))
 		return;
 
-	parser->rtime = g_get_monotonic_time() / 1000; /* convert µs to ms */
-	timestamp_high |= (parser->rtime & 0x1F80) >> 7;
+	/* Make sure timesampt_high is assigned a non-zero value */
+	do {
+		/* convert µs to ms */
+		parser->rtime = g_get_monotonic_time() / 1000;
+		timestamp_high |= (parser->rtime & 0x1F80) >> 7;
+	} while (timestamp_high == 0x80);
+
 	/* set timestampHigh */
 	buffer_append_byte(&parser->midi_stream, timestamp_high);
 }
-- 
2.25.4


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH V2 1/2] midi: Fix SysEx parser in MIDI plugin
  2020-06-19 18:34 [PATCH V2 1/2] midi: Fix SysEx parser in MIDI plugin tedd.an
  2020-06-19 18:34 ` [PATCH V2 2/2] midi: Fix random empty timestamp_high value tedd.an
@ 2020-06-22 19:28 ` Luiz Augusto von Dentz
  1 sibling, 0 replies; 3+ messages in thread
From: Luiz Augusto von Dentz @ 2020-06-22 19:28 UTC (permalink / raw)
  To: Tedd Ho-Jeong An; +Cc: linux-bluetooth, Tedd Ho-Jeong An

Hi Tedd,

On Fri, Jun 19, 2020 at 9:27 PM <tedd.an@linux.intel.com> wrote:
>
> From: Tedd Ho-Jeong An <tedd.an@intel.com>
>
> The SysEx end of message parser didn't consider the fact that
> timestampsLow are in the stream and it might have the EOX (F7)
> byte as well.
>
> Fix that by always assuming the first system message byte is
> the timestampLow.
>
> Future work would involve support other type of system message
> bytes, such as real-time.
> ---
>  profiles/midi/libmidi.c | 38 +++++++++++++++++++++++++++++++-------
>  1 file changed, 31 insertions(+), 7 deletions(-)
>
> diff --git a/profiles/midi/libmidi.c b/profiles/midi/libmidi.c
> index 4b4df799f..7d57e7335 100644
> --- a/profiles/midi/libmidi.c
> +++ b/profiles/midi/libmidi.c
> @@ -331,6 +331,30 @@ static size_t handle_end_of_sysex(struct midi_read_parser *parser,
>         return sysex_length + 1; /* +1 because of timestampLow */
>  }
>
> +/* Searches the end of a SysEx message that contains a timestampLow
> + * before the SysEx end byte. Returns the number of bytes of valid
> + * SysEx payload in the buffer.
> + */
> +static size_t sysex_eox_len(const uint8_t *data, size_t size)
> +{
> +       size_t i = 0;
> +
> +       MIDI_ASSERT(size > 0);
> +
> +       if (data[i] == 0xF0)
> +               i++;
> +
> +       /* Search for timestamp low */
> +       while (i < size) {
> +               if ((data[i] & 0x80)) {
> +                       i++;
> +                       break;
> +               }
> +               i++;
> +       }
> +
> +       return (i < size && data[i] == 0xF7) ? i : 0;
> +}
>
>
>  size_t midi_read_raw(struct midi_read_parser *parser, const uint8_t *data,
> @@ -368,14 +392,14 @@ size_t midi_read_raw(struct midi_read_parser *parser, const uint8_t *data,
>
>                 /* System Common Messages */
>         case 0xF0: /* SysEx Start */ {
> -               uint8_t *pos;
> +               size_t sysex_length;
>
>                 /* cleanup Running Status Message */
>                 parser->rstatus = 0;
>
> -               /* Avoid parsing if SysEx is contained in one BLE packet */
> -               if ((pos = memchr(data + i, 0xF7, size - i))) {
> -                       const size_t sysex_length = pos - (data + i);
> +               sysex_length = sysex_eox_len(data + i, size - i);
> +               /* Search for End of SysEx message in one BLE message */
> +               if (sysex_length > 0) {
>                         midi_size = handle_end_of_sysex(parser, ev, data + i,
>                                                         sysex_length);
>                 } else {
> @@ -424,10 +448,10 @@ size_t midi_read_raw(struct midi_read_parser *parser, const uint8_t *data,
>
>                 /* Check for SysEx messages */
>                 if (parser->sysex_stream.len > 0) {
> -                       uint8_t *pos;
> +                       size_t sysex_length;
>
> -                       if ((pos = memchr(data + i, 0xF7, size - i))) {
> -                               const size_t sysex_length = pos - (data + i);
> +                       sysex_length = sysex_eox_len(data + i, size - i);
> +                       if (sysex_length > 0) {
>                                 midi_size = handle_end_of_sysex(parser, ev, data + i,
>                                                                 sysex_length);
>                         } else {
> --
> 2.25.4
>

Applied, thanks.

-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-06-22 19:29 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-19 18:34 [PATCH V2 1/2] midi: Fix SysEx parser in MIDI plugin tedd.an
2020-06-19 18:34 ` [PATCH V2 2/2] midi: Fix random empty timestamp_high value tedd.an
2020-06-22 19:28 ` [PATCH V2 1/2] midi: Fix SysEx parser in MIDI plugin Luiz Augusto von Dentz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).