Skip to content

Commit

Permalink
Merge pull request #61 from tw-mosip/develop
Browse files Browse the repository at this point in the history
[Release 30-05-2023] Android & iOS Stability Changes, Spec Implementations & Exception Handling
  • Loading branch information
vharsh authored May 30, 2023
2 parents 93eb32c + a6826dd commit 0955769
Show file tree
Hide file tree
Showing 72 changed files with 793 additions and 397 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ node_modules/
npm-debug.log
yarn-debug.log
yarn-error.log
.yalc

# BUCK
buck-out/
Expand All @@ -72,4 +73,4 @@ ios/libs
ios/generated/
android/src/main/jniLibs/
rust/purerust/target/
rust/rustlib_binding/target/
rust/rustlib_binding/target/
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package io.mosip.tuvali.ble.central

import android.bluetooth.BluetoothDevice
import android.bluetooth.le.ScanRecord
import io.mosip.tuvali.exception.BLEException
import java.util.*

interface ICentralListener {
Expand All @@ -21,5 +22,5 @@ interface ICentralListener {
fun onSubscriptionFailure(charUUID: UUID, err: Int)
fun onNotificationReceived(charUUID: UUID, value: ByteArray?)
fun onClosed()
fun onException(exception: Throwable)
fun onException(exception: BLEException)
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ const val MTU_HEADER_SIZE = 3
const val REQUEST_MTU_TIME_OUT = -1

class Controller(val context: Context) {
private lateinit var scanner: Scanner
private val logTag = getLogTag(javaClass.simpleName)

private var gattClient: GattClient? = null
private var scanner: Scanner? = null
private lateinit var messageSender: IMessageSender
private var requestedMTUValue = -1
private lateinit var mtuValues : Array<Int>
Expand All @@ -34,7 +34,7 @@ class Controller(val context: Context) {

fun scan(scanStartMessage: ScanStartMessage) {
scanner = Scanner(context)
scanner.start(
scanner?.start(
scanStartMessage.serviceUUID,
scanStartMessage.advPayload,
this::onDeviceFound,
Expand All @@ -43,7 +43,7 @@ class Controller(val context: Context) {
}

fun stopScan() {
scanner.stopScan()
scanner?.stopScan()
}

@SuppressLint("MissingPermission")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,6 @@ class GattClient(var context: Context) {
}
}

override fun onPhyRead(gatt: BluetoothGatt?, txPhy: Int, rxPhy: Int, status: Int) {
Log.d(logTag, "Central onPhyRead: txPhy: $txPhy, rxPhy: $rxPhy, status: $status")
}

override fun onPhyUpdate(gatt: BluetoothGatt?, txPhy: Int, rxPhy: Int, status: Int) {
Log.d(logTag, "Central onPhyUpdate: txPhy: $txPhy, rxPhy: $rxPhy, status: $status")
}

override fun onCharacteristicRead(
gatt: BluetoothGatt?,
characteristic: BluetoothGattCharacteristic?,
Expand Down Expand Up @@ -178,8 +170,6 @@ class GattClient(var context: Context) {

gatt.requestConnectionPriority(CONNECTION_PRIORITY_HIGH)
gatt.readPhy()
gatt.setPreferredPhy(2, 2, 0)
gatt.readPhy()
this.bluetoothGatt = gatt
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import android.util.Log
import io.mosip.tuvali.ble.central.impl.Controller
import io.mosip.tuvali.ble.central.ICentralListener
import io.mosip.tuvali.ble.central.state.message.*
import io.mosip.tuvali.openid4vpble.exception.exception.StateHandlerException
import io.mosip.tuvali.ble.exception.CentralStateHandlerException
import io.mosip.tuvali.transfer.Util.Companion.getLogTag

class StateHandler(
Expand Down Expand Up @@ -165,14 +165,14 @@ class StateHandler(
currentState = States.Writing
}
IMessage.CentralStates.WRITE_SUCCESS.ordinal -> {
val writeSuccessMessage = msg.obj as WriteSuccessMessage;
val writeSuccessMessage = msg.obj as WriteSuccessMessage
Log.d(logTag, "Completed writing to ${writeSuccessMessage.charUUID} successfully")

listener.onWriteSuccess(writeSuccessMessage.device, writeSuccessMessage.charUUID)
currentState = States.Connected
}
IMessage.CentralStates.WRITE_FAILURE.ordinal -> {
val writeFailureMessage = msg.obj as WriteFailureMessage;
val writeFailureMessage = msg.obj as WriteFailureMessage

Log.d(logTag, "write failed for ${writeFailureMessage.charUUID} due to ${writeFailureMessage.err}")
listener.onWriteFailed(writeFailureMessage.device, writeFailureMessage.charUUID, writeFailureMessage.err)
Expand Down Expand Up @@ -255,9 +255,9 @@ class StateHandler(
override fun dispatchMessage(msg: Message) {
try {
super.dispatchMessage(msg)
} catch (e: Throwable) {
listener.onException(StateHandlerException("Exception in Central State Handler", e))
Log.d(logTag, "dispatchMessage " + e.message)
} catch (e: Exception) {
listener.onException(CentralStateHandlerException("Exception in Central State Handler", e))
Log.e(logTag, "dispatchMessage " + e.message)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.mosip.tuvali.ble.exception

import io.mosip.tuvali.exception.BLEException
import io.mosip.tuvali.exception.ErrorCode

class CentralStateHandlerException(message: String, cause: Exception): BLEException(message, cause,
ErrorCode.CentralStateHandlerException
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.mosip.tuvali.ble.exception

import io.mosip.tuvali.exception.BLEException
import io.mosip.tuvali.exception.ErrorCode

class PeripheralStateHandlerException(message: String, cause: Exception): BLEException(message, cause,
ErrorCode.PeripheralStateHandlerException
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.mosip.tuvali.ble.peripheral

import io.mosip.tuvali.exception.BLEException
import java.util.UUID

interface IPeripheralListener {
Expand All @@ -11,5 +12,5 @@ interface IPeripheralListener {
fun onSendDataNotified(uuid: UUID, isSent: Boolean)
fun onClosed()
fun onMTUChanged(mtu: Int)
fun onException(exception: Throwable)
fun onException(exception: BLEException)
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import android.util.Log
import io.mosip.tuvali.ble.peripheral.state.IMessageSender
import io.mosip.tuvali.ble.peripheral.state.message.*
import io.mosip.tuvali.transfer.Util.Companion.getLogTag

const val MTU_HEADER_SIZE = 3

class Controller(val context: Context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ class GattServer(private val context: Context) : BluetoothGattServerCallback() {
Log.i(logTag, "Connection initiated to central: $connect with device address: ${device?.address}")

onDeviceConnectedCallback(status, newState)
device?.let { setPhy(it) }
device
} else {
Log.i(logTag,"Received disconnect from central with device address: ${device?.address}")
Expand All @@ -90,14 +89,6 @@ class GattServer(private val context: Context) : BluetoothGattServerCallback() {
onMTUChangedCallback(allowedMTU)
}

private fun setPhy(bluetoothDevice: BluetoothDevice) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
gattServer.readPhy(bluetoothDevice)
gattServer.setPreferredPhy(bluetoothDevice, 2, 2, 0)
gattServer.readPhy(bluetoothDevice)
}
}

override fun onCharacteristicWriteRequest(
device: BluetoothDevice?,
requestId: Int,
Expand Down Expand Up @@ -144,14 +135,6 @@ class GattServer(private val context: Context) : BluetoothGattServerCallback() {
}
}

override fun onPhyRead(device: BluetoothDevice?, txPhy: Int, rxPhy: Int, status: Int) {
Log.d(logTag, "Peripheral onPhyRead: txPhy: $txPhy, rxPhy: $rxPhy, status: $status")
}

override fun onPhyUpdate(device: BluetoothDevice?, txPhy: Int, rxPhy: Int, status: Int) {
Log.d(logTag, "Peripheral onPhyUpdate: txPhy: $txPhy, rxPhy: $rxPhy, status: $status")
}

fun disconnect(): Boolean {
return if(bluetoothDevice != null) {
Log.d(logTag, "Disconnecting from central with device address: ${bluetoothDevice?.address}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import android.util.Log
import com.facebook.common.util.Hex
import io.mosip.tuvali.ble.peripheral.IPeripheralListener
import io.mosip.tuvali.ble.peripheral.impl.Controller
import io.mosip.tuvali.openid4vpble.exception.exception.StateHandlerException
import io.mosip.tuvali.ble.peripheral.state.message.*
import io.mosip.tuvali.transfer.Util.Companion.getLogTag
import io.mosip.tuvali.ble.exception.PeripheralStateHandlerException

class StateHandler(
looper: Looper,
Expand Down Expand Up @@ -156,9 +156,9 @@ class StateHandler(
override fun dispatchMessage(msg: Message) {
try {
super.dispatchMessage(msg)
} catch (e: Throwable) {
peripheralListener.onException(StateHandlerException("Exception in Peripheral State Handler", e))
Log.d(logTag, "dispatchMessage " + e.message)
} catch (e: Exception) {
peripheralListener.onException(PeripheralStateHandlerException("Exception in Peripheral State Handler", e))
Log.e(logTag, "dispatchMessage " + e.message)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.mosip.tuvali.common.safeExecute

import io.mosip.tuvali.exception.handlers.OpenIdBLEExceptionHandler

class TryExecuteSync(private val bleExceptionHandler: OpenIdBLEExceptionHandler) {
private val mutex = Object()

fun <T> run(fn: () -> T): T? {
var returnValue: T? = null

synchronized(mutex) {
try {
returnValue = fn()
} catch (e: Exception) {
bleExceptionHandler.handleException(e)
}
}

return returnValue
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package io.mosip.tuvali.exception

open class BLEException(message: String, cause: Exception?, val errorCode: ErrorCode): RuntimeException(message, cause) {
}
29 changes: 29 additions & 0 deletions android/src/main/java/io/mosip/tuvali/exception/ErrorCode.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.mosip.tuvali.exception

// Error Code format
// <Component(2)+Role(1)>(3char)_<Stage>(3char)_<Number>(3char) Eg: TVW-CON-001
// Stage --> CON(Connection) | KEX(Key Exchange) | ENC(Encryption) | TRA(Transfer) | REP(Report) | DEC(Decryption)
// Component+ROLE --> TVW(Tuvali+Wallet) | TVV(Tuvali+Verifier) | TUV(Tuvali where role is unknown)
// UNK --> If stage is not known

enum class ErrorCode(val code: String) {
UnknownException("TUV_UNK_001"),

WalletUnknownException("TVW_UNK_001"),
CentralStateHandlerException("TVW_UNK_002"),
WalletTransferHandlerException("TVW_UNK_003"),

VerifierUnknownException("TVV_UNK_001"),
PeripheralStateHandlerException("TVV_UNK_002"),
VerifierTransferHandlerException("TVV_UNK_003"),

MTUNegotiationException("TVW_CON_001"),
//TODO: Create specific error codes for the below exception
TransferFailedException("TVW_REP_001"),

UnsupportedMTUSizeException("TVV_CON_001"),
CorruptedChunkReceivedException("TVV_TRA_001"),
TooManyFailureChunksException("TVV_TRA_002"),
}


13 changes: 13 additions & 0 deletions android/src/main/java/io/mosip/tuvali/exception/ExceptionUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.mosip.tuvali.exception

class ExceptionUtils {
companion object {
fun getRootBLECause(e: BLEException): BLEException {
var cause: BLEException = e
while (cause.cause != null && cause.cause is BLEException) {
cause = cause.cause as BLEException
}
return cause
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package io.mosip.tuvali.exception

class UnknownException(message: String, cause: Exception): BLEException(message, cause, ErrorCode.UnknownException) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package io.mosip.tuvali.exception.handlers

import android.util.Log
import com.facebook.react.bridge.Callback
import io.mosip.tuvali.exception.BLEException
import io.mosip.tuvali.exception.ErrorCode
import io.mosip.tuvali.exception.ExceptionUtils
import io.mosip.tuvali.exception.UnknownException

import io.mosip.tuvali.transfer.Util
import io.mosip.tuvali.verifier.exception.VerifierException
import io.mosip.tuvali.wallet.exception.WalletException

class OpenIdBLEExceptionHandler(private val sendError: (String, ErrorCode) -> Unit, private val stopBle: (Callback) -> Unit) {
private val logTag = Util.getLogTag(javaClass.simpleName)
private var walletExceptionHandler: WalletExceptionHandler = WalletExceptionHandler(sendError)
private var verifierExceptionHandler: VerifierExceptionHandler = VerifierExceptionHandler(sendError)

private fun handleWalletException(e: WalletException) {
walletExceptionHandler.handleException(e)
}

private fun handleVerifierException(e: VerifierException) {
verifierExceptionHandler.handleException(e)
}

fun handleException(e: Exception) {
when (e) {
is WalletException -> {
handleWalletException(e)
}
is VerifierException -> {
handleVerifierException(e)
}
else -> {
handleUnknownException(UnknownException("Unknown Exception in Tuvali", e))
}
}

try{
stopBle {}
} catch (e: Exception) {
Log.d(logTag,"Failed to stop BLE connection while handling exception: $e")
}
}

private fun handleUnknownException(e: BLEException) {
val rootCause = ExceptionUtils.getRootBLECause(e)

Log.e(logTag, "Handling Unknown Exception: ", e)
sendError(e.message ?: "Something went wrong in BLE: $rootCause", rootCause.errorCode)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.mosip.tuvali.exception.handlers

import android.util.Log
import io.mosip.tuvali.exception.ErrorCode
import io.mosip.tuvali.exception.ExceptionUtils
import io.mosip.tuvali.transfer.Util
import io.mosip.tuvali.verifier.exception.VerifierException

class VerifierExceptionHandler(val sendError: (String, ErrorCode) -> Unit) {
private val logTag = Util.getLogTag(javaClass.simpleName)

fun handleException(e: VerifierException){
val rootCause = ExceptionUtils.getRootBLECause(e)

Log.e(logTag, "Handling Verifier Exception: ", e)
sendError(e.message ?: "Something went wrong in Verifier: $rootCause", rootCause.errorCode)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.mosip.tuvali.exception.handlers

import android.util.Log
import io.mosip.tuvali.exception.ErrorCode
import io.mosip.tuvali.exception.ExceptionUtils
import io.mosip.tuvali.transfer.Util
import io.mosip.tuvali.wallet.exception.WalletException

class WalletExceptionHandler(val sendError: (String, ErrorCode) -> Unit) {
private val logTag = Util.getLogTag(javaClass.simpleName)

fun handleException(e: WalletException) {
val rootCause = ExceptionUtils.getRootBLECause(e)

Log.e(logTag, "Handling Wallet Exception: ", e)
sendError(e.message ?: "Something went wrong in Wallet: $rootCause", rootCause.errorCode)
}
}
Loading

0 comments on commit 0955769

Please sign in to comment.