Class BlePsFtpClient
-
- All Implemented Interfaces:
public final class BlePsFtpClient extends BleGattBase
Polar simple file transfer client declaration.
Operations (request, query, write, sendNotification) can suspend for up to 90 seconds while waiting for BLE packets from the device. Without an early-exit path, a BLE disconnection would leave those coroutines blocked on the internal channels — holding operationMutex and preventing any subsequent operation from starting.
To solve this, every operation participates in a two-sided race via Kotlin's select:
withTimeoutOrNull(timeoutMillis) { select { channel.onReceive { ... } // normal path: BLE packet arrives disconnectSignal.onAwait { ... } // fast path: disconnect fires } }disconnectSignalis a snapshot of disconnectDeferred taken at the start of each operation, before the mutex is acquired. When reset is called on disconnection:disconnectDeferred is replaced with a fresh
CompletableDeferredfor the next connection.The old deferred is completed exceptionally with BleDisconnected.
Any coroutine suspended in
onAwaiton the old deferred is immediately unblocked: because the deferred completed exceptionally,onAwaitre-throws BleDisconnected rather than executing its lambda. That exception propagates throughwithTimeoutOrNull(which only catchesTimeoutCancellationException), out of the suspend helper, and up tooperationMutex.withLock, whosefinallyblock releases the lock — freeing the next waiting operation immediately.Capture-before-lock ordering prevents a race: even if reset runs between the snapshot (
val disconnectSignal = disconnectDeferred) and the first suspension point, the old deferred is already completed exceptionally, soonAwaitthrows the moment theselectstarts.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description public interfaceBlePsFtpClient.ProgressCallback
-
Field Summary
Fields Modifier and Type Field Description public final BleGattTxInterfacetxInterfacepublic BooleanisPrimaryServiceprivate final BooleanisEncryptionRequiredprivate final BooleanisServiceDiscovered
-
Constructor Summary
Constructors Constructor Description BlePsFtpClient(BleGattTxInterface txInterface)
-
Method Summary
Modifier and Type Method Description final UnitsetProgressCallback(BlePsFtpClient.ProgressCallback callback)final UnitsetPacketsCount(Integer count)Set amount of packets written consecutive with BLE ATT WRITE before adding the BLE ATT WRITE REQUEST. final IntegergetPacketsCount()Unitreset()UnitprocessServiceData(UUID characteristic, ByteArray data, Integer status, Boolean notifying)Callback for GATT service characteristic data processing UnitprocessServiceDataWritten(UUID characteristic, Integer status)UnitprocessServiceDataWrittenWithResponse(UUID characteristic, Integer status)StringtoString()UnitclientReady(Boolean checkConnection)final ByteArrayOutputStreamrequest(ByteArray header, BlePsFtpClient.ProgressCallback progressCallback)Sends a request to the device and returns the response. final Flow<Long>write(ByteArray header, ByteArrayInputStream data)Writes file to a device, atomic operation. final ByteArrayOutputStreamquery(Integer id, ByteArray parameters)Sends a query to device. final <Error class: unknown class>sendNotification(Integer id, ByteArray parameters)Sends a single notification to device. final Flow<BlePsFtpUtils.PftpNotificationMessage>waitForNotification()Wait endlessly for notifications from device using a shared Flow. final <Error class: unknown class>waitPsFtpClientReady(Boolean checkConnection)Suspend until both PS-FTP MTU and D2H notifications are enabled. final UnitsuspendReadResponse(ByteArrayOutputStream outputStream, Long timeoutMillis, CompletableDeferred<Unit> disconnectSignal)-
Methods inherited from class com.polar.androidcommunications.api.ble.model.gatt.BleGattBase
addCharacteristicNotification, authenticationCompleted, authenticationFailed, containsCharacteristic, containsCharacteristicRead, containsNotifyCharacteristic, descriptorWritten, getAvailableCharacteristics, getNotificationAtomicInteger, isAutomatic, isAutomaticRead, isEncryptionRequired, isServiceDiscovered, processCharacteristicDiscovered, removeCharacteristicNotification, serviceBelongsToClient, setMtuSize, setServiceDiscovered, waitNotificationEnabled, waitNotificationEnabled, waitServiceDiscovered -
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
-
Constructor Detail
-
BlePsFtpClient
BlePsFtpClient(BleGattTxInterface txInterface)
-
-
Method Detail
-
setProgressCallback
final Unit setProgressCallback(BlePsFtpClient.ProgressCallback callback)
-
setPacketsCount
final Unit setPacketsCount(Integer count)
Set amount of packets written consecutive with BLE ATT WRITE before adding the BLE ATT WRITE REQUEST.
- Parameters:
count- number of packets
-
getPacketsCount
final Integer getPacketsCount()
-
processServiceData
Unit processServiceData(UUID characteristic, ByteArray data, Integer status, Boolean notifying)
Callback for GATT service characteristic data processing
- Parameters:
characteristic- characteristic UUIDdata- data in byte arraystatus- status code of processed datanotifying- if true data is notification data from GATT service
-
processServiceDataWritten
Unit processServiceDataWritten(UUID characteristic, Integer status)
-
processServiceDataWrittenWithResponse
Unit processServiceDataWrittenWithResponse(UUID characteristic, Integer status)
-
clientReady
Unit clientReady(Boolean checkConnection)
-
request
final ByteArrayOutputStream request(ByteArray header, BlePsFtpClient.ProgressCallback progressCallback)
Sends a request to the device and returns the response.
- Parameters:
header- protobuf pftp operation bytesprogressCallback- optional callback for progress updates- Returns:
ByteArrayOutputStream containing the response
-
write
final Flow<Long> write(ByteArray header, ByteArrayInputStream data)
Writes file to a device, atomic operation.
- Parameters:
header- protobuf pftp operation bytesdata- actual file data- Returns:
Flow emitting current byte offset progress; completes after device confirms write
-
query
final ByteArrayOutputStream query(Integer id, ByteArray parameters)
Sends a query to device.
- Parameters:
id- query id valueparameters- optional parameters- Returns:
ByteArrayOutputStream containing the query response
-
sendNotification
final <Error class: unknown class> sendNotification(Integer id, ByteArray parameters)
Sends a single notification to device.
- Parameters:
id- one of the PbPFtpHostToDevNotification valuesparameters- matching parameter for PbPFtpHostToDevNotification value if any
-
waitForNotification
final Flow<BlePsFtpUtils.PftpNotificationMessage> waitForNotification()
Wait endlessly for notifications from device using a shared Flow.
- Returns:
Flow emitting PftpNotificationMessage for each complete notification received. Throws on error; never completes on its own.
-
waitPsFtpClientReady
final <Error class: unknown class> waitPsFtpClientReady(Boolean checkConnection)
Suspend until both PS-FTP MTU and D2H notifications are enabled.
- Parameters:
checkConnection- if true, checks connection state before waiting
-
suspendReadResponse
final Unit suspendReadResponse(ByteArrayOutputStream outputStream, Long timeoutMillis, CompletableDeferred<Unit> disconnectSignal)
-
-
-
-