Mac IOKit USB signal detection - macos
matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vendorId);
CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), numberRef);
CFRelease(numberRef);
numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &deviceProductId);
CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), numberRef);
CFRelease(numberRef);
numberRef = NULL;
kr = IOServiceAddMatchingNotification(gNotifyPort,
kIOFirstMatchNotification,
matchingDict,
DeviceAdded,
NULL,
&gAddedIter);
For handle the notification while add the usb device to Mac pc is ok, but can i getting the signal while user press the button on the usb device?
Thanks ALL!
If a user presses a button on a device, this will not create a device notification. Unless this is a device Apple has a driver for (in which case you may receive an input event, e.g. an NSEvent), you will have to get the device interface and talk to that device through its interface. E.g. USB devices have interfaces, each interface has endpoints and the connections to those endpoints are labeled pipelines. There are outgoing and incoming pipelines and you can send data to or read data from those pipelines. Different kind of pipelines exist, bulk, isochronous and interrupt pipelines. Further every device has a control pipe, the only pipeline you can use bidirectionally.
Apple ships a tool named USB Prober with Xcode, have a look at your USB devices with it. E.g. my Apple Cinema Display, also connected via USB, reports the following:
Full Speed device # 3 (0xFD520000): ............................................. Composite device: "Apple Cinema HD Display"
Port Information: 0x0019
Captive
External Device
Connected
Enabled
Device Descriptor
Descriptor Version Number: 0x0110
Device Class: 0 (Composite)
Device Subclass: 0
Device Protocol: 0
Device MaxPacketSize: 8
Device VendorID/ProductID: 0x05AC/0x9223 (Apple Inc.)
Device Version Number: 0x0114
Number of Configurations: 1
Manufacturer String: 1 "Apple Computer, Inc."
Product String: 2 "Apple Cinema HD Display"
Serial Number String: 0 (none)
Configuration Descriptor
Length (and contents): 34
Raw Descriptor (hex) 0000: 09 02 22 00 01 01 00 E0 01 09 04 00 00 01 03 00
Raw Descriptor (hex) 0010: 00 00 09 21 11 01 00 01 22 37 00 07 05 81 03 08
Raw Descriptor (hex) 0020: 00 10
Number of Interfaces: 1
Configuration Value: 1
Attributes: 0xE0 (self-powered, remote wakeup)
MaxPower: 2 ma
Interface #0 - HID
Alternate Setting 0
Number of Endpoints 1
Interface Class: 3 (HID)
Interface Subclass; 0
Interface Protocol: 0
HID Descriptor
Descriptor Version Number: 0x0111
Country Code: 0
Descriptor Count: 1
Descriptor 1
Type: 0x22 (Report Descriptor)
Length (and contents): 55
Raw Descriptor (hex) 0000: 05 80 09 01 A1 01 15 00 26 FF 00 75 08 85 02 96
Raw Descriptor (hex) 0010: 01 01 09 02 B2 02 01 05 82 95 02 85 10 09 10 B1
Raw Descriptor (hex) 0020: 02 25 04 85 D6 09 D6 B1 02 25 07 85 E7 B1 02 26
Raw Descriptor (hex) 0030: FF 00 85 E4 81 02 C0
Parsed Report Descriptor:
Usage Page (Monitor)
Usage 1 (0x1)
Collection (Application)
Logical Minimum......... (0)
Logical Maximum......... (255)
Report Size............. (8)
ReportID................ (2)
Report Count............ (257)
Usage 2 (0x2)
Feature................. (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Nonvolatile, Buffered bytes)
Usage Page (VESA Virtual Controls)
Report Count............ (2)
ReportID................ (16)
Usage 16 (0x10)
Feature................. (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Nonvolatile, Bitfield)
Logical Maximum......... (4)
ReportID................ (214)
Usage 214 (0xd6)
Feature................. (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Nonvolatile, Bitfield)
Logical Maximum......... (7)
ReportID................ (231)
Feature................. (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Nonvolatile, Bitfield)
Logical Maximum......... (255)
ReportID................ (228)
Input................... (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Bitfield)
End Collection
Endpoint 0x81 - Interrupt Input
Address: 0x81 (IN)
Attributes: 0x03 (Interrupt no synchronization data endpoint)
Max Packet Size: 8
Polling Interval: 16 ms
This device has one Interface, Interface #0 and there exist one endpoint on this interface (0x81), which is connected through an interrupt pipeline, that can transfer packets up to 8 bytes in size every 16 ms. If you'd now want to communicate with that pipeline, you'll have to get the USB driver interface of the device and this interface offers functions to communicate with the pipeline in question, synchronously or asynchronously, it's all pretty similar to network code.
If you now ask yourself, what this pipeline is good for at a monitor in the first place, it's how the monitor communicates button presses to the system. Apple's Cinema Displays have 3 buttons, "+" and "-" for brightness and a power button. The functionality of the power button is configurable in the system prefs, e.g. it can send the whole Mac to sleep if I want that. Whenever I hit one of those button, an interrupt event is created and sent via this USB pipe to the system (actually the system has to poll for such an event every 16 ms, but the system does that for you - your code can pretend the event was pushed by the monitor).
Have a look at the IOUSBDeviceInterface197, and please note, that it inherits of IOUSBDeviceInterface187, which inherits of IOUSBDeviceInterface182, which again inherits of IOUSBDeviceInterface. That means if you retrieve a 197 version of the interface, all methods of the interfaces it inherits from are available for this interface as well (they are just not listed again on the page). Apple has to use interface with versions in the name to stay compatible with older code. Apple extended the USB interfaces over the time (e.g. with new OS X releases) and to be sure that old code still runs, they always added a new interfaces, otherwise they'd break existing code.
Here you get a list of all these interfaces. Yes, the documentation is horrible. You have to learn by try and and/or and sample code. Please note there are DeviceInterfaces and InterfaceInterfaces; that's not the same thing. A DeviceInterface is the driver interface to a device itself, every device can have multiple "USB interfaces" (this is a term of the USB standard) and the interface to such an "usb interface" is named an "InterfaceInterface". Simple devices, as the monitor shown above, only have a single interface, though.
You think that this is darn complicated? Well, most developers from other platforms say, that once they figured out how all this stuff works, Mac OS is the easiest of all platforms if you need raw access to USB pipes. However, it gets even worse: Every interface can have multiple configurations and you can set a configuration on the interface which might change the pipelines (e.g. in one configuration a pipe is a bulk pipe and in another one the very same pipe is now an isochronous pipe). You can see all this in the USB Prober application (it shows alternative configuration). And please note, that an USB device can have a completely different set of interfaces, pipelines and configurations for different speeds (e.g. one for USB 1.2, aka low + full speed, and one for USB 2, aka hi-speed).
Apple tries to explain most of the USB basics you should know before you start writing any code on this page. And if you click on "Working With USB Device Interfaces", Apple even has plenty of sample code for you how to get a DeviceInterface, which you can use to get InterfaceInterfaces.
I hope I could get you some pointers and some interesting links for reading. It's not really the answer to your question, but it is a good start. Of course, you could also write a kernel driver (kernel extension) to add support for your device to the system, so that pressing the button generates an event that any software can handle without having to use IOKit at all... but I somehow doubt you want to go there.
Related
Missing HIDs from Teams
I'm developing a USB HID device that interfaces with Teams. The issue: I get ring-HID for Incoming Teams call, but when I accept the call from the host-- I don't get the hook-off HID, nor any other HID from the same usage-page, like mute or hold. Details: Using pywinusb (from the same windows10 host), I'm able to receive all HIDs. Using Wireshark to sniff usb-- I don't see the off-hook HID from Teams, so I can assume it simply "decides" not to send it to my device. Now, Teams is a real blackbox for me, but I wonder whether anyone has some insights into that (maybe relevant Teams-dev || someone that encountered this issue is the past || fw-dev for Teams-compliant device). The relevant device's HID report descriptor usage page looks like this: Usage Page (LEDs) 05 08 Logical Minimum (0) 15 00 Logical Maximum (1) 25 01 Usage (Off-Hook) 09 17 Usage (Mute) 09 09 Usage (Ring) 09 18 Usage (Hold) 09 20 Usage (Microphone) 09 21 Report Size (1) 75 01 Report Count (5) 95 05 Output (Data,Var,Abs,NWrp,Lin,NPrf,NNul,NVol,Bit) 91 22 EDIT: The device uses Android OS, using linux usb gadget function f_hid via configfs. For this reason I decided to add the linux-related tags.
Getting chip card PAN or PAN sequence with the sequence of APDU commands: how can I get them?
I've got a contactless chip card (not bank or SIM) which I can interact by NFC channel (ISO14443, ISO 7816 Part 4). All I want to get from this card is getting of UID of the card, which can help me to differ one card from others. As I understand this is PAN value which I can get under the tag '5A'. Firstly, I can send this command to the card 00:a4:04:00:0e:32:50:41:59:2e:53:59:53:2e:44:44:46:30:31:00 and get positive answer (SW:9000) with the AID value. So, I have AID and I can send such command 00:a4:04:00:LеnAID:<AID>:00 to open file for reading TLV-based info under different Tag, am I right? But when I send ('5A' - tag for PAN) 00:CA:00:5A:00 I have bad response -> 6E:00 So, 1)Should I change Class value (CLA = 00 for right now)? And for what value? 2)Maybe I have to change INS value for READ RECORD (B0 or B2 or something else) because "The kernel uses the value of the AFL (i.e. tag ‘94’) to issue one or more READ RECORD commands retrieve the Application data elements", in my case tag '5A' for PAN. If so, what the complete workflow should be for getting PAN? UPD. When I sent ff:ca:00:00:00 I receive 6e:00
For unknown for me reason I couldn't get positive answer on command FF:CA:00:00:00 I got answer 6E:00 But I found another way how to get card info. I have to execute not one but a sequence of commands: 1) Firstly I have to find out the AID of the applet. If you know AID you can skip this step (2PAY.SYS.DDF in my case) 00:a4:04:00:0e:32:50:41:59:2e:53:59:53:2e:44:44:46:30:31:00 2) Then SELECT APPLICATION 00 A4 04 00 AID-Lenth AID 3) After that we GET PROCESSING OPTIONS 80 A8 00 00 02 83 00 00 4) And READ RECORD 00 B2 01 14 00 For decoding TLV-response I use this utility - https://www.emvlab.org/tlvutils In response I got not only 5A tag but also others and for right now I have to parse the whole R-APDU for fetching particular tag value. Is there any java-libs for parsing TLV-response?
APDU command to write the Changed PIN into the card
What APDU command gets the PIN from the smart card and write the Changed PIN into the card? For writing the code on card I have found 80 D4 00 00 08 01 02 03 04 05 06 07 08 to set pin 1 2 3 4 5 6 7 8 but we got 6D 00 in response i.e Instruction code not supported or invalid. Or are there any WIN APIs that can be used? Thanks in advance.
Severe misunderstanding: Nothing gets the stored PIN from the card. Using the VERIFY command you can only supply a comparison value and find out, whether it is correct - if it is not, the retry counter will decrease and the PIN may block. There is the standard command CHANGE REFERENCE DATA, see ISO 7816-4, but standard commands have CLA=00 while you currently try CLA=80 (first byte of the command). 6D00 can also be found there and since it means "wrong INS code" the whole command may be wrong. (A PIN consisting of non-printable bytes is also somewhat untypical.) Without knowing, which card you have and which specification it complies to, you will not make significant progress. While WINSCARD may be your friend to get the command transported, it will not help in the respect of finding the correct bytes.
How do I read the Apple Wallet Walgreens Loyalty card using APDU?
Apple Wallet supports the Value Added Services protocol. I want to use this to read the Walgreens loyalty card (the only NFC-enabled loyalty card I have), to better understand the technology. The APDU commands needed for this can be found on page 68 in the NFC.15 spec, where APDU command SELECT FILE is described: http://www.gsma.com/digitalcommerce/wp-content/uploads/2014/07/NFC.15-Version-1.0-Mobile-Commerce-NFC-Coupons-and-Acceptance-Technical-Proposal.pdf Trancieving the following APDU SELECT FILE to the Apple Watch (while having the card selected) 00 A4 04 00 07 A0 00 00 05 59 00 01 00 Returns 6A 82 (File not found) From the documentation I expected this command to select the present loyalty card file, or a special response containing a list of more specific IDs if multiple files are available. What am I doing wrong? Does the Apple Wallet use a custom RID?
Karl, You need the Merchant ID or Application ID. Without the AID (Based on the NFC Spec) you will not be able to get the Customer ID or even get any other data from the Reward pass. Check this blog entry for more details: http://flomio.com/2016/07/nfc-enabled-passes-on-apple-wallet/
In case anyone is wondering if simply specifying a different 2 byte Application Code after the RID of A0 00 00 05 59, which the NFC.15 document assumes is 00 01 will yield a successful file/application selection (SW 90 00), it won't. I tried all 65,536 combinations of these two bytes with no luck. So yes, some additional information is clearly needed. The link above is now dead, so I have raised a support inquiry with Apple Pay (as other posts mention) to see if the documentation required by NFC terminal makers/integrators can be made available under NDA. So far the Apple support team is giving me a bit of a runaround but I think once they understand that I'm seeking non public documentation I'll get the information I need :) I'll keep this post updated if they respond to my inquiry.
Smart Card interaction with ACR122U
I'm trying to write an application that will interact with smart cards using an ACS ACR122U card terminal. According to all that I can find the API uses a combination of standard APDU commands and psuedo-APDUs to interact with the terminal, however psuedo-APDUs don't seem to work as claimed. The API Reference (provided on the ACS site) indicates that APDUs of the form "FF XX XX XX ..." will be interpreted by the terminal (rather than sent to the card) but I always get a response status of "6E XX" (which I interpret as me sending an invalid class ID). I've tried sending commands to flash the LEDs on the terminal using "FF 00 40 0F 04 00 00 00 00" and also tried to get some unique identifier from the card using "FF CA 01 00". I can't find anything useful within the ISO 7816-4 document (the standard for smart cards) and the API reference provided by ACS. Also, ACS are not very forthcoming with information. Does anyone have any ideas as to what I may be doing wrong or where I might look for additional information? I can get an ATR - Answer To Reset from the terminal when a card is connected. I'm developing for interaction with Mifare 1K cards and would like to read from them and interact with the LEDs and buzzer on the terminal.
You can retrieve the API documentation here. This is ACS' proprietary APDUs so don't refer to standard ISO-7816 specification. Refer to section 6 for pseudo-APDU requirements. To simulate LED, refer to section 6.2 for details and appendix E for example. You may try changing your APDU as follow: FF 00 40 FF 04 0A 0A 03 03. Please note that I set the LED control and also put non-zero values for LED duration. For the second APDU, refer to section 4. Please note that you are missing P3/Le in your APDU (shall be FF CA 01 00 00) and you need the card reader connected with PICC.