public SpineObject decode(Node node, byte[] payload) throws PacketDecodingException {

    BufferedRawData data = new BufferedRawData();

    data.baseInit(node, payload);
    // data.setFunctionCode(SPINEFunctionConstants.BUFFERED_RAW_DATA);

    short pldIndex = 2;

    byte sensorCode = (byte) (payload[pldIndex] >> 4);
    data.setSensorCode(sensorCode);

    byte channelBitmask = (byte) (payload[pldIndex++] & 0x0F);
    data.setChannelBitmask(channelBitmask);

    byte dataWordLength = payload[pldIndex++];
    data.setDataWordLength(dataWordLength);

    pldIndex++; // skip MSB of the bufferSize because it will be always 0
    int bufferSize = payload[pldIndex++];

    int[][] values = new int[SPINESensorConstants.MAX_VALUE_TYPES][];

    // if the actual sensor readings data ((payload.length - pldIndex) bytes)
    // in the payload is less than what is declared (by channelBitmask, bufferSize, and
    // dataWordLength)
    // then this message is somehow malformed or corrupted.
    if (((payload.length - pldIndex)
        < (SPINESensorConstants.countChannelsInBitmask(channelBitmask)
            * bufferSize
            * dataWordLength)))
      throw new PacketDecodingException(
          "Malformed or corrupted BufferedRawData message received "
              + "[from node: "
              + node.getPhysicalID()
              + "]");

    byte[] dataTmp = new byte[4];
    for (int i = 0; i < SPINESensorConstants.MAX_VALUE_TYPES; i++) {
      if (SPINESensorConstants.chPresent(i, channelBitmask)) {
        values[i] = new int[bufferSize];
        for (int j = bufferSize - 1; j >= 0; j--) {
          if (dataWordLength == 1) {
            dataTmp[3] = payload[pldIndex++];
            dataTmp[2] = 0;
            dataTmp[1] = 0;
            dataTmp[0] = 0;

          } else if (dataWordLength == 2) {
            dataTmp[3] = payload[pldIndex++];
            dataTmp[2] = payload[pldIndex++];
            dataTmp[1] = 0;
            dataTmp[0] = 0;
          } else if (dataWordLength == 3) {
            dataTmp[3] = payload[pldIndex++];
            dataTmp[2] = payload[pldIndex++];
            dataTmp[1] = payload[pldIndex++];
            dataTmp[0] = 0;
          } else if (dataWordLength == 4) {
            dataTmp[3] = payload[pldIndex++];
            dataTmp[2] = payload[pldIndex++];
            dataTmp[1] = payload[pldIndex++];
            dataTmp[0] = payload[pldIndex++];
          }

          values[i][j] = Data.convertFourBytesToInt(dataTmp, 0);
        }
      }
    }

    data.setValues(values);

    return data;
  }