Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save sj-i/02dc296e3e1f8dfae3285d21fdbc3699 to your computer and use it in GitHub Desktop.
Save sj-i/02dc296e3e1f8dfae3285d21fdbc3699 to your computer and use it in GitHub Desktop.
Example for using libnfc with written in PHP
<?php
/**
* Merged
* - https://github.com/nfc-tools/libnfc/blob/master/libnfc/nfc-internal.h
* - https://github.com/nfc-tools/libnfc/blob/2b5ad9ce0be19fbca5abc04b4ee0b59fb612e590/include/nfc/nfc-types.h
*
* @license https://github.com/nfc-tools/libnfc/blob/master/COPYING
*/
$ffi = FFI::cdef(<<<_
/**
* Connection string
*/
typedef char nfc_connstring[1024];
typedef enum {
NOT_INTRUSIVE,
INTRUSIVE,
NOT_AVAILABLE,
} scan_type_enum;
struct nfc_user_defined_device {
char name[256];
nfc_connstring connstring;
bool optional;
};
/**
* @struct nfc_context
* @brief NFC library context
* Struct which contains internal options, references, pointers, etc. used by library
*/
struct nfc_context {
bool allow_autoscan;
bool allow_intrusive_scan;
uint32_t log_level;
struct nfc_user_defined_device user_defined_devices[4];
unsigned int user_defined_device_count;
};
/**
* NFC context
*/
typedef struct nfc_context nfc_context;
/**
* @struct nfc_device
* @brief NFC device information
*/
struct nfc_device {
const nfc_context *context;
const struct nfc_driver *driver;
void *driver_data;
void *chip_data;
/** Device name string, including device wrapper firmware */
char name[256];
/** Device connection string */
nfc_connstring connstring;
/** Is the CRC automaticly added, checked and removed from the frames */
bool bCrc;
/** Does the chip handle parity bits, all parities are handled as data */
bool bPar;
/** Should the chip handle frames encapsulation and chaining */
bool bEasyFraming;
/** Should the chip try forever on select? */
bool bInfiniteSelect;
/** Should the chip switch automatically activate ISO14443-4 when
selecting tags supporting it? */
bool bAutoIso14443_4;
/** Supported modulation encoded in a byte */
uint8_t btSupportByte;
/** Last reported error */
int last_error;
};
/**
* NFC device
*/
typedef struct nfc_device nfc_device;
/**
* Properties
*/
typedef enum {
/**
* Default command processing timeout
* Property value's (duration) unit is ms and 0 means no timeout (infinite).
* Default value is set by driver layer
*/
NP_TIMEOUT_COMMAND,
/**
* Timeout between ATR_REQ and ATR_RES
* When the device is in initiator mode, a target is considered as mute if no
* valid ATR_RES is received within this timeout value.
* Default value for this property is 103 ms on PN53x based devices.
*/
NP_TIMEOUT_ATR,
/**
* Timeout value to give up reception from the target in case of no answer.
* Default value for this property is 52 ms).
*/
NP_TIMEOUT_COM,
/** Let the PN53X chip handle the CRC bytes. This means that the chip appends
* the CRC bytes to the frames that are transmitted. It will parse the last
* bytes from received frames as incoming CRC bytes. They will be verified
* against the used modulation and protocol. If an frame is expected with
* incorrect CRC bytes this option should be disabled. Example frames where
* this is useful are the ATQA and UID+BCC that are transmitted without CRC
* bytes during the anti-collision phase of the ISO14443-A protocol. */
NP_HANDLE_CRC,
/** Parity bits in the network layer of ISO14443-A are by default generated and
* validated in the PN53X chip. This is a very convenient feature. On certain
* times though it is useful to get full control of the transmitted data. The
* proprietary MIFARE Classic protocol uses for example custom (encrypted)
* parity bits. For interoperability it is required to be completely
* compatible, including the arbitrary parity bits. When this option is
* disabled, the functions to communicating bits should be used. */
NP_HANDLE_PARITY,
/** This option can be used to enable or disable the electronic field of the
* NFC device. */
NP_ACTIVATE_FIELD,
/** The internal CRYPTO1 co-processor can be used to transmit messages
* encrypted. This option is automatically activated after a successful MIFARE
* Classic authentication. */
NP_ACTIVATE_CRYPTO1,
/** The default configuration defines that the PN53X chip will try indefinitely
* to invite a tag in the field to respond. This could be desired when it is
* certain a tag will enter the field. On the other hand, when this is
* uncertain, it will block the application. This option could best be compared
* to the (NON)BLOCKING option used by (socket)network programming. */
NP_INFINITE_SELECT,
/** If this option is enabled, frames that carry less than 4 bits are allowed.
* According to the standards these frames should normally be handles as
* invalid frames. */
NP_ACCEPT_INVALID_FRAMES,
/** If the NFC device should only listen to frames, it could be useful to let
* it gather multiple frames in a sequence. They will be stored in the internal
* FIFO of the PN53X chip. This could be retrieved by using the receive data
* functions. Note that if the chip runs out of bytes (FIFO = 64 bytes long),
* it will overwrite the first received frames, so quick retrieving of the
* received data is desirable. */
NP_ACCEPT_MULTIPLE_FRAMES,
/** This option can be used to enable or disable the auto-switching mode to
* ISO14443-4 is device is compliant.
* In initiator mode, it means that NFC chip will send RATS automatically when
* select and it will automatically poll for ISO14443-4 card when ISO14443A is
* requested.
* In target mode, with a NFC chip compliant (ie. PN532), the chip will
* emulate a 14443-4 PICC using hardware capability */
NP_AUTO_ISO14443_4,
/** Use automatic frames encapsulation and chaining. */
NP_EASY_FRAMING,
/** Force the chip to switch in ISO14443-A */
NP_FORCE_ISO14443_A,
/** Force the chip to switch in ISO14443-B */
NP_FORCE_ISO14443_B,
/** Force the chip to run at 106 kbps */
NP_FORCE_SPEED_106,
} nfc_property;
// Compiler directive, set struct alignment to 1 uint8_t for compatibility
# pragma pack(1)
/**
* @enum nfc_dep_mode
* @brief NFC D.E.P. (Data Exchange Protocol) active/passive mode
*/
typedef enum {
NDM_UNDEFINED = 0,
NDM_PASSIVE,
NDM_ACTIVE,
} nfc_dep_mode;
/**
* @struct nfc_dep_info
* @brief NFC target information in D.E.P. (Data Exchange Protocol) see ISO/IEC 18092 (NFCIP-1)
*/
typedef struct {
/** NFCID3 */
uint8_t abtNFCID3[10];
/** DID */
uint8_t btDID;
/** Supported send-bit rate */
uint8_t btBS;
/** Supported receive-bit rate */
uint8_t btBR;
/** Timeout value */
uint8_t btTO;
/** PP Parameters */
uint8_t btPP;
/** General Bytes */
uint8_t abtGB[48];
size_t szGB;
/** DEP mode */
nfc_dep_mode ndm;
} nfc_dep_info;
/**
* @struct nfc_iso14443a_info
* @brief NFC ISO14443A tag (MIFARE) information
*/
typedef struct {
uint8_t abtAtqa[2];
uint8_t btSak;
size_t szUidLen;
uint8_t abtUid[10];
size_t szAtsLen;
uint8_t abtAts[254]; // Maximal theoretical ATS is FSD-2, FSD=256 for FSDI=8 in RATS
} nfc_iso14443a_info;
/**
* @struct nfc_felica_info
* @brief NFC FeLiCa tag information
*/
typedef struct {
size_t szLen;
uint8_t btResCode;
uint8_t abtId[8];
uint8_t abtPad[8];
uint8_t abtSysCode[2];
} nfc_felica_info;
/**
* @struct nfc_iso14443b_info
* @brief NFC ISO14443B tag information
*/
typedef struct {
/** abtPupi store PUPI contained in ATQB (Answer To reQuest of type B) (see ISO14443-3) */
uint8_t abtPupi[4];
/** abtApplicationData store Application Data contained in ATQB (see ISO14443-3) */
uint8_t abtApplicationData[4];
/** abtProtocolInfo store Protocol Info contained in ATQB (see ISO14443-3) */
uint8_t abtProtocolInfo[3];
/** ui8CardIdentifier store CID (Card Identifier) attributted by PCD to the PICC */
uint8_t ui8CardIdentifier;
} nfc_iso14443b_info;
/**
* @struct nfc_iso14443bi_info
* @brief NFC ISO14443B' tag information
*/
typedef struct {
/** DIV: 4 LSBytes of tag serial number */
uint8_t abtDIV[4];
/** Software version & type of REPGEN */
uint8_t btVerLog;
/** Config Byte, present if long REPGEN */
uint8_t btConfig;
/** ATR, if any */
size_t szAtrLen;
uint8_t abtAtr[33];
} nfc_iso14443bi_info;
/**
* @struct nfc_iso14443biclass_info
* @brief NFC ISO14443BiClass tag information
*/
typedef struct {
uint8_t abtUID[8];
} nfc_iso14443biclass_info;
/**
* @struct nfc_iso14443b2sr_info
* @brief NFC ISO14443-2B ST SRx tag information
*/
typedef struct {
uint8_t abtUID[8];
} nfc_iso14443b2sr_info;
/**
* @struct nfc_iso14443b2ct_info
* @brief NFC ISO14443-2B ASK CTx tag information
*/
typedef struct {
uint8_t abtUID[4];
uint8_t btProdCode;
uint8_t btFabCode;
} nfc_iso14443b2ct_info;
/**
* @struct nfc_jewel_info
* @brief NFC Jewel tag information
*/
typedef struct {
uint8_t btSensRes[2];
uint8_t btId[4];
} nfc_jewel_info;
/**
* @struct nfc_barcode_info
* @brief Thinfilm NFC Barcode information
*/
typedef struct {
size_t szDataLen;
uint8_t abtData[32];
} nfc_barcode_info;
/**
* @union nfc_target_info
* @brief Union between all kind of tags information structures.
*/
typedef union {
nfc_iso14443a_info nai;
nfc_felica_info nfi;
nfc_iso14443b_info nbi;
nfc_iso14443bi_info nii;
nfc_iso14443b2sr_info nsi;
nfc_iso14443b2ct_info nci;
nfc_jewel_info nji;
nfc_dep_info ndi;
nfc_barcode_info nti; // "t" for Thinfilm, "b" already used
nfc_iso14443biclass_info nhi; // hid iclass / picopass - nii already used
} nfc_target_info;
/**
* @enum nfc_baud_rate
* @brief NFC baud rate enumeration
*/
typedef enum {
NBR_UNDEFINED = 0,
NBR_106,
NBR_212,
NBR_424,
NBR_847,
} nfc_baud_rate;
/**
* @enum nfc_modulation_type
* @brief NFC modulation type enumeration
*/
typedef enum {
NMT_ISO14443A = 1,
NMT_JEWEL,
NMT_ISO14443B,
NMT_ISO14443BI, // pre-ISO14443B aka ISO/IEC 14443 B' or Type B'
NMT_ISO14443B2SR, // ISO14443-2B ST SRx
NMT_ISO14443B2CT, // ISO14443-2B ASK CTx
NMT_FELICA,
NMT_DEP,
NMT_BARCODE, // Thinfilm NFC Barcode
NMT_ISO14443BICLASS, // HID iClass 14443B mode
NMT_END_ENUM = NMT_ISO14443BICLASS, // dummy for sizing - always should alias last
} nfc_modulation_type;
/**
* @enum nfc_mode
* @brief NFC mode type enumeration
*/
typedef enum {
N_TARGET,
N_INITIATOR,
} nfc_mode;
/**
* @struct nfc_modulation
* @brief NFC modulation structure
*/
typedef struct {
nfc_modulation_type nmt;
nfc_baud_rate nbr;
} nfc_modulation;
/**
* @struct nfc_target
* @brief NFC target structure
*/
typedef struct {
nfc_target_info nti;
nfc_modulation nm;
} nfc_target;
_);
$ffi->new('char');
$context = $ffi->new('nfc_context *');
$nt = $ffi->new('nfc_target');
echo $ffi::sizeof($nt);
var_dump($nt);
$nmmMifare = $ffi->new('nfc_modulation[6]');
@sj-i
Copy link
Author

sj-i commented Oct 13, 2021

304object(FFI\CData:struct <anonymous>)#3 (2) {
  ["nti"]=>
  object(FFI\CData:union <anonymous>)#4 (10) {
    ["nai"]=>
    object(FFI\CData:struct <anonymous>)#6 (6) {
      ["abtAtqa"]=>
      object(FFI\CData:uint8_t[2])#16 (2) {
        [0]=>
        int(0)
        [1]=>
        int(0)
      }
      ["btSak"]=>
      int(0)
      ["szUidLen"]=>
      int(0)
      ["abtUid"]=>
      object(FFI\CData:uint8_t[10])#17 (10) {
        [0]=>
        int(0)
        [1]=>
        int(0)
        [2]=>
        int(0)
        [3]=>
        int(0)
        [4]=>
        int(0)
        [5]=>
        int(0)
        [6]=>
        int(0)
        [7]=>
        int(0)
        [8]=>
        int(0)
        [9]=>
        int(0)
      }
      ["szAtsLen"]=>
      int(0)
      ["abtAts"]=>
      object(FFI\CData:uint8_t[254])#18 (254) {
        [0]=>
        int(0)
        [1]=>
        int(0)
        [2]=>
        int(0)
        [3]=>
        int(0)
        [4]=>
        int(0)
        [5]=>
        int(0)
        [6]=>
        int(0)
        [7]=>
        int(0)
        [8]=>
        int(0)
        [9]=>
        int(0)
        [10]=>
        int(0)
        [11]=>
        int(0)
        [12]=>
        int(0)
        [13]=>
        int(0)
        [14]=>
        int(0)
        [15]=>
        int(0)
        [16]=>
        int(0)
        [17]=>
        int(0)
        [18]=>
        int(0)
        [19]=>
        int(0)
        [20]=>
        int(0)
        [21]=>
        int(0)
        [22]=>
        int(0)
        [23]=>
        int(0)
        [24]=>
        int(0)
        [25]=>
        int(0)
        [26]=>
        int(0)
        [27]=>
        int(0)
        [28]=>
        int(0)
        [29]=>
        int(0)
        [30]=>
        int(0)
        [31]=>
        int(0)
        [32]=>
        int(0)
        [33]=>
        int(0)
        [34]=>
        int(0)
        [35]=>
        int(0)
        [36]=>
        int(0)
        [37]=>
        int(0)
        [38]=>
        int(0)
        [39]=>
        int(0)
        [40]=>
        int(0)
        [41]=>
        int(0)
        [42]=>
        int(0)
        [43]=>
        int(0)
        [44]=>
        int(0)
        [45]=>
        int(0)
        [46]=>
        int(0)
        [47]=>
        int(0)
        [48]=>
        int(0)
        [49]=>
        int(0)
        [50]=>
        int(0)
        [51]=>
        int(0)
        [52]=>
        int(0)
        [53]=>
        int(0)
        [54]=>
        int(0)
        [55]=>
        int(0)
        [56]=>
        int(0)
        [57]=>
        int(0)
        [58]=>
        int(0)
        [59]=>
        int(0)
        [60]=>
        int(0)
        [61]=>
        int(0)
        [62]=>
        int(0)
        [63]=>
        int(0)
        [64]=>
        int(0)
        [65]=>
        int(0)
        [66]=>
        int(0)
        [67]=>
        int(0)
        [68]=>
        int(0)
        [69]=>
        int(0)
        [70]=>
        int(0)
        [71]=>
        int(0)
        [72]=>
        int(0)
        [73]=>
        int(0)
        [74]=>
        int(0)
        [75]=>
        int(0)
        [76]=>
        int(0)
        [77]=>
        int(0)
        [78]=>
        int(0)
        [79]=>
        int(0)
        [80]=>
        int(0)
        [81]=>
        int(0)
        [82]=>
        int(0)
        [83]=>
        int(0)
        [84]=>
        int(0)
        [85]=>
        int(0)
        [86]=>
        int(0)
        [87]=>
        int(0)
        [88]=>
        int(0)
        [89]=>
        int(0)
        [90]=>
        int(0)
        [91]=>
        int(0)
        [92]=>
        int(0)
        [93]=>
        int(0)
        [94]=>
        int(0)
        [95]=>
        int(0)
        [96]=>
        int(0)
        [97]=>
        int(0)
        [98]=>
        int(0)
        [99]=>
        int(0)
        [100]=>
        int(0)
        [101]=>
        int(0)
        [102]=>
        int(0)
        [103]=>
        int(0)
        [104]=>
        int(0)
        [105]=>
        int(0)
        [106]=>
        int(0)
        [107]=>
        int(0)
        [108]=>
        int(0)
        [109]=>
        int(0)
        [110]=>
        int(0)
        [111]=>
        int(0)
        [112]=>
        int(0)
        [113]=>
        int(0)
        [114]=>
        int(0)
        [115]=>
        int(0)
        [116]=>
        int(0)
        [117]=>
        int(0)
        [118]=>
        int(0)
        [119]=>
        int(0)
        [120]=>
        int(0)
        [121]=>
        int(0)
        [122]=>
        int(0)
        [123]=>
        int(0)
        [124]=>
        int(0)
        [125]=>
        int(0)
        [126]=>
        int(0)
        [127]=>
        int(0)
        [128]=>
        int(0)
        [129]=>
        int(0)
        [130]=>
        int(0)
        [131]=>
        int(0)
        [132]=>
        int(0)
        [133]=>
        int(0)
        [134]=>
        int(0)
        [135]=>
        int(0)
        [136]=>
        int(0)
        [137]=>
        int(0)
        [138]=>
        int(0)
        [139]=>
        int(0)
        [140]=>
        int(0)
        [141]=>
        int(0)
        [142]=>
        int(0)
        [143]=>
        int(0)
        [144]=>
        int(0)
        [145]=>
        int(0)
        [146]=>
        int(0)
        [147]=>
        int(0)
        [148]=>
        int(0)
        [149]=>
        int(0)
        [150]=>
        int(0)
        [151]=>
        int(0)
        [152]=>
        int(0)
        [153]=>
        int(0)
        [154]=>
        int(0)
        [155]=>
        int(0)
        [156]=>
        int(0)
        [157]=>
        int(0)
        [158]=>
        int(0)
        [159]=>
        int(0)
        [160]=>
        int(0)
        [161]=>
        int(0)
        [162]=>
        int(0)
        [163]=>
        int(0)
        [164]=>
        int(0)
        [165]=>
        int(0)
        [166]=>
        int(0)
        [167]=>
        int(0)
        [168]=>
        int(0)
        [169]=>
        int(0)
        [170]=>
        int(0)
        [171]=>
        int(0)
        [172]=>
        int(0)
        [173]=>
        int(0)
        [174]=>
        int(0)
        [175]=>
        int(0)
        [176]=>
        int(0)
        [177]=>
        int(0)
        [178]=>
        int(0)
        [179]=>
        int(0)
        [180]=>
        int(0)
        [181]=>
        int(0)
        [182]=>
        int(0)
        [183]=>
        int(0)
        [184]=>
        int(0)
        [185]=>
        int(0)
        [186]=>
        int(0)
        [187]=>
        int(0)
        [188]=>
        int(0)
        [189]=>
        int(0)
        [190]=>
        int(0)
        [191]=>
        int(0)
        [192]=>
        int(0)
        [193]=>
        int(0)
        [194]=>
        int(0)
        [195]=>
        int(0)
        [196]=>
        int(0)
        [197]=>
        int(0)
        [198]=>
        int(0)
        [199]=>
        int(0)
        [200]=>
        int(0)
        [201]=>
        int(0)
        [202]=>
        int(0)
        [203]=>
        int(0)
        [204]=>
        int(0)
        [205]=>
        int(0)
        [206]=>
        int(0)
        [207]=>
        int(0)
        [208]=>
        int(0)
        [209]=>
        int(0)
        [210]=>
        int(0)
        [211]=>
        int(0)
        [212]=>
        int(0)
        [213]=>
        int(0)
        [214]=>
        int(0)
        [215]=>
        int(0)
        [216]=>
        int(0)
        [217]=>
        int(0)
        [218]=>
        int(0)
        [219]=>
        int(0)
        [220]=>
        int(0)
        [221]=>
        int(0)
        [222]=>
        int(0)
        [223]=>
        int(0)
        [224]=>
        int(0)
        [225]=>
        int(0)
        [226]=>
        int(0)
        [227]=>
        int(0)
        [228]=>
        int(0)
        [229]=>
        int(0)
        [230]=>
        int(0)
        [231]=>
        int(0)
        [232]=>
        int(0)
        [233]=>
        int(0)
        [234]=>
        int(0)
        [235]=>
        int(0)
        [236]=>
        int(0)
        [237]=>
        int(0)
        [238]=>
        int(0)
        [239]=>
        int(0)
        [240]=>
        int(0)
        [241]=>
        int(0)
        [242]=>
        int(0)
        [243]=>
        int(0)
        [244]=>
        int(0)
        [245]=>
        int(0)
        [246]=>
        int(0)
        [247]=>
        int(0)
        [248]=>
        int(0)
        [249]=>
        int(0)
        [250]=>
        int(0)
        [251]=>
        int(0)
        [252]=>
        int(0)
        [253]=>
        int(0)
      }
    }
    ["nfi"]=>
    object(FFI\CData:struct <anonymous>)#7 (5) {
      ["szLen"]=>
      int(0)
      ["btResCode"]=>
      int(0)
      ["abtId"]=>
      object(FFI\CData:uint8_t[8])#18 (8) {
        [0]=>
        int(0)
        [1]=>
        int(0)
        [2]=>
        int(0)
        [3]=>
        int(0)
        [4]=>
        int(0)
        [5]=>
        int(0)
        [6]=>
        int(0)
        [7]=>
        int(0)
      }
      ["abtPad"]=>
      object(FFI\CData:uint8_t[8])#17 (8) {
        [0]=>
        int(0)
        [1]=>
        int(0)
        [2]=>
        int(0)
        [3]=>
        int(0)
        [4]=>
        int(0)
        [5]=>
        int(0)
        [6]=>
        int(0)
        [7]=>
        int(0)
      }
      ["abtSysCode"]=>
      object(FFI\CData:uint8_t[2])#16 (2) {
        [0]=>
        int(0)
        [1]=>
        int(0)
      }
    }
    ["nbi"]=>
    object(FFI\CData:struct <anonymous>)#8 (4) {
      ["abtPupi"]=>
      object(FFI\CData:uint8_t[4])#16 (4) {
        [0]=>
        int(0)
        [1]=>
        int(0)
        [2]=>
        int(0)
        [3]=>
        int(0)
      }
      ["abtApplicationData"]=>
      object(FFI\CData:uint8_t[4])#17 (4) {
        [0]=>
        int(0)
        [1]=>
        int(0)
        [2]=>
        int(0)
        [3]=>
        int(0)
      }
      ["abtProtocolInfo"]=>
      object(FFI\CData:uint8_t[3])#18 (3) {
        [0]=>
        int(0)
        [1]=>
        int(0)
        [2]=>
        int(0)
      }
      ["ui8CardIdentifier"]=>
      int(0)
    }
    ["nii"]=>
    object(FFI\CData:struct <anonymous>)#9 (5) {
      ["abtDIV"]=>
      object(FFI\CData:uint8_t[4])#18 (4) {
        [0]=>
        int(0)
        [1]=>
        int(0)
        [2]=>
        int(0)
        [3]=>
        int(0)
      }
      ["btVerLog"]=>
      int(0)
      ["btConfig"]=>
      int(0)
      ["szAtrLen"]=>
      int(0)
      ["abtAtr"]=>
      object(FFI\CData:uint8_t[33])#17 (33) {
        [0]=>
        int(0)
        [1]=>
        int(0)
        [2]=>
        int(0)
        [3]=>
        int(0)
        [4]=>
        int(0)
        [5]=>
        int(0)
        [6]=>
        int(0)
        [7]=>
        int(0)
        [8]=>
        int(0)
        [9]=>
        int(0)
        [10]=>
        int(0)
        [11]=>
        int(0)
        [12]=>
        int(0)
        [13]=>
        int(0)
        [14]=>
        int(0)
        [15]=>
        int(0)
        [16]=>
        int(0)
        [17]=>
        int(0)
        [18]=>
        int(0)
        [19]=>
        int(0)
        [20]=>
        int(0)
        [21]=>
        int(0)
        [22]=>
        int(0)
        [23]=>
        int(0)
        [24]=>
        int(0)
        [25]=>
        int(0)
        [26]=>
        int(0)
        [27]=>
        int(0)
        [28]=>
        int(0)
        [29]=>
        int(0)
        [30]=>
        int(0)
        [31]=>
        int(0)
        [32]=>
        int(0)
      }
    }
    ["nsi"]=>
    object(FFI\CData:struct <anonymous>)#10 (1) {
      ["abtUID"]=>
      object(FFI\CData:uint8_t[8])#17 (8) {
        [0]=>
        int(0)
        [1]=>
        int(0)
        [2]=>
        int(0)
        [3]=>
        int(0)
        [4]=>
        int(0)
        [5]=>
        int(0)
        [6]=>
        int(0)
        [7]=>
        int(0)
      }
    }
    ["nci"]=>
    object(FFI\CData:struct <anonymous>)#11 (3) {
      ["abtUID"]=>
      object(FFI\CData:uint8_t[4])#17 (4) {
        [0]=>
        int(0)
        [1]=>
        int(0)
        [2]=>
        int(0)
        [3]=>
        int(0)
      }
      ["btProdCode"]=>
      int(0)
      ["btFabCode"]=>
      int(0)
    }
    ["nji"]=>
    object(FFI\CData:struct <anonymous>)#12 (2) {
      ["btSensRes"]=>
      object(FFI\CData:uint8_t[2])#17 (2) {
        [0]=>
        int(0)
        [1]=>
        int(0)
      }
      ["btId"]=>
      object(FFI\CData:uint8_t[4])#18 (4) {
        [0]=>
        int(0)
        [1]=>
        int(0)
        [2]=>
        int(0)
        [3]=>
        int(0)
      }
    }
    ["ndi"]=>
    object(FFI\CData:struct <anonymous>)#13 (9) {
      ["abtNFCID3"]=>
      object(FFI\CData:uint8_t[10])#18 (10) {
        [0]=>
        int(0)
        [1]=>
        int(0)
        [2]=>
        int(0)
        [3]=>
        int(0)
        [4]=>
        int(0)
        [5]=>
        int(0)
        [6]=>
        int(0)
        [7]=>
        int(0)
        [8]=>
        int(0)
        [9]=>
        int(0)
      }
      ["btDID"]=>
      int(0)
      ["btBS"]=>
      int(0)
      ["btBR"]=>
      int(0)
      ["btTO"]=>
      int(0)
      ["btPP"]=>
      int(0)
      ["abtGB"]=>
      object(FFI\CData:uint8_t[48])#17 (48) {
        [0]=>
        int(0)
        [1]=>
        int(0)
        [2]=>
        int(0)
        [3]=>
        int(0)
        [4]=>
        int(0)
        [5]=>
        int(0)
        [6]=>
        int(0)
        [7]=>
        int(0)
        [8]=>
        int(0)
        [9]=>
        int(0)
        [10]=>
        int(0)
        [11]=>
        int(0)
        [12]=>
        int(0)
        [13]=>
        int(0)
        [14]=>
        int(0)
        [15]=>
        int(0)
        [16]=>
        int(0)
        [17]=>
        int(0)
        [18]=>
        int(0)
        [19]=>
        int(0)
        [20]=>
        int(0)
        [21]=>
        int(0)
        [22]=>
        int(0)
        [23]=>
        int(0)
        [24]=>
        int(0)
        [25]=>
        int(0)
        [26]=>
        int(0)
        [27]=>
        int(0)
        [28]=>
        int(0)
        [29]=>
        int(0)
        [30]=>
        int(0)
        [31]=>
        int(0)
        [32]=>
        int(0)
        [33]=>
        int(0)
        [34]=>
        int(0)
        [35]=>
        int(0)
        [36]=>
        int(0)
        [37]=>
        int(0)
        [38]=>
        int(0)
        [39]=>
        int(0)
        [40]=>
        int(0)
        [41]=>
        int(0)
        [42]=>
        int(0)
        [43]=>
        int(0)
        [44]=>
        int(0)
        [45]=>
        int(0)
        [46]=>
        int(0)
        [47]=>
        int(0)
      }
      ["szGB"]=>
      int(0)
      ["ndm"]=>
      int(0)
    }
    ["nti"]=>
    object(FFI\CData:struct <anonymous>)#14 (2) {
      ["szDataLen"]=>
      int(0)
      ["abtData"]=>
      object(FFI\CData:uint8_t[32])#17 (32) {
        [0]=>
        int(0)
        [1]=>
        int(0)
        [2]=>
        int(0)
        [3]=>
        int(0)
        [4]=>
        int(0)
        [5]=>
        int(0)
        [6]=>
        int(0)
        [7]=>
        int(0)
        [8]=>
        int(0)
        [9]=>
        int(0)
        [10]=>
        int(0)
        [11]=>
        int(0)
        [12]=>
        int(0)
        [13]=>
        int(0)
        [14]=>
        int(0)
        [15]=>
        int(0)
        [16]=>
        int(0)
        [17]=>
        int(0)
        [18]=>
        int(0)
        [19]=>
        int(0)
        [20]=>
        int(0)
        [21]=>
        int(0)
        [22]=>
        int(0)
        [23]=>
        int(0)
        [24]=>
        int(0)
        [25]=>
        int(0)
        [26]=>
        int(0)
        [27]=>
        int(0)
        [28]=>
        int(0)
        [29]=>
        int(0)
        [30]=>
        int(0)
        [31]=>
        int(0)
      }
    }
    ["nhi"]=>
    object(FFI\CData:struct <anonymous>)#15 (1) {
      ["abtUID"]=>
      object(FFI\CData:uint8_t[8])#17 (8) {
        [0]=>
        int(0)
        [1]=>
        int(0)
        [2]=>
        int(0)
        [3]=>
        int(0)
        [4]=>
        int(0)
        [5]=>
        int(0)
        [6]=>
        int(0)
        [7]=>
        int(0)
      }
    }
  }
  ["nm"]=>
  object(FFI\CData:struct <anonymous>)#5 (2) {
    ["nmt"]=>
    int(0)
    ["nbr"]=>
    int(0)
  }
}

@sj-i
Copy link
Author

sj-i commented Oct 13, 2021

tested on PHP 8.0.9 on Ubuntu 21.04 (x86-64)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment