@animo-id/expo-mdoc-data-transfer 0.1.5 → 0.2.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/MdocDataTransfer.podspec +14 -14
- package/android/build/.transforms/1b8378295914042bd56f454fccadf450/results.bin +1 -0
- package/android/build/.transforms/1b8378295914042bd56f454fccadf450/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/.transforms/b1c7825c26ef74820bf1a2f9b0863b9c/results.bin +1 -0
- package/android/build/.transforms/b1c7825c26ef74820bf1a2f9b0863b9c/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/.transforms/bd47d41628a1234539d52fed18dc00d8/results.bin +1 -0
- package/android/build/.transforms/bd47d41628a1234539d52fed18dc00d8/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/.transforms/ca70f32e4c31dcc1e27ce5e573009a23/results.bin +1 -0
- package/android/build/.transforms/ca70f32e4c31dcc1e27ce5e573009a23/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/generated/source/buildConfig/debug/id/animo/mdoc/datatransfer/BuildConfig.java +10 -0
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +7 -0
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +18 -0
- package/android/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties +6 -0
- package/android/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json +1 -0
- package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
- package/android/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +0 -0
- package/android/build/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +3 -0
- package/android/build/intermediates/compiled_local_resources/debug/compileDebugLibraryResources/out/xml_nfc_engagement_apdu_service.xml.flat +0 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +2 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/merged.dir/values/values.xml +5 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +2 -0
- package/android/build/intermediates/incremental/mergeDebugAssets/merger.xml +2 -0
- package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +2 -0
- package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +2 -0
- package/android/build/intermediates/java_res/debug/processDebugJavaRes/out/META-INF/animo-id-expo-mdoc-data-transfer_debug.kotlin_module +0 -0
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/id/animo/mdoc/datatransfer/BuildConfig.class +0 -0
- package/android/build/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +5 -0
- package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +7 -0
- package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +7 -0
- package/android/build/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +1 -0
- package/android/build/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +1 -0
- package/android/build/intermediates/packaged_res/debug/packageDebugResources/values/values.xml +5 -0
- package/android/build/intermediates/packaged_res/debug/packageDebugResources/xml/nfc_engagement_apdu_service.xml +30 -0
- package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
- package/android/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +4 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/package-parts.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/counters.tab +2 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/file-to-id.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
- package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
- package/android/build/kotlin/compileDebugKotlin/local-state/build-history.bin +0 -0
- package/android/build/outputs/logs/manifest-merger-debug-report.txt +14 -0
- package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
- package/android/build/tmp/kotlin-classes/debug/META-INF/animo-id-expo-mdoc-data-transfer_debug.kotlin_module +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/TransferEvent$Connected.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/TransferEvent$Connecting.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/TransferEvent$Disconnected.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/TransferEvent$Error.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/TransferEvent$IntentToSend.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/TransferEvent$Listenable.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/TransferEvent$Listener.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/TransferEvent$QrEngagementReady.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/TransferEvent$Redirect.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/TransferEvent$RequestReceived.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/TransferEvent$ResponseSent.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/TransferEvent.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/TransferManager$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/TransferManager$DefaultImpls.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/TransferManager.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/TransferManagerImpl$Builder.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/TransferManagerImpl$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/TransferManagerImpl.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/engagement/BleRetrievalMethod.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/engagement/DeviceRetrievalMethod.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/engagement/NfcEngagementService$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/engagement/NfcEngagementService$deviceRetrievalHelperListener$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/engagement/NfcEngagementService$nfcEngagementListener$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/engagement/NfcEngagementService.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/engagement/RetrievalMethod.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/internal/DeviceRetrievalHelperExtKt.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/internal/DeviceRetrievalMethodExtKt.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/internal/EngagementToApp$presentationListener$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/internal/EngagementToApp.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/internal/ExtensionsKt.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/internal/QrEngagement$deviceRetrievalHelperListener$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/internal/QrEngagement$qrEngagementListener$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/eu/europa/ec/eudi/iso18013/transfer/internal/QrEngagement.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/id/animo/mdoc/datatransfer/MdocDataTransfer$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/id/animo/mdoc/datatransfer/MdocDataTransfer.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/id/animo/mdoc/datatransfer/MdocDataTransferEvent.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/id/animo/mdoc/datatransfer/MdocDataTransferException$NotInitialized.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/id/animo/mdoc/datatransfer/MdocDataTransferException.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/id/animo/mdoc/datatransfer/MdocDataTransferManager.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/id/animo/mdoc/datatransfer/MdocDataTransferModule$definition$1$1$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/id/animo/mdoc/datatransfer/MdocDataTransferModule$definition$1$2$1$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/id/animo/mdoc/datatransfer/MdocDataTransferModule$definition$lambda$6$$inlined$AsyncFunction$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/id/animo/mdoc/datatransfer/MdocDataTransferModule$definition$lambda$6$$inlined$AsyncFunction$2.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/id/animo/mdoc/datatransfer/MdocDataTransferModule$definition$lambda$6$$inlined$AsyncFunction$3.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/id/animo/mdoc/datatransfer/MdocDataTransferModule$definition$lambda$6$$inlined$Function$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/id/animo/mdoc/datatransfer/MdocDataTransferModule$definition$lambda$6$$inlined$Function$2.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/id/animo/mdoc/datatransfer/MdocDataTransferModule$definition$lambda$6$$inlined$FunctionWithoutArgs$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/id/animo/mdoc/datatransfer/MdocDataTransferModule$definition$lambda$6$$inlined$FunctionWithoutArgs$2.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/id/animo/mdoc/datatransfer/MdocDataTransferModule$definition$lambda$6$$inlined$FunctionWithoutArgs$3.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/id/animo/mdoc/datatransfer/MdocDataTransferModule.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/id/animo/mdoc/datatransfer/NfcEngagementServiceImpl.class +0 -0
- package/android/build.gradle +17 -42
- package/android/src/main/java/eu/europa/ec/eudi/iso18013/transfer/TransferEvent.kt +39 -0
- package/android/src/main/java/eu/europa/ec/eudi/iso18013/transfer/TransferManager.kt +34 -0
- package/android/src/main/java/eu/europa/ec/eudi/iso18013/transfer/TransferManagerImpl.kt +258 -0
- package/android/src/main/java/eu/europa/ec/eudi/iso18013/transfer/engagement/BleRetrievalMethod.kt +23 -0
- package/android/src/main/java/eu/europa/ec/eudi/iso18013/transfer/engagement/DeviceRetrievalMethod.kt +19 -0
- package/android/src/main/java/eu/europa/ec/eudi/iso18013/transfer/engagement/NfcEngagementService.kt +198 -0
- package/android/src/main/java/eu/europa/ec/eudi/iso18013/transfer/engagement/RetrievalMethod.kt +19 -0
- package/android/src/main/java/eu/europa/ec/eudi/iso18013/transfer/internal/DeviceRetrievalHelperExt.kt +41 -0
- package/android/src/main/java/eu/europa/ec/eudi/iso18013/transfer/internal/DeviceRetrievalMethodExt.kt +55 -0
- package/android/src/main/java/eu/europa/ec/eudi/iso18013/transfer/internal/EngagementToApp.kt +97 -0
- package/android/src/main/java/eu/europa/ec/eudi/iso18013/transfer/internal/Extensions.kt +42 -0
- package/android/src/main/java/eu/europa/ec/eudi/iso18013/transfer/internal/QrEngagement.kt +141 -0
- package/android/src/main/java/id/animo/{mdocdatatransfer → mdoc/datatransfer}/MdocDataTransfer.kt +18 -11
- package/android/src/main/java/id/animo/{mdocdatatransfer → mdoc/datatransfer}/MdocDataTransferEvent.kt +2 -2
- package/android/src/main/java/id/animo/{mdocdatatransfer → mdoc/datatransfer}/MdocDataTransferException.kt +2 -2
- package/android/src/main/java/id/animo/{mdocdatatransfer → mdoc/datatransfer}/MdocDataTransferManager.kt +2 -16
- package/android/src/main/java/id/animo/{mdocdatatransfer → mdoc/datatransfer}/MdocDataTransferModule.kt +8 -9
- package/android/src/main/java/id/animo/{mdocdatatransfer → mdoc/datatransfer}/NfcEngagementServiceImpl.kt +2 -2
- package/android/src/main/res/values/strings.xml +20 -0
- package/android/src/main/res/xml/nfc_engagement_apdu_service.xml +30 -0
- package/build/MdocDataTransfer.d.ts +8 -4
- package/build/MdocDataTransfer.d.ts.map +1 -1
- package/build/MdocDataTransfer.js +26 -18
- package/build/MdocDataTransfer.js.map +1 -1
- package/build/MdocDataTransferError.d.ts +3 -0
- package/build/MdocDataTransferError.d.ts.map +1 -0
- package/build/MdocDataTransferError.js +3 -0
- package/build/MdocDataTransferError.js.map +1 -0
- package/build/MdocDataTransferEvent.d.ts +9 -5
- package/build/MdocDataTransferEvent.d.ts.map +1 -1
- package/build/MdocDataTransferEvent.js +1 -0
- package/build/MdocDataTransferEvent.js.map +1 -1
- package/build/NativeMdocDataTransfer.d.ts +16 -2
- package/build/NativeMdocDataTransfer.d.ts.map +1 -1
- package/build/NativeMdocDataTransfer.js +1 -1
- package/build/NativeMdocDataTransfer.js.map +1 -1
- package/build/specs/NativeMdocDataTransfer.d.ts +6 -4
- package/build/specs/NativeMdocDataTransfer.d.ts.map +1 -1
- package/build/specs/NativeMdocDataTransfer.js +2 -1
- package/build/specs/NativeMdocDataTransfer.js.map +1 -1
- package/expo-module.config.json +7 -5
- package/ios/MdocDataTransfer-Bridging-Header.h +1 -2
- package/ios/MdocDataTransfer.swift +186 -221
- package/ios/MdocDataTransferError.swift +36 -36
- package/ios/MdocDataTransferEvent.swift +12 -0
- package/ios/MdocDataTransferModule.swift +39 -0
- package/ios/eudi/BLETransfer/MdocGATTServer.swift +315 -0
- package/ios/eudi/BLETransfer/MdocOfflineDelegate.swift +15 -0
- package/ios/eudi/BLETransfer/ServiceCharacteristics.swift +48 -0
- package/ios/eudi/Enumerations.swift +67 -0
- package/ios/eudi/MdocDataTransfer18013.swift +21 -0
- package/ios/eudi/MdocHelpers.swift +94 -0
- package/package.json +14 -16
- package/plugin/build/withAndroid.js +16 -3
- package/plugin/src/index.ts +16 -0
- package/plugin/src/withAndroid.ts +199 -0
- package/plugin/src/withIos.ts +48 -0
- package/plugin/tsconfig.json +9 -0
- package/plugin/tsconfig.tsbuildinfo +1 -0
- package/src/MdocDataTransfer.ts +89 -0
- package/src/MdocDataTransferError.ts +1 -0
- package/src/MdocDataTransferEvent.ts +16 -0
- package/src/NativeMdocDataTransfer.ts +18 -0
- package/src/index.ts +2 -0
- package/src/useMdocDataTransferShutdownOnUnmount.ts +9 -0
- package/tsconfig.json +9 -0
- package/README.md +0 -41
- package/ios/MdocDataTransfer.mm +0 -23
- package/src/specs/NativeMdocDataTransfer.ts +0 -13
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2023 European Commission
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import Foundation
|
|
18
|
+
import SwiftCBOR
|
|
19
|
+
import CoreBluetooth
|
|
20
|
+
import Logging
|
|
21
|
+
import MdocDataModel18013
|
|
22
|
+
import MdocSecurity18013
|
|
23
|
+
import WalletStorage
|
|
24
|
+
|
|
25
|
+
public class MdocGattServer: @unchecked Sendable, ObservableObject {
|
|
26
|
+
var secureArea: SecureEnclaveSecureArea!
|
|
27
|
+
var crv = CoseEcCurve.P256
|
|
28
|
+
|
|
29
|
+
var peripheralManager: CBPeripheralManager!
|
|
30
|
+
var bleDelegate: Delegate!
|
|
31
|
+
var remoteCentral: CBCentral!
|
|
32
|
+
var stateCharacteristic: CBMutableCharacteristic!
|
|
33
|
+
var server2ClientCharacteristic: CBMutableCharacteristic!
|
|
34
|
+
public var deviceEngagement: DeviceEngagement?
|
|
35
|
+
public var qrCodePayload: String?
|
|
36
|
+
public weak var delegate: (any MdocOfflineDelegate)?
|
|
37
|
+
var continuationQrCodeReady: CheckedContinuation<Void, Error>?
|
|
38
|
+
public var advertising: Bool = false
|
|
39
|
+
public var error: Error? = nil {
|
|
40
|
+
willSet {
|
|
41
|
+
handleErrorSet(newValue)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
public var status: TransferStatus = .initializing {
|
|
45
|
+
willSet {
|
|
46
|
+
Task { @MainActor in
|
|
47
|
+
await handleStatusChange(newValue)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
public var unlockData: [String: Data]!
|
|
52
|
+
public var deviceResponseBytes: Data?
|
|
53
|
+
var readBuffer = Data()
|
|
54
|
+
var sendBuffer = [Data]()
|
|
55
|
+
var numBlocks: Int = 0
|
|
56
|
+
var subscribeCount: Int = 0
|
|
57
|
+
var initSuccess:Bool = false
|
|
58
|
+
|
|
59
|
+
public init() {
|
|
60
|
+
secureArea = SecureEnclaveSecureArea.create(storage: KeyChainSecureKeyStorage(serviceName: "TODO_SERVICE_NAME", accessGroup: nil))
|
|
61
|
+
status = .initialized
|
|
62
|
+
initPeripheralManager()
|
|
63
|
+
initSuccess = true
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@objc(CBPeripheralManagerDelegate)
|
|
67
|
+
class Delegate: NSObject, CBPeripheralManagerDelegate {
|
|
68
|
+
unowned var server: MdocGattServer
|
|
69
|
+
|
|
70
|
+
init(server: MdocGattServer) {
|
|
71
|
+
self.server = server
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
func peripheralManagerIsReady(toUpdateSubscribers peripheral: CBPeripheralManager) {
|
|
75
|
+
if server.sendBuffer.count > 0 {
|
|
76
|
+
self.server.sendDataWithUpdates()
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
|
|
81
|
+
logger.info("CBPeripheralManager didUpdateState:")
|
|
82
|
+
logger.info(peripheral.state == .poweredOn ? "Powered on" : peripheral.state == .unauthorized ? "Unauthorized" : peripheral.state == .unsupported ? "Unsupported" : "Powered off")
|
|
83
|
+
if peripheral.state == .poweredOn, server.qrCodePayload != nil {
|
|
84
|
+
server.continuationQrCodeReady?.resume()
|
|
85
|
+
server.continuationQrCodeReady = nil
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveWrite requests: [CBATTRequest]) {
|
|
90
|
+
if requests[0].characteristic.uuid == MdocServiceCharacteristic.state.uuid, let h = requests[0].value?.first {
|
|
91
|
+
if h == BleTransferMode.START_REQUEST.first! {
|
|
92
|
+
logger.info("Start request received to state characteristic") // --> start
|
|
93
|
+
server.status = .started
|
|
94
|
+
server.readBuffer.removeAll()
|
|
95
|
+
} else if h == BleTransferMode.END_REQUEST.first! {
|
|
96
|
+
guard server.status == .responseSent else {
|
|
97
|
+
logger.error("State END command rejected. Not in responseSent state")
|
|
98
|
+
peripheral.respond(to: requests[0], withResult: .unlikelyError)
|
|
99
|
+
return
|
|
100
|
+
}
|
|
101
|
+
logger.info("End received to state characteristic") // --> end
|
|
102
|
+
server.status = .disconnected
|
|
103
|
+
}
|
|
104
|
+
} else if requests[0].characteristic.uuid == MdocServiceCharacteristic.client2Server.uuid {
|
|
105
|
+
for r in requests {
|
|
106
|
+
guard let data = r.value, let h = data.first else {
|
|
107
|
+
continue
|
|
108
|
+
}
|
|
109
|
+
let bStart = h == BleTransferMode.START_DATA.first!
|
|
110
|
+
let bEnd = (h == BleTransferMode.END_DATA.first!)
|
|
111
|
+
if data.count > 1 {
|
|
112
|
+
server.readBuffer.append(data.advanced(by: 1))
|
|
113
|
+
}
|
|
114
|
+
if !bStart && !bEnd {
|
|
115
|
+
logger.warning("Not a valid request block: \(data)")
|
|
116
|
+
}
|
|
117
|
+
if bEnd {
|
|
118
|
+
server.status = .requestReceived
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
peripheral.respond(to: requests[0], withResult: .success)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didSubscribeTo characteristic: CBCharacteristic) {
|
|
126
|
+
guard server.status == .qrEngagementReady else {
|
|
127
|
+
return
|
|
128
|
+
}
|
|
129
|
+
let mdocCbc = MdocServiceCharacteristic(uuid: characteristic.uuid)
|
|
130
|
+
logger.info("Remote central \(central.identifier) connected for \(mdocCbc?.rawValue ?? "") characteristic")
|
|
131
|
+
server.remoteCentral = central
|
|
132
|
+
if characteristic.uuid == MdocServiceCharacteristic.state.uuid || characteristic.uuid == MdocServiceCharacteristic.server2Client.uuid {
|
|
133
|
+
server.subscribeCount += 1
|
|
134
|
+
}
|
|
135
|
+
if server.subscribeCount > 1 {
|
|
136
|
+
server.status = .connected
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
public func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didUnsubscribeFrom characteristic: CBCharacteristic) {
|
|
141
|
+
let mdocCbc = MdocServiceCharacteristic(uuid: characteristic.uuid)
|
|
142
|
+
logger.info("Remote central \(central.identifier) disconnected for \(mdocCbc?.rawValue ?? "") characteristic")
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/// Returns true if the peripheralManager state is poweredOn
|
|
147
|
+
public var isBlePoweredOn: Bool { peripheralManager.state == .poweredOn }
|
|
148
|
+
|
|
149
|
+
/// Returns true if the peripheralManager state is unauthorized
|
|
150
|
+
public var isBlePermissionDenied: Bool { peripheralManager.state == .unauthorized }
|
|
151
|
+
|
|
152
|
+
// Create a new device engagement object and start the device engagement process.
|
|
153
|
+
///
|
|
154
|
+
/// ``qrCodePayload`` is set to QR code data corresponding to the device engagement.
|
|
155
|
+
public func performDeviceEngagement() async throws -> String {
|
|
156
|
+
guard status == .initialized || status == .disconnected || status == .responseSent else {
|
|
157
|
+
throw MdocHelpers.makeError(code: .unexpected_error, str: error?.localizedDescription ?? "Not initialized!")
|
|
158
|
+
}
|
|
159
|
+
deviceEngagement = DeviceEngagement(isBleServer: true, rfus: nil)
|
|
160
|
+
try await deviceEngagement!.makePrivateKey(crv: crv, secureArea: secureArea)
|
|
161
|
+
qrCodePayload = deviceEngagement!.getQrCodePayload()
|
|
162
|
+
guard peripheralManager.state != .unauthorized else {
|
|
163
|
+
throw MdocHelpers.makeError(code: .bleNotAuthorized)
|
|
164
|
+
}
|
|
165
|
+
if !isBlePoweredOn {
|
|
166
|
+
try await withCheckedThrowingContinuation { c in
|
|
167
|
+
continuationQrCodeReady = c
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
startBleAdvertising()
|
|
171
|
+
return qrCodePayload!
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
func buildServices(uuid: String) {
|
|
175
|
+
let bleUserService = CBMutableService(type: CBUUID(string: uuid), primary: true)
|
|
176
|
+
stateCharacteristic = CBMutableCharacteristic(type: MdocServiceCharacteristic.state.uuid, properties: [.notify, .writeWithoutResponse], value: nil, permissions: [.writeable])
|
|
177
|
+
let client2ServerCharacteristic = CBMutableCharacteristic(type: MdocServiceCharacteristic.client2Server.uuid, properties: [.writeWithoutResponse], value: nil, permissions: [.writeable])
|
|
178
|
+
server2ClientCharacteristic = CBMutableCharacteristic(type: MdocServiceCharacteristic.server2Client.uuid, properties: [.notify], value: nil, permissions: [])
|
|
179
|
+
bleUserService.characteristics = [stateCharacteristic, client2ServerCharacteristic, server2ClientCharacteristic]
|
|
180
|
+
peripheralManager.removeAllServices()
|
|
181
|
+
peripheralManager.add(bleUserService)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
func startBleAdvertising() {
|
|
185
|
+
guard !isPreview && !isInErrorState else {
|
|
186
|
+
logger.info("Current status is \(status)")
|
|
187
|
+
return
|
|
188
|
+
}
|
|
189
|
+
if peripheralManager.state == .poweredOn {
|
|
190
|
+
logger.info("Peripheral manager powered on")
|
|
191
|
+
error = nil
|
|
192
|
+
guard let uuid = deviceEngagement?.ble_uuid else {
|
|
193
|
+
logger.error("BLE initialization error")
|
|
194
|
+
return
|
|
195
|
+
}
|
|
196
|
+
buildServices(uuid: uuid)
|
|
197
|
+
let advertisementData: [String: Any] = [ CBAdvertisementDataServiceUUIDsKey: [CBUUID(string: uuid)], CBAdvertisementDataLocalNameKey: uuid ]
|
|
198
|
+
// advertise the peripheral with the short UUID
|
|
199
|
+
peripheralManager.startAdvertising(advertisementData)
|
|
200
|
+
advertising = true
|
|
201
|
+
status = .qrEngagementReady
|
|
202
|
+
} else {
|
|
203
|
+
// once bt is powered on, advertise
|
|
204
|
+
if peripheralManager.state == .resetting {
|
|
205
|
+
DispatchQueue.main.asyncAfter(deadline: .now()+1) {
|
|
206
|
+
self.startBleAdvertising()
|
|
207
|
+
}
|
|
208
|
+
} else {
|
|
209
|
+
logger.info("Peripheral manager powered off")
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
public func stop() {
|
|
215
|
+
guard !isPreview else {
|
|
216
|
+
return
|
|
217
|
+
}
|
|
218
|
+
if let peripheralManager, peripheralManager.isAdvertising {
|
|
219
|
+
peripheralManager.stopAdvertising()
|
|
220
|
+
}
|
|
221
|
+
qrCodePayload = nil
|
|
222
|
+
advertising = false
|
|
223
|
+
subscribeCount = 0
|
|
224
|
+
if let pk = deviceEngagement?.privateKey {
|
|
225
|
+
Task { @MainActor in
|
|
226
|
+
try? await pk.secureArea.deleteKeyBatch(id: pk.privateKeyId, startIndex: 0, batchSize: 1)
|
|
227
|
+
deviceEngagement?.privateKey = nil
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if status == .error && initSuccess {
|
|
231
|
+
status = .initializing
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
fileprivate func initPeripheralManager() {
|
|
236
|
+
guard peripheralManager == nil else {
|
|
237
|
+
return
|
|
238
|
+
}
|
|
239
|
+
bleDelegate = Delegate(server: self)
|
|
240
|
+
logger.info("Initializing BLE peripheral manager")
|
|
241
|
+
peripheralManager = CBPeripheralManager(delegate: bleDelegate, queue: nil)
|
|
242
|
+
subscribeCount = 0
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
func handleStatusChange(_ newValue: TransferStatus) async {
|
|
246
|
+
guard !isPreview && !isInErrorState else {
|
|
247
|
+
return
|
|
248
|
+
}
|
|
249
|
+
logger.log(level: .info, "Transfer status will change to \(newValue)")
|
|
250
|
+
delegate?.didChangeStatus(newValue)
|
|
251
|
+
if newValue == .requestReceived {
|
|
252
|
+
peripheralManager.stopAdvertising()
|
|
253
|
+
delegate?.didReceiveRequest(readBuffer)
|
|
254
|
+
}
|
|
255
|
+
else if newValue == .initialized {
|
|
256
|
+
initPeripheralManager()
|
|
257
|
+
} else if newValue == .disconnected && status != .disconnected {
|
|
258
|
+
stop()
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
var isPreview: Bool {
|
|
263
|
+
ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1"
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
var isInErrorState: Bool { status == .error }
|
|
267
|
+
|
|
268
|
+
func handleErrorSet(_ newValue: Error?) {
|
|
269
|
+
guard let newValue else {
|
|
270
|
+
return
|
|
271
|
+
}
|
|
272
|
+
status = .error
|
|
273
|
+
delegate?.didFinishedWithError(newValue)
|
|
274
|
+
logger.log(level: .error, "Transfer error \(newValue) (\(newValue.localizedDescription)")
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
func prepareDataToSend(_ msg: Data) {
|
|
278
|
+
let mbs = min(511, remoteCentral.maximumUpdateValueLength-1)
|
|
279
|
+
numBlocks = MdocHelpers.CountNumBlocks(dataLength: msg.count, maxBlockSize: mbs)
|
|
280
|
+
logger.info("Sending response of total bytes \(msg.count) in \(numBlocks) blocks and block size: \(mbs)")
|
|
281
|
+
sendBuffer.removeAll()
|
|
282
|
+
// send blocks
|
|
283
|
+
for i in 0..<numBlocks {
|
|
284
|
+
let (block,bEnd) = MdocHelpers.CreateBlockCommand(data: msg, blockId: i, maxBlockSize: mbs)
|
|
285
|
+
var blockWithHeader = Data()
|
|
286
|
+
blockWithHeader.append(contentsOf: !bEnd ? BleTransferMode.START_DATA : BleTransferMode.END_DATA)
|
|
287
|
+
// send actual data after header
|
|
288
|
+
blockWithHeader.append(contentsOf: block)
|
|
289
|
+
sendBuffer.append(blockWithHeader)
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
func sendDataWithUpdates() {
|
|
294
|
+
guard !isPreview else {
|
|
295
|
+
return
|
|
296
|
+
}
|
|
297
|
+
guard sendBuffer.count > 0 else {
|
|
298
|
+
status = .responseSent
|
|
299
|
+
logger.info("Finished sending BLE data")
|
|
300
|
+
stop()
|
|
301
|
+
return
|
|
302
|
+
}
|
|
303
|
+
let b = peripheralManager.updateValue(sendBuffer.first!, for: server2ClientCharacteristic, onSubscribedCentrals: [remoteCentral])
|
|
304
|
+
if b, sendBuffer.count > 0 {
|
|
305
|
+
sendBuffer.removeFirst()
|
|
306
|
+
sendDataWithUpdates()
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
func sendDeviceResponse(deviceResponse: Data) {
|
|
311
|
+
self.prepareDataToSend(deviceResponse)
|
|
312
|
+
self.sendDataWithUpdates()
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//
|
|
2
|
+
// MdocOfflineHandler.swift
|
|
3
|
+
|
|
4
|
+
import Foundation
|
|
5
|
+
import MdocDataModel18013
|
|
6
|
+
import MdocSecurity18013
|
|
7
|
+
|
|
8
|
+
/// delegate protocol for clients of the mdoc offline transfer manager
|
|
9
|
+
public protocol MdocOfflineDelegate: AnyObject {
|
|
10
|
+
func didChangeStatus(_ newStatus: TransferStatus)
|
|
11
|
+
func didFinishedWithError(_ error: Error)
|
|
12
|
+
func didReceiveRequest(_ deviceRequest: Data)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2023 European Commission
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
// ServiceDefinition.swift
|
|
18
|
+
import Foundation
|
|
19
|
+
import CoreBluetooth
|
|
20
|
+
import SwiftCBOR
|
|
21
|
+
|
|
22
|
+
/// The enum BleTransferMode defines the two roles in the communication, which can be a server or a client.
|
|
23
|
+
///
|
|
24
|
+
/// The four static variables are used to signal the start and the end of the communication. This is done by sending the bytes 0x01 and 0x02 for the start and end of the communication, respectively. For the start and end of the data transmission, the bytes 0x01 and 0x00 are used.
|
|
25
|
+
public enum BleTransferMode: Sendable {
|
|
26
|
+
case server
|
|
27
|
+
case client
|
|
28
|
+
// signals for coordination
|
|
29
|
+
static let START_REQUEST: [UInt8] = [0x01]
|
|
30
|
+
static let END_REQUEST: [UInt8] = [0x02]
|
|
31
|
+
static let START_DATA: [UInt8] = [0x01]
|
|
32
|
+
static let END_DATA: [UInt8] = [0x00]
|
|
33
|
+
public static let BASE_UUID_SUFFIX_SERVICE = "-0000-1000-8000-00805F9B34FB"
|
|
34
|
+
public static let QRHandover = CBOR.null
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/// mdoc service characteristic definitions (mdoc is the GATT server)
|
|
38
|
+
public enum MdocServiceCharacteristic: String, Sendable {
|
|
39
|
+
case state = "00000001-A123-48CE-896B-4C76973373E6"
|
|
40
|
+
case client2Server = "00000002-A123-48CE-896B-4C76973373E6"
|
|
41
|
+
case server2Client = "00000003-A123-48CE-896B-4C76973373E6"
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
extension MdocServiceCharacteristic {
|
|
45
|
+
init?(uuid: CBUUID) { self.init(rawValue: uuid.uuidString.uppercased()) }
|
|
46
|
+
var uuid: CBUUID { CBUUID(string: rawValue) }
|
|
47
|
+
}
|
|
48
|
+
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2023 European Commission
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
// TransferStatus.swift
|
|
18
|
+
|
|
19
|
+
import Foundation
|
|
20
|
+
|
|
21
|
+
/// Transfer status enumeration
|
|
22
|
+
public enum TransferStatus: String, Sendable {
|
|
23
|
+
case initializing
|
|
24
|
+
case initialized
|
|
25
|
+
case qrEngagementReady
|
|
26
|
+
case connected
|
|
27
|
+
case started
|
|
28
|
+
case requestReceived
|
|
29
|
+
case userSelected
|
|
30
|
+
case responseSent
|
|
31
|
+
case disconnected
|
|
32
|
+
case error
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public enum ErrorCode: Int, CustomStringConvertible, Sendable {
|
|
36
|
+
case documents_not_provided
|
|
37
|
+
case invalidInputDocument
|
|
38
|
+
case invalidUrl
|
|
39
|
+
case device_private_key_not_provided
|
|
40
|
+
case noDocumentToReturn
|
|
41
|
+
case userRejected
|
|
42
|
+
case requestDecodeError
|
|
43
|
+
case bleNotAuthorized
|
|
44
|
+
case bleNotSupported
|
|
45
|
+
case unexpected_error
|
|
46
|
+
case sessionEncryptionNotInitialized
|
|
47
|
+
case deviceEngagementMissing
|
|
48
|
+
case readerKeyMissing
|
|
49
|
+
|
|
50
|
+
public var description: String {
|
|
51
|
+
switch self {
|
|
52
|
+
case .documents_not_provided: return "DOCUMENTS_NOT_PROVIDED"
|
|
53
|
+
case .invalidInputDocument: return "INVALID_INPUT_DOCUMENT"
|
|
54
|
+
case .invalidUrl: return "INVALID_URL"
|
|
55
|
+
case .device_private_key_not_provided: return "DEVICE_PRIVATE_KEY_NOT_PROVIDED"
|
|
56
|
+
case .noDocumentToReturn: return "NO_DOCUMENT_TO_RETURN"
|
|
57
|
+
case .requestDecodeError: return "REQUEST_DECODE_ERROR"
|
|
58
|
+
case .userRejected: return "USER_REJECTED"
|
|
59
|
+
case .bleNotAuthorized: return "BLE_NOT_AUTHORIZED"
|
|
60
|
+
case .bleNotSupported: return "BLE_NOT_SUPPORTED"
|
|
61
|
+
case .deviceEngagementMissing: return "DEVICE_ENGAGEMENT_MISSING"
|
|
62
|
+
case .readerKeyMissing: return "READER_KEY_MISSING"
|
|
63
|
+
case .sessionEncryptionNotInitialized: return "SESSION_ENCYPTION_NOT_INITIALIZED"
|
|
64
|
+
default: return "GENERIC_ERROR"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2023 European Commission
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
// The Swift Programming Language
|
|
18
|
+
// https://docs.swift.org/swift-book
|
|
19
|
+
import Logging
|
|
20
|
+
// abstract logger. By default writes to console
|
|
21
|
+
let logger = Logger(label: "MdocDataTransfer18013")
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2023 European Commission
|
|
3
|
+
|
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
you may not use this file except in compliance with the License.
|
|
6
|
+
You may obtain a copy of the License at
|
|
7
|
+
|
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
See the License for the specific language governing permissions and
|
|
14
|
+
limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
// Helpers.swift
|
|
18
|
+
import Foundation
|
|
19
|
+
//import CoreBluetooth
|
|
20
|
+
//import Combine
|
|
21
|
+
import MdocDataModel18013
|
|
22
|
+
import MdocSecurity18013
|
|
23
|
+
//import AVFoundation
|
|
24
|
+
import SwiftCBOR
|
|
25
|
+
import Logging
|
|
26
|
+
|
|
27
|
+
/// Helper methods
|
|
28
|
+
public class MdocHelpers {
|
|
29
|
+
|
|
30
|
+
static var errorNoDocumentsDescriptionKey: String { "doctype_not_found" }
|
|
31
|
+
static func getErrorNoDocuments(_ docType: String) -> Error { NSError(domain: "\(MdocGattServer.self)", code: 0, userInfo: ["key": Self.errorNoDocumentsDescriptionKey, "%s": docType]) }
|
|
32
|
+
|
|
33
|
+
public static func makeError(code: ErrorCode, str: String? = nil) -> NSError {
|
|
34
|
+
let errorMessage = str ?? NSLocalizedString(code.description, comment: code.description)
|
|
35
|
+
logger.error(Logger.Message(unicodeScalarLiteral: errorMessage))
|
|
36
|
+
return NSError(domain: "\(MdocGattServer.self)", code: code.rawValue, userInfo: [NSLocalizedDescriptionKey: errorMessage, "key": code.description])
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/// Get the session data to send to the reader. The session data is encrypted using the session encryption object
|
|
40
|
+
/// - Parameters:
|
|
41
|
+
/// - sessionEncryption: Instance of session encryption object
|
|
42
|
+
/// - status: Transfer status
|
|
43
|
+
/// - docToSend: Device response object to send
|
|
44
|
+
///
|
|
45
|
+
/// - Returns: A tuple containing the encrypted session data and the clear text data to send.
|
|
46
|
+
public static func getSessionDataToSend(sessionEncryption: SessionEncryption?, status: TransferStatus, docToSend: DeviceResponse) async -> Result<(Data, Data), Error> {
|
|
47
|
+
do {
|
|
48
|
+
guard var sessionEncryption else { logger.error("Session Encryption not initialized"); return .failure(Self.makeError(code: .sessionEncryptionNotInitialized)) }
|
|
49
|
+
if docToSend.documents == nil, status != .error { logger.error("Could not create documents to send") }
|
|
50
|
+
let cborToSend = docToSend.toCBOR(options: CBOROptions())
|
|
51
|
+
let clearBytesToSend = cborToSend.encode()
|
|
52
|
+
let cipherData = try await sessionEncryption.encrypt(clearBytesToSend)
|
|
53
|
+
let sd = SessionData(cipher_data: status == .error ? nil : cipherData, status: status == .error ? 11 : 20)
|
|
54
|
+
return .success((Data(sd.encode(options: CBOROptions())), Data(clearBytesToSend)))
|
|
55
|
+
} catch { return .failure(error) }
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/// Creates a block for a given block id from a data object. The block size is limited to maxBlockSize bytes.
|
|
59
|
+
/// - Parameters:
|
|
60
|
+
/// - data: The data object to be sent
|
|
61
|
+
/// - blockId: The id (number) of the block to be sent
|
|
62
|
+
/// - maxBlockSize: The maximum block size
|
|
63
|
+
/// - Returns: (chunk:The data block, bEnd: True if this is the last block, false otherwise)
|
|
64
|
+
public static func CreateBlockCommand(data: Data, blockId: Int, maxBlockSize: Int) -> (Data, Bool) {
|
|
65
|
+
let start = blockId * maxBlockSize
|
|
66
|
+
var end = (blockId+1) * maxBlockSize
|
|
67
|
+
var bEnd = false
|
|
68
|
+
if end >= data.count {
|
|
69
|
+
end = data.count
|
|
70
|
+
bEnd = true
|
|
71
|
+
}
|
|
72
|
+
let chunk = data.subdata(in: start..<end)
|
|
73
|
+
return (chunk,bEnd)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/// Returns the number of blocks that dataLength bytes of data can be split into, given a maximum block size of maxBlockSize bytes.
|
|
77
|
+
/// - Parameters:
|
|
78
|
+
/// - dataLength: Length of data to be split
|
|
79
|
+
/// - maxBlockSize: The maximum block size
|
|
80
|
+
/// - Returns: Number of blocks
|
|
81
|
+
public static func CountNumBlocks(dataLength: Int, maxBlockSize: Int) -> Int {
|
|
82
|
+
let blockSize = maxBlockSize
|
|
83
|
+
var numBlocks = 0
|
|
84
|
+
if dataLength > maxBlockSize {
|
|
85
|
+
numBlocks = dataLength / blockSize;
|
|
86
|
+
if numBlocks * blockSize < dataLength {
|
|
87
|
+
numBlocks += 1
|
|
88
|
+
}
|
|
89
|
+
} else if dataLength > 0 {
|
|
90
|
+
numBlocks = 1
|
|
91
|
+
}
|
|
92
|
+
return numBlocks
|
|
93
|
+
}
|
|
94
|
+
}
|
package/package.json
CHANGED
|
@@ -1,19 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@animo-id/expo-mdoc-data-transfer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0-alpha.0",
|
|
4
4
|
"description": "Expo mdoc data transfer module",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"access": "public"
|
|
9
9
|
},
|
|
10
|
-
"scripts": {
|
|
11
|
-
"build": "EXPO_NONINTERACTIVE=1 expo-module build && EXPO_NONINTERACTIVE=1 expo-module build plugin",
|
|
12
|
-
"style:check": "biome check --unsafe",
|
|
13
|
-
"style:fix": "pnpm style:check --write",
|
|
14
|
-
"types:check": "EXPO_NONINTERACTIVE=1 expo-module typecheck && EXPO_NONINTERACTIVE=1 expo-module plugin typecheck",
|
|
15
|
-
"release": "release-it"
|
|
16
|
-
},
|
|
17
10
|
"keywords": [
|
|
18
11
|
"react-native",
|
|
19
12
|
"expo",
|
|
@@ -28,22 +21,27 @@
|
|
|
28
21
|
"license": "Apache-2.0",
|
|
29
22
|
"homepage": "https://github.com/animo/expo-mdoc-data-transfer#readme",
|
|
30
23
|
"devDependencies": {
|
|
31
|
-
"@
|
|
32
|
-
"@
|
|
33
|
-
"@types/node": "^22.8.1",
|
|
24
|
+
"@expo/config-types": "^54.0.8",
|
|
25
|
+
"@types/node": "^24.10.0",
|
|
34
26
|
"@types/react": "~18.2.79",
|
|
35
27
|
"expo-module-scripts": "3.5.2",
|
|
36
28
|
"expo-modules-core": "~1.12.26",
|
|
37
29
|
"react-native": "0.75.3",
|
|
38
30
|
"release-it": "^17.4.1",
|
|
39
|
-
"typescript": "~5.
|
|
31
|
+
"typescript": "~5.9.3"
|
|
40
32
|
},
|
|
41
33
|
"peerDependencies": {
|
|
42
34
|
"expo": ">= 51",
|
|
43
|
-
"react
|
|
44
|
-
"react": "
|
|
35
|
+
"react": "*",
|
|
36
|
+
"react-native": ">= 0.75"
|
|
45
37
|
},
|
|
46
38
|
"dependencies": {
|
|
47
|
-
"@expo/config-plugins": "^8.0.10"
|
|
39
|
+
"@expo/config-plugins": "^8.0.10",
|
|
40
|
+
"buffer": "^6.0.3"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "EXPO_NONINTERACTIVE=1 expo-module build && EXPO_NONINTERACTIVE=1 expo-module build plugin",
|
|
44
|
+
"types:check": "EXPO_NONINTERACTIVE=1 expo-module typecheck && EXPO_NONINTERACTIVE=1 expo-module plugin typecheck",
|
|
45
|
+
"release": "release-it"
|
|
48
46
|
}
|
|
49
|
-
}
|
|
47
|
+
}
|
|
@@ -81,13 +81,13 @@ const withAndroidNfcProperties = (expoConfig) => (0, config_plugins_1.withAndroi
|
|
|
81
81
|
});
|
|
82
82
|
}
|
|
83
83
|
for (const app of androidManifest.application ?? []) {
|
|
84
|
-
if (app.service?.some((s) => s.$['android:name'] === 'id.animo.
|
|
84
|
+
if (app.service?.some((s) => s.$['android:name'] === 'id.animo.mdoc.datatransfer.NfcEngagementServiceImpl'))
|
|
85
85
|
continue;
|
|
86
86
|
app.service ??= [];
|
|
87
87
|
app.service.push({
|
|
88
88
|
$: {
|
|
89
89
|
'android:exported': 'true',
|
|
90
|
-
'android:name': 'id.animo.
|
|
90
|
+
'android:name': 'id.animo.mdoc.datatransfer.NfcEngagementServiceImpl',
|
|
91
91
|
'android:permission': 'android.permission.BIND_NFC_SERVICE',
|
|
92
92
|
},
|
|
93
93
|
'intent-filter': [
|
|
@@ -106,7 +106,7 @@ const withAndroidNfcProperties = (expoConfig) => (0, config_plugins_1.withAndroi
|
|
|
106
106
|
],
|
|
107
107
|
},
|
|
108
108
|
],
|
|
109
|
-
// @ts-
|
|
109
|
+
// @ts-expect-error
|
|
110
110
|
'meta-data': {
|
|
111
111
|
$: {
|
|
112
112
|
'android:name': 'android.nfc.cardemulation.host_apdu_service',
|
|
@@ -117,10 +117,23 @@ const withAndroidNfcProperties = (expoConfig) => (0, config_plugins_1.withAndroi
|
|
|
117
117
|
}
|
|
118
118
|
return c;
|
|
119
119
|
});
|
|
120
|
+
const withAndroidFixMetaInfConflict = (expoConfig) => (0, config_plugins_1.withAppBuildGradle)(expoConfig, (c) => {
|
|
121
|
+
if (c.modResults.contents.includes('META-INF/versions/9/OSGI-INF/MANIFEST.MF')) {
|
|
122
|
+
return c;
|
|
123
|
+
}
|
|
124
|
+
c.modResults.contents = c.modResults.contents.replace(/android\s?{/, `android {
|
|
125
|
+
packagingOptions {
|
|
126
|
+
resources {
|
|
127
|
+
excludes += "META-INF/versions/9/OSGI-INF/MANIFEST.MF"
|
|
128
|
+
}
|
|
129
|
+
}`);
|
|
130
|
+
return c;
|
|
131
|
+
});
|
|
120
132
|
const withAndroid = (config) => (0, config_plugins_1.withPlugins)(config, [
|
|
121
133
|
(c) => config_plugins_1.AndroidConfig.Permissions.withPermissions(c, ['android.permission.BLUETOOTH_CONNECT']),
|
|
122
134
|
withBleAndroidManifest,
|
|
123
135
|
withAndroidExcludeBcProv,
|
|
124
136
|
withAndroidNfcProperties,
|
|
137
|
+
withAndroidFixMetaInfConflict,
|
|
125
138
|
]);
|
|
126
139
|
exports.withAndroid = withAndroid;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type ConfigPlugin, createRunOncePlugin, withPlugins } from '@expo/config-plugins'
|
|
2
|
+
|
|
3
|
+
import { withAndroid } from './withAndroid'
|
|
4
|
+
import { withIos } from './withIos'
|
|
5
|
+
|
|
6
|
+
export type Props = {
|
|
7
|
+
ios?: {
|
|
8
|
+
buildStatic?: Array<string>
|
|
9
|
+
bluetoothDescription?: string
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const withMdocDataTransfer: ConfigPlugin<Props> = (config, props) =>
|
|
14
|
+
withPlugins(config, [withAndroid, [withIos, props]])
|
|
15
|
+
|
|
16
|
+
export default createRunOncePlugin(withMdocDataTransfer, '@animo-id/mdoc-data-transfer')
|