The IOCTL_SMARTCARD_POWER command (aka, smartcard reset) is supposed to
return the smartcard's ATR in the I/O request's output buffer. However
the NFC CX has a long standing issue where this isn't done for the NFC
smartcard interface. This change fixes this.
In addition, a test is being added to the UT suite that tests the
behavior of the NFC smartcard reset operation, including checking the
ATR is returned. Also, the TagTests class is being refactored slightly
to remove duplicate code.
1. In the NfcCxSequence class, fix an issue where synchronous completion
of a sequence isn't handled correctly.
2. Fix an issue where if tag activation fails, the driver will not be
able to exit RF discovery mode. This prevents NFC from working until the
driver is restarted.
Currently there is code in the NFC CX that triggers NFC-A's SLP_REQ
command (NFC Forum, Digital Protocol, Version 2.1, Section 6.9.1) when
connecting to a T2T (e.g. Mifare) NFC tag when in NCI 2 mode.
However there are two problems:
1. The NCI specs (both versions 1 and 2) explictly call out that the
SLP_REQ command should be handled by the NFC Controller not the driver.
(NFC Forum, NCI, Version 2.0, Section 8.2.4.2, Table 94.)
2. The wrong command code is being used. Specifically, '05 00' instead
of '50 00'. So even if the SLP_REQ command was required, it would be
broken.
This change removes the code that invokes the SLP_REQ command.
In addition, tests are added for reading a T2T tag in NCI 2 mode. Also,
some code duplication was removed from the `TagTests` class.
The tag formatting processing can take place once we know the tag size provided
in this case by the ISO15693 command EXT_GET_SYSTEM_INFO.
In case of success, The next command tag will be sent by the NfcCx should be
READ_SINGLE_BLOCK command.
This changes remove the auto installation of the test device when the
test driver is installed. Instead the test suite will install the device
during test initialization and uninstall the test device when the test
uninitializes (including when the test suite crashes).
This is being done to make it easier to re-run the test suite when
debugging test failures. (Previously you would have to manually disable
and enable the test device, to reset the test device's state.) It also
means the system will be left in a cleaner state when the test suite has
finished running, which will be useful in lab test runs which run
multiple test suites on the same VM.
Currently the test client driver has an implicit assumption that the
first test suite connection will be opened when the driver is not in D0.
If this isn't the case, which can happen if the test suite is started
immediately after the driver is initialized, then the test suite will
hang indefinitely.
To fix this problem, the test driver will no longer start and stop NfcCx
during D0Entry and D0Exit. Instead the test suite will directly control
when NfcCx is started and stopped via IOCTLs. In addition, the test
driver will inform the test suite of the D0Entry and D0Exit events via
callbacks so that the test suite can verify the behavior of the NfcCx
Power Manager.
As part of this change, the `NciSimConnector` callback retrieval was
changed so that it is done asynchronously in the background. This was
done to make it possible to split the LibNfc thread callbacks and the
power manager callbacks, as these callback events are not synchronized
and therefore can arrive in a non-determined order.
In addition, the synchronous commands of `NciSimConnector` were changed
to have a timeout value, to help reduce the likelihood of the test suite
becoming blocked indefinitely.
For some device interfaces (e.g. eSE smartcard), there isn't a signal
from the simulator driver that provides a gaurantee that the device
interface has been created and is ready to be used. So we have to wait
an unspecified amount of time for the interface to show up.
This change modifies the `DeviceQuery::FindDriverInterfaces` function
to take a timeout value. Once at least 1 interface has been found, this
interface is returned immediately. Otherwise the function will wait for
the timout to expire.
As part of this change the `DeviceQuery` was rewritten to use the
`windows.devices.enumeration` APIs as they are more flexible than the
Configuration Manager APIs.
1. Don't log the I/O requests in `NciSimConnector` as these are always
expected to succeed.
2. Improve the logging when the expected test step doesn't match the
simulator driver message that is received. This will make it easier to
debug test failures if and when they occur.
STM is providing T5T tags with "high" storage capacity (for instance up to 8192).
The M24LRxxx family seems to some sort of support in the NfcCx but was incomplete.
Those tags were produced before NFC Forum defined a method to address memory above 256 blocks
(blocks above 0xFF).
This patch completes M24LRxxx support and support for the NFC Forum T5T defined way of addressing the extended memory range (blocks above 0xFF).
* Make phLibNfc_GetSysInfoCmd/Resp static in phLibNfc_Iso15693.c
* Improve support for STM M24LR tags
STMicroelectronics M24LRxxx tags provide "high" storage capacity.
The extended memory range (above 256 blocks) was made possible by extending
the regular ISO15693 commands with 2 bytes address. This was made before
NFC Forum standardize the way of addressing such extended memory range.
On top fixes for the existing M24LR support in the class extension, this
patch now allow to address to tag complete capacity.
The SmartCard interface was allowing to address only the first 256 blocks
of a "high" capacity ISO15693 tag.
It wasn't possible to address STM M24LRxxx tags through ISO7816 command over
the smartcard interface.
As a results update commands UpdateBinary and ReadBinary in order to build
correctly the ISO15693 command.
* Update T5T support for extended tag capacity > 256 blocks
Tags which support NFC-Forum defined extended capacity and commands are now
using the EXT_ (0x3x based) commands.
The NFC-Forum T5T is stating for each EXTENDED_xxx commands the regular one
is supported. Using EXTENDED_xxx commands when the tags supports it allow
addressing the extended range of the tag memory (> 256 blocks) as well as the
"regular" range of the tag memory (< 256 blocks).
Tested against ST25DV64K-J
* Rework GET_SYSTEM_INFO parsing, add support for different response formats, improved various definitions
* Rework definitions and get_system_info parsing.
Improve new code clarity, simplify T5T response parsing flow.
* Add comment about commands formating for first block information for M24L tags family and derivative.
* Add comment about the way the CC is written when NDEF formatting a tag
* Improve Extended Get System Information command formatting
This fix a coding mistake where this part try to recover a command misformating in phFriNfc_ISO15693_H_FmtReadWrite.
The current code currently generate the following byte flow:
<REQ_FLAG><command><Uid><data>
While the extended get system info format is:
<REQ_FLAG><command><data><Uid>
* Add comment for ISO15693_CAPABILITY_MASK
* Improve phFriNfc_ReadRemainingInMultiple when handling READ_MULTIPLE
* Fix some regressions introduced by phFriNfc_ISO15693_H_ProcessSystemInfo.
The aim of phFriNfc_ISO15693_H_ProcessSystemInfo is to retrieve the tag
max_data_size.
In case the tag size is greater than 256 blocks, Get System Info will
return VICC memory size = 0. This value should be available in
Extended Get System Info.
In the case VICC memory size is 0, phFriNfc_ISO15693_H_ProcessSystemInfo
should return an error (i.e PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_DEVICE_REQUEST)
Another fix in that commit is that SUCCEEDED check that the function returns
a value >= 0.
PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_DEVICE_REQUEST) >= 0
and was causing Extended Get System Info to be never executed.
* Retrieve VICC command list correctly and store in card_capability
VICC command list is 4 bytes long.
* Integration of follow-up commits + various updates addressing review feedback
* Fix byte ordering in EXT_GET_SYSTEM_INFO request
Currently the test suite requires sequence steps to be specified in a
single continuous array. However it would be useful to have some easy
way to concatenate sequences together so that the sequences can be
modular.
While it would be possible to do this concatenation at runtime, this
would come at a runtime cost. So extra code would be required to
mitigate these costs to prevent them from becoming problematic. For
example, in the airplane mode tests the `InitializeNoSEs`,
`DiscoveryStart`, `DiscoveryStop` and `Uninitialize` sequences are all
used multiple times. So some form of caching mechanism would be required
to avoid regenerating the same data over and over again.
To avoid these problems, the sequences will instead be concatenated at
compile time using a tree structure. This has the nice feature of not
duplicating data if one sequence is used by multiple other sequences.
2.23 is the release when 'nt_assert.h' was removed from WDK and
NT_ASSERT-like definitions were added to 'wudfwdm.h'.
Also since 'wudfwdm.h' is being included now, there's no need for generic
'WdmLinkedList.h', it can be deleted.
1. Remove the concept of sequence process functions. These functions
were originally intended to be used to process the results of
asynchronous operations. However the result processing logic instead
exists in the operations' callback handlers. So the sequence process
functions are always set to NULL and are therefore pointless.
2. Store the value of the sequence complete function (the function
called when the sequence has finished) separately, instead of having it
be part of the the list of sequence handlers. This was done because
there is a number of sequences that only differ by their complete
function. So it makes the code cleaner to support this directly.
3. Ensure that all sequence lists are specified in immutable global
memory, instead of mutable global memory. (#2 made doing this a lot
easier.)
4. Store the state of a running sequence in heap allocated memory. This
memory is used:
1. To uniquely identify a running sequence, so that sequence
conflicts can be detected.
2. As the context value for (LibNfc) asynchronous operations. This
replaces the mutable global variables that were previously used for
this purpose. (e.g. NFCCX_RF_LIBNFC_REQUEST_CONTEXT.)
5. Make the sequence complete functions return `void` instead of
`NTSTATUS`. This error code was never used for anything. So its
existence only causes confusion.
6. Remove the `Status` parameter from the sequence handler functions.
This value was alaways `STATUS_SUCCESS` and was never used for anything.
So its existence only causes confusion.
7. If the initial sequence handler completes synchronously (either
success or failure), then call complete function in a new message to the
LibNfc thread. This ensures that the state handler function is not
called recursively.
The primary purpose of this change is to ensure that a state transition
caused by internal driver event (e.g. a user tapping a tag) doesn't
interfere with an already running state transition (if any). There is
already logic that delays user events (e.g. a tag read I/O request)
for the same reason. This change rewrites this logic so that it supports
both internal and user events.
Unfortunatley, the existing logic that delays users events used "magic"
to determine when an event should be delayed and when it should be
handled immediately. This made the state machine logic an absolute
nightmare to read and comprehend. In addition, updating the "magic"
logic to handle internal events and user events would have been almost
impossible.
This change rips out the "magic" logic and instead requires the callers
that are issuing the events to explictly state if the event is
deferrable or not.
Miscellaneous changes:
- Fix `NfcCxRFInterfaceExecute` so that it only needs a single event
handle instead of two.
In the current code, when an NCI write I/O request is made and a
response packet is expected, the response watchdog timer is started when
the NCI write is sent instead of when it has completed. In most cases,
this is fine as the NCI write is expected to only take a short amount of
time and therefore is likely to finish well before the response watchdog
timer fires. However on some hardware, it seems that the NCI write can
take a somewhat long time to complete in certain situations. When this
occurs, the driver code treats the error like any other error and
resumes what it was doing. However, since a new NCI write can't be sent
before the old one has completed, any new NCI commands fail which can
cause the various state machines to become confused.
To fix this issue, the response watchdog timer was changed so that it is
only started after the NCI write has completed (instead of when the NCI
write is sent).
Bug steps:
1. A P2P connection is established.
2. The NFC radio is shutdown. (e.g. to apply a new radio config.)
3. LLCP is told to deactivate itself.
4. LLCP starts an asynchronous operation as part of its deactivation.
5. When the asynchronous operation completes, LLCP starts a new state
transition, which overrides the currently executing state transition
(that was started in Step 2). This messes up the state of a driver,
causing a fatal error to occur.
This change ensures that in Step 5, LLCP resumes the current state
transition instead of starting a new one.
- NFCEE_MODE_SET_NTF callback getting overwritten in NCI 2.0 in case when other NCI packets with upper layer callback take place between NFCEE_MODE_SET_RSP and NFCEE_MODE_SET_NTF
- in case of corrupted INS byte in HCI packet failed APDU pipe initialization error was not set
This change ensures that a call to retrieve the ATR through
IOCTL_SMARTCARD_GET_ATTRIBUTE doesn't invoke a card reset,
as such behavior is not compliant with the smartcard driver interface
and can cause client scenarios to fail unexpectedly.
Instead the eSE' ATR is cached after all successful card
reset operations. This cached value is then used for any
IOCTL_SMARTCARD_GET_ATTRIBUTE ATR requests. In addition, a card reset
operation is run when on the first client connection to the eSE to
ensure the ATR value is available if and when it is requested.
- Updated initial HCI credit value according to NCI specification.
- Change NFC Features field in CORE_INIT_RSP structure to a bitfield
- Change the flag that used for HCI static connection check.
Callbacks for pipe events are never being unregistered in HCI part of NfcCx.
Add unregistration of pipe events as part of ClearAllPipe notification
processing.
Fix support of Type 5 tags, memory area size of which are not listed in
NfcCx. Over the past few years ST have released a various NFC tags with different
size options.
Proprietary HCI v9 APDU pipe initialization is implemented with a different
control packets flow:
- _HCI v9_: **ADM_NOTIFY_PIPE_CREATED(1)** / ANY_OPEN_PIPE
- _HCI v12_: **ADM_CREATE_PIPE(2)** / ANY_OPEN_PIPE
For HCI v12 registration takes place in the response to
**ADM_CREATE_PIPE(2)**, therefore we need update
**ADM_NOTIFY_PIPE_CREATED(1)** appropriately.