Johannes Zweng
Johannes Zweng

Reputation: 133

NFC Offhost routing to the UICC on the Nexus 5X and the Nexus 6P

I am trying to configure the NFC chipset on the Nexus 5X (bullhead) or Nexus 6P (angler) to use the UICC as NFC offhost route for AIDs I declare in my OffHostApduService.

Edit Jan 17, 2016: I've updated this question and also included the Nexus 6P as I had the chance to test it too and it behaves exactly like the 5X. So all previous findings from the 5X also seem to apply to the 6P.

I managed to do this before on a Nexus 5 (hammerhead) thanks to Michael Roland's answer on this question here and also on a Nexus 6 (shamu) (see the Nexus 6 bcm2079x config in my Github repository).

However, the Nexus 5X (and also 6P) seem to be different:

As a starting point I modified the trace/log settings in both config files

What made me wonder was that I see a lot of the BrcmNfcJnimessages in logcat during bootup, similiar to the ones I've seen on Nexus 5 and 6 (which I wouldn't have expected on a device with NXP chipset):

12-11 20:45:36.840 D/BrcmNfcJni( 3434): JNI_OnLoad: enter
12-11 20:45:36.841 I/BrcmNfcJni( 3434): NFC Service: loading nci JNI
12-11 20:45:36.841 D/BrcmNfcJni( 3434): register_com_android_nfc_NativeNfcManager: enter
12-11 20:45:36.841 D/BrcmNfcJni( 3434): PowerSwitch::initialize: level=PS-UNKNOWN (0)
12-11 20:45:36.923 D/BrcmNfcJni( 3434): PowerSwitch::initialize: desired screen-off state=1
12-11 20:45:36.923 D/BrcmNfcJni( 3434): register_com_android_nfc_NativeNfcManager: exit
12-11 20:45:36.923 D/BrcmNfcJni( 3434): register_com_android_nfc_NativeNfcTag
12-11 20:45:36.924 D/BrcmNfcJni( 3434): RoutingManager::RoutingManager(): default route is 0x00
12-11 20:45:36.924 D/BrcmNfcJni( 3434): RoutingManager::RoutingManager(): mOffHostEe=0xF2
12-11 20:45:36.924 D/BrcmNfcJni( 3434): RoutingManager::registerJniFunctions
12-11 20:45:36.924 D/BrcmNfcJni( 3434): JNI_OnLoad: exit
....
....

Edit 1: I learned from the source that these "BrcmNfc.." log messages are emitted from the code in the libnfc-nci library. On previous devices the NCI (stands for: NFC controller interface) was only used by Broadcom chipsets (I guess that's the reason why the code uses the prefix "Brcm" for logging). But apparently the new NXP chipsets now also use this standardized interface (which is good), and now we also see the "Brcm..." log messages even with a NXP chipset.

Edit 3: Both phones (Nexus 5X and 6P) seem to contain the NXP PN548/C2 NFC chipset running firmware version 10.01.19 (at least in the Android 6.0.1 release).

Of course there are also outputs from the NXP pn54x halimpl:

12-11 20:45:37.407 D/        ( 3434): phNxpLog_InitializeLogLevel: global =1, Fwdnld =3, extns =3,                 hal =3, tml =3, ncir     =3,                 ncix =3
12-11 20:45:37.408 D/NxpHal  ( 3434): Entering phNxpNciHal_init_monitor
12-11 20:45:37.408 D/NxpHal  ( 3434): Returning with SUCCESS
12-11 20:45:37.408 D/NxpTml  ( 3434): Opening port=/dev/pn54x
12-11 20:45:37.408 D/NxpTml  ( 3434): phTmlNfc_i2c_reset(), VEN level 1
12-11 20:45:37.527 D/NxpTml  ( 3434): phTmlNfc_i2c_reset(), VEN level 0
12-11 20:45:37.647 D/NxpTml  ( 3434): phTmlNfc_i2c_reset(), VEN level 1
12-11 20:45:37.667 D/NxpTml  ( 3434): PN54X - Tml Reader Thread Started................
12-11 20:45:37.667 D/NxpTml  ( 3434): PN54X - Read requested.....
12-11 20:45:37.667 D/NxpTml  ( 3434): PN54X - Invoking I2C Read.....
....
....

So as a first start I tried modifiying the libnfc-nxp.conf file, starting with parameters where the comments indicated a realtion to UICC or SWP:

 # No secure element 0x00
 # eSE               0x01
 # UICC              0x02
-NXP_DEFAULT_SE=0x03
+NXP_DEFAULT_SE=0x02

and also setting the A0EC tag in NXP_CORE_CONF_EXTN to 0x01 (as the comment indicates this tag is responsible for the SWP1 connector):

# A0EC      - SWP1 interface
#             0x00 - Disabled
#             0x01 - Enabled

-        A0, EC, 01, 00,
+        A0, EC, 01, 01,

Unfortunately this didn't work and I still receive the APDUs targeted to my offhost-service in the host system (as indicated by this logcat message: E/HostEmulationManager( 3434): AID that was meant to go off-host was routed to host.).

In later tries I also tried playing around with the parameters in libnfc-brcm.conf (as described by Michael Roland in the mentioned question above), but still was not successful.

QUESTION:

Edit 2: I still did not find a working solution, but I pushed my tries until now to my github repository under the dev1 branch. I also pushed the resulting logcat outputs for each test. I am testing with a new unrooted Nexus 5X on Stock Android 6.0.1. (Edit: In the meantime I also got a Nexus 6P for testing but it behaves identically.) For modifying the config files on the system partition I temporalily boot into a sideloaded recovery image: (fastboot boot twrp-2.8.7.2-bullhead.img).

At the moment I always get this error (I also tried already with 0xf2 and 0xf4 as off-host routing target):

12-16 09:38:05.524 I/BrcmNfcNfa( 3480): NFA_EeAddAidRouting(): handle:<0xf3>
12-16 09:38:05.524 I/BrcmNfcNfa( 3480): nfa_ee_find_ecb ()
12-16 09:38:05.524 E/BrcmNfcNfa( 3480): Bad ee_handle or AID (len=14)
12-16 09:38:05.524 E/BrcmNfcJni( 3480): RoutingManager::addAidRouting: failed to route AID

Upvotes: 8

Views: 2667

Answers (2)

Johannes Zweng
Johannes Zweng

Reputation: 133

Short answer:

NFC Offhost routing to the UICC seems not to be possible on the Nexus 5X (edit: and also on Nexus 6P). As far as I understand, the SWP lines of the NFC chip are not connected to the UICC (on both phones).


Edit 1: In the meantime I got hands on a Nexus 6P made all the same tests like I did on the 5X. I can confirm now that the 6P behaves identically. I even got the same errors in logcat when calling the phNxpNciHal_SwpTest function. So also on the Nexus 6P the SWP line is not connected to the UICC.


Details:

After numerous unsuccessful tries with different config file settings I looked into the NXP implementation within the libnfc-hci library and found the interesting function "phNxpNciHal_SwpTest" in "self-test/phNxpNciHal_SelfTest.c" which according to the comment, seems to test the SWP lines:

/*******************************************************************************
 **
 ** Function         phNxpNciHal_SwpTest
 **
 ** Description      Test function to validate the SWP line. SWP line number is
 **                  is sent as parameter to the API.
 **
 ** Returns          NFCSTATUS_SUCCESS if successful,otherwise NFCSTATUS_FAILED.
 **
 *******************************************************************************/

I then modified the hal/phNxpNciHal.c file (added lots of debugging log statements just for better understanding the flow and) added 2 calls to this test function. First I tried adding it at the end of the phNxpNciHal_open function (see my changes here on GitHub) and later also tried to add it at the beginning of the phNxpNciHal_close function before actually closing the NFCC interface, just to be sure that UICC and everything is initialized at this point in time (see commit 6b33149 on my GitHub account linked above).

During the tests a SWP-capable UICC was inserted in the device.

Unfortunately all calls to phNxpNciHal_SwpTest returned an error (for both SWP lines). Look for the string "phNxpNciHal_SwpTest - FAILED" in the logcat output below:

12-22 08:48:01.597 D/NxpHal  ( 3691): JZJZ phNxpNciHal_SwpTest - testing SWP line 0x01
12-22 08:48:01.597 D/NxpHal  ( 3691): JZJZ phNxpNciHal_SwpTest - performing test...
12-22 08:48:01.597 D/NxpTml  ( 3691): PN54X - Write requested.....
12-22 08:48:01.597 D/NxpTml  ( 3691): PN54X - Invoking I2C Write.....
12-22 08:48:01.598 D/NxpNciX ( 3691): len =   4 > 20000101
12-22 08:48:01.598 D/NxpTml  ( 3691): PN54X - I2C Write successful.....
12-22 08:48:01.598 D/NxpTml  ( 3691): PN54X - Posting Fresh Write message.....
12-22 08:48:01.598 D/NxpTml  ( 3691): PN54X - Tml Writer Thread Running................
12-22 08:48:01.598 D/NxpHal  ( 3691): write successful status = 0x0
12-22 08:48:01.598 D/NxpHal  ( 3691): JZJZ performTest: write success. staring read locked from NFCC..
12-22 08:48:01.598 D/NxpHal  ( 3691): JZJZ readLocked: semaphore created, starting tml nfc read..
12-22 08:48:01.598 D/NxpHal  ( 3691): JZJZ readLocked: read returned..
12-22 08:48:01.598 E/NxpHal  ( 3691): TML Read status error status = 16f
12-22 08:48:01.598 D/NxpHal  ( 3691): JZJZ performTest: at clean_and_return label.. concurrency_unlock..
12-22 08:48:01.598 D/NxpHal  ( 3691): JZJZ phNxpNciHal_SwpTest - performing test FAILED...will break loop
12-22 08:48:01.598 D/NxpHal  ( 3691): phNxpNciHal_SwpTest - FAILED
12-22 08:48:01.598 D/NxpHal  ( 3691): phNxpNciHal_SwpTest - end


12-22 08:48:01.598 D/NxpHal  ( 3691): JZJZ: SWP1 test done, will perform SWP2 test now.
12-22 08:48:01.598 D/NxpHal  ( 3691): JZJZ phNxpNciHal_SwpTest - start
12-22 08:48:01.598 D/NxpHal  ( 3691): JZJZ phNxpNciHal_SwpTest - testing SWP line 0x02
12-22 08:48:01.598 D/NxpHal  ( 3691): JZJZ phNxpNciHal_SwpTest - performing test..
12-22 08:48:01.598 D/NxpHal  ( 3691): JZJZ performTest: concurrency locked. write locked to NFCC..
12-22 08:48:01.598 D/NxpTml  ( 3691): PN54X - Write requested.....
12-22 08:48:01.598 D/NxpTml  ( 3691): PN54X - Invoking I2C Write.....
12-22 08:48:01.599 D/NxpNciX ( 3691): len =   4 > 20000101
12-22 08:48:01.599 D/NxpTml  ( 3691): PN54X - I2C Write successful.....
12-22 08:48:01.599 D/NxpTml  ( 3691): PN54X - Posting Fresh Write message.....
12-22 08:48:01.599 D/NxpTml  ( 3691): PN54X - Tml Writer Thread Running................
12-22 08:48:01.599 D/NxpHal  ( 3691): write successful status = 0x0
12-22 08:48:01.599 D/NxpHal  ( 3691): JZJZ performTest: write success. staring read locked from NFCC..
12-22 08:48:01.599 D/NxpHal  ( 3691): JZJZ readLocked: semaphore created, starting tml nfc read..
12-22 08:48:01.599 D/NxpHal  ( 3691): JZJZ readLocked: read returned..
12-22 08:48:01.599 E/NxpHal  ( 3691): TML Read status error status = 16f
12-22 08:48:01.599 D/NxpHal  ( 3691): JZJZ performTest: at clean_and_return label.. concurrency_unlock..
12-22 08:48:01.599 D/NxpHal  ( 3691): JZJZ phNxpNciHal_SwpTest - performing test FAILED...will break loop.
12-22 08:48:01.599 D/NxpHal  ( 3691): phNxpNciHal_SwpTest - FAILED
12-22 08:48:01.599 D/NxpHal  ( 3691): phNxpNciHal_SwpTest - end
12-22 08:48:01.599 D/NxpHal  ( 3691): JZJZ: SWP2 test done.

Conclusion:

Without further knowledge of hardware details of the NXP PN548/C2 chipset, I assume this means that both SWP lines of the chipset are not connected in the Nexus 5X (bullhead) phone.

If anybody has more insight in this topic, please feel free correct me! :)

Upvotes: 5

Martijn Coenen
Martijn Coenen

Reputation: 981

As you already found out, the SWP lines aren't connected to the UICC slot. We usually don't do this for Nexus devices, since we don't support secure elements on the UICC in AOSP. The one exception to this is the Nexus 6 on Lollipop, which supported SoftCard mobile payments in the US (along with HCE). After SoftCard was acquired by Google, we removed the code to support UICCs again in Marshmallow.

I'm surprised BTW that this worked on N5 - it was supposed to not have SWP connected either. Perhaps this wasn't done correctly on all devices.

Upvotes: 6

Related Questions