7878import io .calimero .log .LogService ;
7979import io .calimero .mgmt .ManagementClient .EraseCode ;
8080import io .calimero .mgmt .ManagementClient .TestResult ;
81+ import io .calimero .mgmt .ManagementClientImpl .SupportedServiceGroup ;
8182import io .calimero .mgmt .PropertyAccess .PID ;
8283import io .calimero .secure .SecureApplicationLayer ;
8384import io .calimero .secure .Security ;
@@ -653,8 +654,11 @@ public void writeMemory(final IndividualAddress device, final long startAddress,
653654 "verify write and verify by server not both applicable" );
654655
655656 final Destination d = getOrCreateDestination (device , false , verifyByServer );
657+ final boolean extMemoryServices = ((ManagementClientImpl ) mc ).supportsFeature (d , SupportedServiceGroup .ExtMemory );
658+
656659 // if automatic server verification is requested, turn verify flag on
657- if (verifyByServer ) {
660+ // with extended memory services, the verify mode setting of the server is ignored
661+ if (!extMemoryServices && verifyByServer ) {
658662 // reading description checks whether property exists
659663 /* final byte[] desc = */ mc .readPropertyDesc (d , DEVICE_OBJECT_INDEX ,
660664 PropertyAccess .PID .DEVICE_CONTROL , 0 );
@@ -668,7 +672,7 @@ public void writeMemory(final IndividualAddress device, final long startAddress,
668672 }
669673
670674 // write memory in chunks with a maximum length of asduLength
671- final int asduLength = readMaxAsduLength ( d );
675+ final int asduLength = maxApduLength ( d ) - ( extMemoryServices ? 5 : 3 );
672676 for (int i = 0 ; i < data .length ; i += asduLength ) {
673677 int remainingBytes = data .length - i ;
674678 final byte [] range = Arrays .copyOfRange (data , i , i + Math .min (asduLength , remainingBytes ));
@@ -699,9 +703,10 @@ public byte[] readMemory(final IndividualAddress device, final long startAddress
699703 // + "(hope you know what you are doing)");
700704
701705 final Destination d = getOrCreateDestination (device );
706+ final boolean extMemoryServices = ((ManagementClientImpl ) mc ).supportsFeature (d , SupportedServiceGroup .ExtMemory );
702707
703708 final byte [] read = new byte [bytes ];
704- final int asduLength = readMaxAsduLength ( d );
709+ final int asduLength = maxApduLength ( d ) - ( extMemoryServices ? 5 : 3 );
705710 for (int i = 0 ; i < read .length ; i += asduLength ) {
706711 final int size = i + asduLength <= read .length ? asduLength : read .length - i ;
707712 final byte [] range = mc .readMemory (d , (int ) startAddress + i , size );
@@ -914,16 +919,13 @@ private void sendDD0Read(final Destination dst) throws KNXLinkClosedException {
914919 catch (final KNXDisconnectException ignore ) {}
915920 }
916921
917- private int readMaxAsduLength (final Destination d ) throws InterruptedException
922+ private int maxApduLength (final Destination d ) throws InterruptedException
918923 {
919- // asdu is 3 bytes shorter than apdu
920924 try {
921- final byte [] data = mc .readProperty (d , DEVICE_OBJECT_INDEX ,
922- PropertyAccess .PID .MAX_APDULENGTH , 1 , 1 );
923- return toUnsigned (data ) - 3 ;
925+ return ((ManagementClientImpl ) mc ).maxApduLength (d );
924926 }
925- catch (final KNXException e ) {
926- return defaultApduLength - 3 ;
927+ catch (final KNXLinkClosedException e ) {
928+ return defaultApduLength ;
927929 }
928930 }
929931
0 commit comments