Reimplementing usb code with libusb-1.0
This commit is contained in:
parent
c4e04d52d3
commit
1ac0d803da
394
NEWS.md
394
NEWS.md
@ -1,394 +0,0 @@
|
|||||||
New in 1.8.0:
|
|
||||||
|
|
||||||
API Changes:
|
|
||||||
- Restore nfc_modulation_type enum order to keep compatibility with libnfc 1.7.1
|
|
||||||
- Bump library version to 6.0.0
|
|
||||||
|
|
||||||
New in 1.7.2:
|
|
||||||
|
|
||||||
Drivers:
|
|
||||||
|
|
||||||
* New driver for pn71xx NXP's NFC Controllers through Linux Libnfc-nci (untested)
|
|
||||||
* New driver for contactless PC/SC readers (only as initiator)
|
|
||||||
|
|
||||||
API Changes:
|
|
||||||
|
|
||||||
* nfc_device_get_supported_baud_rate() now takes also "mode" as argument
|
|
||||||
* New nfc_device_get_supported_baud_rate_target_mode()
|
|
||||||
* New NFC modulation type NMT_BARCODE and nfc_barcode_info struct to support Thinfilm NFC Barcode protocol
|
|
||||||
* New NFC modulation type NMT_ISO14443BICLASS and NMT_ISO14443BICLASS struct to support HID iClass (Picopass)
|
|
||||||
* pn53x_transceive() is now part of public API
|
|
||||||
|
|
||||||
New in 1.7.1:
|
|
||||||
|
|
||||||
API Changes:
|
|
||||||
|
|
||||||
* nfc_initiator_select_passive_target() provides defaults if pbtInitData=NULL
|
|
||||||
* nfc_initiator_target_is_present() allow NULL pointer to tag
|
|
||||||
|
|
||||||
New in 1.7.0:
|
|
||||||
|
|
||||||
Drivers:
|
|
||||||
|
|
||||||
* New PN532 over I2C driver, see contrib/libnfc/pn532_i2c_on_rpi.conf.sample
|
|
||||||
|
|
||||||
API Changes:
|
|
||||||
|
|
||||||
* New function iso14443b_crc_append()
|
|
||||||
|
|
||||||
New in 1.7.0-rc7:
|
|
||||||
|
|
||||||
Drivers:
|
|
||||||
|
|
||||||
* New PN532 over SPI driver, see contrib/libnfc/pn532_spi_on_rpi.conf.sample
|
|
||||||
|
|
||||||
API Changes:
|
|
||||||
|
|
||||||
* Functions
|
|
||||||
- nfc_initiator_target_is_present() & str_nfc_target():
|
|
||||||
now take a pointer to nfc_target as argument
|
|
||||||
- nfc_init(): upon malloc error, doesn't force exit() anymore
|
|
||||||
so now you should test if context != NULL after nfc_init() call
|
|
||||||
|
|
||||||
New in 1.7.0-rc5:
|
|
||||||
|
|
||||||
API Changes:
|
|
||||||
|
|
||||||
* Functions
|
|
||||||
- New nfc_register_driver() function allowing to hook custom drivers.
|
|
||||||
|
|
||||||
New in 1.7.0-rc3:
|
|
||||||
|
|
||||||
API Changes:
|
|
||||||
|
|
||||||
* Functions
|
|
||||||
- Add timeout param to nfc_emulate_target()
|
|
||||||
|
|
||||||
New in 1.7.0-rc2:
|
|
||||||
|
|
||||||
Configuration:
|
|
||||||
libnfc can now use a configuration file for special setups, or features
|
|
||||||
activation. This file (/etc/nfc/libnfc.conf under GNU/Linux systems)
|
|
||||||
supports already some keywords:
|
|
||||||
- "allow_autoscan" to enable/disable device auto-detection feature;
|
|
||||||
- "allow_intrusive_scan" to enable/disable intrusive auto-detection
|
|
||||||
(ie. serial port probing);
|
|
||||||
- "log_level" to select library verbosity;
|
|
||||||
- "device.name" and "device.connstring" to define a user device,
|
|
||||||
this is the recommended method if user has a not easily detectable
|
|
||||||
device (ie. a serial one).
|
|
||||||
It is also possible to define devices using dedicated configuration files and
|
|
||||||
put them into device search directory (/etc/nfc/devices.d under GNU/Linux).
|
|
||||||
Example for the OpenPCD2: create /etc/nfc/devices.d/openpcd2.conf with:
|
|
||||||
name = "OpenPCD2"
|
|
||||||
connstring = "pn532_uart:/dev/ttyACM0"
|
|
||||||
optional = true
|
|
||||||
The keyword "optional" does not mandate the device to be present always
|
|
||||||
(it detects if the reader is indeed present before using it)
|
|
||||||
|
|
||||||
API Changes:
|
|
||||||
|
|
||||||
* Types
|
|
||||||
- New NFC_ESOFT error to handle software errors (allocations, pipe
|
|
||||||
creation, etc.)
|
|
||||||
|
|
||||||
* Functions
|
|
||||||
- Remove nfc_get_default_device() function: the default device is now the
|
|
||||||
first in nfc_list_devices() or could be open using NULL connstring with
|
|
||||||
nfc_open() function.
|
|
||||||
- New enum-to-string converter functions str_nfc_modulation_type() and
|
|
||||||
str_nfc_baud_rate()
|
|
||||||
- New str_nfc_target() to convert nfc_target struct into allocated string
|
|
||||||
- New nfc_device_get_information_about() function to retreive some device's
|
|
||||||
information
|
|
||||||
- No more in/out function parameter: nfc_initiator_transceive_*() now
|
|
||||||
take a constant size for Rx buffer
|
|
||||||
- New nfc_initiator_target_is_present() to test is the previously selected
|
|
||||||
target is available in the field
|
|
||||||
- nfc_initiator_transceive_bytes() returns NFC_EMFCAUTHFAIL when AUTH
|
|
||||||
command failed on a Mifare Classic
|
|
||||||
- New nfc_initiator_init_secure_element() to initiate a connection with
|
|
||||||
secure element (Only supported with a PN532 with SAM equipped)
|
|
||||||
|
|
||||||
New in 1.6.0-rc1:
|
|
||||||
|
|
||||||
API Changes:
|
|
||||||
|
|
||||||
* Types
|
|
||||||
- '_t' suffix removed from all types (e.g. nfc_device_t is now nfc_device)
|
|
||||||
- All errors removed in flavour of NFC_EIO, NFC_EINVARG, NFC_EDEVNOTSUPP,
|
|
||||||
NFC_ENOTSUCHDEV, NFC_EOVFLOW, NFC_ETIMEOUT, NFC_EOPABORTED, NFC_ENOTIMPL,
|
|
||||||
NFC_ETGRELEASED, NFC_ERFTRANS, NFC_ECHIP and NFC_SUCCESS
|
|
||||||
- nfc_device_desc_t replaced by nfc_connstring: libnfc now uses connection
|
|
||||||
strings to describe a device
|
|
||||||
- byte_t typedef removed, libnfc now uses uint8_t from C99
|
|
||||||
- nfc_device is now an opaque type
|
|
||||||
- nfc_properties replaces nfc_options
|
|
||||||
|
|
||||||
* Functions
|
|
||||||
- New nfc_get_default_device() function that allows to grab the connstring
|
|
||||||
stored in LIBNFC_DEFAULT_DEVICE environnement variable or returns the
|
|
||||||
first available device if not set
|
|
||||||
- New nfc_device_get_connstring() accessor function to know the device
|
|
||||||
connstring
|
|
||||||
- New nfc_device_set_property_bool() function that replace nfc_configure()
|
|
||||||
- New nfc_device_set_property_int() function to set integer property
|
|
||||||
- nfc_device_name() renamed to nfc_device_get_name() for the sake of
|
|
||||||
consistency
|
|
||||||
- New nfc_device_get_last_error() function, an accessor to last error occured
|
|
||||||
- Whole libnfc's functions now return 0 (NFC_SUCCESS) or positive value if
|
|
||||||
appropriated on success and libnfc's error code on failure
|
|
||||||
- nfc_connect(), nfc_disconnect() renamed to nfc_open(), nfc_close()
|
|
||||||
respectively
|
|
||||||
- Add 2 new functions: initialization and deinitialization functions:
|
|
||||||
nfc_init() and nfc_exit()
|
|
||||||
- New nfc_device_get_supported_modulation() and
|
|
||||||
nfc_device_get_supported_baud_rate() functions
|
|
||||||
|
|
||||||
* Dependencies
|
|
||||||
- log4c is not anymore used for debugging facility. It was a bad choice,
|
|
||||||
sorry for inconvenience.
|
|
||||||
|
|
||||||
New in 1.5.1:
|
|
||||||
|
|
||||||
API Changes
|
|
||||||
|
|
||||||
* Types
|
|
||||||
- Communication-level errors DEIO and DETIMEOUT are now know as ECOMIO,
|
|
||||||
ECOMTIMEOUT respectively
|
|
||||||
- Common device-level errors DEINVAL and DEABORT are now know as EINVALARG,
|
|
||||||
EOPABORT respectively
|
|
||||||
- New errors: EFRAACKMISMATCH, EFRAISERRFRAME, EDEVNOTSUP and ENOTIMPL
|
|
||||||
|
|
||||||
* Functions
|
|
||||||
- nfc_abort_command() returns a boolean
|
|
||||||
- timeout (struct timeval) pointer added to
|
|
||||||
nfc_initiator_transceive_bytes(), nfc_target_send_bytes() and
|
|
||||||
nfc_target_receive_bytes()
|
|
||||||
- timed functions nfc_initiator_transceive_bytes_timed() and
|
|
||||||
nfc_initiator_transceive_bits_timed() now takes uint32_t as cycles
|
|
||||||
pointer
|
|
||||||
- nfc_initiator_poll_targets() renamed to nfc_initiator_poll_target() and
|
|
||||||
only return one target
|
|
||||||
|
|
||||||
New in 1.5.0:
|
|
||||||
|
|
||||||
Installed files
|
|
||||||
- nfc-message.h have been removed, internal macros are not part of API.
|
|
||||||
- New nfc-emulation.h file offers a middle level API to handle emulation (see
|
|
||||||
nfc-emulate-forum-tag4 example)
|
|
||||||
|
|
||||||
API Changes
|
|
||||||
|
|
||||||
* Types
|
|
||||||
- New error: DEABORT raised when operation is aborted by user (using
|
|
||||||
nfc_abort_command())
|
|
||||||
- nfc_chip_t type removed from public API (have been renamed to pn53x_type
|
|
||||||
in chips/pn53x)
|
|
||||||
- nfc_device_spec_t removed, each driver can use his own way to keep a
|
|
||||||
connection pointer
|
|
||||||
|
|
||||||
* Structures
|
|
||||||
- nfc_device_t now have a nfc_driver_t struct pointer (named .driver) and
|
|
||||||
void pointer (.driver_data) to handle device specific wrapping
|
|
||||||
- nfc_device_t now have a void pointer (.chip_data) to keep some chip
|
|
||||||
specific data
|
|
||||||
- nfc_device_t now have an file descriptor array to manage to abort request
|
|
||||||
- nfc_device_t does have .nc member (nfc_chip_t) anymore (different chips
|
|
||||||
handling in now in chip level)
|
|
||||||
- nfc_device_t does have .nds member (nfc_device_spec_t) anymore, each
|
|
||||||
driver handle its communication using driver_data pointer
|
|
||||||
- nfc_device_t does have .bActive member (bool) anymore, this variable was
|
|
||||||
almost not used and was not efficient
|
|
||||||
- nfc_device_t does have chip's register caches anymore, this is handle in
|
|
||||||
chip level (using chip_data pointer)
|
|
||||||
- driver_callbacks structure have been removed from public API
|
|
||||||
- New nfc_emulator structure used by the new emulation API (see
|
|
||||||
nfc_emulate_target())
|
|
||||||
- New nfc_emulation_state_machine structure used by the new emulation API,
|
|
||||||
it handles an I/O function and data pointer to create a software based
|
|
||||||
state-machine.
|
|
||||||
|
|
||||||
* Functions
|
|
||||||
- New nfc_abort_command() function to abort current running command.
|
|
||||||
- New nfc_initiator_transceive_bits_timed() and
|
|
||||||
nfc_initiator_transceive_bytes_timed() to transceive bits/bytes and
|
|
||||||
measure the time to have a reply
|
|
||||||
- New nfc_emulate_target() function to start a target emulation using an
|
|
||||||
nfc_emulator structure (it contains a custom state-machine
|
|
||||||
(nfc_emulation_state_machine struct) and a custom target (nfc_target_t)
|
|
||||||
(see nfc-emulate-forum-tag4 to have a look on how-to use it)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
New in 1.4.1:
|
|
||||||
|
|
||||||
API Changes
|
|
||||||
|
|
||||||
* Types
|
|
||||||
- New error: ETGUIDNOTSUP raised when UID is not 4 bytes long or does not
|
|
||||||
start with 0x08 (Security restriction present in the NXP PN53x chips)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
New in 1.4.0:
|
|
||||||
|
|
||||||
API Changes
|
|
||||||
|
|
||||||
* Types
|
|
||||||
- New nfc_device_option value (enum): NDO_FORCE_ISO14443_A to force the
|
|
||||||
chip to switch in ISO14443-A
|
|
||||||
- New nfc_dep_mode_t (enum) for DEP mode:
|
|
||||||
NDM_UNDEFINED, NDM_PASSIVE, NDM_ACTIVE
|
|
||||||
- New nfc_modulation_type_t (enum) that lists modulation types:
|
|
||||||
NMT_ISO14443A, NMT_ISO14443B, NMT_FELICA, NMT_JEWEL, NMT_DEP
|
|
||||||
- New nfc_baud_rate_t (enum): list of baud rates:
|
|
||||||
NBR_UNDEFINED, NBR_106, NBR_212, NBR_424, NBR_847
|
|
||||||
- nfc_target_type_t have been removed from API (use nfc_modulation_t
|
|
||||||
instead)
|
|
||||||
|
|
||||||
* Structures
|
|
||||||
- nfc_device_t now have a boolean bAutoIso14443_4 to keep the locally the
|
|
||||||
state of NDO_AUTO_ISO14443_4 (should not be directly set, use
|
|
||||||
nfc_configure() with NDO_AUTO_ISO14443_4)
|
|
||||||
- nfc_device_t now have an uint8_t ui8Parameters to cache PN53x parameters
|
|
||||||
- nfc_device_t now have a byte_t btSupportByte to cache supported
|
|
||||||
modulations
|
|
||||||
- nfc_dep_info_t have completely changed, please see API documentation
|
|
||||||
- nfc_iso14443b_info_t have completely changed, please see API
|
|
||||||
documentation
|
|
||||||
- nfc_modulation_t have completely changed: it now contains a
|
|
||||||
nfc_modulation_type_t and nfc_baud_rate_t couple. Initialization example:
|
|
||||||
nfc_modulation_t nm = {
|
|
||||||
.nmt = NMT_ISO14443A,
|
|
||||||
.nbr = NBR_106,
|
|
||||||
};
|
|
||||||
- nfc_target_t now contains new nfc_modulation_t instead of
|
|
||||||
nfc_target_type_t. Initialization example:
|
|
||||||
nfc_target_t nt = {
|
|
||||||
.nm.nmt = NMT_ISO14443A,
|
|
||||||
.nm.nbr = NBR_UNDEFINED,
|
|
||||||
.nti.nai.abtAtqa = { 0x03, 0x44 },
|
|
||||||
.nti.nai.abtUid = { 0x08, 0xab, 0xcd, 0xef },
|
|
||||||
.nti.nai.btSak = 0x20,
|
|
||||||
.nti.nai.szUidLen = 4,
|
|
||||||
.nti.nai.abtAts = { 0x75, 0x77, 0x81, 0x02, 0x80 },
|
|
||||||
.nti.nai.szAtsLen = 5,
|
|
||||||
};
|
|
||||||
|
|
||||||
* Functions
|
|
||||||
- nfc_initiator_select_passive_target() now use new nfc_modulation_t and
|
|
||||||
nfc_target_t instead of nfc_target_info_t
|
|
||||||
- nfc_initiator_list_passive_targets() now use new nfc_modulation_t and
|
|
||||||
nfc_target_t instead of nfc_target_info_t
|
|
||||||
- nfc_initiator_poll_targets() use new nfc_modulation_t instead of
|
|
||||||
nfc_target_type_t
|
|
||||||
- nfc_initiator_select_dep_target() completely changed, use now
|
|
||||||
nfc_dep_mode_t, nfc_baudrate_t, nfc_dep_info_t and nfc_target_t, please
|
|
||||||
see API documentation
|
|
||||||
- nfc_target_init() have an additional argument: nfc_target_t to describe
|
|
||||||
the wanted target
|
|
||||||
- append_iso14443a_crc() was renamed to iso14443a_crc_append()
|
|
||||||
- New iso14443a_locate_historical_bytes() to locate historical bytes in ATS
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
New in 1.3.9 (since 1.3.4):
|
|
||||||
|
|
||||||
Installed files
|
|
||||||
|
|
||||||
- mifaretag.h and mifareultag.h are removed, Mifare features are not a part
|
|
||||||
of libnfc API anymore (these features are always available in examples/)
|
|
||||||
|
|
||||||
API Changes
|
|
||||||
|
|
||||||
* Types
|
|
||||||
- New nfc_device_option_t value (enum): NDO_AUTO_14443_4, an option to
|
|
||||||
enable/disable auto-switching to ISO/IEC 14443-4 if device is compliliant
|
|
||||||
- New nfc_device_option_t value (enum): NDO_EASY_FRAMING, an option to
|
|
||||||
enable/disable automatic frames encapsulation and chaining
|
|
||||||
- New nfc_target_type_t (enum), with values like NTT_MIFARE,
|
|
||||||
NTT_ISO14443B_106, NTT_DEP_ACTIVE_424, etc.
|
|
||||||
- Mifare related types have been removed from API: mifare_cmd,
|
|
||||||
mifare_param_auth, mifare_param_data, mifare_param_value, mifare_param
|
|
||||||
|
|
||||||
* Structures
|
|
||||||
- nfc_device_t now have boolean bEasyFraming to enable/disable "easy
|
|
||||||
framing" feature (should not be directly set, use nfc_configure() with
|
|
||||||
NDO_EASY_FRAMING)
|
|
||||||
- nfc_device_t now have integer iLastError to handle last error
|
|
||||||
- New chip_callbacks to handle error lookup per chip
|
|
||||||
- driver_callbacks now have a pointer to chip_callbacks
|
|
||||||
- New nfc_target_t that contains nfc_target_info_t and nfc_target_type_t
|
|
||||||
|
|
||||||
* Functions
|
|
||||||
- nfc_initiator_select_tag() became nfc_initiator_select_passive_target()
|
|
||||||
- New nfc_initiator_list_passive_targets() returns a list of detected
|
|
||||||
target on desired modulation
|
|
||||||
- (experimental) New nfc_initiator_poll_targets() returns targets that are
|
|
||||||
detected during hardware polling (available only with PN532)
|
|
||||||
- nfc_initiator_transceive_dep_bytes(), nfc_target_receive_dep_bytes() and
|
|
||||||
nfc_target_send_dep_bytes() have been removed from API, use
|
|
||||||
NDO_EASY_FRAMING option to switch from raw mode to "easy framing"
|
|
||||||
- nfc_initiator_mifare_cmd() have been removed: no more Mifare related
|
|
||||||
stuff in libnfc's API
|
|
||||||
- New nfc_strerror(), nfc_strerror_r() and nfc_perror() to report errors
|
|
||||||
- New append_iso14443a_crc() to append iso14443a_crc() to a string
|
|
||||||
|
|
||||||
|
|
||||||
New in 1.3.4 (since 1.2.1):
|
|
||||||
|
|
||||||
Installed files
|
|
||||||
|
|
||||||
- Headers are now installed in include/nfc instead of include/libnfc
|
|
||||||
- libnfc.h have been renamed to nfc.h
|
|
||||||
- defines.h and types.h have been merge into nfc-types.h
|
|
||||||
- bitutils.h is not installed anymore, some functions are now in
|
|
||||||
examples/nfc-utils.c
|
|
||||||
- devices.h, dev_acr122.h, dev_arygon.h, dev_pn531.h, dev_pn533.h and rs232.h
|
|
||||||
are not installed anymore
|
|
||||||
- New header mifareultag.h, like mifaretag.h for Mifare UltraLight
|
|
||||||
- New header nfc-messages.h with messages macros (DBG, ERR, INFO)
|
|
||||||
|
|
||||||
API Changes
|
|
||||||
|
|
||||||
* Types
|
|
||||||
- uint32_t which was used as size now are size_t
|
|
||||||
- chip_type became nfc_chip_t (enum)
|
|
||||||
- init_modulation became nfc_modulation_t (enum), and now have
|
|
||||||
NM_ACTIVE_DEP and NM_PASSIVE_DEP modulation values added
|
|
||||||
|
|
||||||
* Structures
|
|
||||||
- dev_info became nfc_device_t
|
|
||||||
- dev_config_option became nfc_device_option_t
|
|
||||||
- New nfc_device_desc_t to describe the way to access to a NFC device.
|
|
||||||
Initialisation example:
|
|
||||||
nfc_device_desc_t ndd = {
|
|
||||||
ndd.pcDriver = "ARYGON";
|
|
||||||
ndd.pcPort = "/dev/ttyUSB0";
|
|
||||||
ndd.uiSpeed = 115200;
|
|
||||||
};
|
|
||||||
- dev_callbacks became driver_callbacks and now have two function pointers
|
|
||||||
more: pick_device() and list_devices()
|
|
||||||
- New nfc_dep_info_t to handle DEP targets info
|
|
||||||
- tag_info_iso14443a became nfc_iso14443a_info_t
|
|
||||||
- tag_info_iso14443b became nfc_iso14443b_info_t
|
|
||||||
- tag_info_felica became nfc_felica_info_t
|
|
||||||
- tag_info_jewel became nfc_jewel_info_t
|
|
||||||
- tag_info became nfc_target_info_t, and now have extended union to
|
|
||||||
nfc_dep_info_t
|
|
||||||
|
|
||||||
* Functions
|
|
||||||
- nfc_connect() now takes 1 nfc_devive_desc_t argument (can be NULL)
|
|
||||||
- New nfc_list_devices(), it find available NFC devices using all know
|
|
||||||
drivers
|
|
||||||
- (experimental) New nfc_initiator_select_dep(), it looks for DEP targets
|
|
||||||
- (experimental) New nfc_initiator_transceive_dep_bytes(), like
|
|
||||||
nfc_initiator_transceive_bytes() for DEP targets
|
|
||||||
- (experimental) New nfc_target_receive_dep_bytes() and
|
|
||||||
nfc_target_send_dep_bytes(), to receive/send bytes to DEP target
|
|
||||||
(configured as initiator) while local NFC device is configured as target
|
|
||||||
- New nfc_device_name() returns the device's name
|
|
||||||
- New iso14443a_crc() computes CRC as described in ISO/IEC 14443
|
|
||||||
- New nfc_version() returns the actual version of libnfc (with SVN
|
|
||||||
revision, if available)
|
|
||||||
@ -7,6 +7,7 @@
|
|||||||
* Copyright (C) 2010-2012 Romain Tartière
|
* Copyright (C) 2010-2012 Romain Tartière
|
||||||
* Copyright (C) 2010-2013 Philippe Teuwen
|
* Copyright (C) 2010-2013 Philippe Teuwen
|
||||||
* Copyright (C) 2012-2013 Ludovic Rousseau
|
* Copyright (C) 2012-2013 Ludovic Rousseau
|
||||||
|
* Copyright (C) 2022 Kenspeckle
|
||||||
* See AUTHORS file for a more comprehensive list of contributors.
|
* See AUTHORS file for a more comprehensive list of contributors.
|
||||||
* Additional contributors of this file:
|
* Additional contributors of this file:
|
||||||
*
|
*
|
||||||
@ -24,634 +25,300 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
#include <stdbool.h>
|
||||||
/**
|
#include <string.h>
|
||||||
* @file usbbus.c
|
|
||||||
* @brief libusb 0.1 driver wrapper
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include "config.h"
|
|
||||||
#endif // HAVE_CONFIG_H
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <libusb.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "usbbus.h"
|
#include "usbbus.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#define LOG_CATEGORY "libnfc.buses.usbbus"
|
|
||||||
|
|
||||||
|
#define LOG_CATEGORY "libnfc.bus.usbbus"
|
||||||
#define LOG_GROUP NFC_LOG_GROUP_DRIVER
|
#define LOG_GROUP NFC_LOG_GROUP_DRIVER
|
||||||
|
|
||||||
/*
|
|
||||||
* This file embeds partially libusb-compat-0.1 by:
|
|
||||||
* Copyright (C) 2008 Daniel Drake <dsd@gentoo.org>
|
|
||||||
* Copyright (c) 2000-2003 Johannes Erdfelt <johannes@erdfelt.com>
|
|
||||||
* This layer will be removed ASAP before integration in the main trunk
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#define LIST_ADD(begin, ent) \
|
|
||||||
do { \
|
|
||||||
if (begin) { \
|
|
||||||
ent->next = begin; \
|
|
||||||
ent->next->prev = ent; \
|
|
||||||
} else \
|
|
||||||
ent->next = NULL; \
|
|
||||||
ent->prev = NULL; \
|
|
||||||
begin = ent; \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define LIST_DEL(begin, ent) \
|
|
||||||
do { \
|
|
||||||
if (ent->prev) \
|
|
||||||
ent->prev->next = ent->next; \
|
|
||||||
else \
|
|
||||||
begin = ent->next; \
|
|
||||||
if (ent->next) \
|
|
||||||
ent->next->prev = ent->prev; \
|
|
||||||
ent->prev = NULL; \
|
|
||||||
ent->next = NULL; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define USBBUS_DT_CONFIG_SIZE 9
|
|
||||||
#define USBBUS_DT_INTERFACE_SIZE 9
|
|
||||||
#define USBBUS_DT_ENDPOINT_AUDIO_SIZE 9
|
|
||||||
|
|
||||||
static libusb_context *ctx = NULL;
|
static libusb_context *ctx = NULL;
|
||||||
|
|
||||||
struct usbbus_bus *usb_busses = NULL;
|
uint8_t get_usb_num_configs(struct libusb_device *dev);
|
||||||
|
|
||||||
static void _usb_finalize(void)
|
int usbbus_prepare() {
|
||||||
{
|
static bool usb_initialized = false;
|
||||||
if (ctx) {
|
int res;
|
||||||
libusb_exit(ctx);
|
if (!usb_initialized) {
|
||||||
ctx = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void usb_init(void)
|
|
||||||
{
|
|
||||||
if (!ctx) {
|
|
||||||
int r;
|
|
||||||
r = libusb_init(&ctx);
|
|
||||||
if (r < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
atexit(_usb_finalize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int find_busses(struct usbbus_bus **ret)
|
|
||||||
{
|
|
||||||
libusb_device **dev_list = NULL;
|
|
||||||
struct usbbus_bus *busses = NULL;
|
|
||||||
struct usbbus_bus *bus;
|
|
||||||
int dev_list_len = 0;
|
|
||||||
int i;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
r = libusb_get_device_list(ctx, &dev_list);
|
|
||||||
if (r < 0) {
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r == 0) {
|
|
||||||
libusb_free_device_list(dev_list, 1);
|
|
||||||
/* no buses */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* iterate over the device list, identifying the individual busses.
|
|
||||||
* we use the location field of the usbbus_bus structure to store the
|
|
||||||
* bus number. */
|
|
||||||
|
|
||||||
dev_list_len = r;
|
|
||||||
for (i = 0; i < dev_list_len; i++) {
|
|
||||||
libusb_device *dev = dev_list[i];
|
|
||||||
uint8_t bus_num = libusb_get_bus_number(dev);
|
|
||||||
|
|
||||||
/* if we already know about it, continue */
|
|
||||||
if (busses) {
|
|
||||||
bus = busses;
|
|
||||||
int found = 0;
|
|
||||||
do {
|
|
||||||
if (bus_num == bus->location) {
|
|
||||||
found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while ((bus = bus->next) != NULL);
|
|
||||||
if (found)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* add it to the list of busses */
|
|
||||||
bus = malloc(sizeof(*bus));
|
|
||||||
if (!bus)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
memset(bus, 0, sizeof(*bus));
|
|
||||||
bus->location = bus_num;
|
|
||||||
snprintf(bus->dirname, USBBUS_PATH_MAX, "%03d", bus_num);
|
|
||||||
LIST_ADD(busses, bus);
|
|
||||||
}
|
|
||||||
|
|
||||||
libusb_free_device_list(dev_list, 1);
|
|
||||||
*ret = busses;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err:
|
|
||||||
bus = busses;
|
|
||||||
while (bus) {
|
|
||||||
struct usbbus_bus *tbus = bus->next;
|
|
||||||
free(bus);
|
|
||||||
bus = tbus;
|
|
||||||
}
|
|
||||||
return LIBUSB_ERROR_NO_MEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int usb_find_busses(void)
|
|
||||||
{
|
|
||||||
struct usbbus_bus *new_busses = NULL;
|
|
||||||
struct usbbus_bus *bus;
|
|
||||||
int changes = 0;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
/* libusb-1.0 initialization might have failed, but we can't indicate
|
|
||||||
* this with libusb-0.1, so trap that situation here */
|
|
||||||
if (!ctx)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
r = find_busses(&new_busses);
|
|
||||||
if (r < 0) {
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* walk through all busses we already know about, removing duplicates
|
|
||||||
* from the new list. if we do not find it in the new list, the bus
|
|
||||||
* has been removed. */
|
|
||||||
|
|
||||||
bus = usb_busses;
|
|
||||||
while (bus) {
|
|
||||||
struct usbbus_bus *tbus = bus->next;
|
|
||||||
struct usbbus_bus *nbus = new_busses;
|
|
||||||
int found = 0;
|
|
||||||
|
|
||||||
while (nbus) {
|
|
||||||
struct usbbus_bus *tnbus = nbus->next;
|
|
||||||
|
|
||||||
if (bus->location == nbus->location) {
|
|
||||||
LIST_DEL(new_busses, nbus);
|
|
||||||
free(nbus);
|
|
||||||
found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
nbus = tnbus;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found) {
|
|
||||||
/* bus removed */
|
|
||||||
changes++;
|
|
||||||
LIST_DEL(usb_busses, bus);
|
|
||||||
free(bus);
|
|
||||||
}
|
|
||||||
|
|
||||||
bus = tbus;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* anything remaining in new_busses is a new bus */
|
|
||||||
bus = new_busses;
|
|
||||||
while (bus) {
|
|
||||||
struct usbbus_bus *tbus = bus->next;
|
|
||||||
LIST_DEL(new_busses, bus);
|
|
||||||
LIST_ADD(usb_busses, bus);
|
|
||||||
changes++;
|
|
||||||
bus = tbus;
|
|
||||||
}
|
|
||||||
|
|
||||||
return changes;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int find_devices(libusb_device **dev_list, int dev_list_len,
|
|
||||||
struct usbbus_bus *bus, struct usbbus_device **ret)
|
|
||||||
{
|
|
||||||
struct usbbus_device *devices = NULL;
|
|
||||||
struct usbbus_device *dev;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < dev_list_len; i++) {
|
|
||||||
libusb_device *newlib_dev = dev_list[i];
|
|
||||||
uint8_t bus_num = libusb_get_bus_number(newlib_dev);
|
|
||||||
|
|
||||||
if (bus_num != bus->location)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
dev = malloc(sizeof(*dev));
|
|
||||||
if (!dev)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
/* No need to reference the device now, just take the pointer. We
|
|
||||||
* increase the reference count later if we keep the device. */
|
|
||||||
dev->dev = newlib_dev;
|
|
||||||
|
|
||||||
dev->bus = bus;
|
|
||||||
dev->devnum = libusb_get_device_address(newlib_dev);
|
|
||||||
snprintf(dev->filename, USBBUS_PATH_MAX, "%03d", dev->devnum);
|
|
||||||
LIST_ADD(devices, dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
*ret = devices;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err:
|
|
||||||
dev = devices;
|
|
||||||
while (dev) {
|
|
||||||
struct usbbus_device *tdev = dev->next;
|
|
||||||
free(dev);
|
|
||||||
dev = tdev;
|
|
||||||
}
|
|
||||||
return LIBUSB_ERROR_NO_MEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void clear_endpoint_descriptor(struct usbbus_endpoint_descriptor *ep)
|
|
||||||
{
|
|
||||||
if (ep->extra)
|
|
||||||
free(ep->extra);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void clear_interface_descriptor(struct usbbus_interface_descriptor *iface)
|
|
||||||
{
|
|
||||||
if (iface->extra)
|
|
||||||
free(iface->extra);
|
|
||||||
if (iface->endpoint) {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < iface->bNumEndpoints; i++)
|
|
||||||
clear_endpoint_descriptor(iface->endpoint + i);
|
|
||||||
free(iface->endpoint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void clear_interface(struct usbbus_interface *iface)
|
|
||||||
{
|
|
||||||
if (iface->altsetting) {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < iface->num_altsetting; i++)
|
|
||||||
clear_interface_descriptor(iface->altsetting + i);
|
|
||||||
free(iface->altsetting);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void clear_config_descriptor(struct usbbus_config_descriptor *config)
|
|
||||||
{
|
|
||||||
if (config->extra)
|
|
||||||
free(config->extra);
|
|
||||||
if (config->interface) {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < config->bNumInterfaces; i++)
|
|
||||||
clear_interface(config->interface + i);
|
|
||||||
free(config->interface);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void clear_device(struct usbbus_device *dev)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
|
|
||||||
clear_config_descriptor(dev->config + i);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int copy_endpoint_descriptor(struct usbbus_endpoint_descriptor *dest,
|
|
||||||
const struct libusb_endpoint_descriptor *src)
|
|
||||||
{
|
|
||||||
memcpy(dest, src, USBBUS_DT_ENDPOINT_AUDIO_SIZE);
|
|
||||||
|
|
||||||
dest->extralen = src->extra_length;
|
|
||||||
if (src->extra_length) {
|
|
||||||
dest->extra = malloc(src->extra_length);
|
|
||||||
if (!dest->extra)
|
|
||||||
return LIBUSB_ERROR_NO_MEM;
|
|
||||||
memcpy(dest->extra, src->extra, src->extra_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int copy_interface_descriptor(struct usbbus_interface_descriptor *dest,
|
|
||||||
const struct libusb_interface_descriptor *src)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int num_endpoints = src->bNumEndpoints;
|
|
||||||
size_t alloc_size = sizeof(struct usbbus_endpoint_descriptor) * num_endpoints;
|
|
||||||
|
|
||||||
memcpy(dest, src, USBBUS_DT_INTERFACE_SIZE);
|
|
||||||
dest->endpoint = malloc(alloc_size);
|
|
||||||
if (!dest->endpoint)
|
|
||||||
return LIBUSB_ERROR_NO_MEM;
|
|
||||||
memset(dest->endpoint, 0, alloc_size);
|
|
||||||
|
|
||||||
for (i = 0; i < num_endpoints; i++) {
|
|
||||||
int r = copy_endpoint_descriptor(dest->endpoint + i, &src->endpoint[i]);
|
|
||||||
if (r < 0) {
|
|
||||||
clear_interface_descriptor(dest);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dest->extralen = src->extra_length;
|
|
||||||
if (src->extra_length) {
|
|
||||||
dest->extra = malloc(src->extra_length);
|
|
||||||
if (!dest->extra) {
|
|
||||||
clear_interface_descriptor(dest);
|
|
||||||
return LIBUSB_ERROR_NO_MEM;
|
|
||||||
}
|
|
||||||
memcpy(dest->extra, src->extra, src->extra_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int copy_interface(struct usbbus_interface *dest,
|
|
||||||
const struct libusb_interface *src)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int num_altsetting = src->num_altsetting;
|
|
||||||
size_t alloc_size = sizeof(struct usbbus_interface_descriptor)
|
|
||||||
* num_altsetting;
|
|
||||||
|
|
||||||
dest->num_altsetting = num_altsetting;
|
|
||||||
dest->altsetting = malloc(alloc_size);
|
|
||||||
if (!dest->altsetting)
|
|
||||||
return LIBUSB_ERROR_NO_MEM;
|
|
||||||
memset(dest->altsetting, 0, alloc_size);
|
|
||||||
|
|
||||||
for (i = 0; i < num_altsetting; i++) {
|
|
||||||
int r = copy_interface_descriptor(dest->altsetting + i,
|
|
||||||
&src->altsetting[i]);
|
|
||||||
if (r < 0) {
|
|
||||||
clear_interface(dest);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int copy_config_descriptor(struct usbbus_config_descriptor *dest,
|
|
||||||
const struct libusb_config_descriptor *src)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int num_interfaces = src->bNumInterfaces;
|
|
||||||
size_t alloc_size = sizeof(struct usbbus_interface) * num_interfaces;
|
|
||||||
|
|
||||||
memcpy(dest, src, USBBUS_DT_CONFIG_SIZE);
|
|
||||||
dest->interface = malloc(alloc_size);
|
|
||||||
if (!dest->interface)
|
|
||||||
return LIBUSB_ERROR_NO_MEM;
|
|
||||||
memset(dest->interface, 0, alloc_size);
|
|
||||||
|
|
||||||
for (i = 0; i < num_interfaces; i++) {
|
|
||||||
int r = copy_interface(dest->interface + i, &src->interface[i]);
|
|
||||||
if (r < 0) {
|
|
||||||
clear_config_descriptor(dest);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dest->extralen = src->extra_length;
|
|
||||||
if (src->extra_length) {
|
|
||||||
dest->extra = malloc(src->extra_length);
|
|
||||||
if (!dest->extra) {
|
|
||||||
clear_config_descriptor(dest);
|
|
||||||
return LIBUSB_ERROR_NO_MEM;
|
|
||||||
}
|
|
||||||
memcpy(dest->extra, src->extra, src->extra_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int initialize_device(struct usbbus_device *dev)
|
|
||||||
{
|
|
||||||
libusb_device *newlib_dev = dev->dev;
|
|
||||||
int num_configurations;
|
|
||||||
size_t alloc_size;
|
|
||||||
int r;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* device descriptor is identical in both libs */
|
|
||||||
r = libusb_get_device_descriptor(newlib_dev,
|
|
||||||
(struct libusb_device_descriptor *) &dev->descriptor);
|
|
||||||
if (r < 0) {
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
num_configurations = dev->descriptor.bNumConfigurations;
|
|
||||||
alloc_size = sizeof(struct usbbus_config_descriptor) * num_configurations;
|
|
||||||
dev->config = malloc(alloc_size);
|
|
||||||
if (!dev->config)
|
|
||||||
return LIBUSB_ERROR_NO_MEM;
|
|
||||||
memset(dev->config, 0, alloc_size);
|
|
||||||
|
|
||||||
for (i = 0; i < num_configurations; i++) {
|
|
||||||
struct libusb_config_descriptor *newlib_config;
|
|
||||||
r = libusb_get_config_descriptor(newlib_dev, i, &newlib_config);
|
|
||||||
if (r < 0) {
|
|
||||||
clear_device(dev);
|
|
||||||
free(dev->config);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
r = copy_config_descriptor(dev->config + i, newlib_config);
|
|
||||||
libusb_free_config_descriptor(newlib_config);
|
|
||||||
if (r < 0) {
|
|
||||||
clear_device(dev);
|
|
||||||
free(dev->config);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dev->num_children = 0;
|
|
||||||
dev->children = NULL;
|
|
||||||
|
|
||||||
libusb_ref_device(newlib_dev);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void free_device(struct usbbus_device *dev)
|
|
||||||
{
|
|
||||||
clear_device(dev);
|
|
||||||
libusb_unref_device(dev->dev);
|
|
||||||
free(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int usb_find_devices(void)
|
|
||||||
{
|
|
||||||
struct usbbus_bus *bus;
|
|
||||||
libusb_device **dev_list;
|
|
||||||
int dev_list_len;
|
|
||||||
int changes = 0;
|
|
||||||
|
|
||||||
/* libusb-1.0 initialization might have failed, but we can't indicate
|
|
||||||
* this with libusb-0.1, so trap that situation here */
|
|
||||||
if (!ctx)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
dev_list_len = libusb_get_device_list(ctx, &dev_list);
|
|
||||||
if (dev_list_len < 0)
|
|
||||||
return dev_list_len;
|
|
||||||
|
|
||||||
for (bus = usb_busses; bus; bus = bus->next) {
|
|
||||||
int r;
|
|
||||||
struct usbbus_device *new_devices = NULL;
|
|
||||||
struct usbbus_device *dev;
|
|
||||||
|
|
||||||
r = find_devices(dev_list, dev_list_len, bus, &new_devices);
|
|
||||||
if (r < 0) {
|
|
||||||
libusb_free_device_list(dev_list, 1);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* walk through the devices we already know about, removing duplicates
|
|
||||||
* from the new list. if we do not find it in the new list, the device
|
|
||||||
* has been removed. */
|
|
||||||
dev = bus->devices;
|
|
||||||
while (dev) {
|
|
||||||
int found = 0;
|
|
||||||
struct usbbus_device *tdev = dev->next;
|
|
||||||
struct usbbus_device *ndev = new_devices;
|
|
||||||
|
|
||||||
while (ndev) {
|
|
||||||
if (ndev->devnum == dev->devnum) {
|
|
||||||
LIST_DEL(new_devices, ndev);
|
|
||||||
free(ndev);
|
|
||||||
found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ndev = ndev->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found) {
|
|
||||||
LIST_DEL(bus->devices, dev);
|
|
||||||
free_device(dev);
|
|
||||||
changes++;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev = tdev;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* anything left in new_devices is a new device */
|
|
||||||
dev = new_devices;
|
|
||||||
while (dev) {
|
|
||||||
struct usbbus_device *tdev = dev->next;
|
|
||||||
r = initialize_device(dev);
|
|
||||||
if (r < 0) {
|
|
||||||
dev = tdev;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
LIST_DEL(new_devices, dev);
|
|
||||||
LIST_ADD(bus->devices, dev);
|
|
||||||
changes++;
|
|
||||||
dev = tdev;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
libusb_free_device_list(dev_list, 1);
|
|
||||||
return changes;
|
|
||||||
}
|
|
||||||
|
|
||||||
int usbbus_prepare(void)
|
|
||||||
{
|
|
||||||
static bool usb_initialized = false;
|
|
||||||
if (!usb_initialized) {
|
|
||||||
|
|
||||||
#ifdef ENVVARS
|
#ifdef ENVVARS
|
||||||
char *env_log_level = getenv("LIBNFC_LOG_LEVEL");
|
char *env_log_level = getenv("LIBNFC_LOG_LEVEL");
|
||||||
// Set libusb debug only if asked explicitely:
|
// Set libusb debug only if asked explicitely:
|
||||||
// LIBUSB_LOG_LEVEL=12288 (= NFC_LOG_PRIORITY_DEBUG * 2 ^ NFC_LOG_GROUP_LIBUSB)
|
// LIBUSB_LOG_LEVEL=12288 (= NFC_LOG_PRIORITY_DEBUG * 2 ^ NFC_LOG_GROUP_LIBUSB)
|
||||||
if (env_log_level && (((atoi(env_log_level) >> (NFC_LOG_GROUP_LIBUSB * 2)) & 0x00000003) >= NFC_LOG_PRIORITY_DEBUG)) {
|
if (env_log_level
|
||||||
setenv("USB_DEBUG", "255", 1);
|
&& (((atoi(env_log_level) >> (NFC_LOG_GROUP_LIBUSB * 2)) & 0x00000003) >= NFC_LOG_PRIORITY_DEBUG)) {
|
||||||
}
|
setenv("USB_DEBUG", "255", 1);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
usb_init();
|
res = libusb_init(&ctx);
|
||||||
usb_initialized = true;
|
if (res != 0) {
|
||||||
}
|
log_put(LOG_GROUP,
|
||||||
|
LOG_CATEGORY,
|
||||||
|
NFC_LOG_PRIORITY_ERROR,
|
||||||
|
"Unable to init libusb (%s)",
|
||||||
|
libusb_strerror(res));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
usb_initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
int res;
|
// usb_find_devices will find all of the devices on each bus. This should be
|
||||||
// usb_find_busses will find all of the busses on the system. Returns the
|
// called after usb_find_busses. Returns the number of changes since the
|
||||||
// number of changes since previous call to this function (total of new
|
// previous call to this function (total of new device and devices removed).
|
||||||
// busses and busses removed).
|
libusb_device **tmp_devices;
|
||||||
if ((res = usb_find_busses()) < 0) {
|
ssize_t num_devices = libusb_get_device_list(ctx, &tmp_devices);
|
||||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to find USB busses (%s)", usbbus_strerror(res));
|
libusb_free_device_list(tmp_devices, (int) num_devices);
|
||||||
return -1;
|
if (num_devices <= 0) {
|
||||||
}
|
log_put(LOG_GROUP,
|
||||||
// usb_find_devices will find all of the devices on each bus. This should be
|
LOG_CATEGORY,
|
||||||
// called after usb_find_busses. Returns the number of changes since the
|
NFC_LOG_PRIORITY_ERROR,
|
||||||
// previous call to this function (total of new device and devices removed).
|
"Unable to find USB devices (%s)",
|
||||||
if ((res = usb_find_devices()) < 0) {
|
libusb_strerror((int) num_devices));
|
||||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to find USB devices (%s)", usbbus_strerror(res));
|
return -1;
|
||||||
return -1;
|
}
|
||||||
}
|
return 0;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
usbbus_device_handle *usbbus_open(struct usbbus_device *dev)
|
|
||||||
{
|
TODO kenspeckle
|
||||||
int r;
|
beim ende vom programm libusb dinge wieder freigeben
|
||||||
usbbus_device_handle *udev;
|
|
||||||
r = libusb_open((libusb_device *) dev->dev, (libusb_device_handle **)&udev);
|
size_t usbbus_usb_scan(char **connstrings,
|
||||||
if (r < 0) {
|
const size_t connstrings_len,
|
||||||
return NULL;
|
struct usbbus_device *nfc_usb_devices,
|
||||||
}
|
const size_t num_nfc_usb_devices,
|
||||||
return (usbbus_device_handle *)udev;
|
char *usb_driver_name) {
|
||||||
|
usbbus_prepare();
|
||||||
|
|
||||||
|
size_t device_found = 0;
|
||||||
|
struct libusb_device **devices;
|
||||||
|
ssize_t num_devices = libusb_get_device_list(ctx, &devices);
|
||||||
|
for (size_t i = 0; i < num_devices; i++) {
|
||||||
|
struct libusb_device *dev = devices[i];
|
||||||
|
|
||||||
|
for (size_t nfc_dev_idx = 0; nfc_dev_idx < num_nfc_usb_devices; nfc_dev_idx++) {
|
||||||
|
if (nfc_usb_devices[nfc_dev_idx].vendor_id == usbbus_get_vendor_id(dev)
|
||||||
|
&& nfc_usb_devices[nfc_dev_idx].product_id == usbbus_get_product_id(dev)) {
|
||||||
|
|
||||||
|
size_t valid_config_idx = 1;
|
||||||
|
|
||||||
|
// Make sure there are 2 endpoints available
|
||||||
|
// with libusb-win32 we got some null pointers so be robust before looking at endpoints
|
||||||
|
if (nfc_usb_devices[nfc_dev_idx].max_packet_size == 0) {
|
||||||
|
|
||||||
|
bool found_valid_config = false;
|
||||||
|
|
||||||
|
for (size_t config_idx = 0; config_idx < get_usb_num_configs(dev); i++) {
|
||||||
|
struct libusb_config_descriptor *usb_config;
|
||||||
|
int r = libusb_get_config_descriptor(dev, config_idx, &usb_config);
|
||||||
|
|
||||||
|
if (r != 0
|
||||||
|
|| usb_config->interface == NULL
|
||||||
|
|| usb_config->interface->altsetting == NULL
|
||||||
|
|| usb_config->interface->altsetting->bNumEndpoints < 2) {
|
||||||
|
// Nope, we maybe want the next one, let's try to find another
|
||||||
|
libusb_free_config_descriptor(usb_config);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
libusb_free_config_descriptor(usb_config);
|
||||||
|
|
||||||
|
found_valid_config = true;
|
||||||
|
valid_config_idx = config_idx;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!found_valid_config) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
libusb_device_handle *udev;
|
||||||
|
int res = libusb_open(dev, &udev);
|
||||||
|
if (res < 0 && udev == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set configuration
|
||||||
|
res = libusb_set_configuration(udev, (int) valid_config_idx);
|
||||||
|
if (res < 0) {
|
||||||
|
log_put(LOG_GROUP,
|
||||||
|
LOG_CATEGORY,
|
||||||
|
NFC_LOG_PRIORITY_ERROR,
|
||||||
|
"Unable to set USB configuration (%s)",
|
||||||
|
libusb_strerror(res));
|
||||||
|
libusb_close(udev);
|
||||||
|
// we failed to use the device
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "device found: Vendor-Id: %d Product-Id %d",
|
||||||
|
usbbus_get_vendor_id(dev), usbbus_get_product_id(dev));
|
||||||
|
libusb_close(udev);
|
||||||
|
|
||||||
|
uint8_t dev_address = libusb_get_device_address(dev);
|
||||||
|
size_t size_new_str = snprintf(
|
||||||
|
connstrings[device_found],
|
||||||
|
sizeof(nfc_connstring),
|
||||||
|
"%s:%03d:%03d",
|
||||||
|
usb_driver_name,
|
||||||
|
dev_address, (int) valid_config_idx);
|
||||||
|
if (size_new_str >= (int) sizeof(nfc_connstring)) {
|
||||||
|
// truncation occurred, skipping that one
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
device_found++;
|
||||||
|
// Test if we reach the maximum "wanted" devices
|
||||||
|
if (device_found == connstrings_len) {
|
||||||
|
return device_found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return device_found;
|
||||||
}
|
}
|
||||||
|
|
||||||
void usbbus_close(usbbus_device_handle *dev)
|
void usbbus_get_usb_endpoints(struct libusb_device *dev,
|
||||||
{
|
uint8_t *endpoint_in,
|
||||||
libusb_close((libusb_device_handle *)dev);
|
uint8_t *endpoint_out,
|
||||||
|
uint16_t *max_packet_size) {
|
||||||
|
|
||||||
|
bool endpoint_in_set = false;
|
||||||
|
bool endpoint_out_set = false;
|
||||||
|
size_t num_configs = get_usb_num_configs(dev);
|
||||||
|
for (size_t config_idx = 0; config_idx < num_configs; config_idx++) {
|
||||||
|
struct libusb_config_descriptor *usb_config;
|
||||||
|
|
||||||
|
int r = libusb_get_config_descriptor(dev, config_idx, &usb_config);
|
||||||
|
if (r != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!usb_config->interface) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (size_t interface_idx = 0; interface_idx < usb_config->bNumInterfaces; interface_idx++) {
|
||||||
|
struct libusb_interface interface = usb_config->interface[interface_idx];
|
||||||
|
if (!interface.altsetting) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (size_t settings_idx = 0; settings_idx < interface.num_altsetting; settings_idx++) {
|
||||||
|
struct libusb_interface_descriptor settings = interface.altsetting[settings_idx];
|
||||||
|
if (!settings.endpoint) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3 Endpoints maximum: Interrupt In, Bulk In, Bulk Out
|
||||||
|
for (size_t endpoint_idx = 0; endpoint_idx < settings.bNumEndpoints; endpoint_idx++) {
|
||||||
|
struct libusb_endpoint_descriptor endpoint = settings.endpoint[endpoint_idx];
|
||||||
|
|
||||||
|
// Only accept bulk transfer endpoints (ignore interrupt endpoints)
|
||||||
|
if (endpoint.bmAttributes != LIBUSB_ENDPOINT_TRANSFER_TYPE_BULK) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the endpoint to a local var, makes it more readable code
|
||||||
|
uint8_t endpoint_address = endpoint.bEndpointAddress;
|
||||||
|
|
||||||
|
// Test if we dealing with a bulk IN endpoint
|
||||||
|
if ((endpoint_address & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN && !endpoint_in_set) {
|
||||||
|
*endpoint_in = endpoint_address;
|
||||||
|
*max_packet_size = endpoint.wMaxPacketSize;
|
||||||
|
endpoint_in_set = true;
|
||||||
|
}
|
||||||
|
// Test if we dealing with a bulk OUT endpoint
|
||||||
|
if ((endpoint_address & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT && !endpoint_out_set) {
|
||||||
|
*endpoint_out = endpoint_address;
|
||||||
|
*max_packet_size = endpoint.wMaxPacketSize;
|
||||||
|
endpoint_out_set = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endpoint_in_set && endpoint_out_set) {
|
||||||
|
libusb_free_config_descriptor(usb_config);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
libusb_free_config_descriptor(usb_config);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int usbbus_set_configuration(usbbus_device_handle *dev, int configuration)
|
uint8_t get_usb_num_configs(struct libusb_device *dev) {
|
||||||
{
|
struct libusb_device_descriptor descriptor;
|
||||||
return libusb_set_configuration((libusb_device_handle *)dev, configuration);
|
libusb_get_device_descriptor(dev, &descriptor);
|
||||||
|
return descriptor.bNumConfigurations;
|
||||||
}
|
}
|
||||||
|
|
||||||
int usbbus_get_string_simple(usbbus_device_handle *dev, int index, char *buf, size_t buflen)
|
void usbbus_get_usb_device_name(struct libusb_device *dev, libusb_device_handle *udev, char *buffer, size_t len) {
|
||||||
{
|
struct libusb_device_descriptor descriptor;
|
||||||
return libusb_get_string_descriptor_ascii((libusb_device_handle *)dev, index & 0xff,
|
libusb_get_device_descriptor(dev, &descriptor);
|
||||||
(unsigned char *) buf, (int) buflen);
|
if (descriptor.iManufacturer || descriptor.iProduct) {
|
||||||
|
if (udev) {
|
||||||
|
libusb_get_string_descriptor_ascii(udev, descriptor.iManufacturer & 0xff, (unsigned char *) buffer, len);
|
||||||
|
if (strlen(buffer) > 0) {
|
||||||
|
strncpy(buffer + strlen(buffer), " / ", 4);
|
||||||
|
}
|
||||||
|
libusb_get_string_descriptor_ascii(udev,
|
||||||
|
descriptor.iProduct & 0xff,
|
||||||
|
(unsigned char *) buffer + strlen(buffer),
|
||||||
|
len - strlen(buffer));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int usbbus_bulk_transfer(usbbus_device_handle *dev, int ep, char *bytes, int size, int *actual_length, int timeout)
|
|
||||||
{
|
void usbbus_get_device(uint8_t dev_address, struct libusb_device * dev, struct libusb_device_handle * dev_handle) {
|
||||||
return libusb_bulk_transfer((libusb_device_handle *)dev, ep & 0xff, (unsigned char *)bytes, size, actual_length, timeout);
|
struct libusb_device ** device_list;
|
||||||
|
ssize_t num_devices = libusb_get_device_list(ctx, &device_list);
|
||||||
|
for (size_t i = 0; i < num_devices; i++) {
|
||||||
|
if (libusb_get_device_address(device_list[i]) != dev_address) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
dev = device_list[i];
|
||||||
|
int res = libusb_open(dev, &dev_handle);
|
||||||
|
if (res != 0 || dev_handle == NULL) {
|
||||||
|
log_put(LOG_GROUP,LOG_CATEGORY,NFC_LOG_PRIORITY_ERROR,
|
||||||
|
"Unable to open libusb device (%s)",libusb_strerror(res));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// libusb works with a reference counter which is set to 1 for each device when calling libusb_get_device_list and increased
|
||||||
|
// by libusb_open. Thus we decrease the counter by 1 for all devices and only the "real" device will survive
|
||||||
|
libusb_free_device_list(device_list, num_devices);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int usbbus_claim_interface(usbbus_device_handle *dev, int interface)
|
|
||||||
{
|
uint16_t usbbus_get_vendor_id(struct libusb_device *dev) {
|
||||||
return libusb_claim_interface((libusb_device_handle *)dev, interface);
|
struct libusb_device_descriptor descriptor;
|
||||||
|
libusb_get_device_descriptor(dev, &descriptor);
|
||||||
|
return descriptor.idVendor;
|
||||||
}
|
}
|
||||||
|
|
||||||
int usbbus_release_interface(usbbus_device_handle *dev, int interface)
|
uint16_t usbbus_get_product_id(struct libusb_device *dev) {
|
||||||
{
|
struct libusb_device_descriptor descriptor;
|
||||||
return libusb_release_interface((libusb_device_handle *)dev, interface);
|
libusb_get_device_descriptor(dev, &descriptor);
|
||||||
|
return descriptor.idProduct;
|
||||||
}
|
}
|
||||||
|
|
||||||
int usbbus_set_interface_alt_setting(usbbus_device_handle *dev, int interface, int alternate)
|
|
||||||
{
|
int usbbus_get_num_alternate_settings(struct libusb_device *dev, uint8_t config_idx) {
|
||||||
return libusb_set_interface_alt_setting((libusb_device_handle *)dev, interface, alternate);
|
struct libusb_config_descriptor *usb_config;
|
||||||
|
int r = libusb_get_config_descriptor(dev, config_idx, &usb_config);
|
||||||
|
if (r != 0 || usb_config == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
libusb_free_config_descriptor(usb_config);
|
||||||
|
return usb_config->interface->num_altsetting;
|
||||||
}
|
}
|
||||||
|
|
||||||
int usbbus_reset(usbbus_device_handle *dev)
|
|
||||||
{
|
|
||||||
return libusb_reset_device((libusb_device_handle *)dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *usbbus_strerror(int errcode)
|
|
||||||
{
|
|
||||||
return libusb_strerror((enum libusb_error)errcode);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct usbbus_bus *usbbus_get_busses(void)
|
|
||||||
{
|
|
||||||
return usb_busses;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
* Copyright (C) 2010-2012 Romain Tartière
|
* Copyright (C) 2010-2012 Romain Tartière
|
||||||
* Copyright (C) 2010-2013 Philippe Teuwen
|
* Copyright (C) 2010-2013 Philippe Teuwen
|
||||||
* Copyright (C) 2012-2013 Ludovic Rousseau
|
* Copyright (C) 2012-2013 Ludovic Rousseau
|
||||||
|
* Copyright (C) 2022 Kenspeckle
|
||||||
* See AUTHORS file for a more comprehensive list of contributors.
|
* See AUTHORS file for a more comprehensive list of contributors.
|
||||||
* Additional contributors of this file:
|
* Additional contributors of this file:
|
||||||
*
|
*
|
||||||
@ -25,150 +26,29 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
#ifndef __NFC_BUS_USBBUS_H__
|
||||||
* @file usbbus.h
|
#define __NFC_BUS_USBBUS_H__
|
||||||
* @brief libusb 0.1 driver header
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __NFC_BUS_USB_H__
|
#include <libusb-1.0/libusb.h>
|
||||||
# define __NFC_BUS_USB_H__
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
#define EMPTY_STRING "\0";
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define USBBUS_ERROR_ACCESS -3
|
|
||||||
#define USBBUS_ERROR_TIMEOUT -7
|
|
||||||
|
|
||||||
int usbbus_prepare(void);
|
|
||||||
|
|
||||||
// Libusb-0.1 API:
|
|
||||||
#define USBBUS_ENDPOINT_DIR_MASK 0x80
|
|
||||||
#define USBBUS_ENDPOINT_TYPE_BULK 2
|
|
||||||
#define USBBUS_ENDPOINT_IN 0x80
|
|
||||||
#define USBBUS_ENDPOINT_OUT 0x00
|
|
||||||
|
|
||||||
#ifdef PATH_MAX
|
|
||||||
#define USBBUS_PATH_MAX PATH_MAX
|
|
||||||
#else
|
|
||||||
#define USBBUS_PATH_MAX 4096
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct usbbus_device_handle;
|
|
||||||
typedef struct usbbus_device_handle usbbus_device_handle;
|
|
||||||
|
|
||||||
struct usbbus_endpoint_descriptor {
|
|
||||||
uint8_t bLength;
|
|
||||||
uint8_t bDescriptorType;
|
|
||||||
uint8_t bEndpointAddress;
|
|
||||||
uint8_t bmAttributes;
|
|
||||||
uint16_t wMaxPacketSize;
|
|
||||||
uint8_t bInterval;
|
|
||||||
uint8_t bRefresh;
|
|
||||||
uint8_t bSynchAddress;
|
|
||||||
|
|
||||||
unsigned char *extra;
|
|
||||||
int extralen;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct usbbus_interface_descriptor {
|
|
||||||
uint8_t bLength;
|
|
||||||
uint8_t bDescriptorType;
|
|
||||||
uint8_t bInterfaceNumber;
|
|
||||||
uint8_t bAlternateSetting;
|
|
||||||
uint8_t bNumEndpoints;
|
|
||||||
uint8_t bInterfaceClass;
|
|
||||||
uint8_t bInterfaceSubClass;
|
|
||||||
uint8_t bInterfaceProtocol;
|
|
||||||
uint8_t iInterface;
|
|
||||||
|
|
||||||
struct usbbus_endpoint_descriptor *endpoint;
|
|
||||||
|
|
||||||
unsigned char *extra;
|
|
||||||
int extralen;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct usbbus_interface {
|
|
||||||
struct usbbus_interface_descriptor *altsetting;
|
|
||||||
int num_altsetting;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct usbbus_config_descriptor {
|
|
||||||
uint8_t bLength;
|
|
||||||
uint8_t bDescriptorType;
|
|
||||||
uint16_t wTotalLength;
|
|
||||||
uint8_t bNumInterfaces;
|
|
||||||
uint8_t bConfigurationValue;
|
|
||||||
uint8_t iConfiguration;
|
|
||||||
uint8_t bmAttributes;
|
|
||||||
uint8_t MaxPower;
|
|
||||||
|
|
||||||
struct usbbus_interface *interface;
|
|
||||||
|
|
||||||
unsigned char *extra;
|
|
||||||
int extralen;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Device descriptor */
|
|
||||||
struct usbbus_device_descriptor {
|
|
||||||
uint8_t bLength;
|
|
||||||
uint8_t bDescriptorType;
|
|
||||||
uint16_t bcdUSB;
|
|
||||||
uint8_t bDeviceClass;
|
|
||||||
uint8_t bDeviceSubClass;
|
|
||||||
uint8_t bDeviceProtocol;
|
|
||||||
uint8_t bMaxPacketSize0;
|
|
||||||
uint16_t idVendor;
|
|
||||||
uint16_t idProduct;
|
|
||||||
uint16_t bcdDevice;
|
|
||||||
uint8_t iManufacturer;
|
|
||||||
uint8_t iProduct;
|
|
||||||
uint8_t iSerialNumber;
|
|
||||||
uint8_t bNumConfigurations;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct usbbus_bus;
|
|
||||||
|
|
||||||
struct usbbus_device {
|
struct usbbus_device {
|
||||||
struct usbbus_device *next, *prev;
|
uint16_t vendor_id;
|
||||||
|
uint16_t product_id;
|
||||||
char filename[USBBUS_PATH_MAX + 1];
|
const char *name;
|
||||||
|
uint16_t max_packet_size;
|
||||||
struct usbbus_bus *bus;
|
|
||||||
|
|
||||||
struct usbbus_device_descriptor descriptor;
|
|
||||||
struct usbbus_config_descriptor *config;
|
|
||||||
|
|
||||||
void *dev;
|
|
||||||
|
|
||||||
uint8_t devnum;
|
|
||||||
|
|
||||||
unsigned char num_children;
|
|
||||||
struct usbbus_device **children;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct usbbus_bus {
|
|
||||||
struct usbbus_bus *next, *prev;
|
|
||||||
|
|
||||||
char dirname[USBBUS_PATH_MAX + 1];
|
|
||||||
|
|
||||||
struct usbbus_device *devices;
|
|
||||||
uint32_t location;
|
|
||||||
|
|
||||||
struct usbbus_device *root_dev;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
usbbus_device_handle *usbbus_open(struct usbbus_device *dev);
|
|
||||||
void usbbus_close(usbbus_device_handle *dev);
|
|
||||||
int usbbus_set_configuration(usbbus_device_handle *dev, int configuration);
|
|
||||||
int usbbus_get_string_simple(usbbus_device_handle *dev, int index, char *buf, size_t buflen);
|
|
||||||
int usbbus_bulk_transfer(usbbus_device_handle *dev, int ep, char *bytes, int size, int *actual_length, int timeout);
|
|
||||||
int usbbus_claim_interface(usbbus_device_handle *dev, int interface);
|
|
||||||
int usbbus_release_interface(usbbus_device_handle *dev, int interface);
|
|
||||||
int usbbus_set_interface_alt_setting(usbbus_device_handle *dev, int interface, int alternate);
|
|
||||||
int usbbus_reset(usbbus_device_handle *dev);
|
|
||||||
const char *usbbus_strerror(int errcode);
|
|
||||||
struct usbbus_bus *usbbus_get_busses(void);
|
|
||||||
|
|
||||||
#endif // __NFC_BUS_USB_H__
|
int usbbus_prepare();
|
||||||
|
|
||||||
|
size_t usbbus_usb_scan(char ** connstrings, size_t connstrings_len, struct usbbus_device * nfc_usb_devices, size_t num_nfc_usb_devices, char * usb_driver_name);
|
||||||
|
void usbbus_get_usb_endpoints(struct libusb_device *dev, uint8_t * endpoint_in, uint8_t * endpoint_out, uint16_t * max_packet_size);
|
||||||
|
void usbbus_get_usb_device_name(struct libusb_device * dev, libusb_device_handle *udev, char *buffer, size_t len);
|
||||||
|
void usbbus_get_device(uint8_t dev_address, struct libusb_device * dev, struct libusb_device_handle * dev_handle);
|
||||||
|
uint16_t usbbus_get_vendor_id(struct libusb_device * dev);
|
||||||
|
uint16_t usbbus_get_product_id(struct libusb_device * dev);
|
||||||
|
int usbbus_get_num_alternate_settings(struct libusb_device *dev, uint8_t config_idx);
|
||||||
|
#endif
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user