Gemalto - 3M Page Reader Programmers' Guidev33
Gemalto - 3M Page Reader Programmers' Guidev33
Programmers’ Guide
Manual No: 97-0183-10
Version 3.3.0
3M™ Page Reader Programmers’ Guide
Contents Page
1 INTRODUCTION ......................................................................................................................................... 7
2 OVERVIEW ................................................................................................................................................ 11
CD_EFSOD_HASH_MAP .............................................................................................. 46
CD_DOC_SIGNER_CERT ............................................................................................. 47
4.5.6 PLUGIN DATA ............................................................................................................... 48
4.5.7 MISC. DATA ITEMS ...................................................................................................... 49
CD_SWIPE_MSR_DATA ............................................................................................... 49
CD_AAMVA_DATA ...................................................................................................... 49
CD_READ_PROGRESS ................................................................................................. 50
4.5.8 UHF DATA ITEMS ......................................................................................................... 51
CD_UHF_TAGID ............................................................................................................ 51
CD_UHF_EPC ................................................................................................................. 51
4.5.9 DOCUMENT DETECTION AND READING ................................................................ 52
4.6 EVENTS ......................................................................................................................................... 53
4.6.1 MMMREADEREVENTCALLBACK ............................................................................. 53
4.6.2 AVAILABLE EVENTS ................................................................................................... 53
DOC_ON_WINDOW ...................................................................................................... 53
DOC_REMOVED ............................................................................................................ 53
START_OF_DOCUMENT_DATA ................................................................................. 53
END_OF_DOCUMENT_DATA ..................................................................................... 54
READER_ERROR_RESOLVED .................................................................................... 54
SETTINGS_INITIALISED .............................................................................................. 54
PLUGINS_INITIALISED ................................................................................................ 54
RF_CHIP_OPENED_SUCCESSFULLY, RF_APPLICATION_OPENED_SUCCESSFULLY,
RF_CHIP_OPEN_FAILED ............................................................................................. 54
READER_CONNECTED ................................................................................................ 54
READER_DISCONNECTED.......................................................................................... 55
4.7 ERROR CODES ............................................................................................................................. 56
4.8 LOGGING ...................................................................................................................................... 57
4.8.1 LOGGING STRATEGIES ............................................................................................... 57
4.9 E-PASSPORT CERTIFICATES AND SIGNATURES ................................................................. 58
4.9.1
MMMREADERCERTIFICATECALLBACK ................................................................. 58
SIGN REQUEST CALLBACK ....................................................................................... 59
DETAILED API BREAKDOWN................................................................................................................. 61
4.9.2 CONTROL AND STATE ................................................................................................ 62
MMMREADER_INITIALISE ......................................................................................... 62
MMMREADER_SHUTDOWN ....................................................................................... 63
MMMREADER_RESET ................................................................................................. 63
MMMREADER_GETSTATE ......................................................................................... 63
MMMREADER_SETSTATE .......................................................................................... 64
MMMREADER_ENABLEPLUGIN ............................................................................... 64
MMMREADER_ISPLUGINENABLED ......................................................................... 65
MMMREADER_GETPLUGINNAME ........................................................................... 65
MMMREADER_GETCONNECTEDSCANNERS ......................................................... 66
MMMREADER_SELECTSCANNER ............................................................................ 67
MMMREADER_SETSIGNREQUESTCALLBACK ...................................................... 67
MMMREADER_SETRFPASSWORDCALLBACK ...................................................... 67
MMMREADER_SETWARNINGCALLBACK .............................................................. 68
4.9.3 DOCUMENT PROCESSING APIS ................................................................................ 69
MMMREADER_ISDOCUMENTONWINDOW ............................................................ 69
MMMREADER_GETDATA........................................................................................... 69
MMMREADER_GETPLUGINDATA ............................................................................ 71
MMMREADER_WAITFORDOCUMENT ..................................................................... 72
MMMREADER_READDOCUMENT ............................................................................ 72
MMMREADER_CLEARDATA ..................................................................................... 74
MMMREADER_INITIALISEPOSITIONCORRECTION ............................................. 74
POSITION CORRECTION CALLBACK ....................................................................... 75
MMMREADER_RFABORT ........................................................................................... 75
4.9.4 ERROR HANDLING ....................................................................................................... 76
MMMREADER_ENABLELOGGING ............................................................................ 76
MMMREADER_GETLASTERROR .............................................................................. 77
MMMREADER_GETERRORMESSAGE ...................................................................... 77
MMMREADER_LOGMESSAGE ................................................................................... 78
MMMREADER_LOGFORMATTED ............................................................................. 78
4.9.5 SETTINGS ....................................................................................................................... 79
MMMREADER_GETSETTINGS ................................................................................... 79
MMMREADER_UPDATESETTINGS ........................................................................... 80
MMMREADER_SAVESETTINGS ................................................................................ 80
MMMREADER_WRITETEXTFILESETTINGS............................................................ 81
4.9.6 MISCELLANEOUS ......................................................................................................... 81
MMMREADER_GETLOWLEVELAPI .......................................................................... 81
1 Introduction
This manual contains important information regarding the operation of the 3M Page Reader family. For safe and
reliable operation of the readers all users must ensure that they are familiar with and fully understand all instructions
contained herein.
Danger indicates a hazardous situation which, if not avoided, will result in death or serious
injury.
Warning indicates a hazardous situation which, if not avoided, could result in death or
serious injury.
Caution indicates a hazardous situation which, if not avoided, could result in minor or
moderate injury.
Notice indicates a situation which, if not avoided, could result in property damage only.
This includes situations which require you to re-install your software or return your
equipment to the manufacturer for recalibration.
Information indicates important information that helps get the optimum performance from
your scanner and will save you time during evaluation and deployment.
By using the 3M™ Page Reader SDK (the “Product”), you (the “User”), agree to be bound by the following terms
and conditions.
Because use of the Product varies widely and is beyond the control of 3M, the User must evaluate and determine
whether a Product is fit for a particular purpose and suitable for User’s application prior to use. THE FOLLOWING
IS MADE IN LIEU OF ALL EXPRESS AND IMPLIED WARRANTIES OR CONDITIONS (INCLUDING
WARRANTIES OR CONDITIONS OF SUITABILITY AND FITNESS FOR A PARTICULAR PURPOSE). If a Product
is proved to be defective (the “Defective Product”), the exclusive remedy, at 3M’s option, shall be to either repair or
replace the Defective Product or refund the purchase price of the Defective Product.
LIMITATION OF LIABILITY: OTHER THAN IN RELATION TO DEATH OR PERSONAL INJURY CAUSED BY ITS
NEGLIGENCE 3M AND SELLER, IF ANY, SHALL NOT BE LIABLE FOR ANY INJURY, LOSS OR DAMAGE,
WHETHER DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL HOWSOEVER CAUSED,
(INCLUDING DAMAGES FOR LOSS OF PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS
INFORMATION, INCREASED COSTS OF OPERATION, LITIGATION COSTS AND THE LIKE), WHETHER
BASED UPON A CLAIM OR ACTION IN CONTRACT (INCLUDING BREACH OF WARRANTY), TORT,
(INCLUDING NEGLIGENCE) OR OTHERWISE, IN CONNECTION WITH THE USE OR PERFORMANCE OF A
PRODUCT.
3M reserves the right to make changes to its Products at any time and without notice. The information furnished by
3M in this manual is believed to be accurate and reliable. The material contained herein is supplied without any
representation or warranty of any kind. 3M therefore assumes no responsibility, consequential or otherwise, of any
kind arising from the use of the Product.
Windows is a registered trademark of Microsoft Corporation in the United States and other countries.
All trademarks are acknowledged. All 3M trademarks are trademarks of 3M Company.
The Americas
United Kingdom
direct line: +44 (0) 1344 858 024
main number: +44 (0) 1344 858 000
email: [email protected]
2 Overview
2.1 Introduction
This Programmers' Guide describes the features and software implementation of the 3M Page Reader family of full
page travel document readers from 3M Security Systems Division. The aim of the manual is to provide software
developer’s with the necessary information to integrate the page reader into their applications and to understand all
of the configurable items.
The 3M™ Page Reader SDK is implemented to work with the following scanners/page readers:
• 3M™ RTE8000
• 3M™ RTE8000 HS
• 3M™ Kiosk Reader
• 3M™ KR2400
• 3M™ AT9000
• 3M™ AT9000 MK 2
• 3M™ QS1000
• 3M™ CR5400
For a description overview and feature list of the above scanners/page readers, see the Evaluator’s Guide.
2.2 References
The 3M™ Page Reader SDK provides a range of different Application Programming Interfaces (APIs) which may be
used to access the scanner. This allows developers with different requirements to choose the API which most suits
their needs.
Note: Developers must carefully consider which API to use before starting development
work and are encouraged to use the sample programs and check the code samples
provided.
The overall architecture of the 3M™ Page Reader SDK is illustrated by the diagram below.
Client Application
Internal DLLs
Device Drivers
As illustrated, the Client application may interface with a number of different APIs – although in general it may only
access one API at a time, with the exception of “tunnelling” between the High Level API and the Low Level API.
Most client application interfaces communicate to the SDK API using callback functions.
A callback function is a piece of code written as part of the client application but called by the 3M™ Page
Reader SDK when required.
Note that this will probably be asynchronous to any client process flow. If you are
unfamiliar with callbacks then check these links:
http://www.codeguru.com/cpp/cpp/cpp_mfc/callbacks/article.php/c10557/
http://en.wikipedia.org/wiki/Callback_%28computer_science%29
3.2 Configuration
The 3M™ Page Reader SDK is controlled by a series of initialisation files and settings that hold calibration data,
hardware identifiers and SDK control parameters. There are two categories of settings:
• Calibration settings (such as camera exposures, reference images, etc.) are stored on each
scanner/page reader. This category of settings should ideally never be altered, as this may affect the
performance of the scanner/page reader.
• Application settings (i.e. settings referring to the control of the SDK) and stored in the Config folder of
the SDK’s install location in an INI file called Application.ini (also referred to as the SDK configuration
file). This category of settings can be freely changed by manually editing the Application.ini file or using
the MMMReader_SaveSettings() API.
Note that not all of the settings are used by the SDK at all times and the developer needs
to be aware of which settings do what and when. See section 5 for a detailed programmer’s
description of each setting or see the “Customising the Scanner” section of the Evaluator’s
Guide for a general description of the commonly used items.
The differing APIs provided are useful in different situations and for certain applications. In general using the High
Level Non-Blocking mode is recommended unless there is a good reason to use an alternative.
This API allows the client application to initialise the API with a set of callbacks, and whenever an event occurs
(such as a document being placed on the scanner), or data is received, the callback will be called. The application
may then continue its normal processing, and wait for events from the page reader to occur. See section 4 for a
detailed description of this interface.
This interface allows applications to receive the data as quickly as possible, but without significant code required to
perform the processing, and so is likely to be the preferred API for many customers.
The High Level API will respect all the stored SDK settings, unless specifically overridden. This is particularly
important with respect to data items that will be retrieved from a travel document.
The blocking mode allows an application to call a single MMMReader_ReadDocument() API, and it will not return
from this function until all data has been read, and can then be retrieved by calling MMMReader_GetData(). This
allows the application developer to consider the 3M™ Page Reader SDK completely as a “black box”, and does not
have to be concerned with how data arrives, or in what order. See section 4 for a detailed description of this
interface.
Because the API does not return until all data has been read, this API is not suitable for applications where data
that is available early in the document read (such as the codeline) is required as soon as possible to allow for
further client processing, unless no time consuming data is required (e.g. DG2 from an e-Passport’s RFID chip).
The High Level API will respect all the stored SDK settings, unless specifically overridden. This is particularly
important with respect to data items that will be retrieved from a travel document.
Note that calls to MMMReader_GetData() will only succeed on data items that have been
enabled in the Application.ini configuration file or programmatically.
This wrapper is used to interface the High Level API to applications written in C#, Visual Basic.NET, Managed C++,
or any other .NET platform. It supports both blocking and non-blocking mode.
The 32-bit SDK uses .NET 2.0 and the 64-bit SDK uses .NET 4.0.
For .NET versions newer than 2.0, Microsoft support backwards compatibility with referencing assemblies built
upon older versions of the .NET framework, so there should not be an issue with using the .NET 2.0 assembly
within a .NET 4.0 application.
This wrapper is used to interface the High Level API to applications written in Java using the JNI (Java Native
Interface). It supports both blocking and non-blocking mode.
This API provides very fine control over the 3M™ Page Reader SDK, e.g. allowing the ability to take images with
varying exposure times dependent upon the document type. The API is principally non-blocking, and has a multi-
threaded design to allow the RFID, Camera, and image processing operations to be performed in parallel for
optimum performance.
Note: Due to the additional flexibility provided by the Low Level API, the amount of
application code required to read the data is significantly higher. Therefore, the Low
Level API is generally only recommended for use by customers who have specific
requirements that cannot be met by the High Level API. Refer to the Low Level API
Programming Manual for more details.
To visualise the difference between the two APIs the high level is like building a pre-fabricated house whilst the low
level is like building a house from individual bricks and lumber.
The low level is great for individuality as long as you know what you are doing otherwise it might all come tumbling
down. For instance you automatically receive the MRZ data in the callback function of the High Level API, whilst in
the low level API:
• If only a few Low Level API functions are required, they may be used from within the High Level API
through the “tunnelling” API, allowing the two APIs to be mixed.
• In general, the Low Level API does not use the configuration file and scanner/page reader settings
values for data and control.
This wrapper is used to interface the Low Level API to applications written in C#, Visual Basic.NET, Managed C++,
and any other .NET platform. The C# Low Level API is contained in the same assembly as the C# High Level API
(see section 3.3.2).
In some environments it is very difficult (or expensive) to change the host application to receive data from another
source, examples might be mainframe applications, database forms or web based data entry. In these cases the
easiest method of transferring data to the application is to use a program called a software keyboard wedge. This
program takes the OCR data from the page reader and formats it into keyboard strokes. The data appears just as if
it was typed by the user. Generally this data also needs some formatting to fill the form correctly. There is a generic
software keyboard wedge program in the SDK binary directory. If a more complex data input system is required,
contact 3M for information about the Output Wedge application.
This API is specifically designed for Quality Assurance customers, and provides a high level interface similar to the
main High Level API. However, it provides functionality to measure a number of aspects of the document to ensure
that the documents conform to specifications – for example the position of the codeline, or that the DG1 codeline
data matches the printed codeline. Refer to the Quality Assurance High Level API Programming Manual for a
detailed description of this interface and how to use it.
All of the below applications are supplied with full source-code as part of the SDK.
NOTE: To debug sample applications, set the working directory of the project debug properties to the SDK
BIN directory where all of the 3M binaries reside. Right-click on the project and look under Debug for the
working directory.
3.4.1 HLNonBlockingContainer
This application demonstrates the High Level API used in non-blocking mode from within a Microsoft Visual C++
environment.
It demonstrates all major features of the 3M™ Page Reader SDK, including all image types, display of RFID data,
and more advanced features such as BAC key correction, and Document Signer Certificate functionality.
The application uses the configuration from the scanner/page reader and the SDK configuration file, so if it is not
configured to read certain data items, then such data items will not be read. However, the settings may be changed
via the “Data to send” menu item under the “Settings” menu. This will only change the settings for this session,
unless the “Save settings” menu item is selected.
To use the application: simply place a document on the reader, and if the current state is “Enabled”, the document
will be read, and all data displayed.
The “Timings” tab provides a detailed breakdown of the data items received, and the time between the document
being detected, and the data item being returned.
3.4.2 HLBlockingTestContainer
As with the HLNonBlockingContainer, this application demonstrates the High Level API within the Microsoft Visual
C++ environment, but demonstrates the Blocking API.
This application demonstrates reading and displaying all data items, both imaging and RFID, although respects the
Data To Send settings configured.
To use the application: select “Wait For Document” from the “Scanner” menu, and the application will wait until a
document is placed. Once the document has been placed, select “Read Document”, and all data that is to be read
will be displayed.
3.4.3 HLNonBlockingExample.NET
This application demonstrates the High Level API in use within the Microsoft.NET 2003 environment, using C#.
To use the 3M™ Page Reader SDK within your own .NET applications, add a reference in your project to the
MMMReaderDotNet20.dll assembly. This assembly targets the .NET 2.0 runtime. This assembly provides access to
the High Level and Low Level APIs, which can be used in conjunction using C#.
Users of Visual Studio.NET 2005 or newer should use the HLNonBlocking.NET2k5 version of the project.
3.4.4 HLBlockingExample.NET
As with the HLNonBlockingExample.NET, this application demonstrates the High Level Blocking API from within a
C# environment.
The example application demonstrates OCR and imaging features only. However, it is easily extendable to cover
any other functionality using the non-blocking mode example as a guide.
To use the application: select the initialise button to initialise the High Level API.
Then press “Wait For Document”, and place a document on the scanner.
Once a message has been displayed showing the document has been placed, select the Read Document button.
This application demonstrates the High Level API in use within a Java environment, using the Java Native Interface.
The project was built using NetBeans 6.5, however the JNI wrapper should be compatible with other Java
environments.
To use the 3M™ Page Reader SDK within your own Java application, simply add the library mmmreader.jar to the
project, and include the MMMReaderJava.dll binary in your search path (in addition to the other standard SDK
DLLs) which implements the native methods on the com.mmm.readers.FullPage.Reader class.
3.4.6 LowLevelAPITestContainer
This application demonstrates all of the Low Level API functionality within a Microsoft Visual C++ environment.
Each API maybe accessed by clicking the appropriate button, and are grouped into tabs corresponding to each
major area within the API.
Note that in order to be used to retrieve data, the operations must be performed in a
sequence that is appropriate to the API.
For example, one sequence to retrieve the OCR data might be:-
1. Initialise Camera
2. Doc On Window
3. Take Image
4. Initialise Img Proc
5. Post Process Image
6. Read Codeline
4.1 Overview
The 3M™ Page Reader High Level API provides a programming interface which allows data to be read through the
page reader with minimal code required to be written.
This interface is suitable for most customers, unless there are very specific requirements which may be better
satisfied by using the 3M™ Page Reader Low Level API, or the QA API.
This section describes the overall structure of the 3M™ Page Reader High Level API, the data that it returns, and
then finally a detailed breakdown of the API functions and the parameters supplied.
blocking,
and non-blocking
The difference between these is that within the non-blocking style, the application simply registers a number of
callbacks, and these are called whenever data is read.
Using the blocking API, the scanner will only return the data when it is explicitly requested.
When using the High Level API in the blocking mode, the process flow shown below illustrates the sequence of
calls. For clarity, not all MMMReader_GetData() calls are illustrated.
MMMReader_Initialise
MMMReader_WaitForDocument
MMMReader_ReadDocument
MMMReader_GetData(Codeline)
MMMReader_GetData(ImageUV)
NO
MMMReader_Shutdown
Within the non-blocking mode, the process flow below shows how the client application is allowed to continue, and
can respond to callbacks when events occur, such as documents placed on the window, or data being received.
MMMReader_Initialise
Data: Codeline
MMMReader_GetData
NO
MMMReader_Shutdown
There are many data items which can be returned via the High Level API.
These are supplied to either the MMMReaderHLDataCallback, or requested via the MMMReader_GetData() API,
and are each indicated by a value from the MMMReaderDataType enumeration.
This section documents all of the data items, the data format, and any corresponding configuration file settings.
It also documents other useful configuration settings to customise the behaviour of the 3M™ Page Reader SDK.
4.5.1 MMMReaderHLDataCallback
Prototype:
C++ typedef void (*MMMReaderHLDataCallback)(
void* aParam,
MMMReaderDataType aDataType,
int aDataLen,
void* aDataPtr
);
.NET public delegate void MMM.Readers.FullPage.DataDelegate(
MMM.Readers.FullPage.DataType aDataType,
object aData
);
Description:
This is a user-defined function matching the above prototype that will receive data from the High Level API in non-
blocking mode.
aDataType defines what type of data is being returned (see section 4.5.2 below).
aDataLen describes how big the data is in bytes, while aDataPtr is a pointer to the data being returned. It should be
cast to an appropriate type before being used.
aParam will be a pointer that will have been passed to MMMReader_Initialise(), and could be a “this” pointer for
example.
MMMReaderDataType Description
CD_CODELINE Raw codeline (MRZ) from a travel document
CD_CODELINE_DATA Parsed version of the MRZ, broken into the separate fields
CD_CHECKSUM Checksum result
CD_CHECKSUMEXTENDED Detailed checksum result
CD_SECURITYCHECK Security check
CD_IMAGEIR Infra red image
CD_IMAGEIRREAR Second-side infra red image (double-sided readers)
CD_IMAGEVIS Visible image
CD_IMAGEVISREAR Second-side visible image (double-sided readers)
CD_IMAGEUV Ultra violet image
CD_IMAGEUVREAR Second-side ultra violet image (double-sided readers)
CD_IMAGEPHOTO Photo image
CD_IMAGEVIS_OVD1 Visible image with alternate lighting for OVD images
CD_IMAGEVIS_OVD2 Visible image with alternate lighting for OVD images
CD_IMAGERESERVED1 3M Confirm image
CD_IMAGERESERVED2 3M Confirm tamper image
CD_IMAGEBARCODE Optimised image used by the barcode decoders
CD_IMAGEBARCODEREAR Second-side optimised image used by the barcode decoders (double-sided readers)
CD_SCEF_COM_FILE e-Passport raw EF.COM file data
CD_SCEF_SOD_FILE e-Passport raw EF.SOD file data
CD_SCEF_CVCA_FILE e-Passport raw EF.CVCA file data
CD_SCDGn_FILE e-Passport raw DGn file data, where 1 ≤ n ≤ 16
CD_SCDGn_VALIDATE e-Passport DGn hash validation result, where 1 ≤ n ≤ 16
CD_SCDG1_CODELINE e-Passport raw codeline data extracted from DG1
CD_SCDG1_CODELINE_DATA e-Passport codeline extracted from DG1, parsed into the separate fields
CD_SCDG2_PHOTO e-Passport facial image extracted from DG2
CD_SCDG3_FINGERPRINTS e-Passport fingerprint data extracted from DG3
CD_SCSIGNEDATTRS_VALIDATE e-Passport signed attributes validation result
CD_SCSIGNATURE_VALIDATE e-Passport signature validation result
CD_VALIDATE_DOC_SIGNER_CERT e-Passport DSC signature validation result
CD_PASSIVE_AUTHENTICATION e-Passport Passive Authentication result
CD_ACTIVE_AUTHENTICATION e-Passport Active Authentication result
CD_SCAIRBAUD e-Passport over air baud rate
CD_SCCHIPID e-Passport chip id
CD_SCBAC_STATUS e-Passport Basic Access Control status
CD_SAC_STATUS e-Passport Supplement Access Control status
CD_SCTERMINAL_AUTHENTICATION_STATUS e-Passport Terminal Authentication status
CD_SCCHIP_AUTHENTICATION_STATUS e-Passport Chip Authentication status
CD_SCCROSSCHECK_EFCOM_EFSOD e-Passport cross-check of data items between EF.COM and EF.SOD
CD_BACKEY_CORRECTION e-Passport chance to correct MRZ after failure establishing BAC
CD_READ_PROGRESS User feedback on document read progress
CD_PLUGIN + n Plugin Data
MMMReaderDataType Description
CD_QAINFO QA measurements
CD_CODELINE
The codeline is a character array of length 200, containing up to three lines of OCR data. The lines are separated
with returns (‘\r’ or 0x0D) and there is a null terminator at the end of the data.
The following setting in the SDK configuration file (Application.ini) is used to enable CD_CODELINE:
Although this data item is still supported, it may be preferable to use the CD_CODELINE_DATA data item instead
of CD_CODELINE if the codeline needs to be parsed into the component parts.
Allowable characters are 0-9 A-Z and <. The following settings can be modified in the SDK configuration file to
configure the OCR algorithm:
OCRContext Level SOFT Restricts character matching based on field formats of known (e.g. ICAO)
documents
- - HARD Extends soft context by replacing e.g. matched O’s with o’s in the Document
Number and Optional Data fields.
CD_CODELINE_DATA
This data item supplies an MMMReaderCodelineData structure containing all parsed data from the OCR ICAO
codeline read from the Machine Readable Zone (MRZ) of a document. This data item differs from CD_CODELINE
in that more data is returned in the MMMReaderCodelineData structure. The SDK will parse the OCR data to split
up the lines and extract common data fields, such as names and dates.
Therefore, using this data item is recommended over using CD_CODELINE, and is always automatically enabled
by the same setting as CD_CODELINE.
CD_CHECKSUM
The checksum is a 4-byte integer indicating the result of computing the checksum over the codeline.
0 Checksum not checked
>0 Checksum OK
-1 Checksum error
<-1 Checksum warning
The checksum warning signifies that the checksum did not compute but that the document is not an ICAO
document so it could use different checksum rules. Checksum warnings can be found on some three-line US
documents. The following setting in the SDK configuration file (Application.ini) is used to enable CD_CHECKSUM:
CD_CHECKSUMEXTENDED
The extended checksum is an array of integers, which indicate the result of computing the checksum over the
codeline, with details of where each checksum is situated in the codeline and the actual and expected results.
Char position Explanation Type Details
0 Overall checksum result char U = unchecked
P = pass
F = fail
N = Fail but known None ICAO document
1 Checksum type char D = document number
B = DOB
E = DOE
O = Optional
T = Overall (total)
2 Line number int 1, 2, or 3
3 Char position int 1 - 44
4 Calculated checksum char The checksum expected
5 Read checksum char The read checksum
… Repeat 1 – 5 above
n End of data ‘\0’ End of data
The values at positions 1 – 5 are repeated for each checked checksum in the document and finally the array is
terminated with a zero. The following setting in the SDK configuration file (Application.ini) is used to enable
CD_CHECKSUMEXETNDED:
An alternative method of obtaining the checksum results is to use the results returned in the CD_CODELINE_DATA
object.
CD_SECURITYCHECK
This data item returns a 4-byte integer which indicates whether the document has passed the IR and UV security
checks. Bit 0 represents the IR check, and Bit 1 represents the UV check, with the bit being set if that particular
check has failed.
Note that if the document fails the IR check then the UV check is not carried out as this
takes time.
The following setting in the SDK configuration file (Application.ini) is used to enable CD_SECURITYCHECK:
Images are delivered as JPEGs by default, although other formats are also available. The format and level of
compression can be set as follows in the SDK configuration file (Application.ini):
For debug purposes it can be extremely useful to save the images captured by the SDK, as these can allow 3M to
reproduce and diagnose problems. See section 5.5 for information on how to enable this feature.
CD_IMAGEIR
The infrared image is cropped to the document edges, rotated if necessary and converted to greyscale. It can be
sent as an image of the whole document or an image of just the codeline area.
The following setting in the SDK configuration file (Application.ini) is used to enable CD_IMAGEIR:
When using an AT9000 MK 2, this image will default to having Anti-Glare and ambient removal applied to the
image to obtain the best quality image. If you wish to disable these features or change the amount of ambient light
that is removed, this can be done either programmatically or via the Application.ini – see section 5.15.
CD_IMAGEIRREAR
The second-side infrared image on a double-sided reader, such as the CR5400. The infrared image is cropped to
the document edges, rotated if necessary and converted to greyscale. It can be sent as an image of the whole
document or an image of just the codeline area.
The following setting in the SDK configuration file (Application.ini) is used to enable CD_IMAGEIRREAR:
When using a CR5400, this image will default to having Anti-Glare and ambient removal applied to the image to
obtain the best quality image. If you wish to disable these features or change the amount of ambient light that is
removed, this can be done either programmatically or via the Application.ini – see section 5.15.
CD_IMAGEVIS
The visible image is cropped to the document edges and rotated if necessary. It can be sent as a colour or
greyscale image.
The following setting in the SDK configuration file (Application.ini) is used to enable CD_IMAGEVIS:
When using an AT9000 MK 2, this image will default to having Anti-Glare, ambient removal and True Colour are
applied to the image to obtain the best quality image. If you wish to disable these features or change the amount of
ambient light that is removed, this can be done either programmatically or via the Application.ini – see section 5.15.
CD_IMAGEVISREAR
The second-side visible image on a double-sided reader, such as the CR5400. The visible image is cropped to the
document edges and rotated if necessary. It can be sent as a colour or greyscale image.
The following setting in the SDK configuration file (Application.ini) is used to enable CD_IMAGEVISREAR:
When using a CR5400, this image will default to having Anti-Glare, ambient removal and True Colour are applied to
the image to obtain the best quality image. If you wish to disable these features or change the amount of ambient
light that is removed, this can be done either programmatically or via the Application.ini – see section 5.15.
These two images are only valid on the RTE8000 or RTE8000 HS, and only on units that support “light bank
switching”. These two images provide two alternate views of the document with different illumination settings to
highlight / suppress reflections. The following settings in the SDK configuration file (Application.ini) are used:
CD_IMAGEUV
The following setting in the SDK configuration file (Application.ini) is used to enable CD_IMAGEUV:
CD_IMAGEUVREAR
The second-side UV image on a double-sided reader, such as the CR5400. The UV image is cropped to the
document edges and rotated if necessary.
The following setting in the SDK configuration file (Application.ini) is used to enable CD_IMAGEUVREAR:
CD_IMAGEPHOTO
The photo image is cropped from the visible image at fixed positions relative to the document’s bottom left edge and
rotated if necessary. It can be sent as a colour or greyscale image.
The following settings in the SDK configuration file (Application.ini) are used to enable CD_IMAGEPHOTO and
control the cropping area:
When using an AT9000 MK 2, this image will default to having Anti-Glare and ambient removal applied to the
image to obtain the best quality image. If you wish to disable these features or change the amount of ambient light
that is removed, this can be done either programmatically or via the Application.ini – see section 5.15.
CD_IMAGEBARCODE
The barcode image is an optimised visible image that is used exclusively by the barcode decoder plugins. From the
perspective of the user, this image provides no real use, however it is useful for diagnosing problems with reading
barcodes as this is the exact image used to decode any barcodes, therefore tests can be replicated on this image.
Note that this image is only returned when at least one barcode plugin is enabled.
The following settings in the SDK configuration file (Application.ini) are used to enable CD_IMAGEBARCODE:
When using an AT9000 MK 2, this image will default to having Anti-Glare applied to the image, but not using
ambient removal (so that barcodes from cellphones may be read). If you wish to change these default settings, this
can be done either programmatically or via the Application.ini – see section 5.15.
CD_IMAGEBARCODEREAR
The second-side barcode image on a double-sided reader, such as the CR5400. The barcode image is an
optimised visible image that is used exclusively by the barcode decoder plugins. From the perspective of the user,
this image provides no real use, however it is useful for diagnosing problems with reading barcodes as this is the
exact image used to decode any barcodes, therefore tests can be replicated on this image.
Note that this image is only returned when at least one barcode plugin is enabled.
The following settings in the SDK configuration file (Application.ini) are used to enable
CD_IMAGEBARCODEREAR:
When using a CR5400, this image will default to having Anti-Glare applied to the image, but not using ambient
removal (so that barcodes from cellphones may be read). If you wish to change these default settings, this can be
done either programmatically or via the Application.ini – see section 5.15.
The sending of data from the RFID Chip (or Contactless Smart Card) in an e-Passport is globally enabled and
disabled using the following setting in the SDK configuration file (Application.ini):
Some applications may want to communicate directly with the RFID module using PC/SC drivers (contact 3M
Security Systems Division for this as it is a non-standard configuration). To do this, all RFID must be
disabled. The RFID module’s resources will then be available for applications to interface with it directly.
The sending of all the following RFID data items is controlled in the SDK configuration file as follows:
Many of the RFID data items below are dependent upon other data items, e.g. CD_SCDG1_VALIDATE. However, it
is not necessary to enable these other data items; the SDK will simply retrieve them, use them, but not pass them
back out to the host application. The following items are mandatory however:
CD_SCEF_COM_FILE
This is the EF.COM file from the RFID chip, which contains the Data Group Presence Map.
It is likely that this will be the first file that will be read from the RFID chip (even if the data item is not enabled).
For e-Passports with BAC, the read of this file will trigger the establishment of BAC, hence taking longer to read the
file than expected.
CD_SCEF_SOD_FILE
This is the EF.SOD file from the RFID chip, which contains the Document Security Object and optionally the
Document Signer Certificate.
CD_SCEF_CVCA_FILE
This is the EF.CVCA file from the RFID chip, which contains a list of Certification Authority References (CARs) to
identify the public key to be used in the Terminal Authentication stage of EAC. This file should only be present on e-
Passports with EAC.
CD_SCDGn_FILE
CD_SCDGn_VALIDATE
This is result of validating the DGn file hash contained in the LDS Security Object, where 1 ≤ n ≤ 16. The data is
sent as a 4-byte integer:
0 = Invalid, 1 = Valid.
CD_SCDG1_CODELINE
This is the data recovered from the LDS DG1 data group, which contains an ASCII string matching the
e−Passport’s MRZ data.
Note that unlike the OCR data returned in CD_CODELINE, this does not contain return
characters (‘\r’) indicating the line breaks
CD_SCDG1_CODELINE_DATA
This is the data recovered from the LDS DG1 data group, stored as an MMMReaderCodelineData object which
splits the data into the separate fields for “date of birth” etc. This data item is comparable to CD_CODELINE_DATA.
CD_SCDG2_PHOTO
This is the e-Passport photo extracted from the LDS DG2 data group. The data is a JPEG or JPEG 2000 image
(depending on the country) and can be saved straight to disk.
CD_SCDG3_FINGERPRINTS
This is the fingerprint data extracted from the LDS DG3 data group. The data is a DG3FingerprintData structure,
which contains an array of DG3FingerImage objects which contain the fingerprints from the chip. The fingerprints
themselves may be stored as JPEG, JPEG2000, WSQ images, as indicated by the image format member in the
structure.
CD_SCSIGNEDATTRS_VALIDATE
This is the result of validating the hash of the eContents against the Signed Attributes. The data is sent as a 4-byte
integer:
0 = Invalid, 1 = Valid
CD_SCSIGNATURE_VALIDATE
This is the result of validating the signature in the Document Security Object using a public key from a Document
Signer Certificate (DSC). The DSC can be optionally stored on the chip, otherwise it must be provided from an
external source. The following configuration settings in the [RFCertificates] section of the SDK configuration file
(Application.ini) affect the retrieval mechanism for DSCs:
DSC_CRL_MODE CERT_FILE_STORE The DSC will be checked for revocation against all the
CRLs contained in CERTS_DIR, based on a matching
Certificate Issuer and Serial Number.
- CERT_CALLBACK The DSC will be checked for revocation against a CRL
retrieved by calling back to the application using the
MMMReaderCertificateCallback function with a
CERT_TYPE of CT_CERTIFICATE_REVOCATION_
LIST. This request will contain an ASN.1 DER encoded
IssuerAndSerialNumber buffer (see RFC 3369 section
10.2.4). The user must supply a DER encoded CRL (this
can also be Base64 DER encoded).
CERTS_DIR A full directory path. A folder on the host machine (or on the network) where one
or more certificate files are stored
CERTS_DIR_INCLUDE_SUBDIRS 0 or 1 Toggle searching recursively through sub-directories of
CERTS_DIR
CERTS_DIR_FILE_EXTENSIONS A list of file extensions separated by ; Allows file masking certificate files of only specified
or , extensions, e.g. “cer;der;pem;crt;crl”
The result of the Signature validation is sent as a 4-byte integer (see MMMReaderValidationCode in
MMMReaderDataTypes.h):
0 = Invalid, 1 = Valid, 2 = Valid with revoked certificate (determined from check against CRLs), 3 = No DSC Loaded.
RFDataToSend Configuration Key = “VALIDATE_SIGNATURE”
CD_VALIDATE_DOC_SIGNER_CERT
This is the result of validating the DSC’s signature using the public key from an external Country Signer Certificate
(CSC).
The following settings in the [RFCertificates] section of the SDK configuration file (Application.ini) affect the retrieval
mechanism for CSCs, in addition to CERTS_DIR, CERTS_DIR_INCLUDE_SUBDIRS and
CERTS_DIR_FILE_EXTENSIONS in the table above.
The result of the DSC Signature validation is sent as a 4-byte integer (see MMMReaderValidationCode in
MMMReaderDataTypes.h):
0 = Invalid, 1 = Valid, 2 = Valid with revoked certificate (determined from check against CRLs), 3 = No DSC Loaded,
4 = No CSC Loaded.
RFDataToSend Configuration Key = “VALIDATE_DOC_SIGNER_CERT”
CD_ACTIVE_AUTHENTICATION
This is the result of performing Active Authentication (AA) on the e-Passport. AA is an optional security feature of e-
Passports which prevents chip cloning attacks. It is sent as a 4-byte integer, representing the TRISTATE type,
where 1 = TS_SUCCESS, -1 = TS_FAILURE, and 0 = TS_NOT_PERFORMED (eg, DG15 not present).
Note that if DG15 is not present, an ERROR_DATAGROUP_NOT_PRESENT error will be raised, in addition to
returning this data item as “not performed”.
CD_SCAIRBAUD
The e-Passport over air Baud rate is returned as a null-terminated ASCII string. This can have values of “848”,
“424”, “212” or “106”.
CD_SCCHIPID
CD_SCBAC_STATUS
A 4-byte TRISTATE value indicating whether Basic Access Control was used to open the e-Passport for reading.
A value of TS_NOT_PERFORMED (0) indicates that the chip is not a BAC chip,
TS_SUCCESS (1) indicates that BAC has been successfully used.
The value TS_FAILURE (-1) indicates that BAC has been attempted, but failed to successfully open the chip.
CD_SAC_STATUS
A 4-byte TRISTATE value indicating whether Supplemental Access Control was used to open the e-Passport for
reading.
A value of TS_NOT_PERFORMED (0) indicates that the chip is not a BAC chip,
TS_SUCCESS (1) indicates that SAC has been successfully used.
The value TS_FAILURE (-1) indicates that SAC has been attempted, but failed to successfully open the chip.
CD_SCCHIP_AUTHENTICATION_STATUS
A 4-byte TRISTATE value indicating whether the Chip Authentication stage of Extended Access Control was
successfully performed. Chip Authentication will be performed automatically by the SDK immediately after reading
EF.COM if DG14 is present, and the EAC feature is enabled.
CD_SCTERMINAL_AUTHENTICATION_STATUS
A 4-byte TRISTATE value indicating whether the Terminal Authentication stage of Extended Access Control was
successfully performed.
Terminal Authentication will only be attempted if DG3 or DG4 is accessed on an EAC enabled chip, and the EAC
feature has been enabled.
The following settings in the [PASSPORT_SETTINGS] section of #RTEPASSPORTAPI.ini affect the retrieval
mechanism for the Card-Verifiable Certificate (CVC) chain and Inspection System Private Key for Terminal
Authentication, along with some other more general EAC settings.
EAC_ENABLED 0 or 1 Toggle whether or not EAC will be performed. It will only ever
be performed if the e-Passport is identified as being protected
by EAC, e.g. by the presence of DG14 and the format of its
contents. Has no affect for non-EAC enabled SDKs.
EAC_VERSION 1.0 or 1.01 Early incarnations of EAC e-Passports implemented Terminal
Authentication expecting a CV Certificate with an outer ASN.1
tag. This is the “1.0” implementation, whereas the correct
implementation is to send a CV Certificate body and
signature concatenated (“1.01”).
CD_SCCROSSCHECK_EFCOM_EFSOD
This data type will return a 4-byte integer representing an MMMReaderValidationCode to indicate whether we are
able to successfully crosscheck the contents of EF.COM and EF.SOD.
Because Passive Authentication does not check whether EF.COM is altered, a possible form of attack may be to
alter EF.COM so that it contains a different set of data files – eg, to hide DG15, to prevent Active Authentication
from being performed.
This data item will indicate a failure if EF.COM indicates as present a different set of data groups than EF.SOD has
hashes.
CD_BACKEY_CORRECTION
This data type will be received if establishing BAC fails, giving the user application an opportunity to correct the
MRZ (by changing the received buffer).
Note that for this data item, the callback will be called from a different thread to that
normally used, and the callback may be fired independently on another thread for non-
RFID data items. No further RFID data processing will continue until the callback returns.
CD_EFCOM_DG_MAP
This is a 2 byte bitmap of the data groups present in the EF.COM. DG1 to DG16 for bits 0 to 15.
CD_EFSOD_HASH_MAP
This is a 2 byte bitmap of the data group hashes present in the EF.SOD. DG1 to DG16 hashes for bits 0 to 15.
CD_DOC_SIGNER_CERT
This is the DSC (Document Signer Certificate) from the EF.SOD, if present.
Plugins are special document reading extensions, which can be generic (e.g. 1D or 2D barcodes) or customer
specific (e.g. a specific country’s landing card).
The plugins are in the form of extra DLLs, which are always named ‘RTDECODE_xxxxx.DLL’, and are loaded from
the “plugins directory” that has been configured for the SDK e.g.
‘Plugins\RTDECODE_PDF417.DLL’ is a plugin for PDF417 2D barcode reading. In this example, ‘PDF417’ is the
plugin name.
The reading of this data can be toggled on or off by placing the plugin name in the [DataToSend] section of SDK
configuration file Application.ini (e.g. PDF417=1 or PDF417=0), or via the MMMReader_EnablePlugin API.
Each new plugin may optionally have its own configuration file. The configuration file will have the same name as
the plugin DLL, preceded by a ‘#’ character, with an ‘INI’ extension, e.g. ‘#RTDECODE_PDF417.ini’.
Notice: These settings should not be changed without advice from 3M Security Systems
Division. Incorrect changes to these settings may compromise the performance of the
plug-in reading.
A plugin can return one or more data types, and these will be identified by CD_PLUGIN + n.
The value of n is specified by the FEATURE_TYPE_NAME setting in the plugin’s INI file.
If the plugin supports one data type, this will be located in the [MAIN] section.
If the plugin supports more than one data type, each data type will have its own section, and each section will have
its own unique FEATURE_TYPE_NAME.
The data supplied to the data callback with a data type of CD_PLUGIN + n will be an MMMReaderPluginData
structure. This contains the data from the plugin with additional data indicating the total number of features and
parts located.
The plugin data can contain many “decode parts”, for example PDF417 barcodes can contain a number of different
parts within a single barcode. See the MMMReader_GetPluginData() API for a description of how to access all the
plugin data in blocking mode.
CD_SWIPE_MSR_DATA
This is the data read from the magnetic stripe reader add-on for the AT9000.
The following setting in the SDK configuration file (Application.ini) is used to enable CD_SWIPE_MSR_DATA:
CD_AAMVA_DATA
This data item returns an MMMReaderAAMVAData structure containing data that has been parsed from a North
America driving licence that is compliant with the AAMVA standard.
The following setting in the SDK configuration file (Application.ini) is used to enable CD_AAMVA_DATA:
Additionally, this data will only be returned if the PDF417 plugin or the MSR data item has been enabled.
The AAMVAParser.xml file is required in the “config” directory to enable this feature.
CD_READ_PROGRESS
This data item is a floating-point number representing the percentage that is complete on the current read, in the
range 0 - 100, and can be used to provide feedback to the user.
The following data items are sent by the UHF reader add-on for the AT9000.
The sending of data from the UHF tag in a document is globally enabled and disabled using the following setting in
the SDK configuration file (Application.ini):
The sending of all the following UHF data items is controlled in the SDK configuration file as follows:
CD_UHF_TAGID
This is the TagID data read from the UHF tag. The data supplied to the Data callback will be a pointer to an
MMMReaderUHFTagIDData structure. This structure contains all the raw bytes read, as well as the decoded
meaning of the raw bytes.
CD_UHF_EPC
This is the EPC (Electronic Product Code) read from the UHF tag. The data supplied to the Data callback will be an
unsigned char* buffer.
The following settings can be used to customise document detection and reading behaviour:
4.6 Events
A number of events are supplied to the MMMReaderEventCallback, allowing the client application to perform
processing upon actions occurring rather than the data being received. The events are listed below.
4.6.1 MMMReaderEventCallback
Prototype
C++ typedef void (*MMMReaderEventCallback) (
void* aParam,
MMMReaderEventCode aEventType
);
.NET public delegate void MMM.Readers.FullPage.EventDelegate(
MMM.Readers.FullPage.EventCode aEventType
);
Description:
This is a user-defined function matching the above prototype that will receive data from the High Level API in non-
blocking mode.
aEventType defines what type of event has been triggered during a document read (see section 4.6.2 below). At
this point, the client application can perform some custom action based on the current event.
aParam will be a pointer that will have been passed to MMMReader_Initialise(), and could be a “this” pointer for
example.
DOC_ON_WINDOW
This event is triggered when a new document has been detected on the window. This event will only be fired when
the scanner is in READER_ENABLED or READER_DISABLED modes.
DOC_REMOVED
This event is triggered when a document that has been detected has been removed from the window. This event
will only be fired when the scanner is in READER_ENABLED or READER_DISABLED modes.
START_OF_DOCUMENT_DATA
This event is fired immediately before the first data item is read from the document.
END_OF_DOCUMENT_DATA
This event is fired immediately after the last data item is read from the document.
A typical use for this event might be to process all data that has been received.
READER_ERROR_RESOLVED
In the case of an error, the High Level API will automatically switch to the READER_ERRORED state, and then
attempt to restart the scanner.
When the scanner successfully re-initialises, it will automatically be restored to the previous state, and trigger this
event.
SETTINGS_INITIALISED
This event is triggered during the MMMReader_Initialise() call immediately after the SDK configuration settings
have been loaded, but prior to any other initialisation.
This is intended so that settings may be updated by the client application via MMMReader_UpdateSettings() prior
to the initialisation of the High Level API so that any changes may be applied before any document already on the
page reader is processed.
PLUGINS_INITIALISED
This event is triggered during the MMMReader_Initialise() call immediately after the plugins have been loaded and
initialised.
This is intended so that applications may enumerate and enable or disable the plugins as required prior to the
initialisation of the High Level API.
RF_CHIP_OPENED_SUCCESSFULLY, RF_APPLICATION_OPENED_SUCCESSFULLY,
RF_CHIP_OPEN_FAILED
These events are triggered when an RF chip in a document is either successfully opened for reading, or failed to
open.
If the chip failed to open then only RF_CHIP_OPEN_FAILED will be fired. If the chip is a supported application then
both of the two successful events will be fired. If there is a chip, but it is not a supported application, only
RF_CHIP_OPENED_SUCCESSFULLY will be fired.
READER_CONNECTED
READER_DISCONNECTED
In general, the High Level API will automatically attempt to recover from errors in the most appropriate way for the
type of error; however it will always inform the client application that the error has occurred via the
MMMReaderErrorCallback.
Prototype:
typedef void (*MMMReaderErrorCallback)(
MMMReaderErrorCode aErrorCode,
char* aErrorMsg,
void* aParam
);
Description:
This is a user-defined function matching the above prototype that will receive data from the High Level API in non-
blocking mode.
aErrorMsg is a null-terminated ASCII string describing the error in user-friendly terms; this message will also include
context-sensitive information, e.g. if a file cannot be loaded, the file name will appear in the message.
aParam will be a pointer that will have been passed to MMMReader_Initialise(), and could be a “this” pointer for
example.
• An error which indicates a problem with a specific data item – e.g. “DG3 not present”. The High Level
API will simply cancel reading this data item, and continue processing the document.
• RFID error which indicates a problem with the current document - for example, failing to establish BAC.
The High Level API will abort the reading of further RFID data items, but will continue the rest of the
document read.
• A general error which may indicate either a physical issue (e.g. USB cable disconnected) or a software
issue. The High Level API will automatically re-initialise the reader to attempt to resolve the issue. If this
fails, it will periodically attempt to re-initialise the reader until it succeeds. Upon successful re-
initialisation, the event callback will be called with READER_ERROR_RESOLVED.
• ERROR_DEVICE_ALREADY_IN_USE causes the High Level API to be placed into the
READER_SUSPENDED state, and will not attempt to automatically attach to the device. This occurs if
another application is currently using the page reader. The application may re-attempt to acquire the
page reader by calling MMMReader_SetState(READER_ENABLED).
In addition to calling the error callback, if logging is enabled (see MMMReader_EnableLogging()), errors will be
logged to a log file.
Additional information may be written to the log file in case of errors – e.g. in the case of an Access Violation, the
call stack will be logged, which is not supplied to the callback.
A full list of the error codes may be found in MMMReaderDataTypes.h, and error strings associated with the error
codes can be obtained via MMMReader_GetErrorMessage().
Please note that you should not call MMMReader_Shutdown() or MMMReader_Reset() inside the error callback,
since both of these APIs will wait for the thread calling the error callback to terminate. This would therefore cause a
deadlock.
4.8 Logging
As well as handling unexpected errors, the High Level API will also output various messages such as warnings and
debug messages to a log file. To enable logging, use the MMMReader_EnableLogging() API. You can also use
the MMMReader_LogMessage() and MMMReader_LogFormatted() APIs to write your own related messages to
the log file.
There are several ways the log file can behave under certain conditions; these are known as logging strategies. The
strategy to use is defined either through the LoggingSettings structure, or via the configuration file.
Name Description
APPEND On initialisation, opens the last log file specified by the aFilename parameter for
MMMReader_EnableLogging() and append all subsequent messages to the original contents
of this file.
The aFilename parameter for MMMReader_EnableLogging() will be adjusted so that the file
On initialisation, opens the last used log file based on the highest [id] number. If this file is still
smaller than the provided maximum, this file is opened and appended to. Otherwise, a new log
file is created in the format “name.[id + 1].ext”.
All future log messages will be checked to make sure that they fit within the currently opened
log file; if not, then the current file is closed and a new one is created as explained above.
Various security features of the ICAO-compliant e-Passport require external certificates to verify digital signatures,
or external Certificate Revocation Lists to check a certificate’s revocation status.
The specific situations are described in section 4.5.5 above under the relevant data items.
For most situations requiring external certificates, the SDK can be configured to either find a matching certificate for
itself in a file store (CERT_FILE_STORE method) or call back to the host application using the
MMMReaderCertificateCallback function (CERT_CALLBACK method).
The parameters to configure this behaviour can be found in the file the SDK configuration file (Application.ini), which
can also be found in the RFProcessSettings structure (see MMMReaderSettings.h).
4.9.1 MMMReaderCertificateCallback
Prototype:
C++ typedef bool (*MMMReaderCertificateCallback)(
void* aParam,
char* aCertIdentifier,
int aCertIdentifierLen,
CERT_TYPE aCertType,
char* aCertBuffer,
int* aCertBufferLen
);
.NET public delegate bool MMM.Readers.FullPage.CertificateDelegate(
byte[] aCertIdentifier,
MMM.Readers.Modules.RF.CertType aCertType,
out byte[] aCertBuffer
);
Description:
This is a user-defined function matching the above prototype that will receive data from the High Level API.
aCertIdentifier points to a buffer which contains an identifier for the required certificate. See relevant data items in
section 4.5.5 for descriptions of what this buffer will contain.
aCertType will be an enumeration constant to identify the type of certificate being requested. Use this in
combination with aCertIdentifier to uniquely identify the certificate.
aCertBuffer will point to a pre-allocated buffer for the host application to write the certificate to.
aCertBufferLen will initially contain the length of the pre-allocated buffer in bytes; however, on return, the host
application must update this value to be the actual size of the certificate in bytes.
aParam will be a pointer that will have been passed to MMMReader_Initialise(), and could be a “this” pointer for
example.
This callback function must be used with care to avoid memory corruption:
•
If a certificate is successfully located by the host application and it is smaller than aCertBufferLen,
the function must return true and set aCertBufferLen to the actual number of bytes written to
aCertBuffer.
•
If the certificate located by the host application is larger than the pre-allocated buffer size
aCertBufferLen, the function must return false and set aCertBufferLen to the required number of
bytes. The callback will then be fired a second time with a larger buffer allocated.
•
If no certificate is located, the function must return false without changing the value of
aCertBufferLen.
For e-Passports with Extended Access Control to protect DG3 or DG4, an Inspection System Private Key is needed
to generate a digital signature for the Terminal Authentication stage.
It is likely that an Inspection System will want to keep these private keys secure, and therefore not want to use the
CERT_FILE_STORE or CERT_CALLBACK methods.
In these situations, the only alternative is for the host application to generate the signature itself using whatever
method it deems most secure, and pass the resulting signature back to the SDK to complete the Terminal
Authentication protocol.
This is the SIGN_REQUEST method, which can only be used for the EXTERNAL_PRIVATE_KEY_MODE in the
SDK configuration file (Application.ini).
Prototype:
C++ typedef bool (*MMMReaderSignRequestCallback)(
void* aParam,
char* aBufferToSign,
int aBufferToSignLen,
char* aCertBuffer,
int aCertBufferLen,
CERT_TYPE aCertType,
char* aSignature,
int* aSignatureLen
);
.NET public delegate bool MMM.Readers.FullPage.SignRequestDelegate(
byte[] aBufferToSign,
byte[] aCertificateBuffer,
MMM.Readers.Modules.RF.CertType aCertType,
out byte[] aSignature
);
Description:
This is a user-defined function matching the above prototype that will receive data from the High Level API.
aBufferToSign points to a buffer which the host application must sign, which will be aBufferToSignLen bytes long.
aCertBuffer will point to a certificate buffer whose public key (and domain parameters) should correspond to the
private key used to generate the signature. aCertBufferLen will be the length of aCertBuffer in bytes.
aCertType is an enumeration constant used to identify the type of certificate contained in aCertBuffer.
aSignature will point to a pre-allocated buffer for the host application to write the signature to.
aSignatureLen will initially be the size of aSignature, but on return it must be updated to be the actual size of the
signature in bytes.
aParam will be a pointer that will have been passed to MMMReader_Initialise(), and could be a “this” pointer for
example.
Usage of this function is similar to the MMMReaderCertificateCallback:
• If the signature is successfully generated by the host application and it is smaller than aSignatureLen, the
function must return true and set aSignatureLen to the actual number of bytes written to aSignature.
• If the signature generated by the host application is larger than the pre-allocated buffer size
(aSignatureLen), the function must return false and set aSignatureLen to the required number of bytes.
The callback will then be fired a second time with a larger buffer allocated.
• If the signature generation failed, the function must return false without changing the value of
aSignatureLen.
The process flows above illustrate the overall structure of the API. This section documents the specifics of the
functions within the High Level API. Below is a table providing a summary of the all the available APIs. These are
documented in further detail in the following sections:-
Name Description
Control and State
MMMReader_Initialise Initialises the High Level API.
MMMReader_Shutdown Shuts down the High Level API.
MMMReader_Reset Resets the High Level API.
MMMReader_IsInitialised Returns whether the High Level API has been initialised.
MMMReader_GetState Returns the current state of the 3M™ Page Reader SDK.
MMMReader_SetState Changes the current state.
MMMReader_EnablePlugin Enables the given plugin, if present.
MMMReader_IsPluginEnabled Indicates whether the given plugin is currently enabled.
MMMReader_GetPluginName Allows enumeration through the installed plugins.
MMMReader_GetConnectedScanners Returns the serial numbers of all connected page readers.
MMMReader_SelectScanner Selects a specific page reader if multiple are connected.
MMMReader_SetSignRequestCallback Set a host callback to sign signature requests (for EAC documents)
Document Processing
MMMReader_IsDocumentOnWindow Returns whether a document is on the window.
MMMReader_WaitForDocumentOnWindow Blocking API: waits for a document to be placed on the window.
MMMReader_ReadDocument Blocking API: reads all data from the document.
MMMReader_GetData Returns the data for any given data-type.
MMMReader_GetPluginData Returns the data read by a plugin.
MMMReader_ClearData Clears any data stored from the previous document.
MMMReader_InitialisePositionCorrection Enables a document position feedback and correction callback
MMMReader_RFAbort Aborts a current RF chip reading operation.
Settings
MMMReader_GetSettings Returns an MMMReaderSettings structure of the current settings.
MMMReader_UpdateSettings Applies changes to the settings to the High Level API.
MMMReader_SaveSettings Saves changes made to the settings to the INI files.
Error Handling
MMMReader_EnableLogging Enables logging of the 3M™ Page Reader SDK.
MMMReader_GetLastError Returns the code of the last error that occurred.
MMMReader_LogMessage Writes a message to the 3M™ Page Reader SDK log file.
MMMReader_LogFormatted Writes a formatted message to the 3M™ Page Reader SDK log file.
MMMReader_GetErrorMessage Returns the error message associated with the given error code.
Miscellaneous
MMMReader_GetLowLevelAPI Allows tunnelling to the Low Level API.
Prior to using any of the functions within the high-level API it is necessary to initialise the API, and after use it is
necessary to call the shutdown to free any resources that have been allocated. There are also APIs provided to
determine the current state of the scanner, and to change between various different states.
MMMReader_Initialise
Prototype:
C++ MMMReaderErrorCode MMMReader_Initialise(
MMMReaderHLDataCallback aDataCallback,
MMMReaderEventCallback aEventCallback,
MMMReaderErrorCallback aErrorCallback,
MMMReaderCertificateCallback aCertCallback,
bool aProcessMessages,
bool aProcessInputMessages,
void* aParam
);
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.Initialise(
MMM.Readers.FullPage.DataDelegate aDataCallback,
MMM.Readers.FullPage.EventDelegate aEventCallback,
MMM.Readers.ErrorDelegate aErrorCallback,
MMM.Readers.FullPage.CertificateDelegate aCertificateCallback,
bool aProcessMessages,
bool aProcessInputMessages
)
Description:
This function will initialise the High Level API. The High Level will be initialised in blocking mode if no data or event
callback is supplied, or in non-blocking mode if they are supplied.
Note that in non-blocking mode, either callback is optional, although one must be supplied.
In blocking mode, aProcessMessages and aProcessInputMessages flags are used to indicate whether Windows
messages should be processed while blocking - thus making applications responsive while blocking. In non-
blocking mode, these parameters are ignored.
The aParam parameter is available for client use, and will be supplied to the data and event callbacks when they
are called. A typical use for this may be a “this” pointer of the class designated to handle the callbacks.
Within the Initialise function, all configuration settings will be read, and it will then trigger the
SETTINGS_INITIALISED event. After this event callback has been completed, the API will be initialised using these
settings. Similarly the Initialise function will trigger the PLUGINS_INITIALISED event once all plugins have been
loaded and initialised.
The certificate callback will be called when an external certificate (or private key) is required. This callback may be
initialised to NULL if it is not required. Depending upon the configuration of the 3M™ Page Reader, this may never
be called, with the certificates retrieved automatically from a file store, or only processed using the on-chip data.
MMMReader_Shutdown
Prototype:
C++ MMMReaderErrorCode MMMReader_Shutdown();
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Shutdown()
Description:
This API releases all resources allocated during the MMMReader_Initialise() call, and shuts down the 3M™ Page
Reader. After calling this API, if further processing is required, MMMReader_Initialise() must be called again.
MMMReader_Reset
Prototype:
C++ MMMReaderErrorCode MMMReader_Reset();
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.Reset()
Description:
This function shuts down and reinitialises the reader, performing a full software reset of the API. This can be used
to attempt to recover from errors not detected by the 3M™ Page Reader. This function will automatically be
triggered repeatedly when the scanner is in the READER_ERRORED state, to recover from the error without
intervention.
MMMReader_GetState
Prototype:
C++ ReaderState MMMReader_GetState();
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.Reset()
Description:
This function will return the current status of the scanner. These are defined as:
READER_NOT_INITIALISED the MMMReader_Initialise() function has not been called (or MMMReader_Shutdown() has been
called)
READER_ENABLED the reader has been initialised, and is currently waiting for a document to be placed upon the window,
and will then read the document when it is placed.
READER_DISABLED the reader is monitoring for new documents, but will not read a document when it is placed upon the
window.
READER_READING Data is currently being read from the document on the window.
READER_ASLEEP the reader is initialised, but it has been switched into a low power mode. Documents placed upon the
window will not be detected, and will not be read.
READER_SUSPENDED similar to READER_ASLEEP, except that the software disconnects from the physical devices (RFID
and Camera), which lowers power and CPU load even further. Additionally, while within the suspended
state it is possible to access the 3M™ Page Reader device from within another application. This allows
a single 3M Page Reader to be shared between multiple applications running on the same PC.
READER_ERRORED the High Level API has reported an error, and the API is automatically attempting to recover from the
error. Upon successful recovery it will automatically restore the previous state.
READER_FATAL_ERRORED a previous error has occurred from which it could not recover. The reader must be reset.
READER_TERMINATED the reader changes to this state after a successful call to MMMReader_Shutdown().
MMMReader_SetState
Prototype:
C++ MMMReaderErrorCode MMMReader_SetState(
ReaderState aNewState,
bool aForceRedetect
);
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.SetState(
MMM.Readers.FullPage.ReaderState aNewState,
bool aForceRedetect
)
Description:
This API allows the caller to change the state of the 3M™ Page Reader.
The only states that may be set are READER_ENABLED, READER_DISABLED, READER_ASLEEP and
READER_SUSPENDED.
If the aForceRedetect parameter is true, a document already on the window will be re-detected, and a
READER_ENABLED will trigger the document to be re-read.
If aForceRedetect is set to false, the document will not be read until it is removed and replaced.
This function may be called prior to MMMReader_Initialise(), and can be used to control the initial state of the
reader. This is useful if the caller wishes to force the scanner to READER_ASLEEP initially, until the application is
ready to accept data.
MMMReader_EnablePlugin
Prototype:
C++ MMMReaderErrorCode MMMReader_EnablePlugin(
char* aPluginName,
bool aEnabled);
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.EnablePlugin(
string aPluginName,
bool aEnabled)
Description:
This function will enable or disable the plugin with the given name, based on the aEnabled flag. The name is that of
the plugin DLL without the RTDECODE_*.dll pattern – e.g.“PDF417” for the plugin RTDECODE_PDF417.dll.
If the plugin is not present, it will complete successfully if aEnabled is false, however if attempting to enable a plugin
which is not present or errored on initialisation, this API will return an error.
Commonly this API would be used in conjunction with the MMMReader_GetPluginName() function to enumerate
all of the installed plugins, and enable / disable them as required.
MMMReader_IsPluginEnabled
Prototype:
C++ MMMReaderErrorCode MMMReader_IsPluginEnabled(
char* aPluginName,
bool *aEnabled
);
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.IsPluginEnabled(
string aPluginName,
ref bool aEnabled
)
Description:
This function will return the enabled state of the plugin with the given name. The boolean pointed to by aEnabled
will be updated with the current enabled state.
MMMReader_GetPluginName
Prototype:
C++ MMMReaderErrorCode MMMReader_GetPluginName(
char* aPluginName,
int* aPluginNameLen,
int aPluginIndex
);
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.GetPluginName(
ref string aPluginName,
int aPluginIndex
)
Description:
This function will return the plugin name associated with aPluginIndex. To iterate through all plugins, start at
aPluginIndex 0 and increase this value until no plugin name is returned. This is indicated by both the length being
set to 0, and aPluginName updated to an empty string.
If the plugin name is too large for the buffer supplied in aPluginName (the length of which is indicated in
aPluginName), then aPluginNameLen will be updated with the length of buffer required.
MMMReader_GetConnectedScanners
Prototype:
C++ MMMReaderErrorCode MMMReader_GetConnectedScanners(
char* aSerialNumbers,
int* aSerialNumbersLen,
int* aNumScanners
);
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.GetConnectedScanners(
ref string[] aSerialNumbers
)
Description:
This API will return the serial numbers of all readers that are currently connected to the PC. If there may be multiple
3M™ Page Reader devices connected to the same PC, this API should be used in conjunction with the
MMMReader_SelectScanner() function to attach to the appropriate device.
MMMReader_SelectScanner
Prototype:
C++ MMMReaderErrorCode MMMReader_SelectScanner(
char* aSerialNumber
);
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.SelectScanner(
string aSerialNumber
)
Description:
This API should be called prior to calling MMMReader_Initialise(), and indicates which 3M™ Page Reader should
be used by this application. This allows the High Level API to operate correctly when there are multiple 3M™ Page
Reader devices connected to the same PC.
This API need not be called if there will only be one 3M™ Page Reader connected to the PC at any one time.
Note that special configurations may be required to operate in this manner, and so
customers wishing to use the 3M™ Page Reader in this way should contact 3M Security
Systems Division.
Also note that this API does not allow the use of multiple 3M™ Page Readers at the same
time within the same application – although through the use of this API it is possible to run
two instances of the application each of which controls one 3M™ Page Reader.
MMMReader_SetSignRequestCallback
Prototype:
C++ MMMReaderErrorCode MMMReader_SetSignRequestCallback(
MMMReaderSignRequestCallback aSignRequestCallback
);
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.SetSignRequestCallback
(MMM.Readers.FullPage.SignRequestDelegate aSignRequestCallback)
Description:
This API can be called before or after MMMReader_Initialise() to optionally set a callback function to be used
when generating a digital signature for the Terminal Authentication stage of EAC. See section 4.9 above for more
details on the usage of the MMMReaderSignRequestCallback function.
MMMReader_SetRFPasswordCallback
Prototype:
C++ MMMReaderErrorCode MMMReader_SetRFPasswordCallback(
MMMReaderRFPasswordCallback aCallback
);
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.SetRFPasswordCallback(
MMM.Readers.FullPage.RFPasswordDelegate aRFPasswordCallback
)
Description:
This API can be called before optionally set a callback function to be used when a password is needed for opening
an RF chip. This password may either be the MRZ from the document, or it could be a CAN if the document is an
SAC enabled document. When specifying the MRZ (for either BAC or SAC) it is possible to either specify the full
MRZ, or just the date of birth, date of expiry, and document number. .
MMMReader_SetWarningCallback
Prototype:
C++ MMMReaderErrorCode MMMReader_SetWarningCallback(
MMMReaderWarningCallback aCallback
);
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.SetWarningCallback(
MMM.Readers.WarningDelegate aCallback
)
Description:
This API can be used to register a warning callback. Warnings typically are used to indicate possible issues which
will not prevent the SDK from retrieving the data. For example, this could be incorrect / obsolete versions of the
LDS encoding, but the data is still fundamentally possible to decode.
These APIs provide access to the data that has been read from the document.
In general, these APIs are only of significant benefit from within the Blocking API, since the non-blocking API
provides all of this information via the data and event callbacks, however unless otherwise stated, they are available
for use in either style of API.
MMMReader_IsDocumentOnWindow
Prototype:
C++ bool MMMReader_IsDocumentOnWindow();
.NET public static bool MMM.Readers.FullPage.Reader.IsDocumentOnWindow()
Description:
When the reader is in the READER_ENABLED or READER_DISABLED states, this API will return whether a
document is currently placed upon the window or not.
MMMReader_GetData
Prototype:
C++ MMMReaderErrorCode MMMReader_GetData(
MMMReaderDataType aDataType,
void* aDataPtr,
int* aDataLen
);
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.GetData(
MMM.Readers.FullPage.DataType aDataType,
ref object aData,
int aIndex
)
Description:
After a data item has been read from a document it may be obtained via this API.
The buffer supplied in the aDataPtr parameter will be written to with the data, and aDataLen updated to be the
length of the data.
The initial size of the buffer should be indicated by aDataLen – if the buffer is not big enough, then this will be
updated with the required buffer size. The caller should check for ERROR_STRING_BUFFER_TOO_SMALL, and if
returned should allocate the required buffer size, and then re-call this API.
When in non-blocking mode, this API will not wait for the data to be returned – it may return a 0 length if it has not
yet been retrieved. When used in the blocking mode, the data items will have all been read prior to returning from
the MMMReader_ReadDocument() function.
MMMReader_GetPluginData
Prototype:
C++ MMMReaderErrorCode MMMReader_GetPluginData(
char* aPluginName,
int aFeatureNum,
int aPartNum,
MMMReaderPluginData** aDataPtr
);
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.GetPluginData(
string aPluginName,
int aFeatureNumber,
int aPartNumber,
out MMM.Readers.FullPage.PluginData aData
)
Description:
This API is analogous to the MMMReader_GetData() function, except that it returns the data associated with
plugins. This is required because there is potentially more than a single item of data associated with the plugin.
The API takes the name of the plugin – e.g. in the case of RTDECODE_PDF417.dll it would be “PDF417”. Feature
name is either NULL, or the specific feature type. aFeatureNum and aPartNum can be used to index the features,
and parts of the features (both zero based indexes). aDataPtr will be updated to point to a MMMReaderPluginData
object containing the plugin data.
The MMMReaderPluginData structure includes members that indicate the total number of parts within the current
feature, the current feature number, and the total number of features. If there is no data, aDataPtr will be set to
NULL.
It also provides some members for the location, orientation and skew of the located feature, but this information
will not necessarily be set by every plugin.
Often a plugin will simply find a single feature with a single part per document (e.g. an airline boarding card with a
single PDF417 barcode on it), so in this case a single call to MMMReader_GetPluginData() will suffice, with
puDataLen bytes of barcode data contained in puData.
The puECINumber member indicates what format the data takes, and this adheres to the AIM ECI (Extended
Channel Interpretation) Assignments. E.g. 3 (ECI 000003) represents the standard ISO 8859-1 Latin Alphabet
character set, 0 (ECI 000000) represents plain binary byte encoding, and 20 (ECI 000020) represents the JIS8 and
Shift JIS character sets.
Many 2D barcode symbologies support encoding several blocks of data, each using a different ECI, e.g. if a travel
document has 2 DataMatrix barcodes on it, one with 3 ECIs used and the other with 4 ECIs used, then the following
series of calls would be necessary to retrieve all the data:
MMMReaderPluginData* dataPtr;
MMMReader_GetPluginData(“DataMatrix”, 0, 0, &dataPtr);
//dataPtr would tell us there are 2 features,
//and that the current feature has 3 parts
MMMReader_GetPluginData(“DataMatrix”, 0, 1, &dataPtr);
MMMReader_GetPluginData(“DataMatrix”, 0, 2, &dataPtr);
MMMReader_GetPluginData(“DataMatrix”, 1, 0, &dataPtr);
//dataPtr would now tell us the current feature has 4 parts
MMMReader_GetPluginData(“DataMatrix”, 1, 1, &dataPtr);
MMMReader_GetPluginData(“DataMatrix”, 1, 2, &dataPtr);
MMMReader_GetPluginData(“DataMatrix”, 1, 3, &dataPtr);
MMMReader_WaitForDocument
Prototype:
C++ MMMReaderErrorCode MMMReader_WaitForDocumentOnWindow(int aTimeout);
.NET public static MMM.Readers.ErrorCode
MMM.Readers.FullPage.Reader.WaitForDocumentOnWindow(
int aTimeout
)
Description:
This function may only be used when the API is in blocking mode.
It will wait for a new document to be placed upon the reader, and will return when a document has been detected.
MMMReader_ReadDocument
Prototype:
C++ MMMReaderErrorCode MMMReader_ReadDocument();
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.ReadDocument()
Description:
This function may only be used when using the blocking API.
It will read the document that is placed upon the reader, storing all the data items that have been specified via the
configuration, and will return when all data has been read from the document.
If no document is currently placed upon the reader, it will return ERROR_NO_DOC_ON_WINDOW. Typically, you
would only call this function after MMMReader_WaitForDocument has returned NO_ERROR_OCCURRED.
MMMReader_ClearData
Prototype:
C++ MMMReaderErrorCode MMMReader_ClearData();
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.ClearData()
Description:
This API will clear all data that has been stored for the last document that was read.
Typically, this need not be called as it will automatically be cleared upon reading the next document, however it may
be of use when memory requirements are tight, and all information required has been obtained.
MMMReader_InitialisePositionCorrection
Prototype:
C++ MMMReaderErrorCode MMMReader_InitialisePositionCorrection (
MMMReaderPositionCorrectionCallback aPositionCorrectionCallback,
int aBoxCount,
Box aBoxes[]
);
Description:
This API allows an application to register a callback aPositionCorrectionCallback that provides feedback on
document positioning during document detection, so the user can better place the docum ent.
The boxes supplied will be checked during document detection to determine whether the document is covering the
box or not.
When the state of these boxes changes, the aPositionCorrectionCallback function will be called and supplied with
the states of the boxes.
This allows an application to either display this information to the user, or determine programmatically the corrective
action needed by the user to ensure all of the boxes are covered.
When these boxes have been supplied, the document detection will only return that a document is present when all
of the boxes have been covered.
Prototype:
C++ typedef void (*MMMReaderPositionCorrectionCallback)(
void* aParam,
int aBoxCount,
Box* aBoxes,
bool* aStates
);
Description:
A user-defined function implemented by the host application.
aStates points to an array of booleans indicating whether or not the corresponding area on the document window is
covered.
aParam will be a pointer that will have been passed to MMMReader_Initialise(), and could be a “this” pointer for
example.
MMMReader_RFAbort
Prototype:
C++ MMMReaderErrorCode MMMReader_RFAbort();
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.RFAbort()
Description:
This API allows an application to abort all RF chip reading operations whilst currently reading a document.
This can be useful where, for example, an application determines that it will take too long to complete an RF read,
and it would be quicker to abort the operation than wait for all RF reading operations to fail one by one.
If there are no current RF operations waiting to be carried out, this function has no effect.
A typical scenario where this is useful is to abort an RF read if the document has been removed from the window,
which can be detected via the DOC_REMOVED event.
In order to be able to carry out document detection whilst reading the RF chip, the setting
puDocDetectSettings.detectDuringRF must be set to 1/TRUE.
It transitions to the READER_ERRORED state, attempts recovery and informs the client application via a callback
supplied to the MMMReader_Initialise() function.
There are, however, a number of APIs that are intended to help diagnose and record errors.
MMMReader_EnableLogging
Prototype:
C++ MMMReaderErrorCode MMMReader_EnableLogging(
bool aEnabled,
int aLogLevel,
int aLogMask,
char* aFilename
);
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.EnableLogging(
bool aEnabled,
int aLogLevel,
int aLogMask,
string aFileName)
Description:
This API allows the application to enable logging of 3M™ Page Reader functions.
The aLogLevel parameter specifies the detail level of logging that is required – lower values indicate less logging
will be performed.
Typically log-level 0 will indicate only errors, while log-level 5 will capture a full trace of all processing required.
The aLogMask parameter can be used to refine the logging only to functional areas within the 3M™ Page Reader.
It is recommended this value is set to -1, to capture all logging, unless requested by 3M Security Systems
Division.
MMMReader_GetLastError
Prototype:
C++ MMMReaderErrorCode MMMReader_GetLastError(
MMMReaderErrorCode* aErrorCode,
char* aErrorString,
int* aStrLen
);
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.GetLastError(
ref MMM.Readers.ErrorCode aErrorCode,
ref string aErrorMessage
)
Description:
This API returns the error string and code associated with the last error that occurred.
If the buffer at aErrorString is large enough, as indicated by aStrLen, this will be updated with the error string.
If it is not long enough, aStrLen will be updated with the length of buffer required.
MMMReader_GetErrorMessage
Prototype:
C++ MMMReaderErrorCode MMMReader_GetErrorMessage(
MMMReaderErrorCode aErrorCode,
char* aErrorString,
int* aStrLen
);
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.GetErrorMessage(
MMM.Readers.ErrorCode aErrorCode,
ref string aErrorMessage
)
Description:
This returns the error string associated with the given error code.
If the buffer at aErrorString is large enough, as indicated by aStrLen, this will be updated with the error string.
If it is not long enough, aStrLen will be updated with the length of buffer required.
Note that the string returned may include formatting parameters such as “%s” which would
typically be populated with context dependent text when the error occurs, such as the name
of a DLL that is failing to load.
MMMReader_LogMessage
Prototype:
C++ MMMReaderErrorCode MMMReader_LogMessage(
int aLevel,
int aMask,
char* aLocation,
char* aMessage
);
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.ReaderLogMessage(
int aLevel,
int aMask,
string aLocation,
string aMessage)
Description:
This API allows client applications to log messages to the same log as the 3M™ Page Reader API.
We would not recommend this for general logging of activity unrelated to the 3M™ Page Reader, but it may be
useful to log related operations to the same log file, to allow the sequence of events to be recorded.
MMMReader_LogFormatted
Prototype:
C++ MMMReaderErrorCode MMMReader_LogFormatted(
int aLevel,
int aMask,
char* aLocation,
char* aFormat,
…
);
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.LogFormatted(
int aLevel,
int aMask,
string aLocation,
string aFormat,
params object[] aValues
)
Description:
This API allows client applications to log messages to the same log as the 3M™ Page Reader API.
The difference between this API and MMMReader_LogMessage() is that this API acts in a similar way to the C
function sprintf(); you can pass in a formatting string with format flags, then pass in any number of optional
arguments after it for it to be formatted into a single string.
We would not recommend this for general logging of activity unrelated to the 3M™ Page Reader, but it may be
useful to log related operations to the same log file, to allow the sequence of events to be recorded.
4.9.5 Settings
The MMMReader_Initialise() API will automatically load all configuration settings from 3M™ Page Reader and
Application.ini file, which define how the 3M™ Page Reader will operate.
In general, minimal changes will be needed to these configuration settings after the scanner has been initially
configured, however there are times when these may need to be changed.
This section of APIs allows the configuration of the scanner to be changed programmatically at run-time. In some
applications, it may be appropriate to initialise the settings within the SETTINGS_INITIALISED event callback.
MMMReader_GetSettings
Prototype:
C++ MMMReaderErrorCode MMMReader_GetSettings(
MMMReaderSettings* aSettings,
int aSize
);
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.GetSettings(
out MMM.Readers.FullPage.ReaderSettings aSettings
)
Description:
This function will update the MMMReaderSettings object pointed to by aSettings with the values that are currently
in use on the 3M™ Page Reader.
The aSize parameter should be set to the size of the buffer supplied - which should be
sizeof(MMMReaderSettings).
MMMReader_UpdateSettings
Prototype:
C++ MMMReaderErrorCode MMMReader_UpdateSettings (
MMMReaderSettings* aNewSettings
);
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.UpdateSettings(
MMM.Readers.FullPage.ReaderSettings aSettings
)
Description:
This function applies the given settings to the 3M™ Page Reader for the current session.
Typically, the caller will get the current settings using MMMReader_GetSettings(), change any parameters they
wish to change, and then call MMMReader_UpdateSettings() to apply the changes.
The most common settings to change are the values in the puDataToSend member, which controls the data items
that are to be read.
Note that if certain certificate settings in the RFProcessSettings structure are changed, the
files in the certificate store may be reloaded. It is important to remember this if the
certificate store is very large.
If the settings in the RFInitSettings structure are changed, the RFID will be shut down and re-initialised.
The 3M™ Page Reader will temporarily be placed in the READER_ASLEEP state while the settings are applied,
and then restored to its previous state.
MMMReader_SaveSettings
Prototype:
C++ MMMReaderErrorCode MMMReader_SaveSettings();
.NET public static MMM.Readers.ErrorCode MMM.Readers.FullPage.Reader.SaveSettings()
Description:
Calling this function will apply the current settings to the SDK configuration file (Application.ini), thus making them
persistent for all sessions, not just the current session.
This is only of use after calling MMMReader_UpdateSettings(), as otherwise the settings will already be the same
as in the SDK configuration file.
MMMReader_WriteTextfileSettings
Prototype:
C++ MMMReaderErrorCode MMMReader_WriteTextfileSettings(
MMMReaderSettings *aNewSettings,
char *aPathFileName);
.NET public static MMM.Readers.ErrorCode WriteTextfileSettings(
MMM.Readers.FullPage.ReaderSettings aSettings,
ref string aPathFileName)
Description:
Calling this function saves the specified aSettings structure to a text file, which can be very useful when
troubleshooting.
4.9.6 Miscellaneous
MMMReader_GetLowLevelAPI
Prototype:
C++ MMMReaderErrorCode MMMReader_GetLowLevelAPI(
const char* aFuncName,
FARPROC* aFunctPtr
);
.NET Not required – call the low level API functions directly.
Description:
To allow users of the High Level API to make occasional calls to the Low Level API while gaining the benefit of the
overall high level API structure, a tunnelling function is provided.
This works in a similar manner to GetProcAddress, i.e. it is given the name of the function, and returns a pointer to
the function.
Due to the queuing nature of the non-blocking calls in the low-level, in general it is safe to call a Low Level function
while the High Level is currently reading a document - the tunnelled call will be queued as per any other Low Level
API call, potentially amongst the calls being made by the High Level API.
Notice: Despite this, it is recommended that care is taken when calling Low Level API
functions, e.g. indiscriminately calling MMMReader_DestroyCachedData() is likely to
cause errors within the High Level.
This section describes each of the reader configuration settings and its parameters. Settings can be held in either
the SDK configuration file (Application.ini) and/or the API settings structure used for dynamic configuration setting,
although some settings can only be accessed programmatically. The sections below describe the sections within
the Application.ini file.
Notice: Values not given in this section should not be changed from their defaults without
contacting 3M Security Systems Division first. Changing values which calibrate the
scanner can cause the scanner to malfunction or misread documents.
The settings in the [DataToSend] section mostly correspond to the puDataToSend.send and
puDataToSend.special members.
These are both used as a bit mask to enable and disable the reading of various data items.
Note that the RFID data items have a global enable/disable bit in this structure, but the
sending of individual RFID data items is set in the puDataToSend.rfid structure.
The bits in puDataToSend.send correspond with the bits in puDataToSend.special, but not every bit in
puDataToSend.special has an application to its corresponding bit in puDataToSend.send.
The values used for these bit masks are defined in MMMReaderHighLevelAPI.h e.g. to enable sending of the
colour visible image, the IR image cropped to the codeline area, RFID data and the OCR’d codeline:
The RFID data items in this section are disabled by setting them to 0, and enabled by setting them to a value
greater than 0 (values should be incremental starting from 1, as there is an upper limit of the number of available
RFID data items). This value can be used to define a specific order in which the RFID data items should be read. If
the order is not important, they can all be set to 1.
The UHF data items in this section are disabled by setting them to 0, and enabled by setting them to a value greater
than 0 (values should be incremental starting from 1, as there is an upper limit of the number of available UHF data
items). This value can be used to define a specific order in which the UHF data items should be read. If the order is
not important, they can all be set to 1.
RFInitSettings Section
Item Name Structure Reference Description
COM_PORT puRFIDSettings.puRFInitSettings.puCOMPort RFID module virtual COM port number.
The SDK will auto-detect this and update
it when necessary.
COM_TIMEOUT puRFIDSettings.puRFInitSettings.puCOMTimeoutMill Time out (in milliseconds) after no
iseconds response from the RFID chip in a certain
time period. Recommended 2000 –
10000.
EAC_VERSION puRFIDSettings.puRFProcessSettings.puEACVersion Specify the EAC specification version to
work against. 1 = 1.0, 2 = 1.01 to 1.11
This section allows various properties of the different images captured to be adjusted. For the AntiGlare and
AmbientRemoval settings some values are only available on some readers that have support for these features,
such as the AT9000 MK 2.
Select one of 3 sound schemes, turn sounds on and off and configure the ‘beep’ scheme.
This section provides details on settings that can only be accessed programmatically in order to calibrate the
reader.
Notice: Do not change calibration values unless you really want to change the appearance
of the images. Changes to these values may prevent the scanner from reading documents
correctly
5.18.2 Imaging
Settings related to images, such as the threshold settings, positional information and debug image settings.
Recommend configuration:
Note that the best configuration for your system should be tested and evaluated before
deployment. The important factors affecting configuration are the number of images being
retrieved and their compression, whether additional documents are being processed (e.g.
barcodes) the required response overall time and other processing on the PC (e.g. flash
presentations). Background processing during document detection and RFID waiting should
be carefully checked. Other tasks in the system such as flash presentations will affect
performance and must be tested.
Minimum configuration:
Note: This configuration will run a 3M™ Page Reader – but its performance will not be
optimal and must be checked as sufficient. It will not support other heavy computational
loads unless the scanner is in sleep mode.
If you choose to install the 3M™ Page Reader as part of your own application installation package, we strongly
recommend that you include all of the DLL files in the “bin” directory.
Optionally, you may choose to exclude any of the various wrappers provided for different platforms / APIs, if you
are not using that language / API:
• MMMReaderDotNet20.dll - .NET 2.0 wrapper
• MMMReaderDotNet20QA.dll - .NET 2.0 wrapper for QA API
• MMMReaderJava.dll - JAVA wrapper
• MMMReaderLowLevelJava.dll - JAVA Wrapper for the Low Level API
• RTE8000Java.dll - SDK v2 compatibility wrapper for Java
• RTE8000DotNet20.dll - SDK v2 compatibility wrapper for .NET 2.0
• ClientDLL.dll - SDK v1 API compatibility wrapper
• RTQA*.dll - Quality Assurance API
If you are not using the OCR Toolkit or any of plugins that use it to read Human Readable Zones or other non-
standard documents, then you may also optionally exclude:
• OCRToolkitDll.dll
• OCRProcDll.dll
• LoggingDll.dll
• OCR/*.*
You must install the device drivers for the scanners. This is easiest to do by running the
Drivers\3MPageReaderDriverSetup.exe application with a /s parameter to force a silent installation. Please note
that this installer also configures some registry keys in addition to simply installing the .inf files, so a manual
installation via the individual driver files is not recommended without advice from 3M.
We recommend you include the “Config” directory, or the files within it that are required for your system. It is likely
that you will wish to update Application.ini to contain the settings appropriate for your application.
We recommend you include some of the test applications, so that when attempting to perform diagnosis of
problems these tools are available for use. At a minimum, we would suggest including
MMMReaderTroubleShootingWizard.exe, CameraTest.exe, and one sample application using the High Level API
such as HLNonBlockingContainer.exe.
We recommend you include the “plugins” directory if you will ever wish to use any of the supplied plugins.
If using Java, you must redistribute the DependentDLLs.txt file, and the lib\MMMReader.jar file.
We recommend that you include the MMMReader.ini file in the same directory as the core DLL files. The
[DIRECTORIES] section is used by the SDK to locate binaries, configuration files, plugins and where to save data.
The user may wish to change the following settings:
Many of the settings in this ini file are configured automatically on installation as a record of the installation choices,
and would not be important at runtime. The “Release” value from the Install section is the SDK version, and this is
useful information when reporting problems, so please ensure this is correct for the SDK that you are redistributing.
The DIRECTORIES section is important, and determines where the SDK will locate it’s files. If the paths start with a
“.” to indicate that the path is a relative path, then it is relative to the RTE8000_ROOT token, however absolute
paths may be specified. Additionally, paths can contain environment variables such as %TEMP% and
%APPDATA% - any environment variable may be used. Additionally, %ALLUSERSAPPDATA% and
%LOCALAPPDATA% are explicitly handled, even under Windows XP where these are not specified as
environment variables. Note that in the case of the BIN_DIR, it must be possible to load at least a subset of the 3M
dlls from within your application so that it is able to
If no MMMReader.ini file is supplied, the bin, plugin, data and config directories all default to the same directory as
the SDK DLLs.