aboutsummaryrefslogtreecommitdiff
path: root/quantum/api
diff options
context:
space:
mode:
authorFred Sundvik <fsundvik@gmail.com>2016-12-29 12:13:30 +0200
committerFred Sundvik <fsundvik@gmail.com>2016-12-29 12:13:30 +0200
commitdd685eceb2045371d38f24d454f1ab08ca7416f4 (patch)
treeeef012131a9ce190512a899d4850e34741989a26 /quantum/api
parent273faa4d9cd5a84207548f83ba550c9efee90933 (diff)
downloadqmk_firmware-dd685eceb2045371d38f24d454f1ab08ca7416f4.tar.gz
qmk_firmware-dd685eceb2045371d38f24d454f1ab08ca7416f4.zip
API Sysex fixes
Fix memory leaks by using stack instead of malloc Reduce memory usage by having less temporary bufffers Remove warnings by adding includes Decrease code size by 608 bytes (mostly due to not linking malloc) More robust handling of buffer overflows
Diffstat (limited to 'quantum/api')
-rw-r--r--quantum/api/api_sysex.c60
1 files changed, 44 insertions, 16 deletions
diff --git a/quantum/api/api_sysex.c b/quantum/api/api_sysex.c
index a4a554e76..868f854b9 100644
--- a/quantum/api/api_sysex.c
+++ b/quantum/api/api_sysex.c
@@ -1,4 +1,6 @@
1#include "api_sysex.h" 1#include "api_sysex.h"
2#include "sysex_tools.h"
3#include "print.h"
2 4
3void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, uint16_t length) { 5void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, uint16_t length) {
4 // SEND_STRING("\nTX: "); 6 // SEND_STRING("\nTX: ");
@@ -6,24 +8,50 @@ void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes,
6 // send_byte(bytes[i]); 8 // send_byte(bytes[i]);
7 // SEND_STRING(" "); 9 // SEND_STRING(" ");
8 // } 10 // }
9 uint8_t * precode = malloc(sizeof(uint8_t) * (length + 2)); 11 if (length > API_SYSEX_MAX_SIZE) {
10 precode[0] = message_type; 12 xprintf("Sysex msg too big %d %d %d", message_type, data_type, length);
11 precode[1] = data_type; 13 return;
12 memcpy(precode + 2, bytes, length); 14 }
13 uint8_t * encoded = malloc(sizeof(uint8_t) * (sysex_encoded_length(length + 2))); 15
14 uint16_t encoded_length = sysex_encode(encoded, precode, length + 2); 16
15 uint8_t * array = malloc(sizeof(uint8_t) * (encoded_length + 5)); 17 // The buffer size required is calculated as the following
16 array[0] = 0xF0; 18 // API_SYSEX_MAX_SIZE is the maximum length
17 array[1] = 0x00; 19 // In addition to that we have a two byte message header consisting of the message_type and data_type
18 array[2] = 0x00; 20 // This has to be encoded with an additional overhead of one byte for every starting 7 bytes
19 array[3] = 0x00; 21 // We just add one extra byte in case it's not divisible by 7
20 array[encoded_length + 4] = 0xF7; 22 // Then we have an unencoded header consisting of 4 bytes
21 memcpy(array + 4, encoded, encoded_length); 23 // Plus a one byte terminator
22 midi_send_array(&midi_device, encoded_length + 5, array); 24 const unsigned message_header = 2;
25 const unsigned unencoded_message = API_SYSEX_MAX_SIZE + message_header;
26 const unsigned encoding_overhead = unencoded_message / 7 + 1;
27 const unsigned encoded_size = unencoded_message + encoding_overhead;
28 const unsigned unencoded_header = 4;
29 const unsigned terminator = 1;
30 const unsigned buffer_size = encoded_size + unencoded_header + terminator;
31 uint8_t buffer[encoded_size + unencoded_header + terminator];
32 // The unencoded header
33 buffer[0] = 0xF0;
34 buffer[1] = 0x00;
35 buffer[2] = 0x00;
36 buffer[3] = 0x00;
37
38 // We copy the message to the end of the array, this way we can do an inplace encoding, using the same
39 // buffer for both input and output
40 const unsigned message_size = length + message_header;
41 uint8_t* unencoded_start = buffer + buffer_size - message_size;
42 uint8_t* ptr = unencoded_start;
43 *(ptr++) = message_type;
44 *(ptr++) = data_type;
45 memcpy(ptr, bytes, length);
46
47 unsigned encoded_length = sysex_encode(buffer + unencoded_header, unencoded_start, message_size);
48 unsigned final_size = unencoded_header + encoded_length + terminator;
49 buffer[final_size - 1] = 0xF7;
50 midi_send_array(&midi_device, final_size, buffer);
23 51
24 // SEND_STRING("\nTD: "); 52 // SEND_STRING("\nTD: ");
25 // for (uint8_t i = 0; i < encoded_length + 5; i++) { 53 // for (uint8_t i = 0; i < encoded_length + 5; i++) {
26 // send_byte(array[i]); 54 // send_byte(buffer[i]);
27 // SEND_STRING(" "); 55 // SEND_STRING(" ");
28 // } 56 // }
29} \ No newline at end of file 57}