Send and read different types of values

To send different types of values in my snake game, I have a enum “MessageType”. I want it to be just a 2 bits data, so maximum number of type can be 5 ( from 0 to 4)

enum MessageType{
  UPDATE = 1,//to update the tail
  SNAKEDATA = 2,//to send the whole snake data
  LENGTH = 3,//to spread the latest length out
};

Then I have different ways to set up different type of data in binary, but the MessageType is always placed at the final 2 bits of the data. Note that the maximum length of the data should be within 6 bits.

byte data = (tailIndex<<2) + UPDATE;// tailIndex ( 0 - 6, 3bits)
                                     // MessageType ( 1 - 3, 2 bits )
byte data = (snakeLength<<2)+LENGTH;// snakeLength (1 - 4bits)
                                    // MessageType ( 2 bits )
byte data = (snakeLength<<3)+(snakeDirection<<2)+SNAKEDATA;//tailIndex ( 0 - 6, 3bits)
                                                           //snakeDirection ( 0 -1, 1 bits )
                                                           //MessageType ( 2 bits )

Then in the loop(), I have a receiveMessage() function. In which, I have if{}else if(){} to check the MessageType first, then use different lines to read the message accordingly:

 if(!isValueReceivedOnFaceExpired(f)){

      byte data = getLastValueReceivedOnFace(f);
      MessageType type = static_cast<MessageType>(data&3);

  if(type == UPDATE){

      byte tailIndex = (data >> 2);

  }else if(type == DATA){

      //get direction
      Direction dir = static_cast<Direction>((data & 4) >> 2);

      //get length
       byte length = (data >> 3);

  }else if(type == LENGTH){
      //get length
      byte newLength = data >> 2;

  }
}