Buffer Overflow?

I am working in an area that is not my strength so please excuse my ignorance.

The goal the the following code is to recreate the HEX MAC address from a XBee radio by converting and concatenating the two uint32_t values received from the XBee radio so they can be used as the unique device ID to send to data to Ubidots.

It appears that I might be experiencing a buffer overflow issue because strange characters are being appended throughout the reconstructed HEX value. Any suggestions would be appreciated. I cannot take credit for the code, I have been getting help from the Ubidots forum but I think this could be transitioning into more of an issue of not playing well with the Particle environment (I am confident the issue is not Particles but a result of me not knowing any better, so no blame at all!).

void loop() {
    xbee.readPacket();
    if (xbee.getResponse().isAvailable()){
        if (xbee.getResponse().getApiId() == ZB_IO_SAMPLE_RESPONSE) {
            xbee.getResponse().getZBRxIoSampleResponse(ioSample);
            uint32_t msb = ioSample.getRemoteAddress64().getMsb();  //Expected value length & format similar to: 1286656
            uint32_t lsb = ioSample.getRemoteAddress64().getLsb();  //Expected value length & format similar to: 1087549506
            char* macHexa  = (char*) malloc(sizeof(char) * 16);
            toHexString(msb, lsb, macHexa);
            ubidots.send(macHexa);
        }
    }
}


void toHexString(uint32_t msb, uint32_t lsb, char* mac_hexa) {
    sprintf(mac_hexa, "");
    char* msbHexa = (char*) malloc(sizeof(char) * 8);
    char* lsbHexa = (char*) malloc(sizeof(char) * 8);
    uint32_t provisional; 
    for (uint8_t i = 0; i < 4; i++) {
        provisional = (msb >> (24 - (8 * i))) & 0xFF;
        sprintf(msbHexa, "%s%.2x", msbHexa, provisional);
        provisional = (lsb >> (24 - (8 * i))) & 0xFF;
        sprintf(lsbHexa, "%s%.2x", lsbHexa, provisional);
    }
    sprintf(mac_hexa, "%s%s", msbHexa, lsbHexa);
    free(msbHexa);
    free(lsbHexa);
}

@Backpacker87, if your goal is to send the 8 char hex string of the upper and lower address data then you have over complicated things.

First, from getRemoteAddress64(), I gather the total address is 64bits or 8 bytes long which you fetch into two 32bit values. The complete address then is msb << 32 + lsb. However, since you are producing a string of the address representation, you don’t need to calculate the 64bit address, you only need to sprintf() it that way.

You code is fine until you start using malloc() and calling toHexString() which not only creates heap fragmentation but also is over complicated.

I suggest using a plain char array of 9 chars (the last being the null terminator) and using snprintf() like this:

void loop() {
  char macHexa[9];
...
  // using snprintf() to print out MSBLSB in HEX format with filling zeros
  // to get the full 8 byte ascii address into macHexa
  sprintnf(macHexa, sizeof(macHexa), "%04X%04X", msb, lsb);

  ubidots.send(macHexa);
}

No need for malloc() or toHexString().

1 Like

@peekay123 thank you so much for your reply! I have been hammering on this for a while and your recommendation is so much cleaner and is working nicely!

sprintnf(macHexa, sizeof(macHexa), β€œ%04X%04X”, msb, lsb);

I did tweak the sprintnf --> snprintf assuming it was a typo.

Also, I changed char macHexa[9] --> char macHexa[17] because I noticed I was only getting half so I figured I needed to double the char size to accomidate the fully concatenated value.

The last frontier is it appears that the first two leading zeros are not being appended to the front of the address. So I am getting 13A20041A45B08 when the true MAC has two leading zeros like this 0013A20041A45B08.

I have confirmed that the uint32_t msb value starts off as 1286656 in this case which appears to be a matter of the 2’s complement value?

image

@Backpacker87, good catch on the array size and yes that was a typo on snprintf()! The booboo on my part is the %04X for the msb and lsb format. It should be %08X since 32bits is 8 hex digits! So the statement should be:

  snprintf(macHexa, sizeof(macHexa), β€œ%08X%08X”, msb, lsb);

This will add the two missing leading zeros. :wink:

1 Like

@peekay123 I just implemented this small change it it is working absolutely perfectly!

I cannot thank you enough for your help, this issue was really bogging me down and I kept spinning my wheels; you are awesome!

I am going to do some homework on learning about snprintf and what it is doing so I know more for the future.

1 Like