
with the exception of a few methods that are run using b4a's javaobject construct, a fruitful exchange
can be conducted in b4a between a contactless smart card and an android device (in the guise of
a "card reader").

for argument's sake, we are assuming that all i/o and system requests are successful.  any such
interaction could throw an exception.  that is beyond the scope of this outline.

if you are using erel's nfc (ndef) tag reader/writer as a base, that app will react when you place your
device over a contactless smart card (at very close proximity).  that reaction will trigger an intent 
in the app.  information in the intent is needed to start your communication with the card.

1) but first, you need to access android's nfcmanager.
2) then you obtain the device's default nfc adapter
3) then you initialize a static instance of an object which will handle communications using a
     particular technology (the technology is mutally shared by the card and the reader)
4) once you have an instance of that shared technology, the reader can connect to the card.
5) the reader then presents a kind of generic handshake in order to find out which kind
   of card it is dealing with.  this is not unlike what android does when there is an intent and
   a number of apps on the device that could handle the intent.  the user will choose.
6) the generic handshake will lead to a specific application running on the card.
7) the reader will then contact the card once again using that application.
8) the card will reply by presenting a list of things it wants from the reader and what it expects
     the reader to be able to do.  (the card thinks the "reader" is a terminal about to perform
     some financial transaction).
9) the reader replies with an answer to that list
10) the card will then reply with data such as the card account # and date of expiry.  
       in addition, that reply will also include a pointer to where the card keeps other data,
       eg, the cardholder's name and under what conditions any transaction might be carried out.
11) the rest would involve carrying out the transaction in accordance with the card issuer's rules.
      there are a lot of rules.
12) if you are simply trying to read publicly available data in the card, you would have closed the 
      connection after step 10.

the above represents the easiest and most straigtforward part of the process.

separate and apart from the communication is the fun part:  encoding/decoding the 
command/responses.  the data are transmitted as a hex string of varying lengths.  the encoding 
uses TLV, literally, Tag Length Value.  if you are familiar with run-length encoding from a bygone 
era, you will understand immediately how it works.  simply: the first byte is a tag which has a particular
meaning. (actually, a tag might consist of the first 2 bytes, and i believe there is even
a 3-byte tag, which i have not come across as yet).  the next byte is the length of the hex string that 
immediately follows.  next is the hex string which contains the meat.  a given command/response can 
consist of 0 or more TLV strings.  you just step your way through it.  simple math and the occasional
regex pattern are used.  some of the values can be converted to character strings (eg, the cardholder's 
name).  refer to emv's documentation.

the technology used to communicate with the card is done from b4a using the javaobject contruct.
all the technology is built into the device (or not, if the device does not have nfc capability).
you simply declare some javaobjects and have them run the appropriate method.  the actual
communication between card and reader is handled with 1 method: "transceive()".  it is used to
send/receive a command to/from the card.  you simply run the same method over and over as
you move through the process.  responses from the card contain data that are used to formulate
the next command to the card.  you create a given command as a hex string, convert it to bytes,
and send it to the card.  the card's reply (in bytes) is converted to a hex string and dealt with.
technically, because the communication is i/o, it should be run on a separate thread.  i've not had
a problem running transceive() on the main thread.



below please find some code, based on the process outlined above:

		Dim nfcmanager As JavaObject
		nfcmanager = jo.RunMethod("getSystemService", Array("nfc"))

		Dim nfcadapter As JavaObject
		nfcadapter = nfcmanager.RunMethod( "getDefaultAdapter",Null )

                                    ' get a handle to the tag (the card)
		Dim extra As JavaObject = nfcadapter.GetField("EXTRA_TAG")
		Dim jointent As JavaObject
		jointent = intent
		Dim Tag As JavaObject =  jointent.RunMethod("getParcelableExtra", Array( extra ))

                                    ' get an instance of the appropriate technology
		Dim isodep As JavaObject
		isodep.InitializeStatic("android.nfc.tech.IsoDep")

		' connect to the card
                		card = isodep.RunMethod("get",Array(Tag))
		card.RunMethod("connect",Null)
		connected = card.RunMethod("isConnected",Null)

		' run a generic handshake
		Dim PPSE As String = "2PAY.SYS.DDF01"
		Dim SELECT_AID_APDU_HEADER As String = "00A40400"
		Dim APDU As String = SELECT_AID_APDU_HEADER & hlen & cc & "00"

		transceivebytes = card.runmethod("transceive", Array(bc.HexToBytes(APDU)))
		transceive = bc.HexFromBytes( transceivebytes )

                                    ' run a specific handshake ( from data just received)
		Dim APDU As String = SELECT_AID_APDU_HEADER & hlen & gAID & "00"
		Dim transceivebytes() As Byte
		Dim AIDREC As String
		transceivebytes = card.runmethod("transceive", Array(bc.HexToBytes(APDU)))
		AIDREC = bc.HexFromBytes( transceivebytes )

                                    '------------------------------------------------------------------------------------------------------------------
                                    ' at this point, it might be possible to request a sort of "master file"
          
		transceivebytes = card.runmethod("transceive", Array(bc.HexToBytes("00B2010C00")))

                                    ' this file contains track 2
                                    ' if the card refuses, you have to continue below.  a pointer to that file should eventually
                                    ' appear, along with a tag containing the cardholder's name (if available)
                                    '-------------------------------------------------------------------------------------------------------------------

                                    ' request the processing options (using data from AIDREC response just received)
                                    ' the particular data is called PDOL.  if the card  sends it, you have to use it
                                    ' it's the list of things the card wants from you.  you formulate the answer and send
                                    ' it to the card.
		transceivebytes = card.runmethod("transceive", Array(bc.HexToBytes(GPO)))
		transceive = bc.HexFromBytes( transceivebytes )

                                    ' if the card responds favorably, the transeive hex string will have a pointer to
                                    ' its master file and a tag with track 2 data

                                    card.RunMethod("close",Null)



every reply from the card needs to be converted from bytes to a hex string and then parsed.
a typical example of a response from the card might be as follows.  it is the response to the
initial generic handshake ("2PAY.SYS.DDF01") sent by the reader to the card.  in it, you can see
a reference to "Dedicated File (DF) Name", from tag 84.  the DF is the specific handshake
which the read will then turnaround and send to the card.  if you look at tag 84, you will see the
next byte is 0E (that's 14 in decimal).  hex strings are formed in multiples of 2, so 14 bytes
will be a 28-byte hex string.  in this case: 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31. the
spacing is cosmetic.  after you read those 14 bytes, you see the next tag A5, a proprietary
template 1A (26 decimal) bytes in length. as those 26 bytes contain proprietary data, there
isn't much you're going to do with them.  responses are received a one long (or short) byte
array.  there are online tag readers which will pretty print as shown below.  in reality, you
will simply parse the response yourself.  good, clean fun.

PCD     Select File
            CLA: 00
            INS: A4
            P1: 04
            P2: 00
            Lc: 0E
            Data: 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 // Select PPSE (2PAY.SYS.DDF01)
            Le: 00
PICC    Successful
            Data (46 bytes)
                Tag 6F:FCI Template
                Length:2C
                Value :84 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 
                       A5 1A BF 0C 17 61 15 4F 07 A0 00 00 02 77 10 10
                       87 01 01 50 07 49 4E 54 45 52 41 43
                    Tag 84:Dedicated File (DF) Name
                    Length:0E
                    Value :32 50 41 59 2E 53 59 53 2E 44 44 46 30 31
                    Tag A5:FCI Proprietary Template
                    Length:1A
                    Value :BF 0C 17 61 15 4F 07 A0 00 00 02 77 10 10 87 01
                           01 50 07 49 4E 54 45 52 41 43
                        Tag BF0C:FCI Discretionary Data


note: if your "terminal" does not provide the correct answers expected by the card, it will simply
return a 2-byte error code.  it is very difficult to proceed from that point.  the meaning of emv's
error tags is part of emv's documentation.  in some cases it might simply be a formulating
mistake on your part which can be corrected once you figure it out.  dealing in hex does not
help matters.