final ControlMessage parseSegmentedControlLowerTransportPDU(@NonNull final byte[] pdu) {

        final byte header = pdu[10]; //Lower transport pdu starts here
        final int akf = (header >> 6) & 0x01;
        final int aid = header & 0x3F;

        final int szmic = (pdu[11] >> 7) & 0x01;
        final int seqZero = ((pdu[11] & 0x7F) << 6) | ((pdu[12] & 0xFC) >> 2);
        final int segO = ((pdu[12] & 0x3) << 3) | ((pdu[13] & 0xe0) >> 5);
        final int segN = ((pdu[13]) & 0x1F);

        final int ttl = pdu[2] & 0x7F;
        final byte[] src = MeshParserUtils.getSrcAddress(pdu);
        final byte[] dst = MeshParserUtils.getDstAddress(pdu);

        final int blockAckSrc = MeshParserUtils.unsignedBytesToInt(dst[1], dst[0]); //Destination of the received packet would be the source for the ack
        final int blockAckDst = MeshParserUtils.unsignedBytesToInt(src[1], src[0]); //Source of the received packet would be the destination for the ack

        MeshLogger.verbose(TAG, "SEG O: " + segO);
        MeshLogger.verbose(TAG, "SEG N: " + segN);

        //Start the timer irrespective of which segment was received first
        initSegmentedControlAcknowledgementTimer(seqZero, ttl, blockAckDst, blockAckSrc, segN);
        mSegmentedControlBlockAck = BlockAcknowledgementMessage.calculateBlockAcknowledgement(mSegmentedControlBlockAck, segO);
        MeshLogger.verbose(TAG, "Block acknowledgement value for " + mSegmentedControlBlockAck + " Seg O " + segO);

        final int payloadLength = pdu.length - 10;

        final ByteBuffer payloadBuffer = ByteBuffer.allocate(payloadLength);
        payloadBuffer.put(pdu, 10, payloadLength);
        segmentedControlMessageMap.put(segO, payloadBuffer.array());

        //Check the message count against the zero-based segN;
        final int receivedSegmentedMessageCount = segmentedControlMessageMap.size() - 1;
        if (segN == receivedSegmentedMessageCount) {
            MeshLogger.verbose(TAG, "All segments received");
            //Remove the incomplete timer if all segments were received
            mHandler.removeCallbacks(mIncompleteTimerRunnable);
            MeshLogger.verbose(TAG, "Block ack sent? " + mBlockAckSent);
            if (mDuration > System.currentTimeMillis() && !mBlockAckSent) {
                if (MeshAddress.isValidUnicastAddress(dst)) {
                    mHandler.removeCallbacksAndMessages(null);
                    MeshLogger.verbose(TAG, "Cancelling Scheduled block ack and incomplete timer, sending an immediate block ack");
                    sendBlockAck(seqZero, ttl, blockAckSrc, blockAckDst, segN);
                    //mBlockAckSent = false;
                }
            }
            final int upperTransportSequenceNumber = getTransportLayerSequenceNumber(MeshParserUtils.getSequenceNumberFromPDU(pdu), seqZero);
            final byte[] sequenceNumber = MeshParserUtils.getSequenceNumberBytes(upperTransportSequenceNumber);
            final ControlMessage message = new ControlMessage();
            message.setAszmic(szmic);
            message.setSequenceNumber(sequenceNumber);
            message.setAkf(akf);
            message.setAid(aid);
            message.setSegmented(true);
            final SparseArray<byte[]> segmentedMessages = segmentedControlMessageMap.clone();
            segmentedControlMessageMap.clear();
            message.setLowerTransportControlPdu(segmentedMessages);
            return message;
        }

        return null;
    }
Parses a segmented lower transport control pdu.

@param pdu The complete pdu was received from the node. This is already de-obfuscated and decrypted at network layer.
mesh/src/main/java/no/nordicsemi/android/mesh/transport/LowerTransportLayer.java