From 97aa2c488f59fdfcde2c55f4bbffcf8db73c7d8f Mon Sep 17 00:00:00 2001 From: Angel Anton Date: Tue, 6 Jun 2017 14:08:45 +0200 Subject: [PATCH 1/5] Added APDU level fragmenter. --- .../ble/client/apdu/ApduFragmenter.java | 8 +++ .../ble/client/apdu/SimpleApduFragmenter.java | 64 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 app/src/main/java/com/fidesmo/ble/client/apdu/ApduFragmenter.java create mode 100644 app/src/main/java/com/fidesmo/ble/client/apdu/SimpleApduFragmenter.java diff --git a/app/src/main/java/com/fidesmo/ble/client/apdu/ApduFragmenter.java b/app/src/main/java/com/fidesmo/ble/client/apdu/ApduFragmenter.java new file mode 100644 index 0000000..67c6a2f --- /dev/null +++ b/app/src/main/java/com/fidesmo/ble/client/apdu/ApduFragmenter.java @@ -0,0 +1,8 @@ +package com.fidesmo.ble.client.apdu; + +public interface ApduFragmenter { + + byte[][] decode(byte[] encodedApdus); + byte[] encode(byte[][] apdus); + +} diff --git a/app/src/main/java/com/fidesmo/ble/client/apdu/SimpleApduFragmenter.java b/app/src/main/java/com/fidesmo/ble/client/apdu/SimpleApduFragmenter.java new file mode 100644 index 0000000..62a25d6 --- /dev/null +++ b/app/src/main/java/com/fidesmo/ble/client/apdu/SimpleApduFragmenter.java @@ -0,0 +1,64 @@ +package com.fidesmo.ble.client.apdu; + +import android.util.Log; + +import com.fidesmo.ble.client.BleUtils; +import com.fidesmo.ble.client.Utils; + +/** + * This class splits big byte buffer formed by a list of apdus + * into a list of single apdus. + * Spec: https://github.com/fidesmo/apdu-over-ble/blob/master/spec/apdu-service-spec.md + * + * Created by Angel Anton on 30/05/17. + */ + +public class SimpleApduFragmenter implements ApduFragmenter { + + private int TOTAL_HEADER_SIZE = 2; + private int HEADER_SIZE = 2; + + @Override + public byte[][] decode(byte[] encodedApdus) { + int totalNo = BleUtils.unpackInt2(encodedApdus, 0); + byte[][] apdus = new byte[totalNo][]; + int acc = TOTAL_HEADER_SIZE; + + for (int i = 0; i < totalNo; i++) { + int apduSize = BleUtils.unpackInt2(encodedApdus, acc); + byte[] apdu = new byte[apduSize]; + acc += HEADER_SIZE; + System.arraycopy(encodedApdus, acc, apdu, 0, apduSize); + apdus[i] = apdu; + acc += apduSize; + } + return apdus; + } + + @Override + public byte[] encode(byte[][] apdus) { + byte[] buffer = new byte[2]; + BleUtils.packInt2(apdus.length, buffer, 0); + int acc = TOTAL_HEADER_SIZE; + + for (int i = 0; i < apdus.length; i++) { + byte[] apdu = apdus[i]; + buffer = ensureBuffer(buffer, buffer.length + HEADER_SIZE + apdu.length); + BleUtils.packInt2(apdu.length, buffer, acc); + acc += HEADER_SIZE; + System.arraycopy(apdu, 0, buffer, acc, apdu.length); + acc += apdu.length; + } + + return buffer; + } + + private byte[] ensureBuffer(byte[] buffer, int size) { + if (buffer.length < size) { + byte[] oldBuf = buffer; + buffer = new byte[size]; // + 256? + System.arraycopy(oldBuf, 0, buffer, 0, oldBuf.length); + } + return buffer; + } +} From b45103100c5fdb4f9088234ababc06da5075b403 Mon Sep 17 00:00:00 2001 From: Angel Anton Date: Tue, 6 Jun 2017 14:10:39 +0200 Subject: [PATCH 2/5] Custom implementation of PacketFragmenter protocol. --- .../apdu/CustomFragmentationProtocol.java | 9 ++ .../client/apdu/CustomPacketDefragmenter.java | 16 +++ .../client/apdu/CustomPacketFragmenter.java | 123 ++++++++++++++++++ 3 files changed, 148 insertions(+) create mode 100644 app/src/main/java/com/fidesmo/ble/client/apdu/CustomFragmentationProtocol.java create mode 100644 app/src/main/java/com/fidesmo/ble/client/apdu/CustomPacketDefragmenter.java create mode 100644 app/src/main/java/com/fidesmo/ble/client/apdu/CustomPacketFragmenter.java diff --git a/app/src/main/java/com/fidesmo/ble/client/apdu/CustomFragmentationProtocol.java b/app/src/main/java/com/fidesmo/ble/client/apdu/CustomFragmentationProtocol.java new file mode 100644 index 0000000..51100bc --- /dev/null +++ b/app/src/main/java/com/fidesmo/ble/client/apdu/CustomFragmentationProtocol.java @@ -0,0 +1,9 @@ +package com.fidesmo.ble.client.apdu; + +import com.fidesmo.ble.client.protocol.PacketFragmenter; + +public interface CustomFragmentationProtocol { + PacketFragmenter fragmenter(int var1, byte[] var2); + + CustomPacketDefragmenter deframenter(); +} diff --git a/app/src/main/java/com/fidesmo/ble/client/apdu/CustomPacketDefragmenter.java b/app/src/main/java/com/fidesmo/ble/client/apdu/CustomPacketDefragmenter.java new file mode 100644 index 0000000..c6a9b62 --- /dev/null +++ b/app/src/main/java/com/fidesmo/ble/client/apdu/CustomPacketDefragmenter.java @@ -0,0 +1,16 @@ +package com.fidesmo.ble.client.apdu; + + +public interface CustomPacketDefragmenter { + void clear(); + + void append(byte[] buffer); + + void add(byte[] buffer); + + boolean complete(); + + boolean empty(); + + byte[] getBuffer(); +} \ No newline at end of file diff --git a/app/src/main/java/com/fidesmo/ble/client/apdu/CustomPacketFragmenter.java b/app/src/main/java/com/fidesmo/ble/client/apdu/CustomPacketFragmenter.java new file mode 100644 index 0000000..8eb9fcf --- /dev/null +++ b/app/src/main/java/com/fidesmo/ble/client/apdu/CustomPacketFragmenter.java @@ -0,0 +1,123 @@ +package com.fidesmo.ble.client.apdu; + + +import android.util.Log; + +import com.fidesmo.ble.client.BleUtils; +import com.fidesmo.ble.client.protocol.PacketFragmenter; +import com.fidesmo.ble.client.protocol.SimplePacketFragmenter; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class CustomPacketFragmenter implements PacketFragmenter { + public static final int HEADER_SIZE = 4; + private final int maxLength; + private final byte[] buffer; + private final int totalPackets; + private int sentPackets = 0; + + public CustomPacketFragmenter(int maxLength, byte[] buffer) { + if(maxLength <= HEADER_SIZE) { + throw new IllegalArgumentException("MTU size can not be less of equal to header size"); + } else { + this.maxLength = maxLength; + this.buffer = Arrays.copyOf(buffer, buffer.length); + int packetMax = maxLength - HEADER_SIZE; + int carriedLen = Math.max(buffer.length, 1); + this.totalPackets = carriedLen / packetMax + (carriedLen % packetMax > 0?1:0); + } + } + + public byte[] nextFragment() { + int available = this.maxLength - HEADER_SIZE; + int offset = available * this.sentPackets; + int len = Math.min(available, this.buffer.length - offset); + byte[] chunk = new byte[len + HEADER_SIZE]; + BleUtils.packInt2(this.totalPackets, chunk, 0); + BleUtils.packInt2(++this.sentPackets, chunk, HEADER_SIZE/2); + System.arraycopy(this.buffer, offset, chunk, HEADER_SIZE, len); + return chunk; + } + + public boolean hasMoreData() { + return this.sentPackets < this.totalPackets; + } + + public static CustomFragmentationProtocol factory() { + return new CustomPacketFragmenter.Factory(); + } + + private static class Factory implements CustomFragmentationProtocol { + private Factory() { + } + + public PacketFragmenter fragmenter(int mtu, byte[] buffer) { + return new CustomPacketFragmenter(mtu, buffer); + } + + public CustomPacketDefragmenter deframenter() { + return new CustomPacketFragmenter.Builder(); + } + } + + public static class Builder implements CustomPacketDefragmenter { + private int totalNo; + private int packetNo; + + List byteArray; + + private Builder() { + byteArray = new ArrayList<>(); + totalNo = 0; + packetNo = 0; + } + + public void clear(){ + byteArray.clear(); + totalNo = 0; + packetNo = 0; + } + + public void append(byte[] array){ + totalNo = BleUtils.unpackInt2(array, 0); + packetNo = BleUtils.unpackInt2(array, HEADER_SIZE/2); + byte[] buffer = new byte[array.length - HEADER_SIZE]; + System.arraycopy(array, HEADER_SIZE, buffer, 0, buffer.length); + byteArray.add(buffer); + } + + public void add(byte[] array){ + byteArray.add(array); + } + + public byte[] getBuffer(){ + byte[] retArray; + int totalSize = 0; + + for(int i=0; i < byteArray.size();i++){ + totalSize = totalSize + byteArray.get(i).length; + } + + int copuCounter = 0; + if(totalSize > 0) { + retArray = new byte[totalSize]; + for(int ii=0; ii < byteArray.size();ii++){ + byte[] tmpArr = byteArray.get(ii); + System.arraycopy(tmpArr, 0, retArray,copuCounter,tmpArr.length); + copuCounter = copuCounter + tmpArr.length; + } + }else{ + retArray = new byte[]{}; + } + return retArray; + } + + public boolean complete() { + return totalNo == packetNo; + } + + public boolean empty() { return totalNo == 0 && packetNo == 0; } + } +} From f8163e01b86d7dff5944aa9d454b0de620f4b0a4 Mon Sep 17 00:00:00 2001 From: Angel Anton Date: Tue, 6 Jun 2017 14:19:40 +0200 Subject: [PATCH 3/5] Applied APDU fragmenter in received-sent data. --- .../java/com/fidesmo/ble/client/MainActivity.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/fidesmo/ble/client/MainActivity.java b/app/src/main/java/com/fidesmo/ble/client/MainActivity.java index 4f7ce4c..be99bd7 100644 --- a/app/src/main/java/com/fidesmo/ble/client/MainActivity.java +++ b/app/src/main/java/com/fidesmo/ble/client/MainActivity.java @@ -23,6 +23,7 @@ import android.widget.Toast; import com.fidesmo.ble.R; import com.fidesmo.ble.client.apdu.CardInfoClient; +import com.fidesmo.ble.client.apdu.SimpleApduFragmenter; import com.fidesmo.ble.client.models.CardInfo; import com.fidesmo.ble.client.models.CardOperation; import nordpol.IsoCard; @@ -50,6 +51,8 @@ public class MainActivity extends AppCompatActivity implements OnDiscoveredTagLi private LinkedList pendingOperations = new LinkedList<>(); + private SimpleApduFragmenter apduFragmenter = new SimpleApduFragmenter(); + private BroadcastReceiver apduReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -101,7 +104,6 @@ public void onReceive(Context context, Intent intent) { nfcTagDispatcher = TagDispatcher.get(this, this, false, false, false, true, false, true); } - @Override public void tagDiscovered(Tag tag) { try { @@ -271,9 +273,12 @@ private void processPendingCardOperations() { } Log.i(TAG, "Trying to transcieve data to a card: " + byteArrayToString(operation.getRequest())); - - byte[] result = nfcCard.transceive(operation.getRequest()); - operation.setResponse(result); + byte[][] apdus = apduFragmenter.decode(operation.getRequest()); + byte[][] response = new byte[apdus.length][]; + for (int i = 0; i < apdus.length; i ++) { + response[i] = nfcCard.transceive(apdus[i]); + } + operation.setResponse(apduFragmenter.encode(response)); sendResponse(operation); operation = pendingOperations.poll(); From 62082743cef04fa22dd052dcda1d436fab0b0dd4 Mon Sep 17 00:00:00 2001 From: Angel Anton Date: Tue, 6 Jun 2017 14:23:22 +0200 Subject: [PATCH 4/5] Refactored the read-write characteristic handlers. --- .../ble/client/BlePeripheralService.java | 103 ++++++++++-------- 1 file changed, 55 insertions(+), 48 deletions(-) diff --git a/app/src/main/java/com/fidesmo/ble/client/BlePeripheralService.java b/app/src/main/java/com/fidesmo/ble/client/BlePeripheralService.java index 21b60fe..48dd157 100644 --- a/app/src/main/java/com/fidesmo/ble/client/BlePeripheralService.java +++ b/app/src/main/java/com/fidesmo/ble/client/BlePeripheralService.java @@ -17,12 +17,17 @@ import android.support.v4.content.LocalBroadcastManager; import android.util.Log; import android.widget.Toast; + +import com.fidesmo.ble.client.apdu.CustomFragmentationProtocol; +import com.fidesmo.ble.client.apdu.CustomPacketDefragmenter; +import com.fidesmo.ble.client.apdu.CustomPacketFragmenter; import com.fidesmo.ble.client.protocol.FragmentationProtocol; import com.fidesmo.ble.client.protocol.PacketDefragmenter; import com.fidesmo.ble.client.protocol.PacketFragmenter; -import com.fidesmo.ble.client.protocol.SimplePacketFragmenter; +import java.util.ArrayList; import java.util.LinkedList; +import java.util.List; import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicLong; @@ -67,9 +72,9 @@ public class BlePeripheralService extends Service { private LinkedList messagesList = new LinkedList<>(); - private FragmentationProtocol fragmentationProtocol = SimplePacketFragmenter.factory(); + private CustomFragmentationProtocol fragmentationProtocol = CustomPacketFragmenter.factory(); private PacketFragmenter currentResponsePacket; - private PacketDefragmenter currentPacketBuilder; + private CustomPacketDefragmenter currentPacketBuilder = fragmentationProtocol.deframenter(); private int mtu = 512; private AtomicLong requestId = new AtomicLong(0); @@ -213,28 +218,17 @@ public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, i return ; } + if (characteristic.getUuid().equals(BleCard.APDU_READ_CHARACTERISTIC_UUID) && currentResponsePacket != null) { - if (!characteristic.getUuid().equals(BleCard.APDU_READ_CHARACTERISTIC_UUID)) { - gattServer.sendResponse(device, requestId, BluetoothGatt.GATT_FAILURE, 0, null); - log("Unsupported characteristics read: " + characteristic.getUuid()); - return ; - } - - if (currentResponsePacket == null) { - log("No answer ready yet"); - gattServer.sendResponse(device, requestId, BluetoothGatt.GATT_FAILURE, 0, null); - return; - } - - if (currentResponsePacket.hasMoreData()) { - gattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, currentResponsePacket.nextFragment()); - } else { - gattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, new byte[]{0}); - } - + if (offset == 0 && currentResponsePacket.hasMoreData()) { + // save Fidesmo's internal packet inside characteristic + characteristic.setValue(currentResponsePacket.nextFragment()); + } - if (!currentResponsePacket.hasMoreData()) { - currentResponsePacket = null; + int chunkSize = characteristic.getValue().length - offset; + byte[] chunk = new byte[chunkSize]; + System.arraycopy(characteristic.getValue(), offset, chunk, 0, chunkSize); + gattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, chunk); } } @@ -249,37 +243,20 @@ public void onCharacteristicWriteRequest(final BluetoothDevice device, final int ", flags: prepared=" + preparedWrite + ", respNeeded=" + responseNeeded + ", offset: " + offset ); - if (responseNeeded) { - BleUtils.retryCall(new Callable() { - @Override - public Boolean call() throws Exception { - return gattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, new byte[]{0}); - } - }); - } - - if (offset != 0) { - log("Offset is not zero: " + offset); - return; - } - if(APDU_CONVERSATION_FINISHED_CHARACTERISTIC_UUID.equals(characteristic.getUuid())) { finishConversation(); return; } - - if (currentPacketBuilder == null) { - log("Starting APDU request session"); - currentPacketBuilder = fragmentationProtocol.deframenter(); + if (preparedWrite) { + onWriteBuffer(value); + }else { + onWritePacket(value); } - currentPacketBuilder.append(value); - - if (currentPacketBuilder.complete()) { - log("Packet received"); - sendBleAPDUToActivity(currentPacketBuilder.getBuffer()); - currentPacketBuilder = null; + if (gattServer != null && responseNeeded) { + // need to give the same values we got as an reply, in order to get next possible part. + gattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, value); } } @@ -300,8 +277,10 @@ public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, Blue @Override public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) { + super.onExecuteWrite(device, requestId, execute); log("onExecuteWrite(" + requestId + "), execute: " + execute); - gattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, null); + gattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, new byte[] {}); + onExecuteWriteBuffer(execute); } @Override @@ -370,6 +349,34 @@ public void onMtuChanged(BluetoothDevice device, int mtu) { } } + private void onWriteBuffer(byte[] buffer) { + if (currentPacketBuilder.empty()) { + currentPacketBuilder.append(buffer); + } else { + currentPacketBuilder.add(buffer); + } + } + + private void onWritePacket(byte[] buffer) { + currentPacketBuilder.append(buffer); + onApduBufferReady(); + } + + private void onExecuteWriteBuffer(boolean execute) { + if (execute) { + onApduBufferReady(); + } else { + currentPacketBuilder.clear(); + } + } + + private void onApduBufferReady() { + if (currentPacketBuilder.complete()) { + sendBleAPDUToActivity(currentPacketBuilder.getBuffer()); + currentPacketBuilder.clear(); + } + } + private void finishConversation() { Intent intent = new Intent(BlePeripheralService.CONVERSATION_FINISHED); LocalBroadcastManager.getInstance(BlePeripheralService.this).sendBroadcast(intent); From 8df3bf4e1e27b8fc153e156f7e09320fabe078b2 Mon Sep 17 00:00:00 2001 From: Angel Anton Date: Thu, 8 Jun 2017 17:34:36 +0200 Subject: [PATCH 5/5] Updated to use android-ble-client 0.1.11 --- app/build.gradle | 6 +- .../ble/client/BlePeripheralService.java | 32 ++--- .../apdu/CustomFragmentationProtocol.java | 9 -- .../client/apdu/CustomPacketDefragmenter.java | 16 --- .../client/apdu/CustomPacketFragmenter.java | 123 ------------------ 5 files changed, 21 insertions(+), 165 deletions(-) delete mode 100644 app/src/main/java/com/fidesmo/ble/client/apdu/CustomFragmentationProtocol.java delete mode 100644 app/src/main/java/com/fidesmo/ble/client/apdu/CustomPacketDefragmenter.java delete mode 100644 app/src/main/java/com/fidesmo/ble/client/apdu/CustomPacketFragmenter.java diff --git a/app/build.gradle b/app/build.gradle index a80f346..707a885 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -23,11 +23,15 @@ android { if (project.hasProperty('strictCheck')) { warningsAsErrors = strictCheck } + textReport true } } repositories { + maven { + url "file://${System.properties['user.home']}/.m2/repository" + } maven { url 'http://releases.marmeladburk.fidesmo.com' } @@ -45,6 +49,6 @@ dependencies { testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:25.3.1' compile 'io.reactivex:rxjava:1.0.13' - compile 'com.fidesmo:ble-client-android:0.1.10' + compile 'com.fidesmo:ble-client-android:0.1.11' compile 'com.fidesmo:nordpol-android:0.1.18' } diff --git a/app/src/main/java/com/fidesmo/ble/client/BlePeripheralService.java b/app/src/main/java/com/fidesmo/ble/client/BlePeripheralService.java index 48dd157..3d12e73 100644 --- a/app/src/main/java/com/fidesmo/ble/client/BlePeripheralService.java +++ b/app/src/main/java/com/fidesmo/ble/client/BlePeripheralService.java @@ -18,16 +18,12 @@ import android.util.Log; import android.widget.Toast; -import com.fidesmo.ble.client.apdu.CustomFragmentationProtocol; -import com.fidesmo.ble.client.apdu.CustomPacketDefragmenter; -import com.fidesmo.ble.client.apdu.CustomPacketFragmenter; import com.fidesmo.ble.client.protocol.FragmentationProtocol; import com.fidesmo.ble.client.protocol.PacketDefragmenter; import com.fidesmo.ble.client.protocol.PacketFragmenter; +import com.fidesmo.ble.client.protocol.SimplePacketFragmenter; -import java.util.ArrayList; import java.util.LinkedList; -import java.util.List; import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicLong; @@ -72,9 +68,9 @@ public class BlePeripheralService extends Service { private LinkedList messagesList = new LinkedList<>(); - private CustomFragmentationProtocol fragmentationProtocol = CustomPacketFragmenter.factory(); + private FragmentationProtocol fragmentationProtocol = SimplePacketFragmenter.factory(); private PacketFragmenter currentResponsePacket; - private CustomPacketDefragmenter currentPacketBuilder = fragmentationProtocol.deframenter(); + private PacketDefragmenter currentPacketBuilder; private int mtu = 512; private AtomicLong requestId = new AtomicLong(0); @@ -350,30 +346,34 @@ public void onMtuChanged(BluetoothDevice device, int mtu) { } private void onWriteBuffer(byte[] buffer) { - if (currentPacketBuilder.empty()) { - currentPacketBuilder.append(buffer); + if (currentPacketBuilder == null) { + currentPacketBuilder = fragmentationProtocol.deframenter(); + currentPacketBuilder.appendPacket(buffer); } else { - currentPacketBuilder.add(buffer); + currentPacketBuilder.addPacketFragment(buffer); } } private void onWritePacket(byte[] buffer) { - currentPacketBuilder.append(buffer); - onApduBufferReady(); + if (currentPacketBuilder == null) { + currentPacketBuilder = fragmentationProtocol.deframenter(); + currentPacketBuilder.appendPacket(buffer); + onApduBufferReady(); + } } private void onExecuteWriteBuffer(boolean execute) { if (execute) { onApduBufferReady(); } else { - currentPacketBuilder.clear(); + currentPacketBuilder = null; } } private void onApduBufferReady() { - if (currentPacketBuilder.complete()) { - sendBleAPDUToActivity(currentPacketBuilder.getBuffer()); - currentPacketBuilder.clear(); + if (currentPacketBuilder.isCompleted()) { + sendBleAPDUToActivity(currentPacketBuilder.fullData()); + currentPacketBuilder = null; } } diff --git a/app/src/main/java/com/fidesmo/ble/client/apdu/CustomFragmentationProtocol.java b/app/src/main/java/com/fidesmo/ble/client/apdu/CustomFragmentationProtocol.java deleted file mode 100644 index 51100bc..0000000 --- a/app/src/main/java/com/fidesmo/ble/client/apdu/CustomFragmentationProtocol.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.fidesmo.ble.client.apdu; - -import com.fidesmo.ble.client.protocol.PacketFragmenter; - -public interface CustomFragmentationProtocol { - PacketFragmenter fragmenter(int var1, byte[] var2); - - CustomPacketDefragmenter deframenter(); -} diff --git a/app/src/main/java/com/fidesmo/ble/client/apdu/CustomPacketDefragmenter.java b/app/src/main/java/com/fidesmo/ble/client/apdu/CustomPacketDefragmenter.java deleted file mode 100644 index c6a9b62..0000000 --- a/app/src/main/java/com/fidesmo/ble/client/apdu/CustomPacketDefragmenter.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.fidesmo.ble.client.apdu; - - -public interface CustomPacketDefragmenter { - void clear(); - - void append(byte[] buffer); - - void add(byte[] buffer); - - boolean complete(); - - boolean empty(); - - byte[] getBuffer(); -} \ No newline at end of file diff --git a/app/src/main/java/com/fidesmo/ble/client/apdu/CustomPacketFragmenter.java b/app/src/main/java/com/fidesmo/ble/client/apdu/CustomPacketFragmenter.java deleted file mode 100644 index 8eb9fcf..0000000 --- a/app/src/main/java/com/fidesmo/ble/client/apdu/CustomPacketFragmenter.java +++ /dev/null @@ -1,123 +0,0 @@ -package com.fidesmo.ble.client.apdu; - - -import android.util.Log; - -import com.fidesmo.ble.client.BleUtils; -import com.fidesmo.ble.client.protocol.PacketFragmenter; -import com.fidesmo.ble.client.protocol.SimplePacketFragmenter; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -public class CustomPacketFragmenter implements PacketFragmenter { - public static final int HEADER_SIZE = 4; - private final int maxLength; - private final byte[] buffer; - private final int totalPackets; - private int sentPackets = 0; - - public CustomPacketFragmenter(int maxLength, byte[] buffer) { - if(maxLength <= HEADER_SIZE) { - throw new IllegalArgumentException("MTU size can not be less of equal to header size"); - } else { - this.maxLength = maxLength; - this.buffer = Arrays.copyOf(buffer, buffer.length); - int packetMax = maxLength - HEADER_SIZE; - int carriedLen = Math.max(buffer.length, 1); - this.totalPackets = carriedLen / packetMax + (carriedLen % packetMax > 0?1:0); - } - } - - public byte[] nextFragment() { - int available = this.maxLength - HEADER_SIZE; - int offset = available * this.sentPackets; - int len = Math.min(available, this.buffer.length - offset); - byte[] chunk = new byte[len + HEADER_SIZE]; - BleUtils.packInt2(this.totalPackets, chunk, 0); - BleUtils.packInt2(++this.sentPackets, chunk, HEADER_SIZE/2); - System.arraycopy(this.buffer, offset, chunk, HEADER_SIZE, len); - return chunk; - } - - public boolean hasMoreData() { - return this.sentPackets < this.totalPackets; - } - - public static CustomFragmentationProtocol factory() { - return new CustomPacketFragmenter.Factory(); - } - - private static class Factory implements CustomFragmentationProtocol { - private Factory() { - } - - public PacketFragmenter fragmenter(int mtu, byte[] buffer) { - return new CustomPacketFragmenter(mtu, buffer); - } - - public CustomPacketDefragmenter deframenter() { - return new CustomPacketFragmenter.Builder(); - } - } - - public static class Builder implements CustomPacketDefragmenter { - private int totalNo; - private int packetNo; - - List byteArray; - - private Builder() { - byteArray = new ArrayList<>(); - totalNo = 0; - packetNo = 0; - } - - public void clear(){ - byteArray.clear(); - totalNo = 0; - packetNo = 0; - } - - public void append(byte[] array){ - totalNo = BleUtils.unpackInt2(array, 0); - packetNo = BleUtils.unpackInt2(array, HEADER_SIZE/2); - byte[] buffer = new byte[array.length - HEADER_SIZE]; - System.arraycopy(array, HEADER_SIZE, buffer, 0, buffer.length); - byteArray.add(buffer); - } - - public void add(byte[] array){ - byteArray.add(array); - } - - public byte[] getBuffer(){ - byte[] retArray; - int totalSize = 0; - - for(int i=0; i < byteArray.size();i++){ - totalSize = totalSize + byteArray.get(i).length; - } - - int copuCounter = 0; - if(totalSize > 0) { - retArray = new byte[totalSize]; - for(int ii=0; ii < byteArray.size();ii++){ - byte[] tmpArr = byteArray.get(ii); - System.arraycopy(tmpArr, 0, retArray,copuCounter,tmpArr.length); - copuCounter = copuCounter + tmpArr.length; - } - }else{ - retArray = new byte[]{}; - } - return retArray; - } - - public boolean complete() { - return totalNo == packetNo; - } - - public boolean empty() { return totalNo == 0 && packetNo == 0; } - } -}