Hello Sir !, thank you very much for the library, it was working very good with Algerian passports and Idcards, but I'm facing the next error with the new Idcards:
I/flutter (19080): passport FINE: 2024-08-05 16:26:15.734148: Reading EF.CardAccess
I/flutter (19080): passport FINE: 2024-08-05 16:26:15.740979: Selecting MF
I/flutter (19080): mrtd.api FINE: 2024-08-05 16:26:15.742924: Selecting root Master File
I/flutter (19080): icc FINE: 2024-08-05 16:26:15.746479: Transceiving to ICC: C-APDU(CLA:00 INS:A4 P1:00 P2:00 Le:0 Lc:0 Data:null)
I/flutter (19080): icc FINE: 2024-08-05 16:26:15.751509: Sending 4 byte(s) to ICC: data='00a40000'
I/flutter (19080): icc FINE: 2024-08-05 16:26:15.795560: Received 2 byte(s) from ICC
I/flutter (19080): icc FINE: 2024-08-05 16:26:15.797960: Received response from ICC: sw=6700 data_len=0
I/flutter (19080): mrtd.api WARNING: 2024-08-05 16:26:15.802688: Couldn't select MF by P1: 0, P2: 0 sw=sw=6700, re-trying to select MF with FileID=3F00
I/flutter (19080): icc FINE: 2024-08-05 16:26:15.805214: Transceiving to ICC: C-APDU(CLA:00 INS:A4 P1:00 P2:00 Le:0 Lc:2 Data:3f00)
I/flutter (19080): icc FINE: 2024-08-05 16:26:15.806180: Sending 7 byte(s) to ICC: data='00a40000023f00'
I/flutter (19080): icc FINE: 2024-08-05 16:26:15.852395: Received 2 byte(s) from ICC
I/flutter (19080): icc FINE: 2024-08-05 16:26:15.852691: Received response from ICC: sw=6700 data_len=0
I/flutter (19080): mrtd.api WARNING: 2024-08-05 16:26:15.853470: Couldn't select MF by P1=0, P2=0, FileID=3F00 sw=sw=6700, re-trying to select MF with P2=0x0C and FileID=3F00
I/flutter (19080): icc FINE: 2024-08-05 16:26:15.854104: Transceiving to ICC: C-APDU(CLA:00 INS:A4 P1:00 P2:0C Le:0 Lc:2 Data:3f00)
I/flutter (19080): icc FINE: 2024-08-05 16:26:15.854427: Sending 7 byte(s) to ICC: data='00a4000c023f00'
I/flutter (19080): icc FINE: 2024-08-05 16:26:15.892469: Received 2 byte(s) from ICC
I/flutter (19080): icc FINE: 2024-08-05 16:26:15.892794: Received response from ICC: sw=9000 data_len=0
I/flutter (19080): mrtd.api FINE: 2024-08-05 16:26:15.894335: Reading file sfi=0x1C
I/flutter (19080): icc FINE: 2024-08-05 16:26:15.895624: Transceiving to ICC: C-APDU(CLA:00 INS:B0 P1:9C P2:00 Le:8 Lc:0 Data:null)
I/flutter (19080): icc FINE: 2024-08-05 16:26:15.896093: Sending 5 byte(s) to ICC: data='00b09c0008'
I/flutter (19080): icc FINE: 2024-08-05 16:26:15.948402: Received 2 byte(s) from ICC
I/flutter (19080): icc FINE: 2024-08-05 16:26:15.948822: Received response from ICC: sw=6282 data_len=0
I/flutter (19080): nfc.provider FINE: 2024-08-05 16:26:15.950810: Disconnecting
E/flutter (19080): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Null check operator used on a null value
E/flutter (19080): #0 MrtdApi.readFileBySFI (package:dmrtd/src/proto/mrtd_api.dart:167:51)
E/flutter (19080):
E/flutter (19080): #1 Passport._exec (package:dmrtd/src/passport.dart:428:14)
E/flutter (19080):
E/flutter (19080): #2 Passport.readEfCardAccess (package:dmrtd/src/passport.dart:104:11)
E/flutter (19080):
E/flutter (19080): #3 _MrtdHomePageState._readMRTD (package:mrtdeg/main.dart:264:31)
E/flutter (19080):
E/flutter (19080):
String formatProgressMsg(String message, int percentProgress) {
final p = (percentProgress / 20).round();
final full = "🟢 " p;
final empty = "⚪️ " (5 - p);
return message + "\n\n" + full + empty;
}
class _MrtdHomePageState extends State {
var _alertMessage = "";
final _log = Logger("mrtdeg.app");
var _isNfcAvailable = false;
var _isReading = false;
final _mrzData = GlobalKey();
// mrz data
final _docNumber = TextEditingController(text: "411358813");
final _dob = TextEditingController(text: "10/18/1992"); // date of birth
final _doe = TextEditingController(text: "04/22/2034"); // date of doc expiry
MrtdData? _mrtdData;
final NfcProvider _nfc = NfcProvider();
// ignore: unused_field
late Timer _timerStateUpdater;
final _scrollController = ScrollController();
_initPlatformState();
// Update platform state every 3 sec
_timerStateUpdater = Timer.periodic(Duration(seconds: 3), (Timer t) {
_initPlatformState();
});
}
// Platform messages are asynchronous, so we initialize in an async method.
Future _initPlatformState() async {
bool isNfcAvailable;
try {
NfcStatus status = await NfcProvider.nfcStatus;
isNfcAvailable = status == NfcStatus.enabled;
} on PlatformException {
isNfcAvailable = false;
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
_isNfcAvailable = isNfcAvailable;
});
Hello Sir !, thank you very much for the library, it was working very good with Algerian passports and Idcards, but I'm facing the next error with the new Idcards:
I/flutter (19080): passport FINE: 2024-08-05 16:26:15.734148: Reading EF.CardAccess I/flutter (19080): passport FINE: 2024-08-05 16:26:15.740979: Selecting MF I/flutter (19080): mrtd.api FINE: 2024-08-05 16:26:15.742924: Selecting root Master File I/flutter (19080): icc FINE: 2024-08-05 16:26:15.746479: Transceiving to ICC: C-APDU(CLA:00 INS:A4 P1:00 P2:00 Le:0 Lc:0 Data:null) I/flutter (19080): icc FINE: 2024-08-05 16:26:15.751509: Sending 4 byte(s) to ICC: data='00a40000' I/flutter (19080): icc FINE: 2024-08-05 16:26:15.795560: Received 2 byte(s) from ICC I/flutter (19080): icc FINE: 2024-08-05 16:26:15.797960: Received response from ICC: sw=6700 data_len=0 I/flutter (19080): mrtd.api WARNING: 2024-08-05 16:26:15.802688: Couldn't select MF by P1: 0, P2: 0 sw=sw=6700, re-trying to select MF with FileID=3F00 I/flutter (19080): icc FINE: 2024-08-05 16:26:15.805214: Transceiving to ICC: C-APDU(CLA:00 INS:A4 P1:00 P2:00 Le:0 Lc:2 Data:3f00) I/flutter (19080): icc FINE: 2024-08-05 16:26:15.806180: Sending 7 byte(s) to ICC: data='00a40000023f00' I/flutter (19080): icc FINE: 2024-08-05 16:26:15.852395: Received 2 byte(s) from ICC I/flutter (19080): icc FINE: 2024-08-05 16:26:15.852691: Received response from ICC: sw=6700 data_len=0 I/flutter (19080): mrtd.api WARNING: 2024-08-05 16:26:15.853470: Couldn't select MF by P1=0, P2=0, FileID=3F00 sw=sw=6700, re-trying to select MF with P2=0x0C and FileID=3F00 I/flutter (19080): icc FINE: 2024-08-05 16:26:15.854104: Transceiving to ICC: C-APDU(CLA:00 INS:A4 P1:00 P2:0C Le:0 Lc:2 Data:3f00) I/flutter (19080): icc FINE: 2024-08-05 16:26:15.854427: Sending 7 byte(s) to ICC: data='00a4000c023f00' I/flutter (19080): icc FINE: 2024-08-05 16:26:15.892469: Received 2 byte(s) from ICC I/flutter (19080): icc FINE: 2024-08-05 16:26:15.892794: Received response from ICC: sw=9000 data_len=0 I/flutter (19080): mrtd.api FINE: 2024-08-05 16:26:15.894335: Reading file sfi=0x1C I/flutter (19080): icc FINE: 2024-08-05 16:26:15.895624: Transceiving to ICC: C-APDU(CLA:00 INS:B0 P1:9C P2:00 Le:8 Lc:0 Data:null) I/flutter (19080): icc FINE: 2024-08-05 16:26:15.896093: Sending 5 byte(s) to ICC: data='00b09c0008' I/flutter (19080): icc FINE: 2024-08-05 16:26:15.948402: Received 2 byte(s) from ICC I/flutter (19080): icc FINE: 2024-08-05 16:26:15.948822: Received response from ICC: sw=6282 data_len=0 I/flutter (19080): nfc.provider FINE: 2024-08-05 16:26:15.950810: Disconnecting E/flutter (19080): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Null check operator used on a null value E/flutter (19080): #0 MrtdApi.readFileBySFI (package:dmrtd/src/proto/mrtd_api.dart:167:51) E/flutter (19080):
E/flutter (19080): #1 Passport._exec (package:dmrtd/src/passport.dart:428:14)
E/flutter (19080):
E/flutter (19080): #2 Passport.readEfCardAccess (package:dmrtd/src/passport.dart:104:11)
E/flutter (19080):
E/flutter (19080): #3 _MrtdHomePageState._readMRTD (package:mrtdeg/main.dart:264:31)
E/flutter (19080):
E/flutter (19080):
this is my code:
// Created by Crt Vavros, copyright © 2022 ZeroPass. All rights reserved. // ignore_for_file: prefer_adjacent_string_concatenation, prefer_interpolation_to_compose_strings
import 'dart:convert'; import 'dart:io'; import 'package:http/http.dart' as http; import 'package:expandable/expandable.dart'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'dart:async'; import 'dart:typed_data'; import 'package:image_picker/image_picker.dart'; import 'package:dmrtd/dmrtd.dart'; import 'package:dmrtd/extensions.dart'; import 'package:flutter/services.dart'; import 'package:intl/intl.dart'; import 'package:logging/logging.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:toast/toast.dart';
class MrtdData { EfCardAccess? cardAccess; EfCardSecurity? cardSecurity; EfCOM? com; EfSOD? sod; EfDG1? dg1; EfDG2? dg2; EfDG3? dg3; EfDG4? dg4; EfDG5? dg5; EfDG6? dg6; EfDG7? dg7; EfDG8? dg8; EfDG9? dg9; EfDG10? dg10; EfDG11? dg11; EfDG12? dg12; EfDG13? dg13; EfDG14? dg14; EfDG15? dg15; EfDG16? dg16; Uint8List? aaSig; }
final Map<DgTag, String> dgTagToString = { EfDG1.TAG: 'EF.DG1', EfDG2.TAG: 'EF.DG2', EfDG3.TAG: 'EF.DG3', EfDG4.TAG: 'EF.DG4', EfDG5.TAG: 'EF.DG5', EfDG6.TAG: 'EF.DG6', EfDG7.TAG: 'EF.DG7', EfDG8.TAG: 'EF.DG8', EfDG9.TAG: 'EF.DG9', EfDG10.TAG: 'EF.DG10', EfDG11.TAG: 'EF.DG11', EfDG12.TAG: 'EF.DG12', EfDG13.TAG: 'EF.DG13', EfDG14.TAG: 'EF.DG14', EfDG15.TAG: 'EF.DG15', EfDG16.TAG: 'EF.DG16' };
String formatEfCom(final EfCOM efCom) { var str = "version: ${efCom.version}\n" "unicode version: ${efCom.unicodeVersion}\n" "DG tags:";
for (final t in efCom.dgTags) { try { str += " ${dgTagToString[t]!}"; } catch (e) { str += " 0x${t.value.toRadixString(16)}"; } } return str; }
String formatMRZ(final MRZ mrz) { return "MRZ\n" " version: ${mrz.version}\n" + " doc code: ${mrz.documentCode}\n" + " doc No.: ${mrz.documentNumber}\n" + " country: ${mrz.country}\n" + " nationality: ${mrz.nationality}\n" + " name: ${mrz.firstName}\n" + " surname: ${mrz.lastName}\n" + " gender: ${mrz.gender}\n" + " date of birth: ${DateFormat.yMd().format(mrz.dateOfBirth)}\n" + " date of expiry: ${DateFormat.yMd().format(mrz.dateOfExpiry)}\n" + " add. data: ${mrz.optionalData}\n" + " add. data: ${mrz.optionalData2}"; }
String formatDG15(final EfDG15 dg15) { var str = "EF.DG15:\n" " AAPublicKey\n" " type: ";
final rawSubPubKey = dg15.aaPublicKey.rawSubjectPublicKey(); if (dg15.aaPublicKey.type == AAPublicKeyType.RSA) { final tvSubPubKey = TLV.fromBytes(rawSubPubKey); var rawSeq = tvSubPubKey.value; if (rawSeq[0] == 0x00) { rawSeq = rawSeq.sublist(1); }
} else { str += "EC\n SubjectPublicKey: ${rawSubPubKey.hex()}"; } return str; }
String formatProgressMsg(String message, int percentProgress) { final p = (percentProgress / 20).round(); final full = "🟢 " p; final empty = "⚪️ " (5 - p); return message + "\n\n" + full + empty; }
late SharedPreferences prefs;
void main() async { WidgetsFlutterBinding.ensureInitialized(); prefs = await SharedPreferences.getInstance(); Logger.root.level = Level.ALL; Logger.root.onRecord.listen((record) { print( '${record.loggerName} ${record.level.name}: ${record.time}: ${record.message}'); }); runApp(MrtdEgApp()); }
class MrtdEgApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp(localizationsDelegates: [ DefaultMaterialLocalizations.delegate, DefaultCupertinoLocalizations.delegate, DefaultWidgetsLocalizations.delegate, ], home: MrtdHomePage()); } }
class MrtdHomePage extends StatefulWidget { @override // ignore: library_private_types_in_public_api _MrtdHomePageState createState() => _MrtdHomePageState(); }
class _MrtdHomePageState extends State {
var _alertMessage = "";
final _log = Logger("mrtdeg.app");
var _isNfcAvailable = false;
var _isReading = false;
final _mrzData = GlobalKey();
// mrz data final _docNumber = TextEditingController(text: "411358813"); final _dob = TextEditingController(text: "10/18/1992"); // date of birth final _doe = TextEditingController(text: "04/22/2034"); // date of doc expiry
MrtdData? _mrtdData;
final NfcProvider _nfc = NfcProvider(); // ignore: unused_field late Timer _timerStateUpdater; final _scrollController = ScrollController();
@override void initState() { super.initState(); SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]);
}
// Platform messages are asynchronous, so we initialize in an async method. Future _initPlatformState() async {
bool isNfcAvailable;
try {
NfcStatus status = await NfcProvider.nfcStatus;
isNfcAvailable = status == NfcStatus.enabled;
} on PlatformException {
isNfcAvailable = false;
}
}
DateTime? _getDOBDate() { if (_dob.text.isEmpty) { return null; } return DateFormat.yMd().parse(_dob.text); }
DateTime? _getDOEDate() { if (_doe.text.isEmpty) { return null; } return DateFormat.yMd().parse(_doe.text); }
Future<String?> _pickDate(BuildContext context, DateTime firstDate, DateTime initDate, DateTime lastDate) async { final locale = Localizations.localeOf(context); final DateTime? picked = await showDatePicker( context: context, firstDate: firstDate, initialDate: initDate, lastDate: lastDate, locale: locale);
}
void _readMRTD() async { try { setState(() { _mrtdData = null; _alertMessage = "Waiting for Passport tag ..."; _isReading = true; });
}
bool _disabledInput() { return _isReading || !_isNfcAvailable; }
Widget _makeMrtdDataWidget( {required String header, required String collapsedText, required dataText}) { return ExpandablePanel( theme: const ExpandableThemeData( headerAlignment: ExpandablePanelHeaderAlignment.center, tapBodyToCollapse: true, hasIcon: true, iconColor: Colors.red, ), header: Text(header), collapsed: Text(collapsedText, softWrap: true, maxLines: 2, overflow: TextOverflow.ellipsis), expanded: Container( padding: const EdgeInsets.all(18), color: Color.fromARGB(255, 239, 239, 239), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ TextButton( child: Text('Copy'), onPressed: () => Clipboard.setData(ClipboardData(text: dataText)), ), SelectableText(dataText, textAlign: TextAlign.left) ]))); }
List _mrtdDataWidgets() {
List list = [];
if (_mrtdData == null) return list;
}
@override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white,
} }
I really appreciate your help !!