NordicSemiconductor / Android-nRF-Mesh-Library

The Bluetooth Mesh Provisioner and Configurator library.
https://www.nordicsemi.com/
BSD 3-Clause "New" or "Revised" License
414 stars 177 forks source link

Wrong segmentation of Messages where the Payload length is >12 Octets but smaller than 15 octets #579

Closed bengy closed 6 months ago

bengy commented 7 months ago

Describe the bug We noticed Light HSL Set Unacknowledged messages were sent segmented when sent from Android phones while they should be unsegmented.

The message length is 13 Bytes and the Mesh specification states:

3.5.3 Segmentation and reassembly

To transmit Upper Transport PDUs larger than 15 octets, the lower transport layer segments and reassembles Upper Transport PDUs...

Looking into the code it seems the check in the LowerTransportLayer is wrong:

@Override
    @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
    public final void createLowerTransportAccessPDU(@NonNull final AccessMessage message) {
        final byte[] upperTransportPDU = message.getUpperTransportPdu();
        final SparseArray<byte[]> lowerTransportAccessPduMap;
        if (upperTransportPDU.length <= MAX_SEGMENTED_ACCESS_PAYLOAD_LENGTH) {
            message.setSegmented(false);
            final byte[] lowerTransportPDU = createUnsegmentedAccessMessage(message);
            lowerTransportAccessPduMap = new SparseArray<>();
            lowerTransportAccessPduMap.put(0, lowerTransportPDU);
        } else {
            message.setSegmented(true);
            lowerTransportAccessPduMap = createSegmentedAccessMessage(message);
        }

        message.setLowerTransportAccessPdu(lowerTransportAccessPduMap);
    }

this should check for <= MAX_UNSEGMENTED_ACCESS_PAYLOAD_LENGTH which is 15 as expected.

iOS seems to have the correct checks

roshanrajaratnam commented 6 months ago

Hi, nice catch. Expect a release soon