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.
I do a variety of different kinds of data analysis and numerical simulation on my custom-built Ubuntu machine using custom-written programs that sometimes must run for days or even weeks. Some of those programs have been in Fortran, some in Python, some in C; there is literally zero commonality between these programs except that they run a long time and do a lot of disk i/o. Most are single-thread.
The typical execution command line looks like
./myprog &> myprog.log &
If an ordinary runtime error occurs, any buffered program output and the error message both faithfully appear in myprog.log and the logfile is cleanly closed. But what's been happening instead in many cases is that the program simply quits in mid-stream -- usually after half a day to a day or so, without any further output to the log file. It's like the program had been randomly hit with a 'kill -9'.
I don't know why this is happening, and it seems to be specific to this particular machine (I have been doing similar work for 30 years and never experienced this before). The operating system itself seems rock-stable; it has been rebooted only rarely over the past couple years for specific reasons like updates. It's only my longer-running user processes that seem to die abruptly like this with no accompanying diagnostic.
Not being a system-level expert, I'm at a loss for how to diagnose what's going on. Right now, my only option is to regularly check whether my program is still running and restart it if necessary.
System details:
Ubuntu 18.04.4 LTS
Linux kernel: 4.15.0-39-generic
CPU: AMD Ryzen Threadripper 1950x
UPDATE: Since dmesg was mentioned, here are some representive messages, which I have no idea how to interpret. The UFW BLOCK messages are by far the most numerous, but there are also a fair number of the ata6 messages, which seem to have something to do with the SATA hard drive. Could this be relevant?
[5301325.692596] audit: type=1400 audit(1594876149.572:218): apparmor="DENIED" operation="open" profile="/usr/sbin/cups-browsed" name="/usr/share/locale/" pid=19663 comm="cups-browsed" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
[5352288.689739] ata6.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6 frozen
[5352288.689753] ata6.00: cmd a0/00:00:00:08:00/00:00:00:00:00/a0 tag 14 pio 16392 in
Get event status notification 4a 01 00 00 10 00 00 00 08 00res 40/00:03:00:00:00/00:00:00:00:00/a0 Emask 0x4 (timeout)
[5352288.689756] ata6.00: status: { DRDY }
[5352288.689760] ata6: hard resetting link
[5352289.161877] ata6: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
[5352289.166076] ata6.00: configured for PIO0
[5352289.166635] ata6: EH complete
[5353558.066052] [UFW BLOCK] IN=enp5s0 OUT= MAC=10:7b:44:93:2f:58:b4:0c:25:e0:40:12:08:00 SRC=172.105.89.161 DST=144.92.130.162 LEN=40 TOS=0x00 PREC=0x00 TTL=243 ID=50780 PROTO=TCP SPT=58944 DPT=68 WINDOW=1024 RES=0x00 SYN URGP=0
I'm trying to download Xcode (onto version El Capitan) and it seems to be stuck. When I run 'top', I see a process called 'storedownloadd' and the "STATE" column is alternating between sleeping, stuck,and running. The 'FAULTS' has a quickly increasing number with a plus sign after it. The 'FAULTS' column is now over 400,000 and increasing. other than 'top', I see no sign of activity of the download. Does this indicate that something is amiss? Here's a screen shot:
Processes: 203 total, 2 running, 10 stuck, 191 sleeping, 795 threads 11:48:14
Load Avg: 4.72, 3.24, 1.69 CPU usage: 56.54% user, 6.41% sys, 37.3% idle SharedLibs: 139M resident, 19M data, 20M linkedit. MemRegions: 18620 total, 880M resident, 92M private, 255M shared. PhysMem: 7812M used (922M wired), 376M unused.
VM: 564G vsize, 528M framework vsize, 0(0) swapins, 512(0) swapouts. Networks: packets: 122536/172M in, 27316/2246K out. Disks: 78844/6532M read, 240500/6746M written.
PID COMMAND %CPU TIME #TH #WQ #PORT MEM PURG CMPRS PGRP PPID STATE BOOSTS %CPU_ME %CPU_OTHRS UID FAULTS COW MSGSENT MSGRECV SYSBSD SYSMACH
354 storedownloadd 0.3 00:47.58 16 5 200 255M 0B 0B 354 1 sleeping *3[1] 155.53838 0.00000 501 412506+ 54329 359852+ 6620+ 2400843+ 1186426+
57 UserEventAgent 0.0 00:00.35 22 17 378 4524K+ 0B 0B 57 1 sleeping *0[1] 0.23093 0.00000 0 7359+ 235 15403+ 7655+ 24224+ 17770
384 Terminal 3.3 00:12.02 10 4 213 34M+ 12K 0B 384 1 sleeping *0[42] 0.11292 0.04335 501 73189+ 482 31076+ 9091+ 1138809+ 72076+
When top reports back FAULTS it's referring to "page faults", which are more specifically:
The number of major page faults that have occurred for a task. A page
fault occurs when a process attempts to read from or write to a
virtual page that is not currently present in its address space. A
major page fault is when disk access is involved in making that page
available.
If an application tries to access an address on a memory page that is not currently in physical RAM, a page fault occurs. When that happens, the virtual memory system invokes a special page-fault handler to respond to the fault immediately. The page-fault handler stops the code from executing, locates a free page of physical memory, loads the page containing the data needed from disk, updates the page table, and finally returns control to the program — which can then access the memory address normally. This process is known as paging.
Minor page faults can be common depending on the code that is attempting to execute and the current memory availability on the system, however, there are also different levels to be aware of (minor, major, invalid), which are described in more detail at the links below.
↳ Apple : About The Virtual Memory System
↳ Wikipedia : Page Fault
↳ Stackoverflow.com : page-fault
I am trying to connect to Atmega328P chip through eXtreme Burner. I used 22pf capacitors and 10K pull for reset.
I am able to read the chip if I use 8 MHz Crystal. But cannot read if I connect 16MHz crystal. When I looked at the datasheet, it says fuse bits are same for 8 MHz and 16 MHz. I get "Power On Failed" error message with 16 MHz. I am using USBASP programmer.
Please note: With 8 MHz crystal, though I am able to read the device, I get error message "Incorrect Chip Found! Continue". If I press OK, it reads the data. The fuse bits read using 8 MHz crystal are: Low-- FF, High - DE, Extended -- FD, Lock Fuse - CF and Calibration - FFFFFFB1
What could be the issue?
Attached screen shots in the link
http://www.filedropper.com/extremeburnererrors
Its not in your settings then, so it must be in the setup of your hardware. Try different capacitor values. If I remember correctly, you have to vary the value of the capacitors as the frequency of your crystal varies. Also you have to take in to account the added inductance and capacitance of the breadboard or pcb and solder. So I would suggest just trial and error with different capacitor values.
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.