From 008df0e371714317ba256ba5c80d014886a9b8f4 Mon Sep 17 00:00:00 2001 From: Hugo van Galen Date: Mon, 27 Jul 2020 11:06:36 +0200 Subject: [PATCH 1/3] Fix bugs --- send-sds.c | 112 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 79 insertions(+), 33 deletions(-) diff --git a/send-sds.c b/send-sds.c index 12febc8..1f81f2a 100644 --- a/send-sds.c +++ b/send-sds.c @@ -180,6 +180,7 @@ send_file( printf("Packet %d\n", modded_packet_num); + if (__TRACE_SEND_PACKETS) { printf("%s %s reading packet %d\n", trace, __func__, packet_num); } @@ -210,17 +211,6 @@ send_file( trace, __func__, packet_num); } - if (!get_response(midi, channel_num, modded_packet_num, &response)) { - fprintf(stderr, - "get_response failed with response %s\n", - response_to_string(response.type)); - return 0; - } else { - printf("Received %s for packet %d\n", - response_to_string(response.type), - modded_packet_num); - } - /* if (response != RESPONSE_ACK) { */ /* fprintf(stderr, */ /* "received %s instead of %s in response to packet %d", */ @@ -230,20 +220,50 @@ send_file( /* return 0; */ /* } */ - if (response.type == RESPONSE_ACK) { - if (__TRACE_SEND_PACKETS) { - printf("%s %s received response %s from sending packet %d\n", - trace, __func__, response_to_string(response.type), packet_num); + int have_ack = 0; + + const time_t start_time = time(NULL); + const time_t timeout_sec = 2; + time_t now; + while (!have_ack) { + + now = time(NULL); + if (now - start_time > timeout_sec) { + fprintf( stderr, "send_file timed out waiting for response\n" ); + return 0; } - } else if (response.type == RESPONSE_NAK) { - fprintf(stderr, - "received %s instead of %s in response to packet %d\n", + + + if (!get_response(midi, channel_num, modded_packet_num, &response)) { + fprintf(stderr, + "get_response failed with response %s\n", + response_to_string(response.type)); + return 0; + } else { + printf("Received %s for packet %d\n", response_to_string(response.type), - response_to_string(RESPONSE_ACK), - packet_num); - return 0; - } + modded_packet_num); + } + if (response.type == RESPONSE_ACK) { + if (__TRACE_SEND_PACKETS) { + printf("%s %s received response %s from sending packet %d\n", + trace, __func__, response_to_string(response.type), packet_num); + } + + have_ack = 1; + } else if (response.type == RESPONSE_NAK) { + fprintf(stderr, + "received %s instead of %s in response to packet %d\n", + response_to_string(response.type), + response_to_string(RESPONSE_ACK), + packet_num); + return 0; + } else { // if (response.type == RESPONSE_WAIT) { + fprintf( stderr, "received %s while waiting for ACK for packet %d\n", response_to_string(response.type), packet_num ); + } + } + packet_num++; } @@ -257,26 +277,33 @@ get_response(midi_t midi, response_t *response) { const time_t start_time = time(NULL); const time_t timeout_sec = 2; - - response_type rt; - int bytes_read; + response_type rt = RESPONSE_NULL; + + int bytes_read = 0; + int found_expected_packet = 0; time_t now; - unsigned char c, t; - - bytes_read = 0; - - while (bytes_read < SDS_RESPONSE_LENGTH) { + unsigned char c, t = 0; + + int have_response_packet = 0; + while (!have_response_packet) { now = time(NULL); - + if (!midi_read(midi, &c)) { return 0; } + // fprintf(stderr, "Byte#%d %02X\n", bytes_read, c); + if (now - start_time > timeout_sec) { - rt = RESPONSE_TIMEOUT; return 0; } + if (c == 0xf0 && bytes_read > 0) { + fprintf( stderr, "Received start of new SysEx packet; ignoring what we collected so far...\n" ); + bytes_read = 1; + continue; + } + switch (bytes_read) { case 0: if (c == 0xf0) { @@ -303,14 +330,17 @@ get_response(midi_t midi, t = c; bytes_read++; /* printf("read third byte of response (%02X)\n", c); */ + } else { + fprintf( stderr, "Ignoring unsupported packet %02d\n", c ); } break; case 4: if (c == modded_packet_num) { - bytes_read++; + found_expected_packet = 1; /* printf("read fourth byte of response (%02X)\n", c); */ } + bytes_read++; break; case 5: @@ -335,6 +365,22 @@ get_response(midi_t midi, bytes_read++; break; } + + + if (c == 0xf7) { + if (!found_expected_packet) { + // This is the EOX, the last byte of the SysEx message. If + // this is detected, there are no more sysex messages. We may + // have read a partial packet. Perhaps the next packet is + // the ACK we are waiting for? + fprintf(stderr, "Ignoring unexpected / out-of-band packet...\n"); + bytes_read = 0; + continue; + } else { + // We appear to have what we were waiting for. + have_response_packet = 1; + } + } } response_t r = { modded_packet_num, rt }; From 21f7e9f54e81f402f276c785a27ce08b27025002 Mon Sep 17 00:00:00 2001 From: Hugo van Galen Date: Mon, 27 Jul 2020 11:07:45 +0200 Subject: [PATCH 2/3] Fix bug --- midi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/midi.c b/midi.c index 485379a..b69662b 100644 --- a/midi.c +++ b/midi.c @@ -27,7 +27,7 @@ midi_open_interface( snd_rawmidi_t *handle_in, *handle_out; midi_t midi; - r = snd_rawmidi_open(&handle_in, &handle_out, device, 0); + r = snd_rawmidi_open(&handle_in, &handle_out, device, SND_RAWMIDI_NONBLOCK); if (r) { err_set2(err, "snd_rawmidi_open \"%s\": error %d", device, r); return 0; From 18cc970d91b913b6b891e7fdcbc1dd7a22d8a60d Mon Sep 17 00:00:00 2001 From: Hugo van Galen Date: Mon, 27 Jul 2020 11:19:16 +0200 Subject: [PATCH 3/3] Set blocking mode after opening the device --- midi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/midi.c b/midi.c index b69662b..c8b749d 100644 --- a/midi.c +++ b/midi.c @@ -33,6 +33,9 @@ midi_open_interface( return 0; } + snd_rawmidi_nonblock( handle_in, 0 ); + snd_rawmidi_nonblock( handle_out, 0 ); + midi = malloc(sizeof(*midi)); midi->device = strdup(device); midi->handle_in = handle_in;