Sending an encoded byte array in the command string

Continuing the discussion from How to send hash character to Spark.function?:

I am trying to send a unix epoch date encoded as 4 bytes and a control schedule (half hour blocks for 7 days encoded as 42 bytes with each bit representing one half hour bit value 1 = on 0 = off). I seem to be having problems with certain byte values, generally not a-z, A-Z, 0-9, (,),etc. Did the thread from 2 years back get solved or is it still not possible to encode any byte value in the String command? I can solve the problem by encoding as hex characters but that means I need 2 characters out of 63 for each byte and hence 2 function calls instead of 1.

Hi @armor

I would use a higher radix encoding like base-64. That way you stay in the printable ascii subset and get 6-bits per byte transferred.

@bko

I hadn’t thought of encoding in base-64, thanks for the advice. Are there any libraries to decode base-64 for the particle system. I can’t seem to find anything in the community library.

Also, as per the original question - I can’t encode a 32 bit number as 4 bytes because if one byte is value 0 then that will be treated as terminating the string? Ditto any other special characters?

Thanks

Update - I found an entry under Base64 in the community - I have put together a Base64 decode routine but now have a rather stupid error (I am feeling stupid) I can’t get around.

If I put the command string with the base64 encode ascii chars into a substring with String pvalue = command.substring(5); and then pass this to my decode routine as a string like this;
decodeBase64(pvalue); Whatever I declare my function input variable as (String _data) or better (const char* _data) I get a compiler error about can’t convert String to Char. I have looked up how to pass a string to a function on Stackoverflow, etc. and since I am not changing the string contents the (const char* _data) should work. What am I doing wrong?

error: invalid user-defined conversion from 'String' to 'char' [-fpermissive]

else if (command.startsWith("sdata"))
{
    validToDate = 0;                        // zero the validToDate to disable current schedule if in operation
    String pvalue = command.substring(5);
    if (decodeBase64(pvalue)) return -4;    // conversion error
    return 4;                               // all OK
}


int base64_decode(const char* _data)
{
}

Instead of the above code, try this:

...
    validToDate = 0;                        // zero the validToDate to disable current schedule if in operation
    String pvalue = command.substring(5);
    if (decodeBase64(pvalue.c_str())) return -4;    // conversion error
    return 4;                               // all OK
...

Thanks for this suggestion - it didn’t work but then something odd was going on with the compiler. It came back with exactly the same error whatever I changed. In frustration, I move the function contents into the calling location and removed the need to pass a pointer to a string. That works - I will try and refactor it later.

The thing here seems to be missing the deref * somewhere.
String::substring() will give you another String and Sting::c_str() will give you a const char * to the beginning of that String, but your code seem to expect a char, so you'd need to deref the pointer.

But I'd also guess that the error message does not actually belong to the code snippet you provided.
For instance, I can't see the function signature of decodeBase64(), which seems be the place where the illegitimate conversion would happen.