Arduino - how to concatenate byte arrays to get a final array - arduino

I have the following Arduino function:
void SendCommandToDisplay(byte message[], byte size)
{
byte header[] = {0x5A, 0xA5};
byte result[] = {};
memcpy(result, header, sizeof(header));
memcpy(result+sizeof(header), message, size);
for (byte i=0; i<sizeof(result); i++)
{
Serial.print(result[i], HEX);
Serial.print(' ');
}
}
Then I call this function as follows:
byte test[]={0x82, 0x20, 0x10, 0x00, 0x03};
SendCommandToDisplay(test, sizeof(test) / sizeof(byte));
And seems is not working, I'm doing something wrong or maybe I have to do a reference or pointer. Any clue?

You are not allocating memory for the result variable - in your case try this:
void SendCommandToDisplay(byte message[], byte size)
{
byte header[] = {0x5A, 0xA5};
byte result[sizeof(header)+size];
memcpy(result, header, sizeof(header));
memcpy(result+sizeof(header), message, size);
for (byte i=0; i<sizeof(result); i++)
{
Serial.print(result[i], HEX);
Serial.print(' ');
}
}
Once simple approach to inserting the byte count (of message) following header is to change how the header is initialized:
byte header[] = {0x5A, 0xA5, size};
Note: a prior edit added an alternative to use the sizeof(message) but that was incorrect and removed - sizeof(message) where message is a parameter returns the sizeof of a pointer which is 2 on an arduino.

Related

How i can convert a MAC string into byte array?

How i can convert a MAC string, like "5D:41:8F:32:34:H2" to byte array like {0x5D, 0x41, 0x8F, 0x32, 0x34, 0xH2}
I'm using an Arduino WOL library and it requires the MAC to pass it as an array of bytes, but I keep them as strings separated by ":" and I have no idea how that conversion could be done.
I can not put more details if you try because I do not even know where to start trying.
void arrancarPC(String strMac) {
byte mac[] = {0x5D, 0x41, 0x8F, 0x32, 0x34, 0xH2};
WakeOnLan::sendWOL(broadcast_ip, UDP, mac, sizeof mac);
}
the bytes in array must be in reverse order then printed.
H2 is not a valid hex value.
void str2mac(const char* str, uint8_t* mac) {
char buffer[20];
strcpy(buffer, str);
const char* delims = ":";
char* tok = strtok(buffer, delims);
for (int i = 5; i >= 0; i--) {
mac[i] = strtol(tok, NULL, 16);
tok = strtok(NULL, delims);
}
}
void setup() {
Serial.begin(115200);
const char* str = "5D:41:8F:32:34:F2";
uint8_t mac[6];
Serial.println(str);
str2mac(str, mac);
for (int i = 5; i >= 0; i--) {
if (i < 5) {
Serial.print(':');
}
Serial.print(mac[i], HEX);
}
Serial.println();
}
void loop() {
}

Generate Hash of a String that is formed by numbers and letters in Arduino

I'm doing a project where I need to randomly generate Hash numbers.
The code has to work as follows.
A random function generates a random number, these numbers are concatenated with a String to then generate the Hash of this String, ie each time a number is generated, the Hash of that number is also generated, this must be looped. To generate the hash I'm using a library called SpritzCipher.
The problem with this code is that it generates the hash of the word "random" instead of the hash of the concatenation of the value with String (salt).
Here is the code I did:
#include <SpritzCipher.h>
String salt = "fkllrnjnfd";
int randNumber;
String valorConcat;
void randomico() {
//Serial.begin(9600);
randomSeed(analogRead(0)); // Starts the list of random values
randNumber = random(100); // Draw a number from 0 to 99
valorConcat = String(randNumber) + salt;
//Serial.println(valorConcat); // Sends the value of randNumber to the serial
delay(500); // espera 500 ms
}
/* Data to input */
const byte testData[12] = {randomico};
/* Test vectors */
/* Data = 'testData' hash test vectors */
const byte testVector[32] =
{ 0xff, 0x8c, 0xf2, 0x68, 0x09, 0x4c, 0x87, 0xb9,
0x5f, 0x74, 0xce, 0x6f, 0xee, 0x9d, 0x30, 0x03,
0xa5, 0xf9, 0xfe, 0x69, 0x44, 0x65, 0x3c, 0xd5,
0x0e, 0x66, 0xbf, 0x18, 0x9c, 0x63, 0xf6, 0x99
};
void testFunc(const byte ExpectedOutput[32], const byte *data, byte dataLen)
{
byte hashLen = 32; /* 256-bit */
byte digest[hashLen]; /* Output buffer */
byte digest_2[hashLen]; /* Output buffer for chunk by chunk API */
spritz_ctx hash_ctx; /* the CTX for chunk by chunk API */
unsigned int i;
/* Print input */
for (i = 0; i < dataLen; i++) {
Serial.write(data[i]);
}
Serial.println();
spritz_hash_setup(&hash_ctx);
/* For easy test: code add a byte each time */
for (i = 0; i < dataLen; i++) {
spritz_hash_update(&hash_ctx, data + i, 1);
}
spritz_hash_final(&hash_ctx, digest_2, hashLen);
spritz_hash(digest, hashLen, data, dataLen);
for (i = 0; i < sizeof(digest); i++) {
if (digest[i] < 0x10) { /* To print "0F" not "F" */
Serial.write('0');
}
Serial.print(digest[i], HEX);
}
/* Check the output */
if (spritz_compare(digest, ExpectedOutput, sizeof(digest)) || spritz_compare(digest_2, ExpectedOutput, sizeof(digest_2))) {
/* If the output is wrong "Alert" */
digitalWrite(LED_BUILTIN, HIGH); /* Turn pin LED_BUILTIN On (Most boards have this LED connected to digital pin 13) */
Serial.println("\n** WARNING: Output != Test_Vector **");
}
Serial.println();
}
void setup() {
/* Initialize serial and wait for port to open */
Serial.begin(9600);
while (!Serial) {
; /* Wait for serial port to connect. Needed for Leonardo only */
}
/* initialize digital pin LED_BUILTIN (Most boards have this LED connected to digital pin 13) as an output */
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
}
void loop() {
Serial.println("[Spritz spritz_hash*() test]\n");
/* Data: arcfour */
testFunc(testVector, testData, sizeof(testData));
delay(5000); /* Wait 5s */
Serial.println();
}
A lot of your hashing code is just and example of two different options of hashing an array of bytes and comparing it to a known hash.
Since you only need to calculate the hash you only need to call spritz_hash.
As for your string generation, a more efficient way would be to use low level C++ functions, since the String object is using dynamic memory allocation and that can cause memory problems.
#include <SpritzCipher.h>
#define hex_char(n) ((n) < 10 ? '0' + (n) : 'A' + ((n)-10))
const char salt[] = "fkllrnjnfd";
char string[13] = "";
byte hash[32]; // byte hash
char hash_string[65]; // hex string hash
void randomico(char *string)
{
int randNumber = random(100); // Draw a number from 0 to 99
itoa(randNumber, string, 10); // convert int into char array
strcat(string, salt); // concatenate salt
}
void bytes_to_hexstr(char *string, byte *bytes, int size)
{
for (int i = 0; i < size; i++)
{
string[i*2] = bytes[i] < 16 ? '0' : hex_char((bytes[i] >> 4) & 0xF);
string[i*2+1] = hex_char(bytes[i] & 0xF);
}
string[size*2] = 0;
}
void setup()
{
Serial.begin(115200);
while (!Serial);
randomSeed(analogRead(0)); // Starts the list of random values
}
void loop()
{
randomico(string); // generate random salted string into 'string' variable
spritz_hash(hash, 32, (byte*)string, strlen(string)); // hash 'string' into 'hash' variable (hash only the character inside the string not the full char array)
bytes_to_hexstr(hash_string, hash, 32); // convert byte hash into printable hex string
// print out string and hash
Serial.print(string);
Serial.print(" -> ");
Serial.println(hash_string);
delay(1000);
}
But if you really want to use String you can do it as such:
String str = String(random(100))+salt;
spritz_hash(hash, 32, (byte*)str.c_str(), str.length());

pointers passed to functions

I am using the Arduino IDE to to write a sketch that passes data saved in progmem to a function, the function then writes the progmem data to local array.
The code is below:
const uint8_t Data_3 [256] PROGMEM = {0x11, 0x39.....}
void setup() {
Serial.begin(57600);
Data(Data_3, 0x00, 256);
}
void loop() {
}
void Data(const uint8_t *data, uint8_t bank, uint16_t bytes) {
uint8_t buff1 [256];
buff1[0] = data[0];
Serial.println(buff1[0],HEX); // <--Works fine prints the correct value
for ( uint16_t x = 0; x < bytes + 1; x++ ) {
buff1[x] = data[x];
Serial.println(buff1[x],HEX); // <--Just prints garbage
}
}
When I assign buff1[0] = data[0] and print the result the answer is correct. When I loop a print function with buff1[x] = data[x] I just get rubbish. Does anyone know the reason for this?
You have to use #include <avr/pgmspace.h> and Serial.print(pgm_read_byte(data+x)); otherwise it'll try to get data from the same address but from RAM, not from Flash memory.
Or copy into the buffer by memcpy_P(buff, data, bytes);

Arduino reading json from EEPROM / converting uint8_t to char

I'm using ArduinoJSON to write a couple of data points to my EEPROM on Arduino Uno. I'm running into a problem with getGroundedPR where I need to convert a uint8_t to a char to pass retrieved data into my JSON parser.
This is my first time using EEPROM so I'm willing to bet there's a better way to do this. Should I continue to use JSON or is there a better way? I'm being cautious of the 10k write limit (give or take) on the EEPROM.
the EEPROM read/write is commented out until I have my process nailed down
void IMUController::setGroundedPR(double p, double r) {
Serial.print("Setting IMU ground: ");
StaticJsonBuffer<200> jsonBuffer;
JsonObject& root = jsonBuffer.createObject();
root["pitch"] = p;
root["roll"] = r;
root.printTo(Serial);
char buffer[256];
root.printTo(buffer, sizeof(buffer));
Serial.println();
// EEPROM.write(EEPROM_ADDRESS_IMU_GROUNDED, buffer);
}
double* IMUController::getGroundedPR() {
double ret[2] = {0, 0};
StaticJsonBuffer<200> jsonBuffer;
uint8_t json_saved = EEPROM.read(EEPROM_ADDRESS_IMU_GROUNDED);
char json[] = "asdf"; // convert json_saved to char here
JsonObject& root = jsonBuffer.parseObject(json);
if(!root.success()) {
// return the result
ret[0] = (double)root["pitch"];
ret[1] = (double)root["roll"];
return ret;
}
return ret;
}
The EEPROM functions read() and write() only deal with a single character. You need to use put() and get() to deal with arrays.
char buffer[256];
root.printTo(buffer, sizeof(buffer));
EEPROM.put(EEPROM_ADDRESS_IMU_GROUNDED, buffer);
And to read it back:
char json[256];
EEPROM.get(EEPROM_ADDRESS_IMU_GROUNDED, json);
JsonObject& root = jsonBuffer.parseObject(json);
You need to take care with he array sizes though, the EEPROM functions will get and put the number of bytes in the array (256). The string should be null terminated so the extra bytes shouldn't cause a problem.

RFduinoBLE_onReceive when sending bytearray

I'm attempting to send 8-bit byteArrays to an rfduino.
In the sketch, I got
void RFduinoBLE_onReceive(char *data, int len) {
int firstbyte = data[0];
Serial.println(firstbyte)
}
This works fine if the firstbyte is over 32. But if I'm sending a byteArray of [13, ...], firstbyte is parsed as 0.
I think I understand why (?):
RFduinoBLE parses incoming data as characters before sending it to this function, and bytes up to 32 are empty string.
So my question is: how can I use the RFduinoBLE-onReceive to read bytearrays with values below 32?
The following seems to work just fine:
void RFduinoBLE_onReceive(char *data, int length) {
uint8_t firstbyte = data[0];
}
or for arrays
uint8_t getData[20];
void RFduinoBLE_onReceive(char *data, int length) {
for (i = 0; i < length; i++) {
getData[i] = data[i];
}
}
Not quite sure what went right/wrong where, but I suspect either using int firstbyte instead of uint8_t firstbyte or casting uint8_t firstbyte = (uint8_t) data[0] did something I didn't expect.

Resources