From 88072ea752348022ef137ed616d90d86a6b9cc4b Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 1 Jul 2022 11:36:28 +0200 Subject: [PATCH] RFSpyReader -> kt --- .../pump/medtronic/MedtronicPumpPlugin.kt | 17 +-- .../common/hw/rileylink/ble/RFSpyReader.java | 127 ------------------ .../common/hw/rileylink/ble/RFSpyReader.kt | 98 ++++++++++++++ 3 files changed, 102 insertions(+), 140 deletions(-) delete mode 100644 rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyReader.java create mode 100644 rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyReader.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt index 01ff035702..ba19c40278 100644 --- a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt +++ b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt @@ -20,6 +20,7 @@ import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification import info.nightscout.androidaps.plugins.pump.common.PumpPluginAbstract +import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus import info.nightscout.androidaps.plugins.pump.common.defs.PumpDriverState import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.plugins.pump.common.events.EventRefreshButtonState @@ -54,8 +55,6 @@ import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil.Comp import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.TimeChangeType -import info.nightscout.androidaps.interfaces.ResourceHelper -import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag @@ -306,12 +305,8 @@ class MedtronicPumpPlugin @Inject constructor( private val isPumpNotReachable: Boolean get() { val rileyLinkServiceState = rileyLinkServiceData.rileyLinkServiceState - if (rileyLinkServiceState == null) { - aapsLogger.debug(LTag.PUMP, "RileyLink unreachable. RileyLinkServiceState is null.") - return false - } - if (rileyLinkServiceState != RileyLinkServiceState.PumpConnectorReady // - && rileyLinkServiceState != RileyLinkServiceState.RileyLinkReady // + if (rileyLinkServiceState != RileyLinkServiceState.PumpConnectorReady + && rileyLinkServiceState != RileyLinkServiceState.RileyLinkReady && rileyLinkServiceState != RileyLinkServiceState.TuneUpDevice ) { aapsLogger.debug(LTag.PUMP, "RileyLink unreachable.") @@ -998,11 +993,7 @@ class MedtronicPumpPlugin @Inject constructor( } @Synchronized - private fun workWithStatusRefresh( - action: StatusRefreshAction, // - statusRefreshType: MedtronicStatusRefreshType?, // - time: Long? - ): Map? { + private fun workWithStatusRefresh(action: StatusRefreshAction, statusRefreshType: MedtronicStatusRefreshType?, time: Long?): Map? { return when (action) { StatusRefreshAction.Add -> { statusRefreshMap[statusRefreshType!!] = time!! diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyReader.java b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyReader.java deleted file mode 100644 index 9e3a094a9c..0000000000 --- a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyReader.java +++ /dev/null @@ -1,127 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble; - -import android.os.SystemClock; - -import java.util.UUID; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; - -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.GattAttributes; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkEncodingType; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations.BLECommOperationResult; -import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.common.utils.ThreadUtil; -import info.nightscout.shared.logging.AAPSLogger; -import info.nightscout.shared.logging.LTag; - -/** - * Created by geoff on 5/26/16. - */ -public class RFSpyReader { - - private final AAPSLogger aapsLogger; - ExecutorService executor = Executors.newSingleThreadExecutor(); - private final RileyLinkBLE rileyLinkBle; - private final Semaphore waitForRadioData = new Semaphore(0, true); - private final LinkedBlockingQueue mDataQueue = new LinkedBlockingQueue<>(); - private int acquireCount = 0; - private int releaseCount = 0; - private boolean stopAtNull = true; - - - RFSpyReader(AAPSLogger aapsLogger, RileyLinkBLE rileyLinkBle) { - this.aapsLogger = aapsLogger; - this.rileyLinkBle = rileyLinkBle; - } - - - void setRileyLinkEncodingType(RileyLinkEncodingType encodingType) { - aapsLogger.debug("setRileyLinkEncodingType: " + encodingType); - stopAtNull = !(encodingType == RileyLinkEncodingType.Manchester || // - encodingType == RileyLinkEncodingType.FourByteSixByteRileyLink); - } - - - // This timeout must be coordinated with the length of the RFSpy radio operation or Bad Things Happen. - byte[] poll(int timeout_ms) { - aapsLogger.debug(LTag.PUMPBTCOMM, ThreadUtil.sig() + "Entering poll at t==" + SystemClock.uptimeMillis() + ", timeout is " + timeout_ms - + " mDataQueue size is " + mDataQueue.size()); - - if (mDataQueue.isEmpty()) { - try { - // block until timeout or data available. - // returns null if timeout. - byte[] dataFromQueue = mDataQueue.poll(timeout_ms, TimeUnit.MILLISECONDS); - if (dataFromQueue != null) { - aapsLogger.debug(LTag.PUMPBTCOMM, "Got data [" + ByteUtil.shortHexString(dataFromQueue) + "] at t==" - + SystemClock.uptimeMillis()); - } else { - aapsLogger.debug(LTag.PUMPBTCOMM, "Got data [null] at t==" + SystemClock.uptimeMillis()); - } - return dataFromQueue; - } catch (InterruptedException e) { - aapsLogger.error(LTag.PUMPBTCOMM, "poll: Interrupted waiting for data"); - } - } - - return null; - } - - - // Call this from the "response count" notification handler. - void newDataIsAvailable() { - releaseCount++; - - aapsLogger.debug(LTag.PUMPBTCOMM, ThreadUtil.sig() + "waitForRadioData released(count=" + releaseCount + ") at t=" - + SystemClock.uptimeMillis()); - waitForRadioData.release(); - } - - - public void start() { - executor.execute(() -> { - UUID serviceUUID = UUID.fromString(GattAttributes.SERVICE_RADIO); - UUID radioDataUUID = UUID.fromString(GattAttributes.CHARA_RADIO_DATA); - BLECommOperationResult result; - //noinspection InfiniteLoopStatement - while (true) { - try { - acquireCount++; - waitForRadioData.acquire(); - aapsLogger.debug(LTag.PUMPBTCOMM, ThreadUtil.sig() + "waitForRadioData acquired (count=" + acquireCount + ") at t=" - + SystemClock.uptimeMillis()); - SystemClock.sleep(100); - SystemClock.sleep(1); - result = rileyLinkBle.readCharacteristicBlocking(serviceUUID, radioDataUUID); - SystemClock.sleep(100); - - if (result.resultCode == BLECommOperationResult.RESULT_SUCCESS) { - if (stopAtNull) { - // only data up to the first null is valid - for (int i = 0; i < result.value.length; i++) { - if (result.value[i] == 0) { - result.value = ByteUtil.substring(result.value, 0, i); - break; - } - } - } - mDataQueue.add(result.value); - } else if (result.resultCode == BLECommOperationResult.RESULT_INTERRUPTED) { - aapsLogger.error(LTag.PUMPBTCOMM, "Read operation was interrupted"); - } else if (result.resultCode == BLECommOperationResult.RESULT_TIMEOUT) { - aapsLogger.error(LTag.PUMPBTCOMM, "Read operation on Radio Data timed out"); - } else if (result.resultCode == BLECommOperationResult.RESULT_BUSY) { - aapsLogger.error(LTag.PUMPBTCOMM, "FAIL: RileyLinkBLE reports operation already in progress"); - } else if (result.resultCode == BLECommOperationResult.RESULT_NONE) { - aapsLogger.error(LTag.PUMPBTCOMM, "FAIL: got invalid result code: " + result.resultCode); - } - } catch (InterruptedException e) { - aapsLogger.error(LTag.PUMPBTCOMM, "Interrupted while waiting for data"); - } - } - }); - } -} diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyReader.kt b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyReader.kt new file mode 100644 index 0000000000..62abb3fd8e --- /dev/null +++ b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyReader.kt @@ -0,0 +1,98 @@ +package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble + +import android.os.SystemClock +import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.GattAttributes +import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkEncodingType +import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations.BLECommOperationResult +import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil +import info.nightscout.androidaps.plugins.pump.common.utils.ThreadUtil +import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.shared.logging.LTag +import java.util.* +import java.util.concurrent.Executors +import java.util.concurrent.LinkedBlockingQueue +import java.util.concurrent.Semaphore +import java.util.concurrent.TimeUnit + +/** + * Created by geoff on 5/26/16. + */ +class RFSpyReader internal constructor(private val aapsLogger: AAPSLogger, private val rileyLinkBle: RileyLinkBLE) { + + private var executor = Executors.newSingleThreadExecutor() + private val waitForRadioData = Semaphore(0, true) + private val mDataQueue = LinkedBlockingQueue() + private var acquireCount = 0 + private var releaseCount = 0 + private var stopAtNull = true + fun setRileyLinkEncodingType(encodingType: RileyLinkEncodingType) { + aapsLogger.debug("setRileyLinkEncodingType: $encodingType") + stopAtNull = !(encodingType == RileyLinkEncodingType.Manchester || encodingType == RileyLinkEncodingType.FourByteSixByteRileyLink) + } + + // This timeout must be coordinated with the length of the RFSpy radio operation or Bad Things Happen. + fun poll(timeout_ms: Int): ByteArray? { + aapsLogger.debug(LTag.PUMPBTCOMM, "${ThreadUtil.sig()}Entering poll at t==${SystemClock.uptimeMillis()}, timeout is $timeout_ms mDataQueue size is ${mDataQueue.size}") + if (mDataQueue.isEmpty()) { + try { + // block until timeout or data available. + // returns null if timeout. + val dataFromQueue = mDataQueue.poll(timeout_ms.toLong(), TimeUnit.MILLISECONDS) + if (dataFromQueue != null) + aapsLogger.debug(LTag.PUMPBTCOMM, "Got data [${ByteUtil.shortHexString(dataFromQueue)}] at t==${SystemClock.uptimeMillis()}") + else + aapsLogger.debug(LTag.PUMPBTCOMM, "Got data [null] at t==" + SystemClock.uptimeMillis()) + return dataFromQueue + } catch (e: InterruptedException) { + aapsLogger.error(LTag.PUMPBTCOMM, "poll: Interrupted waiting for data") + } + } + return null + } + + // Call this from the "response count" notification handler. + fun newDataIsAvailable() { + releaseCount++ + aapsLogger.debug(LTag.PUMPBTCOMM, "${ThreadUtil.sig()}waitForRadioData released(count=$releaseCount) at t=${SystemClock.uptimeMillis()}") + waitForRadioData.release() + } + + fun start() { + executor.execute { + val serviceUUID = UUID.fromString(GattAttributes.SERVICE_RADIO) + val radioDataUUID = UUID.fromString(GattAttributes.CHARA_RADIO_DATA) + var result: BLECommOperationResult + while (true) { + try { + acquireCount++ + waitForRadioData.acquire() + aapsLogger.debug(LTag.PUMPBTCOMM, "${ThreadUtil.sig()}waitForRadioData acquired (count=$acquireCount) at t=${SystemClock.uptimeMillis()}") + SystemClock.sleep(100) + result = rileyLinkBle.readCharacteristicBlocking(serviceUUID, radioDataUUID) + SystemClock.sleep(100) + if (result.resultCode == BLECommOperationResult.RESULT_SUCCESS) { + if (stopAtNull) { + // only data up to the first null is valid + for (i in result.value.indices) { + if (result.value[i].toInt() == 0) { + result.value = ByteUtil.substring(result.value, 0, i) + break + } + } + } + mDataQueue.add(result.value) + } else if (result.resultCode == BLECommOperationResult.RESULT_INTERRUPTED) + aapsLogger.error(LTag.PUMPBTCOMM, "Read operation was interrupted") + else if (result.resultCode == BLECommOperationResult.RESULT_TIMEOUT) + aapsLogger.error(LTag.PUMPBTCOMM, "Read operation on Radio Data timed out") + else if (result.resultCode == BLECommOperationResult.RESULT_BUSY) + aapsLogger.error(LTag.PUMPBTCOMM, "FAIL: RileyLinkBLE reports operation already in progress") + else if (result.resultCode == BLECommOperationResult.RESULT_NONE) + aapsLogger.error(LTag.PUMPBTCOMM, "FAIL: got invalid result code: ${result.resultCode}") + } catch (e: InterruptedException) { + aapsLogger.error(LTag.PUMPBTCOMM, "Interrupted while waiting for data") + } + } + } + } +} \ No newline at end of file