The structure for verifying an mDL is very similar to implementing the presentation of an mDL. To verify an mDL over BLE you will need to manage the BLEReaderSessionState and provide a UI for every state during the presentation process.
1. Scanning Documents
Rather than generating a QR-code, for a verifier, you will have to implement a scanning ability. For mdoc verification, you can directly use the QRCodeScanner. If you want to implement a generic scanner that can handle PDF417 VC Barcodes and Machine Readable Zones, check out this example of a Scanning Component.
Verify mdocs
Here, we give an example of what your VerifyMdocView could look like. You can also directly reference our example implementation.
@Composable
fun MdocReaderView(
) {
val context = LocalContext.current
var reader: IsoMdlReader? = null
var scanProcessState by remember {
mutableStateOf(State.SCANNING)
}
var result by remember {
mutableStateOf<Map<String, Map<String, MDocItem>>?>(null)
}
fun elementMapToList(elements: Map<String, Map<String, Boolean>>): List<String> {
val elementList = listOf(elements.values.map { it.keys.toList() })
return elementList.flatten().flatten()
}
fun onRead(content: String) {
scanProcessState = State.TRANSMITTING
checkAndRequestBluetoothPermissions(
context,
getPermissions().toTypedArray(),
launcherMultiplePermissions
)
val bluetooth = getBluetoothManager(context)
GlobalScope.launch {
reader = IsoMdlReader(
// Your BleSessionStateDelegate implementation. See the next code block!
<bleCallback>,
// The scanned value
content,
// Define the items you want to query by namespace, attribute_name
// and intent to retain:
<defaultElements>,
// Enter an array of issuer certificates that you accept (e.g. a list of US states).
// These issuer certificates should follow the IACA profile as defined in ISO/IEC 18013-5 Annex B.
<trustAnchorCerts>,
// the Bluetooth manager
<bluetooth>,
// The local app context
context
)
}
}
fun back() {
navController.navigate(
Screen.HomeScreen.route.replace("{tab}", "verifier")
) {
popUpTo(0)
}
}
val elementsList = elementMapToList(defaultElements)
when (scanProcessState) {
// Manage the UI based on the ProcessState here.
}
BLESessionStateDelegate
Build the Delegate that holds the BLEReaderSessionState and the mDocReader sessionManager. The update method on the bleCallback will handle the response, using the IsomDlReader component.
// Define your BLE Session State delegate
val bleCallback: BLESessionStateDelegate = object : BLESessionStateDelegate() {
override fun update(state: Map<String, Any>) {
Log.d("VerifyMDocView", state.toString())
if (state.containsKey("mdl")) {
result = reader?.handleResponse(state["mdl"] as ByteArray)
scanProcessState = State.DONE
}
}
override fun error(error: Exception) {
// Your error implementation
}
}
Once you have your Delegate implemented, you can call it from your MdocReaderView, which manages the UI based on the SessionState.
There you have it, you now have everything you need for an mDL verification flow. You can:
Initiate a QR Code Scanner
Manage the states of the BleReaderSession with the appropriate UI of your design