Skip to content

Commit

Permalink
Merge pull request #3 from ravikp/rename-uuid
Browse files Browse the repository at this point in the history
feat(#444): [Bhargavi|Adityan] [Android] refactor tuvali gatt service to match the spec
  • Loading branch information
tilak-puli authored Jan 27, 2023
2 parents 1b41ad3 + 799f950 commit acb59c2
Show file tree
Hide file tree
Showing 11 changed files with 71 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class Peripheral(context: Context, peripheralListener: IPeripheralListener) {
}

private fun notifyDisconnect(serviceUUID: UUID) {
sendData(serviceUUID, GattService.CONNECTION_STATUS_CHANGE_CHAR_UUID, byteArrayOf(Verifier.DISCONNECT_STATUS.toByte()))
sendData(serviceUUID, GattService.DISCONNECT_CHAR_UUID, byteArrayOf(Verifier.DISCONNECT_STATUS.toByte()))
}

fun setupService(service: BluetoothGattService) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.mosip.tuvali.transfer

class Semaphore {
enum class SemaphoreMarker {
class TransferReportRequest {
enum class ReportType {
UnInitialised,
RequestReport,
Error
Expand Down
56 changes: 32 additions & 24 deletions android/src/main/java/io/mosip/tuvali/verifier/GattService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ import java.util.*
class GattService {
//TODO: Update UUIDs as per specification
companion object {
val IDENTITY_CHARACTERISTIC_UUID: UUID = UUID.fromString("00002030-0000-1000-8000-00805f9b34fb")
val IDENTIFY_REQUEST_CHAR_UUID: UUID = UUID.fromString("00002030-0000-1000-8000-00805f9b34fb")
val REQUEST_SIZE_CHAR_UUID: UUID = UUID.fromString("00002031-0000-1000-8000-00805f9b34fb")
val REQUEST_CHAR_UUID: UUID = UUID.fromString("00002032-0000-1000-8000-00805f9b34fb")
val RESPONSE_SIZE_CHAR_UUID: UUID = UUID.fromString("00002033-0000-1000-8000-00805f9b34fb")
val RESPONSE_CHAR_UUID: UUID = UUID.fromString("00002034-0000-1000-8000-00805f9b34fb")
val SEMAPHORE_CHAR_UUID: UUID = UUID.fromString("00002035-0000-1000-8000-00805f9b34fb")
val VERIFICATION_STATUS_CHAR_UUID: UUID = UUID.fromString("00002036-0000-1000-8000-00805f9b34fb")
val CONNECTION_STATUS_CHANGE_CHAR_UUID: UUID = UUID.fromString("00002037-0000-1000-8000-00805f9b34fb")
val SUBMIT_RESPONSE_CHAR_UUID: UUID = UUID.fromString("00002034-0000-1000-8000-00805f9b34fb")
val TRANSFER_REPORT_REQUEST_CHAR_UUID: UUID = UUID.fromString("00002035-0000-1000-8000-00805f9b34fb")
val TRANSFER_REPORT_RESPONSE_CHAR_UUID: UUID = UUID.fromString("00002036-0000-1000-8000-00805f9b34fb")
val VERIFICATION_STATUS_CHAR_UUID: UUID = UUID.fromString("00002037-0000-1000-8000-00805f9b34fb")
val DISCONNECT_CHAR_UUID: UUID = UUID.fromString("00002038-0000-1000-8000-00805f9b34fb")
}

fun create(): BluetoothGattService {
Expand All @@ -23,9 +24,9 @@ class GattService {
BluetoothGattService.SERVICE_TYPE_PRIMARY
)

val identityChar = BluetoothGattCharacteristic(
IDENTITY_CHARACTERISTIC_UUID,
BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE or BluetoothGattCharacteristic.PROPERTY_WRITE,
val identifyRequestChar = BluetoothGattCharacteristic(
IDENTIFY_REQUEST_CHAR_UUID,
BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE,
BluetoothGattCharacteristic.PERMISSION_WRITE
)

Expand All @@ -43,42 +44,49 @@ class GattService {

val responseSizeChar = BluetoothGattCharacteristic(
RESPONSE_SIZE_CHAR_UUID,
BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE or BluetoothGattCharacteristic.PROPERTY_WRITE,
BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE,
BluetoothGattCharacteristic.PERMISSION_WRITE
)

val responseChar = BluetoothGattCharacteristic(
RESPONSE_CHAR_UUID,
BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE or BluetoothGattCharacteristic.PROPERTY_WRITE,
val submitResponseChar = BluetoothGattCharacteristic(
SUBMIT_RESPONSE_CHAR_UUID,
BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE,
BluetoothGattCharacteristic.PERMISSION_WRITE
)

val semaphoreChar = BluetoothGattCharacteristic(
SEMAPHORE_CHAR_UUID,
BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE or BluetoothGattCharacteristic.PROPERTY_WRITE or BluetoothGattCharacteristic.PROPERTY_READ or BluetoothGattCharacteristic.PROPERTY_INDICATE,
BluetoothGattCharacteristic.PERMISSION_READ or BluetoothGattCharacteristic.PERMISSION_WRITE
val transferReportRequestChar = BluetoothGattCharacteristic(
TRANSFER_REPORT_REQUEST_CHAR_UUID,
BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE,
BluetoothGattCharacteristic.PERMISSION_WRITE
)

val transferReportResponseChar = BluetoothGattCharacteristic(
TRANSFER_REPORT_RESPONSE_CHAR_UUID,
BluetoothGattCharacteristic.PROPERTY_INDICATE,
BluetoothGattCharacteristic.PERMISSION_READ
)

val verificationStatusChar = BluetoothGattCharacteristic(
VERIFICATION_STATUS_CHAR_UUID,
BluetoothGattCharacteristic.PROPERTY_READ or BluetoothGattCharacteristic.PROPERTY_INDICATE,
BluetoothGattCharacteristic.PROPERTY_INDICATE,
BluetoothGattCharacteristic.PERMISSION_READ
)

val connectionStatusChar = BluetoothGattCharacteristic(
CONNECTION_STATUS_CHANGE_CHAR_UUID,
BluetoothGattCharacteristic.PROPERTY_READ or BluetoothGattCharacteristic.PROPERTY_INDICATE,
val disconnectStatusChar = BluetoothGattCharacteristic(
DISCONNECT_CHAR_UUID,
BluetoothGattCharacteristic.PROPERTY_INDICATE,
BluetoothGattCharacteristic.PERMISSION_READ
)

service.addCharacteristic(identityChar)
service.addCharacteristic(identifyRequestChar)
service.addCharacteristic(requestSizeChar)
service.addCharacteristic(requestChar)
service.addCharacteristic(responseSizeChar)
service.addCharacteristic(responseChar)
service.addCharacteristic(semaphoreChar)
service.addCharacteristic(submitResponseChar)
service.addCharacteristic(transferReportRequestChar)
service.addCharacteristic(transferReportResponseChar)
service.addCharacteristic(verificationStatusChar)
service.addCharacteristic(connectionStatusChar)
service.addCharacteristic(disconnectStatusChar)

return service
}
Expand Down
20 changes: 10 additions & 10 deletions android/src/main/java/io/mosip/tuvali/verifier/Verifier.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import io.mosip.tuvali.cryptography.SecretsTranslator
import io.mosip.tuvali.cryptography.VerifierCryptoBox
import io.mosip.tuvali.cryptography.VerifierCryptoBoxBuilder
import com.facebook.react.bridge.Callback
import io.mosip.tuvali.transfer.TransferReportRequest
import io.mosip.tuvali.openid4vpble.Openid4vpBleModule
import io.mosip.tuvali.transfer.Semaphore
import io.mosip.tuvali.transfer.Util
import io.mosip.tuvali.verifier.transfer.ITransferListener
import io.mosip.tuvali.verifier.transfer.TransferHandler
Expand Down Expand Up @@ -120,7 +120,7 @@ class Verifier(

override fun onReceivedWrite(uuid: UUID, value: ByteArray?) {
when (uuid) {
GattService.IDENTITY_CHARACTERISTIC_UUID -> {
GattService.IDENTIFY_REQUEST_CHAR_UUID -> {
value?.let {
// Total size of identity char value will be 12 bytes IV + 32 bytes pub key
if (value.size < 12 + 32) {
Expand All @@ -143,18 +143,18 @@ class Verifier(
peripheral.stopAdvertisement()
}
}
GattService.SEMAPHORE_CHAR_UUID -> {
GattService.TRANSFER_REPORT_REQUEST_CHAR_UUID -> {
value?.let {
if (value.isEmpty()) {
return
}
val semaphoreValue = value[0].toInt()
if (semaphoreValue == Semaphore.SemaphoreMarker.RequestReport.ordinal) {
val receivedReportType = value[0].toInt()
if (receivedReportType == TransferReportRequest.ReportType.RequestReport.ordinal) {
val remoteRequestedTransferReportMessage =
RemoteRequestedTransferReportMessage(semaphoreValue)
RemoteRequestedTransferReportMessage(receivedReportType)
transferHandler.sendMessage(remoteRequestedTransferReportMessage)
} else if (semaphoreValue == Semaphore.SemaphoreMarker.Error.ordinal) {
onResponseReceivedFailed("received error on semaphore from remote")
} else if (receivedReportType == TransferReportRequest.ReportType.Error.ordinal) {
onResponseReceivedFailed("received error on transfer Report request from remote")
}
}
}
Expand All @@ -167,7 +167,7 @@ class Verifier(
transferHandler.sendMessage(responseSizeReadSuccessMessage)
}
}
GattService.RESPONSE_CHAR_UUID -> {
GattService.SUBMIT_RESPONSE_CHAR_UUID -> {
if (value != null) {
Log.d(logTag, "received response chunk on characteristic of size: ${value.size}")
transferHandler.sendMessage(ResponseChunkReceivedMessage(value))
Expand All @@ -178,7 +178,7 @@ class Verifier(

override fun onSendDataNotified(uuid: UUID, isSent: Boolean) {
when (uuid) {
GattService.SEMAPHORE_CHAR_UUID -> {
GattService.TRANSFER_REPORT_RESPONSE_CHAR_UUID -> {
//TODO: Can re-send report if failed to send notification with exponential backoff
Log.d(logTag, "notification sent status $isSent for uuid: $uuid")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ import android.os.Message
import android.util.Log
import io.mosip.tuvali.ble.peripheral.Peripheral
import io.mosip.tuvali.transfer.Assembler
import io.mosip.tuvali.transfer.Semaphore
import io.mosip.tuvali.transfer.TransferReportRequest
import io.mosip.tuvali.transfer.TransferReport
import io.mosip.tuvali.transfer.Util
import io.mosip.tuvali.verifier.GattService
import io.mosip.tuvali.verifier.exception.CorruptedChunkReceivedException
import io.mosip.tuvali.verifier.transfer.message.*
Expand Down Expand Up @@ -48,15 +47,15 @@ class TransferHandler(looper: Looper, private val peripheral: Peripheral, privat
}
currentState = States.ResponseReadPending
}
// On verifier side, we can wait on response char, instead of semaphore to know when chunk arrived
// On verifier side, we can wait on response char, instead of transfer report request to know when chunk arrived
IMessage.TransferMessageTypes.RESPONSE_CHUNK_RECEIVED.ordinal -> {
val responseChunkReceivedMessage = msg.obj as ResponseChunkReceivedMessage
assembleChunk(responseChunkReceivedMessage.chunkData)
}
IMessage.TransferMessageTypes.REMOTE_REQUESTED_TRANSFER_REPORT.ordinal -> {
val remoteRequestedTransferReportMessage = msg.obj as RemoteRequestedTransferReportMessage
when(remoteRequestedTransferReportMessage.semaphoreCharValue) {
Semaphore.SemaphoreMarker.RequestReport.ordinal -> {
when(remoteRequestedTransferReportMessage.transferReportRequestCharValue) {
TransferReportRequest.ReportType.RequestReport.ordinal -> {
var transferReport: TransferReport
if (assembler?.isComplete() == true) {
Log.d(logTag, "success frame: transfer completed")
Expand All @@ -72,13 +71,13 @@ class TransferHandler(looper: Looper, private val peripheral: Peripheral, privat
TransferReport(TransferReport.ReportType.MISSING_CHUNKS, totalPages.toInt(), missedSequenceNumbers.sliceArray(0 until defaultTransferReportPageSize))
}
}
transferListener.sendDataOverNotification(GattService.SEMAPHORE_CHAR_UUID, transferReport.toByteArray())
transferListener.sendDataOverNotification(GattService.TRANSFER_REPORT_RESPONSE_CHAR_UUID, transferReport.toByteArray())
}
Semaphore.SemaphoreMarker.Error.ordinal -> {
transferListener.onResponseReceivedFailed("received error on semaphore from remote")
TransferReportRequest.ReportType.Error.ordinal -> {
transferListener.onResponseReceivedFailed("received error on transfer Report request from remote")
}
else -> {
transferListener.onResponseReceivedFailed("unknown value received on semaphore from remote")
transferListener.onResponseReceivedFailed("unknown value received on transfer Report request from remote")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package io.mosip.tuvali.verifier.transfer.message

class ChunkReadByRemoteStatusUpdatedMessage(val semaphoreCharValue: Int): IMessage(TransferMessageTypes.CHUNK_READ_BY_REMOTE_STATUS_UPDATED) {}
class ChunkReadByRemoteStatusUpdatedMessage(val transferReportRequestCharValue: Int): IMessage(TransferMessageTypes.CHUNK_READ_BY_REMOTE_STATUS_UPDATED) {}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package io.mosip.tuvali.verifier.transfer.message

class RemoteRequestedTransferReportMessage(val semaphoreCharValue: Int): IMessage(TransferMessageTypes.REMOTE_REQUESTED_TRANSFER_REPORT) {}
class RemoteRequestedTransferReportMessage(val transferReportRequestCharValue: Int): IMessage(TransferMessageTypes.REMOTE_REQUESTED_TRANSFER_REPORT) {}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package io.mosip.tuvali.verifier.transfer.message

class UpdateChunkWroteStatusToRemoteMessage(val semaphoreCharValue: Int): IMessage(TransferMessageTypes.UPDATE_CHUNK_WROTE_STATUS_TO_REMOTE) {}
class UpdateChunkWroteStatusToRemoteMessage(val transferReportRequestCharValue: Int): IMessage(TransferMessageTypes.UPDATE_CHUNK_WROTE_STATUS_TO_REMOTE) {}
24 changes: 12 additions & 12 deletions android/src/main/java/io/mosip/tuvali/wallet/Wallet.kt
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class Wallet(
val iv = secretsTranslator?.initializationVector()
central.write(
Verifier.SERVICE_UUID,
GattService.IDENTITY_CHARACTERISTIC_UUID,
GattService.IDENTIFY_REQUEST_CHAR_UUID,
iv!! + publicKey!!
)
Log.d(
Expand Down Expand Up @@ -151,7 +151,7 @@ class Wallet(

//TODO: Can we pass this MTU value to chunker, would this callback always come?
val connectionEstablishedCallBack = callbacks[CentralCallbacks.CONNECTION_ESTABLISHED]
central.subscribe(Verifier.SERVICE_UUID, GattService.CONNECTION_STATUS_CHANGE_CHAR_UUID)
central.subscribe(Verifier.SERVICE_UUID, GattService.DISCONNECT_CHAR_UUID)

connectionEstablishedCallBack?.let {
it()
Expand All @@ -168,14 +168,14 @@ class Wallet(
Log.d(logTag, "Read from $charUUID successfully and value is $value")

when (charUUID) {
GattService.SEMAPHORE_CHAR_UUID -> {
GattService.TRANSFER_REPORT_REQUEST_CHAR_UUID -> {
}
}
}

override fun onReadFailure(charUUID: UUID?, err: Int) {
when (charUUID) {
GattService.SEMAPHORE_CHAR_UUID -> {
GattService.TRANSFER_REPORT_REQUEST_CHAR_UUID -> {
}
}
}
Expand All @@ -198,10 +198,10 @@ class Wallet(
Log.d(logTag, "Failed to write char: $charUUID with error code: $err")

when(charUUID) {
GattService.RESPONSE_CHAR_UUID -> {
GattService.SUBMIT_RESPONSE_CHAR_UUID -> {
transferHandler.sendMessage(ResponseChunkWriteFailureMessage(err))
}
GattService.SEMAPHORE_CHAR_UUID -> {
GattService.TRANSFER_REPORT_REQUEST_CHAR_UUID -> {
transferHandler.sendMessage(ResponseTransferFailureMessage("Failed to request report with err: $err"))
}
}
Expand All @@ -212,17 +212,17 @@ class Wallet(
override fun onWriteSuccess(device: BluetoothDevice, charUUID: UUID) {
Log.d(logTag, "Wrote to $charUUID successfully")
when (charUUID) {
GattService.IDENTITY_CHARACTERISTIC_UUID -> {
GattService.IDENTIFY_REQUEST_CHAR_UUID -> {
messageResponseListener(Openid4vpBleModule.NearbyEvents.EXCHANGE_RECEIVER_INFO.value, "{\"deviceName\": \"Verifier\"}")
}
GattService.RESPONSE_SIZE_CHAR_UUID -> {
transferHandler.sendMessage(ResponseSizeWriteSuccessMessage())
}
GattService.RESPONSE_CHAR_UUID -> {
GattService.SUBMIT_RESPONSE_CHAR_UUID -> {
transferHandler.sendMessage(ResponseChunkWriteSuccessMessage())
}
GattService.SEMAPHORE_CHAR_UUID -> {
central.subscribe(Verifier.SERVICE_UUID, GattService.SEMAPHORE_CHAR_UUID)
GattService.TRANSFER_REPORT_REQUEST_CHAR_UUID -> {
central.subscribe(Verifier.SERVICE_UUID, GattService.TRANSFER_REPORT_RESPONSE_CHAR_UUID)
central.subscribe(Verifier.SERVICE_UUID, GattService.VERIFICATION_STATUS_CHAR_UUID)
}
}
Expand All @@ -238,7 +238,7 @@ class Wallet(

override fun onNotificationReceived(charUUID: UUID, value: ByteArray?) {
when (charUUID) {
GattService.SEMAPHORE_CHAR_UUID -> {
GattService.TRANSFER_REPORT_RESPONSE_CHAR_UUID -> {
value?.let {
transferHandler.sendMessage(HandleTransmissionReportMessage(TransferReport(it)))
}
Expand All @@ -254,7 +254,7 @@ class Wallet(
central.unsubscribe(Verifier.SERVICE_UUID, charUUID)
central.disconnectAndClose()
}
GattService.CONNECTION_STATUS_CHANGE_CHAR_UUID -> {
GattService.DISCONNECT_CHAR_UUID -> {
val status = value?.get(0)?.toInt()

if(status != null && status == DISCONNECT_STATUS) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ class TransferHandler(looper: Looper, private val central: Central, val serviceU
}

private fun requestTransmissionReport() {
central.write(serviceUUID, GattService.SEMAPHORE_CHAR_UUID, byteArrayOf(Semaphore.SemaphoreMarker.RequestReport.ordinal.toByte()))
central.write(serviceUUID, GattService.TRANSFER_REPORT_REQUEST_CHAR_UUID, byteArrayOf(TransferReportRequest.ReportType.RequestReport.ordinal.toByte()))
}

private fun sendResponseChunk() {
Expand All @@ -149,7 +149,7 @@ class TransferHandler(looper: Looper, private val central: Central, val serviceU
private fun writeResponseChunk(chunkArray: ByteArray) {
central.write(
serviceUUID,
GattService.RESPONSE_CHAR_UUID,
GattService.SUBMIT_RESPONSE_CHAR_UUID,
chunkArray
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package io.mosip.tuvali.wallet.transfer.message

class ChunkWriteToRemoteStatusUpdatedMessage(val semaphoreCharValue: Int): IMessage(TransferMessageTypes.CHUNK_WRITE_TO_REMOTE_STATUS_UPDATED) {}
class ChunkWriteToRemoteStatusUpdatedMessage(val transferReportRequestCharValue: Int): IMessage(TransferMessageTypes.CHUNK_WRITE_TO_REMOTE_STATUS_UPDATED) {}

0 comments on commit acb59c2

Please sign in to comment.