UDP message with header and Base64 encoding with ofxIO

I am trying to talk to a device that receives UDP messages and I am stuck on how to format messages.
The documentation I can find states:

Each UDP has header:

1 byte \x01 (byte with hex representation 0x01)
8 bytes Base 64 decoded authentication token
1 byte number of LED definitions in the frame

Then follows body of the frame similarly to movie file format - three bytes for each LED

I am not really sure how to construct this message using the ofxNetwork UDP sender, looking at the UDP data gram protocol I think that the header referred to above is just the first part of the message as the header for a datagram seems to only be able to store the source and destination addresses and message lengths.

I am starting with this:

vector<unsigned char> udpMessage;
udpMessage.push_back(0x01);
//     1 byte \x01 (byte with hex representation 0x01)

Then I need to convert a token I receive from the device into base64. I am using ofxIO to do this:

    ofxIO::ByteBuffer buffer;
    buffer.writeBytes(_token);
    std::string base64Buffer = ofxIO::Base64Encoding::encode(buffer);
    cout << " base64 encoded string size = " + ofToString(base64Buffer.size()) << endl;

    for (int i = 0; i < base64Buffer.size(); i++) {
        udpMessage.push_back(base64Buffer[i]);
    }
//8 bytes Base 64 decoded authentication token

But I notice that the size of the string I get back from the base64 encoding is large (the length is 16). Checking this out it seems strange that the ofxIO::Base64Encoding::encode method returns a string, not an vector of unsigned chars, and that for this example string as input “WpYji0GP4uY=” the size is 16, when because it is base 64 encoded it should be 8 bytes long.

From there I think I know what to do, I would continue like this:

int _number_of_leds = 107;
udpMessage.push_back(_number_of_leds);
//1 byte number of LED definitions in the frame

Then to fill the values of the message body

udpMessage.push_back(_number_of_leds);
    for (int i = 0; i < _number_of_leds*3; i++) {
        udpMessage.push_back(int(ofRandom(0, 255)));
    }
//Then follows body of the frame similarly to movie file format - three bytes for each LED

Lastly is how to send this message with the ofxUDPManager send method:
ofxUDPManager::Send(const char* pBuff, const int iSize);

How can I send a vector<unsigned char> with the UDP sender - or should I have begun with a different type to start with?

Can anyone give any advice on how to encode and send this message with openframeworks?

Cheers

Fred

Is there a spec/data sheet that goes into more detail here?

Not really, someone has worked it out, there is no official SDK. I got the info from here:

https://xled-docs.readthedocs.io/en/latest/protocol_details.html#real-time-led-udp-packet-format

I have implemented the rest of the functionality described, but I would really like to use this real time part that uses UDP.

It appears to me that maybe you should be using ofxIO to decode a base64 encoded authentication string, which should result in 8 decoded bytes that you would send in the udp packet.

8 bytes Base 64 decoded authentication token

This can be done like:


    ofxIO::ByteBuffer encoded(_token);
    ofxIO::ByteBuffer decoded;

    ofxIO::Base64Encoding base64;
    std::size_t size = base64.decode(encoded, decoded);

    std::cout << size << " bytes decoded from token: " << _token << std::endl;

    for (std::size_t i = 0; i < decoded.size(); i++) {
        udpMessage.push_back(decoded[i]);
    }
    
    /// ...

Thanks a lot, that was the trick.

1 Like