@VisibleForTesting
    private AccessMessage parseAccessMessage(@NonNull final NetworkKey key,
                                             @NonNull final byte[] data,
                                             @NonNull final byte[] networkHeader,
                                             @NonNull final byte[] decryptedNetworkPayload,
                                             final int src,
                                             @NonNull final byte[] sequenceNumber,
                                             int ivIndex) throws ExtendedInvalidCipherTextException {
        try {
            int receivedTtl = networkHeader[0] & 0x7F;
            final int dst = MeshParserUtils.unsignedBytesToInt(decryptedNetworkPayload[1], decryptedNetworkPayload[0]);
            MeshLogger.verbose(TAG, "Dst: " + MeshAddress.formatAddress(dst, true));

            if (isSegmentedMessage(decryptedNetworkPayload[2])) {
                MeshLogger.verbose(TAG, "Received a segmented access message from: " + MeshAddress.formatAddress(src, false));

                //Check if the received segmented message is from the same src as the previous segment
                //Ideal case this check is not needed but let's leave it for now.
                if (!mMeshNode.hasUnicastAddress(src)) {
                    MeshLogger.verbose(TAG, "Segment received is from a different src than the one we are processing, let's drop it");
                    return null;
                }

                if (segmentedAccessMessagesMessages == null) {
                    segmentedAccessMessagesMessages = new SparseArray<>();
                    segmentedAccessMessagesMessages.put(0, data);
                } else {
                    final int k = segmentedAccessMessagesMessages.size();
                    segmentedAccessMessagesMessages.put(k, data);
                }
                //Removing the mDst here
                final byte[] pdu = ByteBuffer.allocate(2 + networkHeader.length + decryptedNetworkPayload.length)
                        .order(ByteOrder.BIG_ENDIAN)
                        .put(data, 0, 2)
                        .put(networkHeader)
                        .put(decryptedNetworkPayload)
                        .array();

                // Spec states, section 3.5.2.4 page 77
                // If the received segments were sent with TTL set to 0, it is recommended that the
                // corresponding Segment Acknowledgment message is sent with TTL set to 0.
                final int ttl = receivedTtl == 0 ? receivedTtl : mNetworkLayerCallbacks.getProvisioner().getGlobalTtl();
                final AccessMessage message = parseSegmentedAccessLowerTransportPDU(ttl, pdu, ivIndex, sequenceNumber);

                if (message != null) {
                    final SparseArray<byte[]> segmentedMessages = segmentedAccessMessagesMessages.clone();
                    segmentedAccessMessagesMessages = null;
                    message.setNetworkKey(key);
                    message.setIvIndex(MeshParserUtils.intToBytes(ivIndex));
                    message.setNetworkLayerPdu(segmentedMessages);
                    message.setTtl(receivedTtl);
                    message.setSrc(src);
                    message.setDst(dst);
                    parseUpperTransportPDU(message);
                    parseAccessLayerPDU(message);
                }
                return message;

            } else {

                //Removing the mDst here
                final byte[] pdu = ByteBuffer.allocate(2 + networkHeader.length + decryptedNetworkPayload.length)
                        .order(ByteOrder.BIG_ENDIAN)
                        .put(data, 0, 2)
                        .put(networkHeader)
                        .put(decryptedNetworkPayload)
                        .array();
                final AccessMessage message = parseUnsegmentedAccessLowerTransportPDU(pdu, ivIndex, sequenceNumber);
                if (message == null)
                    return null;
                message.setNetworkKey(key);
                message.setIvIndex(MeshParserUtils.intToBytes(ivIndex));
                final SparseArray<byte[]> pduArray = new SparseArray<>();
                pduArray.put(0, data);
                message.setNetworkLayerPdu(pduArray);
                message.setTtl(receivedTtl);
                message.setSrc(src);
                message.setDst(dst);
                message.setSequenceNumber(sequenceNumber);
                parseUpperTransportPDU(message);
                parseAccessLayerPDU(message);
                return message;
            }
        } catch (InvalidCipherTextException ex) {
            throw new ExtendedInvalidCipherTextException(ex.getMessage(), ex.getCause(), TAG);
        }
    }
Parses access message

@param key                     Network Key used to decrypt
@param data                    Received from the node.
@param networkHeader           De-obfuscated network header.
@param decryptedNetworkPayload Decrypted network payload.
@param src                     Source address.
@param sequenceNumber          Sequence number of the received message.
@param ivIndex                 IV Index used for decryption.
@return access message
mesh/src/main/java/no/nordicsemi/android/mesh/transport/NetworkLayer.java