Problems comparing converted data

Evening all,

I'm having a real head scratch here, hopefully it's just because its late but here goes ...

I need to compare some data received via an MQTT message (which comes in as a byte*) with a piece of known data (a char* in this case). Obviously I have to convert the byte* to a char* in order for this to work but I'm obviously missing a step as the data sent over is different to what is compared at the other end. The code I'm struggling with is ...

void callback(char* topic, byte* payload, unsigned int length) {
  
  // In order to republish this payload, a copy must be made
  // as the orignal payload buffer will be overwritten whilst
  // constructing the PUBLISH packet.
  
  // Allocate the correct amount of memory for the payload copy
  byte* p = (byte*)malloc(length);
 
  // Copy the payload to the new buffer
  memcpy(p,payload,length);
  
  //client.publish("SHHNoT/frontDoor/secSensor/doorLock", p, length);
  char* rcvdMQTT = (char*)p; //need to convert byte* p variable into a char* for comparision
  
  client.publish("SHHNoT/frontDoor/secSensor/doorLock", rcvdMQTT); // debugging - republish after conversion to see what you've actually got
  
  if(rcvdMQTT=="Steve") {
    client.publish("SHHNoT/frontDoor/secSensor/doorLock", "Hello Steve. Come on in.");
  }
  
  else {
    client.publish("SHHNoT/frontDoor/secSensor/doorLock", "Who are you? I'm not opening the door.");
  }
  
  // Free the memory
  free(p);
}

When the code receives a message it converts the byte* to a char* and then republishes that out for debugging purposes. What I can see has been republished is the original data with some extra characters on the on end (two colour inverted question marks and a question mark). Due, presumably, to these additional characters even if I send the correct data over it fails the check.

I'm sure it's just a conversion issue but I just can't see it.

Thanks in advance.

which comes in as a byte*

You can not receive a byte*, that is a pointer to a byte, it does not make any sense. If you are receiving a pointer from an other device that byte is still being stored in that device.

Fair point.

Either way though I still need to convert this byte to a char and and still scratching my head.

xyproblem.info

What are you really trying to do?

if(rcvdMQTT=="Steve")

I am trying to check whether the text message (via MQTT) received (byte* p) is equal to a known text - in this case "Steve"

Thanks - not read that XY problem before, useful advice!

Either way though I still need to convert this byte to a char

No, you don't. A char and a byte are the same size. So, lie to the compiler:

if(memcmp((byte *)topic, payload, length) == 0)
{
    // Hey, they match

Ok so I can see how the char and byte are the same size but I don't understand the code you have included.

I tried swapping out the 0 for the term I need to compare ("Steve" as per the example) and it throws an error about comparisons again.

I tried swapping out the 0 for the term I need to compare ("Steve" as per the example) and it throws an error about comparisons again.

I've got some code I'm not showing you. I have some errors I'm not showing you. Help!

No.

Cheers anyway (genuinely) as you've forced me to rethink this one.

I was massively overcomplicating it, as always, and have now sorted it.

I simply fed the payload into a global char one byte at a time using a for loop, added a null terminator and then converted that to a String.

for(i=0; i<length; i++) {
    messageBuff[i] = payload[i];
  }
  messageBuff[i] = '\0';

String msgString = String(messageBuff);

All sorted :slight_smile:

I simply fed the payload into a global char one byte at a time using a for loop, added a null terminator and then converted that to a String.

And pissed away resources right and left.

String msgString = String(messageBuff);

Why bother doing that?
you can compare char strings you know. strncmp()

thermalhound:
I am trying to check whether the text message (via MQTT) received (byte* p) is equal to a known text - in this case "Steve"

Exactly. What your code will do is check if the memory location rcvdMQTT (which you got from malloc) is the same as the memory location where the compiler has placed the static text in the double quotes.

It won't be.

You need to use strcmp() to compare the content of the memory at those two locations. Docs are here

http://www.nongnu.org/avr-libc/user-manual/group__avr__string.html

Note that this function compares strings. Strings are null-terminated.

  // enough space for the payload and a nul terminator
  byte* p = (byte*)malloc(length+1);
  // Copy the payload to the new buffer
  memcpy(p,payload,length);
  // force null termination
  p[length] = '\0';

Don't use the C++ String class - it chews up memory and is not a suitable solution for microcontrollers with 2K of the stuff.

-- EDIT --

mistergreen suggests using strncmp. With that, you don't need to explicitly add a nul terminator. It's a better solution - that function was built for exactly this purpose.

Thanks very much, thats all really helpful.

Will post up my amended code later if anyone is interested - when I get a chance to check that its working of course!