Mailing Lists: Apple Mailing Lists
Image of Mac OS face in stamp
Where are my HID reports going?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Where are my HID reports going?



I have a full-speed, custom HID, I send it a buffer of 8 bytes and it sends me a buffer of 64 bytes at least one per second but up to one every 1msec if it has something to say - I interpret these bytes so, in terms of TN2187, I use "raw data".

I followed the outline described in TN2187 (see below or attached) but my software does not see any input reports. I have an Ellisys Explorer looking at USB and they are definately there. Am I missing a step? Does anyone have an example that works?

I started with "HID LED test tool" and have made edits to that:
I get a Reference to the HID manager
I create a Matching Dictionary with my VID and PID
I open the HID manager and it finds my device
I print out the VID and PID as a check
I set up a callback for the InputReport
I schedule the HIDManager into the RunLoop (to handle the Callback)
I send a HID output report - this works, it then starts sending me input reports
I send another HID output report - this works too
I then wait around (will do more stuff later)


My Handle_IOHIDDeviceIOHIDReportCallback never gets called.  I was
expecting this to get called whenever there is a HID input packet on
the bus.

Looking through the other examples, some create Input Queues. I
haven't done that. Is that needed? Have I missed something dumb?  I am
working through TN2187 "New HID Manager APIs for Mac OS X version
10.5" and, while it is very good, it is missing some key examples.

Many thanks,  John


----- End forwarded message -----

[Attachment stripped: Original attachment type: "text/plain", name: "main.c"]
//
//	File:		main.c
//
//
// ****************************************************
#pragma mark -
#pragma mark * complation directives *
// ----------------------------------------------------

#ifndef FALSE
#define FALSE 0
#define TRUE !FALSE
#endif

// ****************************************************
#pragma mark -
#pragma mark * includes & imports *
// ----------------------------------------------------

#include <CoreFoundation/CoreFoundation.h>
#include <Carbon/Carbon.h>
#include <IOKit/hid/IOHIDLib.h>

// ****************************************************
#pragma mark -
#pragma mark * typedef's, struct's, enums, defines, etc. *
// ----------------------------------------------------

IOHIDDeviceRef MyHIDDevice;
uint8_t* MyReport;
CFIndex ReportSize = 64;
uint8_t Buffer[1024];
int BufferIndex;
int ReportCallbackCalled;

long IOHIDDevice_GetVendorID( IOHIDDeviceRef inIOHIDDeviceRef );
long IOHIDDevice_GetProductID( IOHIDDeviceRef inIOHIDDeviceRef );
void IOHIDDeviceRegisterInputReportCallback(
											IOHIDDeviceRef                  device,
											uint8_t *                       report,
											CFIndex                         reportLength,
											IOHIDReportCallback             callback,
											void *                          context);

// function to get a long device property
// returns FALSE if the property isn't found or can't be converted to a long
static Boolean IOHIDDevice_GetLongProperty(
	IOHIDDeviceRef inDeviceRef,     // the HID device reference
	CFStringRef inKey,              // the kIOHIDDevice key ( as a CFString )
	long * outValue )	{			// address where to return the output value

    Boolean Result = FALSE;
    CFTypeRef tCFTypeRef = IOHIDDeviceGetProperty( inDeviceRef, inKey );
    if ( tCFTypeRef ) {
        // if this is a number
        if ( CFNumberGetTypeID( ) == CFGetTypeID( tCFTypeRef ) ) {
            // get its value
            Result = CFNumberGetValue( ( CFNumberRef ) tCFTypeRef, kCFNumberSInt32Type, outValue );
			}
		}
    return Result;
	}   // IOHIDDevice_GetLongProperty

// Get a HID device's vendor ID ( long )
long IOHIDDevice_GetVendorID( IOHIDDeviceRef inIOHIDDeviceRef ) {
    long result = 0;
    ( void ) IOHIDDevice_GetLongProperty( inIOHIDDeviceRef, CFSTR( kIOHIDVendorIDKey ), &result );
    return result;
	} // IOHIDDevice_GetVendorID

// Get a HID device's product ID ( long )
long IOHIDDevice_GetProductID( IOHIDDeviceRef inIOHIDDeviceRef ) {
    long result = 0;
    ( void ) IOHIDDevice_GetLongProperty( inIOHIDDeviceRef, CFSTR( kIOHIDProductIDKey ), &result );
    return result;
	} // IOHIDDevice_GetProductID


// function to create a matching dictionary for usage page & usage
static CFMutableDictionaryRef CreateMatchingDictionary( UInt32 inVID, UInt32 inPID ) {
	// create a dictionary to add usage page / usages to
	CFMutableDictionaryRef Result = CFDictionaryCreateMutable( kCFAllocatorDefault,
															  2,
															  &kCFTypeDictionaryKeyCallBacks,
															  &kCFTypeDictionaryValueCallBacks );
	if ( Result ) {
		// Add key for device type to refine the matching dictionary.
		CFNumberRef VIDRef = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &inVID );
		if ( VIDRef) {
			CFDictionarySetValue( Result, CFSTR (kIOHIDVendorIDKey ), VIDRef );
			CFRelease( VIDRef );
			}
		CFNumberRef PIDRef = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &inPID );
		if ( PIDRef) {
			CFDictionarySetValue( Result, CFSTR (kIOHIDProductIDKey ), PIDRef );
			CFRelease( PIDRef );
			}
		} else printf( "CFDictionaryCreateMutable failed." );
	return Result;
	}

static void Handle_IOHIDDeviceIOHIDReportCallback(
	void *          inContext,          // context from IOHIDDeviceRegisterInputReportCallback
	IOReturn        inResult,           // completion result for the input report operation
	void *          inSender,           // IOHIDDeviceRef of the device this report is from
	IOHIDReportType inType,             // the report type
	uint32_t        inReportID,         // the report ID
	uint8_t *       inReport,           // pointer to the report data
	CFIndex         inReportLength ) {  // the actual size of the input report
#pragma unused (inContext, inResult, inSender, inType, inReportID, inReportLength)
	ReportCallbackCalled++;
	uint8_t* BufPtr = inReport;
	while (*BufPtr) {
		Buffer[BufferIndex] = *BufPtr++;
		if (BufferIndex < sizeof(Buffer)) BufferIndex++;
		}
	}

int main( int argc, const char * argv[] ) {
#pragma unused ( argc, argv )
//	int i, j;

	printf("\nMcAmon V0.3\n");

	// create a IO HID Manager reference
	IOHIDManagerRef tIOHIDManagerRef = IOHIDManagerCreate( kCFAllocatorDefault, kIOHIDOptionsTypeNone );
	require( tIOHIDManagerRef, Oops );

	// Create a device matching dictionary
	CFDictionaryRef matchingCFDictRef = CreateMatchingDictionary( 0x1ed6, 0xeee7 );
	require( matchingCFDictRef, Oops );

	// set the HID device matching dictionary
	IOHIDManagerSetDeviceMatching( tIOHIDManagerRef, matchingCFDictRef );

	if ( matchingCFDictRef ) CFRelease( matchingCFDictRef );

	// Now open the IO HID Manager reference
	IOReturn tIOReturn = IOHIDManagerOpen( tIOHIDManagerRef, kIOHIDOptionsTypeNone );
	require_noerr( tIOReturn, Oops );

	// and copy out its devices
	CFSetRef deviceCFSetRef = IOHIDManagerCopyDevices( tIOHIDManagerRef );
	require( deviceCFSetRef, Oops );

	// how many devices in the set?
	CFIndex deviceCount = CFSetGetCount( deviceCFSetRef );
	if ( deviceCount != 1 ) return printf("Only one Pacer device is supported\n");

	// Get device ref from the set
	CFSetGetValues( deviceCFSetRef, (const void **) &MyHIDDevice );

	unsigned int VID = (unsigned int) IOHIDDevice_GetVendorID( MyHIDDevice);
	unsigned int PID = (unsigned int) IOHIDDevice_GetProductID( MyHIDDevice);
	printf("\nCheck: VID = %4.4X, PID = %4.4X\n", VID, PID);

// Setup the InReport Handler
	ReportSize = 64;
	MyReport = malloc(ReportSize);
	IOHIDDeviceRegisterInputReportCallback(
		MyHIDDevice,			// IOHIDDeviceRef for the HID device
		MyReport,				// pointer to the report data ( uint8_t's )
		ReportSize,				// number of bytes in the report ( CFIndex )
		Handle_IOHIDDeviceIOHIDReportCallback,   // the callback routine
		NULL );					// context passed to callback

// Schedule the callbacks in the current RunLoop
	IOHIDManagerScheduleWithRunLoop( tIOHIDManagerRef, CFRunLoopGetCurrent( ), kCFRunLoopDefaultMode );

// Kickstart the Pacer monitor via a Reset command
	uint8_t ResetCommand[] = { 0x12, 0, 0, 0, 0, 0, 0, 0xEE };
	tIOReturn = IOHIDDeviceSetReport(
		MyHIDDevice,			// IOHIDDeviceRef for the HID device
		kIOHIDReportTypeOutput, // IOHIDReportType for the report
		0,						// CFIndex for the report ID
		ResetCommand,			// address of report buffer
		sizeof( ResetCommand ));// length of the report

	sleep(2);
	uint8_t DisplayLBACommand[] = { 3, 0, 0, 0, 0, 0, 0, 0xFD };
	tIOReturn = IOHIDDeviceSetReport(
									 MyHIDDevice,		// IOHIDDeviceRef for the HID device
									 kIOHIDReportTypeOutput, // IOHIDReportType for the report
									 0,						// CFIndex for the report ID
									 DisplayLBACommand,			// address of report buffer
									 sizeof( DisplayLBACommand )); // length of the report

	while (1) {
		usleep(1000000);
		}

	if ( tIOHIDManagerRef ) CFRelease( tIOHIDManagerRef );
Oops:	;
	return 0;
} /* main */
 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Usb mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:

This email sent to email@hidden



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2011 Apple Inc. All rights reserved.