Contactless API: Difference between revisions

From wizarPOS
No edit summary
 
(8 intermediate revisions by the same user not shown)
Line 1: Line 1:
== Functions ==
== API Overview==
* For CPU card, the follow api calling sequence is [[#open|open]]>[[#search_target_begin|search_target_begin]]>[[#attach_target|attach_target]]>[[#transmit|transmit]]>[[#detach_target|detach_target]]>[[#close|close]],but Filicard don't need to do attach.
* For CPU card, the follow API calling sequence is [[#open|open]]>[[#search_target_begin|search_target_begin]]>[[#attach_target|attach_target]]>[[#transmit|transmit]]>[[#detach_target|detach_target]]>[[#close|close]],but Felica card don't need to do attach.
* For memory card such as Mifare1 card, the follow api calling sequence is [[#open|open]]>[[#search_target_bego in|search_target_begin]]>[[#verify|verify]]>[[#read|read]] or [[#write|write]]>[[#close|close]]
* For memory card such as Mifare1 card, the follow API calling sequence is [[#open|open]]>[[#search_target_begin|search_target_begin]]>[[#verify|verify]]>[[#read|read]] or [[#write|write]]>[[#close|close]]
* For eletronic wallet card, the follow api calling sequence is [[#open|open]]>[[#search_target_begin|search_target_begin]]>[[#verify|verify]]>[[#read_value|read_value]] or [[#write_value|write_value]] or [increment/decrement]>[[#transfer|transfer]]>[[#close|close]], the [increment/decrement] includes the flows:[[#restore|restore]]>[[#increment|increment]]/[[#decrement|decrement]]>[[#transfer|transfer]].
* For electronic wallet card, the follow API calling sequence is [[#open|open]]>[[#search_target_begin|search_target_begin]]>[[#verify|verify]]>[[#read_value|read_value]] or [[#write_value|write_value]] or [increment/decrement]>[[#transfer|transfer]]>[[#close|close]], the [increment/decrement] includes the flows:[[#restore|restore]]>[[#increment|increment]]/[[#decrement|decrement]]>[[#transfer|transfer]].
=== open ===
=== <big>open</big> ===
   void* contactless_card_open(CONTACTLESS_CARD_NOTIFIER fNotifier, void* pUserData, int* pErrorCode)
   <syntaxhighlight lang="c">void* contactless_card_open(CONTACTLESS_CARD_NOTIFIER fNotifier, void* pUserData, int* pErrorCode)</syntaxhighlight >
Initialize the contactless card reader.
Initialize the contactless card reader.
 
{|class="wizarpostable"
'''Parameters'''
|-
!  scope="row" colspan="2"| Parameters
|-
| fNotifier || '''CONTACTLESS_CARD_NOTIFIER:''' Notifier of contactless card
|-
| pUserData|| '''void*:''' User data
|-
| pErrorCode|| '''int*:''' [[Error_code|error code]] if return value is equals to 0
|}
{|
{|
|-
|-
| ''fNotifier'' || CONTACTLESS_CARD_NOTIFIER ||Notifier of contactless card
|  
|}
{|class="wizarpostable"
|-
|-
| ''pUserData''|| void* ||User data
!  scope="row" colspan="2"| Returns
|-
|-
| ''pErrorCode''|| int* ||[[Error_code|error code]] if return value is equals to 0
| int || The result code, != 0, success, value is the handle of contactless card device; =0 failed.
|}
|}


'''Returns'''
=== <big>search_target_begin</big> ===
 
   <syntaxhighlight lang="c">int contactless_card_search_target_begin(int nHandle, int nCardMode, int nFlagSearchAll, int nTimeout_MS)</syntaxhighlight >
The result code, != 0, success, value is the handle of contactless card device; <0 failed.
 
=== search_target_begin ===
   int contactless_card_search_target_begin(int nHandle, int nCardMode, int nFlagSearchAll, int nTimeout_MS)
Start searching the contactless card. If you set the nCardMode is auto, reader will try to activate card in type A, type B and type successively;
Start searching the contactless card. If you set the nCardMode is auto, reader will try to activate card in type A, type B and type successively;
If you set the nCardMode is type A, type B, or type C, reader only try to activate card in the specified way.
If you set the nCardMode is type A, type B, or type C, reader only try to activate card in the specified way.
You can terminate it using function [[#search_target_end|search_target_end]].
You can terminate it using function [[#search_target_end|search_target_end]].
 
{|class="wizarpostable"
 
|-
'''Parameters'''
!  scope="row" colspan="2"| Parameters
{|
|-
|-
| ''nHandle'' || int || Handle of this device, returned from open
| nHandle || '''int:''' Handle of this device, returned from open
|-
|-
| ''nCardMode''|| int || Mode to search
| nCardMode|| '''int:''' Mode to search
|-
|-
| ''nFlagSearchAll''||  int || Not used
| nFlagSearchAll|| '''int:''' Not used
|-
|-
| ''nTimeout_MS''|| int || Time out in millseconds. If it is less than 0, then wait forever.
| nTimeout_MS|| '''int:'''  Time out in millseconds. If it is less than 0, then wait forever.
|}
|}
Possible value of nCardMode :
Possible value of nCardMode :
*define ''CONTACTLESS_CARD_MODE_AUTO 0''
<syntaxhighlight lang="c">#define CONTACTLESS_CARD_MODE_AUTO 0
*define ''CONTACTLESS_CARD_MODE_TYPE_A 1''
#define CONTACTLESS_CARD_MODE_TYPE_A 1
*define ''CONTACTLESS_CARD_MODE_TYPE_B 2''
#define CONTACTLESS_CARD_MODE_TYPE_B 2
*define ''CONTACTLESS_CARD_MODE_TYPE_C 3''
#define CONTACTLESS_CARD_MODE_TYPE_C 3</syntaxhighlight >
'''Returns'''


The result code, >= 0, success; <0 [[Error_code|error code]].
{|class="wizarpostable"
|-
!  scope="row" colspan="2"| Returns
|-
| int || The result code, >= 0, success; <0 [[Error_code|error code]].
|}




=== search_target_end ===
=== <big>search_target_end</big> ===
   int contactless_card_search_target_end(int nHandle)
   <syntaxhighlight lang="c">int contactless_card_search_target_end(int nHandle)</syntaxhighlight >
Stop the process of searching card.
Stop the process of searching card.
The [[#search_target_begin|search_target_begin]] and [[#search_target_end|search_target_end]] API are pair operations.


The [[#search_target_begin|search_target_begin]] and [[#search_target_end|search_target_end]] apis are pair operations.
{|class="wizarpostable"
 
|-
'''Parameters'''
!  scope="row" colspan="2"| Parameters
|-
| nHandle || '''int:''' Handle of this device, returned from open
|}
{|
{|
|-
|-
| ''nHandle'' || int || Handle of this device, returned from open
|  
|}
|}


'''Returns'''
{|class="wizarpostable"
|-
!  scope="row" colspan="2"| Returns
|-
| int || The result code, >= 0, success; <0 [[Error_code|error code]].
|}


The result code, >= 0, success; <0 [[Error_code|error code]].


=== close ===
=== <big>close</big> ===
   int contactless_card_close(int nHandle)
   <syntaxhighlight lang="c">int contactless_card_close(int nHandle)</syntaxhighlight >
Close the contactless card reader.
Close the contactless card reader.
[[#open|open]] and [[#close|close]] are pair operations. If you don’t want to use the device, you should call close to release the device.
[[#open|open]] and [[#close|close]] are pair operations. If you don’t want to use the device, you should call close to release the device.
 
{|class="wizarpostable"
'''Parameters'''
|-
!  scope="row" colspan="2"| Parameters
|-
| nHandle || '''int:''' Handle of this device, returned from open
|}
{|
{|
|-
|-
| ''nHandle'' || int || Handle of this device, returned from open
|  
|}
|}


'''Returns'''
{|class="wizarpostable"
|-
!  scope="row" colspan="2"| Returns
|-
| int || The result code, >= 0, success; <0 [[Error_code|error code]].
|}


The result code, >= 0, success; <0 [[Error_code|error code]].


=== query_info ===
=== <big>query_info</big> ===
   int contactless_card_query_info(int nHandle, unsigned int* pHasMoreCards, unsigned int* pCardType)
   <syntaxhighlight lang="c">int contactless_card_query_info(int nHandle, unsigned int* pHasMoreCards, unsigned int* pCardType)</syntaxhighlight >
Query the quantity and type of cards on the contactless card reader.
Query the quantity and type of cards on the contactless card reader.
 
{|class="wizarpostable"
'''Parameters'''
|-
{|
!  scope="row" colspan="2"| Parameters
|-
|-
| ''nHandle'' || int || Handle of this device, returned from open
| nHandle || '''int:''' Handle of this device, returned from open
|-
|-
| ''pHasMoreCards'' || int* || Card quantity
| pHasMoreCards || '''int*:''' Card quantity
|-
|-
| ''pCardType'' || int* || Card type
| pCardType || '''int*:''' Card type
|}
|}
'''Returns'''
The result code, >= 0, success; <0 [[Error_code|error code]].
''pHasMoreCards'':
''pHasMoreCards'':
*''0 : only one PICC in the field''
*''0 : only one PICC in the field''
Line 117: Line 137:
*''CONTACTLESS_CARD_UNKNOWN                0x00FF''
*''CONTACTLESS_CARD_UNKNOWN                0x00FF''


=== attach_target ===
{|class="wizarpostable"
   int contactless_card_attach_target(int nHandle, unsigned char* pATRBuffer, unsigned int nATRBufferLength)
|-
!  scope="row" colspan="2"| Returns
|-
| int || The result code, >= 0, success; <0 [[Error_code|error code]].
|}
 
 
=== <big>attach_target</big> ===
   <syntaxhighlight lang="c">int contactless_card_attach_target(int nHandle, unsigned char* pATRBuffer, unsigned int nATRBufferLength)</syntaxhighlight >
Attach the target before transmitting APDU command. In this process, the target(card) is activated and return ATR.
Attach the target before transmitting APDU command. In this process, the target(card) is activated and return ATR.
If the card is a CPU card, the [[#attach_target|attach_target]], [[#detach_target|detach_target]] and [[#transmit|transmit]] apis are used to get informations from the card.
If the card is a CPU card, the [[#attach_target|attach_target]], [[#detach_target|detach_target]] and [[#transmit|transmit]] API are used to get information from the card.
 
{|class="wizarpostable"
'''Parameters'''
|-
!  scope="row" colspan="2"| Parameters
|-
| nHandle || '''int:''' Handle of this device, returned from open
|-
| pATRBuffer || '''unsigned char*:''' ATR buffer, if null, you can not get data.
|-
| nATRBufferLength || '''int:''' Length of ATR buffer
|}
{|
{|
|-
|-
| ''nHandle'' || int || Handle of this device, returned from open
|  
|}
 
{|class="wizarpostable"
|-
|-
| ''pATRBuffer'' || unsigned char* || ATR buffer, if null, you can not get data.
!  scope="row" colspan="2"| Returns
|-
|-
| ''nATRBufferLength'' || int || Length of ATR buffer
| int || The result code, >= 0, success,length of ATR; <0 [[Error_code|error code]]..
|}
|}


'''Returns'''


The result code, >= 0, success,length of ATR; <0 [[Error_code|error code]].
=== <big>detach_target</big> ===
 
   <syntaxhighlight lang="c">int contactless_card_detach_target(int nHandle)</syntaxhighlight >
=== detach_target ===
   int contactless_card_detach_target(int nHandle)
Detach the target. If you want to send APDU again, you should attach it.
Detach the target. If you want to send APDU again, you should attach it.
The detach is a block method, only when you remove the card can you get the return value of this api.
The detach is a block method, only when you remove the card can you get the return value of this API.
{|class="wizarpostable"
|-
!  scope="row" colspan="2"| Parameters
|-
| nHandle || '''int:''' Handle of this device, returned from open
|}
{|
|-
|}


'''Parameters'''
{|class="wizarpostable"
{|
|-
!  scope="row" colspan="2"| Returns
|-
|-
| ''nHandle'' || int ||Handle of this device, returned from open
| int || The result code, >= 0, success; <0 [[Error_code|error code]].
|}
|}


'''Returns'''


The result code, >= 0, success; <0 [[Error_code|error code]].
=== <big>transmit</big> ===
=== transmit ===
   <syntaxhighlight lang="c">int contactless_card_transmit(int nHandle, unsigned char* pAPDU, unsigned int nAPDULength, unsigned char* pResponse, unsigned int *pResponseLength)</syntaxhighlight >
   int contactless_card_transmit(int nHandle, unsigned char* pAPDU, unsigned int nAPDULength, unsigned char* pResponse, unsigned int *pResponseLength)
Transmit APDU command and get the response.
Transmit APDU command and get the response.
The APDU command of contactless card is the same as the IC card normally.
The APDU command of contactless card is the same as the IC card normally.
{|class="wizarpostable"
|-
!  scope="row" colspan="2"| Parameters
|-
| nHandle || '''int:''' Handle of this device, returned from open
|-
| pAPDU || '''unsigned char*:''' Command of APDU
|-
| nAPDULength || '''unsigned int:''' Length of command
|-
| pResponse || '''unsigned char*:''' Response buffer of APDU command
|-
| pResponseLength || '''unsigned int:''' buffer length of response
|}
{|
|-
|}
{|class="wizarpostable"
|-
!  scope="row" colspan="2"| Returns
|-
| int || The result code, >= 0, success; <0 [[Error_code|error code]].
|}


'''Parameters'''
=== <big>transmit_level3</big> ===
{|
  <syntaxhighlight lang="c">int contactless_card_transmit_level3(int nHandle, unsigned char* pAPDU, unsigned int nAPDULength, unsigned char* pResponse, unsigned int *pResponseLength, int nOperationValue)</syntaxhighlight >
Transmit APDU command and get the response. This is only for ultralight C card.
The APDU command of contactless card is the same as the IC card normally.
{|class="wizarpostable"
|-
!  scope="row" colspan="2"| Parameters
|-
| nHandle || '''int:''' Handle of this device, returned from open
|-
| pAPDU || '''unsigned char*:''' Command of APDU
|-
|-
| ''nHandle'' || int || Handle of this device, returned from open
| nAPDULength || '''unsigned int:''' Length of command
|-
|-
| ''pAPDU'' || unsigned char* || Command of APDU
| pResponse || '''unsigned char*:''' Response buffer of APDU command
|-
|-
| ''nAPDULength'' || unsigned int || Length of command
| pResponseLength || '''unsigned int:''' buffer length of response
|-
|-
| ''pResponse'' || unsigned char* || Response buffer of APDU command
| nOperationValue|| '''int:''' reserved for future, must be set to zero
|}
{|
|-
|-
| ''pResponseLength'' || unsigned int || buffer length of response
|  
|}
|}


'''Returns'''
{|class="wizarpostable"
|-
!  scope="row" colspan="2"| Returns
|-
| int || The result code, >= 0, success; <0 [[Error_code|error code]].
|}


The result code, >= 0, success; <0 [[Error_code|error code]].
=== <big>verify</big> ===
=== verify ===
   <syntaxhighlight lang="c">int contactless_card_mc_verify_pin(int nHandle, unsigned int nSectorIndex, unsigned int nPinType, unsigned char* strPin, unsigned int nPinLength)</syntaxhighlight >
   int contactless_card_mc_verify_pin(int nHandle, unsigned int nSectorIndex, unsigned int nPinType, unsigned char* strPin, unsigned int nPinLength)
Verify the key of the contactless card. You should firstly know the key and corresponding key type(key A or key B).
Verify the key of the contactless card. You should firstly know the key and corresponding key type(key A or key B).
If the card is a Mifare card, the [[#verify|verify]], [[#read|read]] and [[#write|write]] apis are used to get informations from the card.
If the card is a Mifare card, the [[#verify|verify]], [[#read|read]] and [[#write|write]] API are used to get information from the card.
 
{|class="wizarpostable"
'''Parameters'''
|-
{|
!  scope="row" colspan="2"| Parameters
|-
|-
| ''nHandle'' || int || Handle of this device, returned from open
| nHandle || '''int:''' Handle of this device, returned from open
|-
|-
| ''nSectorIndex'' || unsigned int || Sector index
| nSectorIndex || '''unsigned int:''' Sector index
|-
|-
| ''nPinType'' || unsigned int || Key type:0—Key A; 1—Key B
| nPinType || '''unsigned int:''' Key type:0—Key A; 1—Key B; 2-TDEA type (for ultralight C)
|-
|-
| ''strPin'' || unsigned char* || Password of this sector
| strPin || '''unsigned char*:''' Password of this sector
|-
|-
| ''nPinLength'' || unsigned int || Length of password
| nPinLength || '''unsigned int:''' Length of password
|}
{|
|-
|  
|}
|}


'''Returns'''
{|class="wizarpostable"
|-
!  scope="row" colspan="2"| Returns
|-
| int || The result code, >= 0, success; <0 [[Error_code|error code]].
|}


The result code, >= 0, success; <0 [[Error_code|error code]].
=== <big>read</big> ===
=== read ===
   <syntaxhighlight lang="c">int contactless_card_mc_read(int nHandle, unsigned int nSectorIndex, unsigned int nBlockIndex, unsigned char* pDataBuffer, unsigned int nDataBufferLength)</syntaxhighlight >
   int contactless_card_mc_read(int nHandle, unsigned int nSectorIndex, unsigned int nBlockIndex, unsigned char* pDataBuffer, unsigned int nDataBufferLength)
Read data from the contactless card. You should verify the key at first.
Read data from the contactless card. You should verify the key at first.
You should firstly know the card format(how many sectors, blocks and block size) from the card producer.
You should firstly know the card format(how many sectors, blocks and block size) from the card producer.
 
{|class="wizarpostable"
'''Parameters'''
|-
{|
!  scope="row" colspan="2"| Parameters
|-
| nHandle || '''int:''' Handle of this device, returned from open
|-
| nSectorIndex || '''unsigned int:''' Sector index
|-
| nBlockIndex || '''unsigned int:''' Block index of the specified sector
|-
|-
| ''nHandle'' || int || Handle of this device, returned from open
| pDataBuffer || '''unsigned char*:''' Data buffer to read
|-
|-
| ''nSectorIndex'' || unsigned int || Sector index
| nDataBufferLength || '''unsigned int:''' Buffer length
|}
{|
|-
|-
| ''nBlockIndex'' || unsigned int || Block index of the specified sector
|  
|}
 
{|class="wizarpostable"
|-
|-
| ''pDataBuffer'' || unsigned char*|| Data buffer to read
!  scope="row" colspan="2"| Returns
|-
|-
| ''nDataBufferLength'' || unsigned int || Buffer length
| int || The result code, >= 0, success; <0 [[Error_code|error code]].
|}
|}


'''Returns'''


The result code, >= 0, success; <0 [[Error_code|error code]].
=== <big>write</big> ===
=== write ===
   <syntaxhighlight lang="c">int contactless_card_mc_write(int nHandle, unsigned int nSectorIndex, unsigned int nBlockIndex, unsigned char* pData, unsigned int nDataLength)</syntaxhighlight >
   int contactless_card_mc_write(int nHandle, unsigned int nSectorIndex, unsigned int nBlockIndex, unsigned char* pData, unsigned int nDataLength)
Write data to the contactless card. You should verify the key at first.
Write data to the contactless card. You should verify the key at first.
 
{|class="wizarpostable"
'''Parameters'''
|-
{|
!  scope="row" colspan="2"| Parameters
|-
| nHandle || '''int:''' Handle of this device, returned from open
|-
| nSectorIndex || '''unsigned int:''' Sector index
|-
| nBlockIndex || '''unsigned int:''' Block index of the specified sector
|-
|-
| ''nHandle'' || int ||Handle of this device, returned from open
| pData || '''unsigned char*:''' Data buffer to write
|-
|-
| ''nSectorIndex'' || unsigned int || Sector index
| nDataLength || '''unsigned int:''' Buffer length
|}
{|
|-
|-
| ''nBlockIndex'' || unsigned int || Block index of the specified sector
|  
|}
 
{|class="wizarpostable"
|-
|-
| ''pData'' || unsigned char* || Data buffer to write
!  scope="row" colspan="2"| Returns
|-
|-
| ''nDataLength'' || unsigned int || Buffer length
| int || The result code, >= 0, success; <0 [[Error_code|error code]].
|}
|}


'''Returns'''


The result code, >= 0, success; <0 [[Error_code|error code]].
=== <big>write_value</big>===
=== write_value===
   <syntaxhighlight lang="c">int contactless_card_mc_write_value(int nHandle, unsigned int nSectorIndex, unsigned int nBlockIndex, unsigned char* pValue, unsigned int nValueLength, unsigned char pAddrData)</syntaxhighlight >
   int contactless_card_mc_write_value(int nHandle, unsigned int nSectorIndex, unsigned int nBlockIndex, unsigned char* pValue, unsigned int nValueLength, unsigned char pAddrData)
Write money value and user data to the specified block if the card is an electronic wallet format card.
Write money value and user data to the specified block if the card is an electronic wallet format card.
This api will format the MC card as an electronic wallet format card. If you want to use the following apis, you should firstly confirm that the card is an electronic wallet format card.
This API will format the MC card as an electronic wallet format card. If you want to use the following API, you should firstly confirm that the card is an electronic wallet format card.
 
{|class="wizarpostable"
'''Parameters'''
|-
{|
!  scope="row" colspan="2"| Parameters
|-
| nHandle || '''int:''' Handle of this device, returned from open
|-
|-
| ''nHandle'' || int || Handle of this device, returned from open
| nSectorIndex || '''unsigned int:''' Sector index
|-
|-
| ''nSectorIndex'' || unsigned int|| Sector index
| nBlockIndex || '''unsigned int:''' Block index of the specified sector
|-
|-
| ''nBlockIndex'' || unsigned int || Block index of the specified sector
| pValue || '''unsigned char*:''' money value to write
|-
|-
| ''pValue'' || unsigned char* || money value to write
| nValueBufLength || '''unsigned int:''' Buffer length
|-
|-
| ''nValueBufLength'' || unsigned int || Buffer length
| pAddrData || '''unsigned char:''' User data
|}
{|
|-
|-
| ''pAddrData'' || unsigned char || User data
|  
|}
|}


'''Returns'''
{|class="wizarpostable"
|-
!  scope="row" colspan="2"| Returns
|-
| int || The result code, >= 0, success; <0 [[Error_code|error code]].
|}


The result code, >= 0, success; <0 [[Error_code|error code]].
=== read_value ===
  int contactless_card_mc_read_value(int nHandle, unsigned int nSectorIndex, unsigned int nBlockIndex, unsigned char* pValue, unsigned int nValueBufLength, unsigned char* pAddrData)


'''Parameters'''
=== <big>read_value</big> ===
{|
  <syntaxhighlight lang="c">int contactless_card_mc_read_value(int nHandle, unsigned int nSectorIndex, unsigned int nBlockIndex, unsigned char* pValue, unsigned int nValueBufLength, unsigned char* pAddrData)</syntaxhighlight >
{|class="wizarpostable"
|-
!  scope="row" colspan="2"| Parameters
|-
| nHandle || '''int:''' Handle of this device, returned from open
|-
|-
| ''nHandle'' || int || Handle of this device, returned from open
| nSectorIndex || '''unsigned int:''' Sector index
|-
|-
| ''nSectorIndex'' || unsigned int || Sector index
| nBlockIndex || '''unsigned int:''' Block index of the specified sector
|-
|-
| ''nBlockIndex'' || unsigned int || Block index of the specified sector
| pValue || '''unsigned char*:''' buffer for saving value. LSB, 4 bytes
|-
|-
| ''pValue'' || unsigned char* || buffer for saving value. LSB, 4 bytes
| nValueBufLength || '''unsigned int:''' Buffer length
|-
|-
| ''nValueBufLength'' || unsigned int || Buffer length
| pAddrData || '''unsigned char*:''' buffer for saving a user data, 1 byte
|}
{|
|-
|-
| ''pAddrData'' || unsigned char* || buffer for saving a user data, 1 byte
|  
|}
|}


'''Returns'''
{|class="wizarpostable"
|-
!  scope="row" colspan="2"| Returns
|-
| int || The result code, >= 0, success; <0 [[Error_code|error code]].
|}


The result code, >= 0, success; <0 [[Error_code|error code]].
=== increment ===
  int contactless_card_mc_increment(int nHandle, unsigned int nSectorIndex, unsigned int nBlockIndex, unsigned char* pValue, unsigned int nValueLength)
Increase value to a block. This api should be used with restore and transfer.


'''Parameters'''
=== <big>increment</big> ===
{|
  <syntaxhighlight lang="c">int contactless_card_mc_increment(int nHandle, unsigned int nSectorIndex, unsigned int nBlockIndex, unsigned char* pValue, unsigned int nValueLength)</syntaxhighlight >
Increase value to a block. This API should be used with restore and transfer.
{|class="wizarpostable"
|-
!  scope="row" colspan="2"| Parameters
|-
| nHandle || '''int:''' Handle of this device, returned from open
|-
|-
| ''nHandle'' || int || Handle of this device, returned from open
| nSectorIndex || '''unsigned int:''' Sector index
|-
|-
| ''nSectorIndex'' || unsigned int || Sector index
| nBlockIndex || '''unsigned int:''' Block index of the specified sector
|-
|-
| ''nBlockIndex'' || unsigned int || Block index of the specified sector
| pValue || '''unsigned char*:''' money value to write
|-
|-
| ''pValue'' || unsigned char* || money value to write
| nValueBufLength || '''unsigned int:''' Buffer length, must be greater than 4
|}
{|
|-
|-
| ''nValueBufLength'' || unsigned int || Buffer length, must be greater than 4
|  
|}
|}


'''Returns'''
{|class="wizarpostable"
|-
!  scope="row" colspan="2"| Returns
|-
| int || The result code, >= 0, success; <0 [[Error_code|error code]].
|}


The result code, >= 0, success; <0 [[Error_code|error code]].
=== decrement===
  int contactless_card_mc_decrement(int nHandle, unsigned int nSectorIndex, unsigned int nBlockIndex, unsigned char* pValue, unsigned int nValueLength)
Decrease value to a block. This api should be used with restore and transfer.


'''Parameters'''
=== <big>decrement</big>===
{|
  <syntaxhighlight lang="c">int contactless_card_mc_decrement(int nHandle, unsigned int nSectorIndex, unsigned int nBlockIndex, unsigned char* pValue, unsigned int nValueLength)</syntaxhighlight >
Decrease value to a block. This API should be used with restore and transfer.
{|class="wizarpostable"
|-
!  scope="row" colspan="2"| Parameters
|-
| nHandle || '''int:''' Handle of this device, returned from open
|-
| nSectorIndex || '''unsigned int:''' Sector index
|-
| nBlockIndex || '''unsigned int:''' Block index of the specified sector
|-
|-
| ''nHandle'' || int || Handle of this device, returned from open
| pValue || '''unsigned char*:''' money value to write
|-
|-
| ''nSectorIndex'' || unsigned int || Sector index
| nValueBufLength || '''unsigned int:''' Buffer length, must be greater than 4
|}
{|
|-
|-
| ''nBlockIndex'' || unsigned int || Block index of the specified sector
|  
|}
 
{|class="wizarpostable"
|-
|-
| ''pValue'' || unsigned char* || money value to write
!  scope="row" colspan="2"| Returns
|-
|-
| ''nValueBufLength'' || unsigned int || Buffer length, must be greater than 4
| int || The result code, >= 0, success; <0 [[Error_code|error code]].
|}
|}


'''Returns'''


The result code, >= 0, success; <0 [[Error_code|error code]].
=== <big>restore</big> ===
=== restore ===
   <syntaxhighlight lang="c">int contactless_card_mc_restore(int nHandle,unsigned int nSectorIndex, unsigned int nBlockIndex)</syntaxhighlight >
   int contactless_card_mc_restore(int nHandle,unsigned int nSectorIndex, unsigned int nBlockIndex)
Read the money value to the temporary from a block. This is a necessary step if you want to increase or decrease the value of the electronic wallet card.
Read the money value to the temporary from a block. This is a necessary step if you want to increase or decrease the value of the electronic wallet card.
 
{|class="wizarpostable"
'''Parameters'''
|-
!  scope="row" colspan="2"| Parameters
|-
| nHandle ||'''int:'''  Handle of this device, returned from open
|-
| nSectorIndex ||'''unsigned int:''' Sector index
|-
| nBlockIndex ||'''unsigned int:''' Block index of the specified sector
|}
{|
{|
|-
|-
| ''nHandle'' || Handle of this device, returned from open
|  
|}
 
{|class="wizarpostable"
|-
|-
| ''nSectorIndex'' || Sector index
!  scope="row" colspan="2"| Returns
|-
|-
| ''nBlockIndex'' || Block index of the specified sector
| int || The result code, >= 0, success; <0 [[Error_code|error code]].
|}
|}


'''Returns'''


The result code, >= 0, success; <0 [[Error_code|error code]].
=== <big>transfer</big>===
=== transfer===
   <syntaxhighlight lang="c">int contactless_card_mc_restore(int nHandle,unsigned int nSectorIndex, unsigned int nBlockIndex)</syntaxhighlight >
   int contactless_card_mc_restore(int nHandle,unsigned int nSectorIndex, unsigned int nBlockIndex)
This api should be used after increment or decrement.
This api should be used after increment or decrement.
 
{|class="wizarpostable"
'''Parameters'''
|-
!  scope="row" colspan="2"| Parameters
|-
| nHandle || '''int:''' Handle of this device, returned from open
|-
| nSectorIndex || '''unsigned int:''' Sector index
|-
| nBlockIndex || '''unsigned int:''' Block index of the specified sector
|}
{|
{|
|-
|-
| ''nHandle'' || int || Handle of this device, returned from open
|  
|}
 
{|class="wizarpostable"
|-
|-
| ''nSectorIndex'' || unsigned int || Sector index
!  scope="row" colspan="2"| Returns
|-
|-
| ''nBlockIndex'' || unsigned int || Block index of the specified sector
| int || The result code, >= 0, success; <0 [[Error_code|error code]].
|}
|}
'''Returns'''
The result code, >= 0, success; <0 [[Error_code|error code]].

Latest revision as of 09:59, 23 August 2019

API Overview

open

void* contactless_card_open(CONTACTLESS_CARD_NOTIFIER fNotifier, void* pUserData, int* pErrorCode)

Initialize the contactless card reader.

Parameters
fNotifier CONTACTLESS_CARD_NOTIFIER: Notifier of contactless card
pUserData void*: User data
pErrorCode int*: error code if return value is equals to 0
Returns
int The result code, != 0, success, value is the handle of contactless card device; =0 failed.

search_target_begin

int contactless_card_search_target_begin(int nHandle, int nCardMode, int nFlagSearchAll, int nTimeout_MS)

Start searching the contactless card. If you set the nCardMode is auto, reader will try to activate card in type A, type B and type successively; If you set the nCardMode is type A, type B, or type C, reader only try to activate card in the specified way. You can terminate it using function search_target_end.

Parameters
nHandle int: Handle of this device, returned from open
nCardMode int: Mode to search
nFlagSearchAll int: Not used
nTimeout_MS int: Time out in millseconds. If it is less than 0, then wait forever.

Possible value of nCardMode :

#define CONTACTLESS_CARD_MODE_AUTO	0
#define CONTACTLESS_CARD_MODE_TYPE_A	1
#define CONTACTLESS_CARD_MODE_TYPE_B	2
#define CONTACTLESS_CARD_MODE_TYPE_C	3
Returns
int The result code, >= 0, success; <0 error code.


search_target_end

int contactless_card_search_target_end(int nHandle)

Stop the process of searching card. The search_target_begin and search_target_end API are pair operations.

Parameters
nHandle int: Handle of this device, returned from open
Returns
int The result code, >= 0, success; <0 error code.


close

int contactless_card_close(int nHandle)

Close the contactless card reader. open and close are pair operations. If you don’t want to use the device, you should call close to release the device.

Parameters
nHandle int: Handle of this device, returned from open
Returns
int The result code, >= 0, success; <0 error code.


query_info

int contactless_card_query_info(int nHandle, unsigned int* pHasMoreCards, unsigned int* pCardType)

Query the quantity and type of cards on the contactless card reader.

Parameters
nHandle int: Handle of this device, returned from open
pHasMoreCards int*: Card quantity
pCardType int*: Card type

pHasMoreCards:

  • 0 : only one PICC in the field
  • 0x0A : more cards in the field(type A)
  • 0x0B : more cards in the field(type B)
  • 0xAB : more cards in the field(type A and type B)

pCardType:

  • CONTACTLESS_CARD_TYPE_A_CPU 0x0000
  • CONTACTLESS_CARD_TYPE_B_CPU 0x0100
  • CONTACTLESS_CARD_TYPE_A_CLASSIC_MINI 0x0001
  • CONTACTLESS_CARD_TYPE_A_CLASSIC_1K 0x0002
  • CONTACTLESS_CARD_TYPE_A_CLASSIC_4K 0x0003
  • CONTACTLESS_CARD_TYPE_A_UL_64 0x0004
  • CONTACTLESS_CARD_TYPE_A_UL_192 0x0005
  • CONTACTLESS_CARD_TYPE_A_MP_2K_SL1 0x0006
  • CONTACTLESS_CARD_TYPE_A_MP_4K_SL1 0x0007
  • CONTACTLESS_CARD_TYPE_A_MP_2K_SL2 0x0008
  • CONTACTLESS_CARD_TYPE_A_MP_4K_SL2 0x0009
  • CONTACTLESS_CARD_UNKNOWN 0x00FF
Returns
int The result code, >= 0, success; <0 error code.


attach_target

int contactless_card_attach_target(int nHandle, unsigned char* pATRBuffer, unsigned int nATRBufferLength)

Attach the target before transmitting APDU command. In this process, the target(card) is activated and return ATR. If the card is a CPU card, the attach_target, detach_target and transmit API are used to get information from the card.

Parameters
nHandle int: Handle of this device, returned from open
pATRBuffer unsigned char*: ATR buffer, if null, you can not get data.
nATRBufferLength int: Length of ATR buffer
Returns
int The result code, >= 0, success,length of ATR; <0 error code..


detach_target

int contactless_card_detach_target(int nHandle)

Detach the target. If you want to send APDU again, you should attach it. The detach is a block method, only when you remove the card can you get the return value of this API.

Parameters
nHandle int: Handle of this device, returned from open
Returns
int The result code, >= 0, success; <0 error code.


transmit

int contactless_card_transmit(int nHandle, unsigned char* pAPDU, unsigned int nAPDULength, unsigned char* pResponse, unsigned int *pResponseLength)

Transmit APDU command and get the response. The APDU command of contactless card is the same as the IC card normally.

Parameters
nHandle int: Handle of this device, returned from open
pAPDU unsigned char*: Command of APDU
nAPDULength unsigned int: Length of command
pResponse unsigned char*: Response buffer of APDU command
pResponseLength unsigned int: buffer length of response
Returns
int The result code, >= 0, success; <0 error code.

transmit_level3

int contactless_card_transmit_level3(int nHandle, unsigned char* pAPDU, unsigned int nAPDULength, unsigned char* pResponse, unsigned int *pResponseLength, int nOperationValue)

Transmit APDU command and get the response. This is only for ultralight C card. The APDU command of contactless card is the same as the IC card normally.

Parameters
nHandle int: Handle of this device, returned from open
pAPDU unsigned char*: Command of APDU
nAPDULength unsigned int: Length of command
pResponse unsigned char*: Response buffer of APDU command
pResponseLength unsigned int: buffer length of response
nOperationValue int: reserved for future, must be set to zero
Returns
int The result code, >= 0, success; <0 error code.

verify

int contactless_card_mc_verify_pin(int nHandle, unsigned int nSectorIndex, unsigned int nPinType, unsigned char* strPin, unsigned int nPinLength)

Verify the key of the contactless card. You should firstly know the key and corresponding key type(key A or key B). If the card is a Mifare card, the verify, read and write API are used to get information from the card.

Parameters
nHandle int: Handle of this device, returned from open
nSectorIndex unsigned int: Sector index
nPinType unsigned int: Key type:0—Key A; 1—Key B; 2-TDEA type (for ultralight C)
strPin unsigned char*: Password of this sector
nPinLength unsigned int: Length of password
Returns
int The result code, >= 0, success; <0 error code.

read

int contactless_card_mc_read(int nHandle, unsigned int nSectorIndex, unsigned int nBlockIndex, unsigned char* pDataBuffer, unsigned int nDataBufferLength)

Read data from the contactless card. You should verify the key at first. You should firstly know the card format(how many sectors, blocks and block size) from the card producer.

Parameters
nHandle int: Handle of this device, returned from open
nSectorIndex unsigned int: Sector index
nBlockIndex unsigned int: Block index of the specified sector
pDataBuffer unsigned char*: Data buffer to read
nDataBufferLength unsigned int: Buffer length
Returns
int The result code, >= 0, success; <0 error code.


write

int contactless_card_mc_write(int nHandle, unsigned int nSectorIndex, unsigned int nBlockIndex, unsigned char* pData, unsigned int nDataLength)

Write data to the contactless card. You should verify the key at first.

Parameters
nHandle int: Handle of this device, returned from open
nSectorIndex unsigned int: Sector index
nBlockIndex unsigned int: Block index of the specified sector
pData unsigned char*: Data buffer to write
nDataLength unsigned int: Buffer length
Returns
int The result code, >= 0, success; <0 error code.


write_value

int contactless_card_mc_write_value(int nHandle, unsigned int nSectorIndex, unsigned int nBlockIndex, unsigned char* pValue, unsigned int nValueLength, unsigned char pAddrData)

Write money value and user data to the specified block if the card is an electronic wallet format card. This API will format the MC card as an electronic wallet format card. If you want to use the following API, you should firstly confirm that the card is an electronic wallet format card.

Parameters
nHandle int: Handle of this device, returned from open
nSectorIndex unsigned int: Sector index
nBlockIndex unsigned int: Block index of the specified sector
pValue unsigned char*: money value to write
nValueBufLength unsigned int: Buffer length
pAddrData unsigned char: User data
Returns
int The result code, >= 0, success; <0 error code.


read_value

int contactless_card_mc_read_value(int nHandle, unsigned int nSectorIndex, unsigned int nBlockIndex, unsigned char* pValue, unsigned int nValueBufLength, unsigned char* pAddrData)
Parameters
nHandle int: Handle of this device, returned from open
nSectorIndex unsigned int: Sector index
nBlockIndex unsigned int: Block index of the specified sector
pValue unsigned char*: buffer for saving value. LSB, 4 bytes
nValueBufLength unsigned int: Buffer length
pAddrData unsigned char*: buffer for saving a user data, 1 byte
Returns
int The result code, >= 0, success; <0 error code.


increment

int contactless_card_mc_increment(int nHandle, unsigned int nSectorIndex, unsigned int nBlockIndex, unsigned char* pValue, unsigned int nValueLength)

Increase value to a block. This API should be used with restore and transfer.

Parameters
nHandle int: Handle of this device, returned from open
nSectorIndex unsigned int: Sector index
nBlockIndex unsigned int: Block index of the specified sector
pValue unsigned char*: money value to write
nValueBufLength unsigned int: Buffer length, must be greater than 4
Returns
int The result code, >= 0, success; <0 error code.


decrement

int contactless_card_mc_decrement(int nHandle, unsigned int nSectorIndex, unsigned int nBlockIndex, unsigned char* pValue, unsigned int nValueLength)

Decrease value to a block. This API should be used with restore and transfer.

Parameters
nHandle int: Handle of this device, returned from open
nSectorIndex unsigned int: Sector index
nBlockIndex unsigned int: Block index of the specified sector
pValue unsigned char*: money value to write
nValueBufLength unsigned int: Buffer length, must be greater than 4
Returns
int The result code, >= 0, success; <0 error code.


restore

int contactless_card_mc_restore(int nHandle,unsigned int nSectorIndex, unsigned int nBlockIndex)

Read the money value to the temporary from a block. This is a necessary step if you want to increase or decrease the value of the electronic wallet card.

Parameters
nHandle int: Handle of this device, returned from open
nSectorIndex unsigned int: Sector index
nBlockIndex unsigned int: Block index of the specified sector
Returns
int The result code, >= 0, success; <0 error code.


transfer

int contactless_card_mc_restore(int nHandle,unsigned int nSectorIndex, unsigned int nBlockIndex)

This api should be used after increment or decrement.

Parameters
nHandle int: Handle of this device, returned from open
nSectorIndex unsigned int: Sector index
nBlockIndex unsigned int: Block index of the specified sector
Returns
int The result code, >= 0, success; <0 error code.