2013-12-15 6 views
5

का उपयोग करके IOKit का उपयोग करके कॉलबैक प्राप्त करें IOKit पर एक समझ पाने की कोशिश कर रहा हूं और मुझे लगता है कि मैं करीब हूं, लेकिन अभी तक नहीं। तो मेरे भ्रम बहाना।इंटरप्ट इनपुट एंडपॉइंट

मैंने कोड लिखने में कामयाब रहा है जो मेरे यूएसबी डिवाइस का पता लगाता है (एक यूएसबी केबल के अंत में एक साधारण बटन जिसमें विंडोज चालक है, लेकिन कोई मैक ड्राइवर नहीं है)।

बटन दबाए जाने पर मैं कुछ प्रकार की कॉलबैक प्राप्त करने का प्रयास कर रहा हूं।

जब डिवाइस यूएसबी से कनेक्ट होता है या हटा दिया जाता है तो मैं कॉलबैक प्राप्त करता हूं। अब, मैं यह पता लगाने की कोशिश कर रहा हूं कि बटन दबाए जाने पर सूचित कैसे किया जाए, लेकिन मैं इसे समझ नहीं सकता। प्रलेखन मेरे लिए बहुत भ्रमित है, क्योंकि आईओकिट एक सी ++ और सी दोनों उपलब्ध है, इस पर निर्भर करता है कि आप इसे कैसे एक्सेस करते हैं (कर्नेल एक्सटेंशन या उपयोगकर्ता-स्थान चालक, या कुछ इसी तरह। मुझे यकीन नहीं है कि मेरे पास सही शब्दावली है।

जब भी कोई इंटरप्ट वैल्यू बदलता है तो कॉलबैक प्राप्त करने के लिए मैंने कुछ तरीकों को जोड़ने का प्रयास किया है। लेकिन कुछ भी नहीं होता है।

यहां मेरी वर्तमान AppDelegate.m फ़ाइल के साथ-साथ यूएसबी जांच जानकारी भी है । डिवाइस

Low Speed device @ 5 (0x14100000): ............................................. Composite device: "DL100B Dream Cheeky Generic Controller" 
Port Information: 0x101a 
Number Of Endpoints (includes EP0): 
Device Descriptor 
Configuration Descriptor (current config) 
    Length (and contents): 34 
    Number of Interfaces: 1 
    Configuration Value: 1 
    Attributes: 0x80 (bus-powered) 
    MaxPower: 500 mA 
    Interface #0 - HID 
     Alternate Setting 0 
     Number of Endpoints 1 
     Interface Class: 3 (HID) 
     Interface Subclass; 0 
     Interface Protocol: 0 
     HID Descriptor 
     Endpoint 0x81 - Interrupt Input 
      Address: 0x81 (IN) 
      Attributes: 0x03 (Interrupt) 
      Max Packet Size: 8 
      Polling Interval: 10 ms 

अनुप्रयोग Delegate.m फ़ाइल:

// 
// USBHIDAppDelegate.m 
// USBHID 
// 
// Created by Michael Dolinar on 12-05-02. 
// Copyright (c) 2012 __MyCompanyName__. All rights reserved. 
// 

#import "USBHIDAppDelegate.h"  
#import "IOKit/hid/IOHIDManager.h" 
#include <IOKit/IOKitLib.h> 
#include <IOKit/IOCFPlugIn.h> 
#include <IOKit/usb/IOUSBLib.h> 
#include <IOKit/usb/USBSpec.h> 

@implementation USBHIDAppDelegate 

@synthesize window = _window; 

// New USB device specified in the matching dictionary has been added (callback function) 
static void Handle_DeviceMatchingCallback(void *inContext, 
              IOReturn inResult, 
              void *inSender, 
              IOHIDDeviceRef inIOHIDDeviceRef){ 

    // Retrieve the device name & serial number 
    NSString *devName = [NSString stringWithUTF8String: 
         CFStringGetCStringPtr(
               IOHIDDeviceGetProperty(inIOHIDDeviceRef, 
                     CFSTR("Product")), 
               kCFStringEncodingMacRoman)]; 

    UInt32 serialString = CFStringGetCStringPtr(
          IOHIDDeviceGetProperty(inIOHIDDeviceRef, 
               CFSTR("SerialNumber")), 
          kCFStringEncodingMacRoman); 
    NSString *devSerialNumber; 
    if (serialString == 0) { 
     devSerialNumber = @"No Serial Number"; 

    } else { 
     devSerialNumber = [NSString stringWithUTF8String:serialString]; 

    } 
    // Log the device reference, Name, Serial Number & device count 
    NSLog(@"\nDevice added: %p\nModel: %@\nSerial Number:%@\nDevice count: %ld", 
      inIOHIDDeviceRef, 
      devName, 
      devSerialNumber, 
      USBDeviceCount(inSender)); 

//Open the device (Was missing) 
IOReturn err = IOHIDDeviceOpen(inIOHIDDeviceRef, 0); 

// यहाँ त्रुटि के लिए जाँच करना चाहिए ...

IOHIDDeviceRegisterInputValueCallback(inIOHIDDeviceRef, Handle_IOHIDDeviceInputValueCallback, NULL); 

// भी फिर से यहाँ RunLoop के लिए रजिस्टर करना होगा ... भी IOHIDDeviceScheduleWithRunLoop (inIOHIDDeviceRef, CFRunLoopGetCurrent(), kCFRunLoopCommonModes) याद आ रही थी;

} 

static void Handle_IOHIDDeviceInputValueCallback(void *inContext, 
               IOReturn inResult, 
                void *inSender, 
               IOHIDValueRef inIOHIDValueRef 
               ) 
{ 
    NSLog(@"Value changed"); 
} 


// USB device specified in the matching dictionary has been removed (callback function) 
static void Handle_DeviceRemovalCallback(void *inContext, 
             IOReturn inResult, 
             void *inSender, 
             IOHIDDeviceRef inIOHIDDeviceRef){ 

    // Log the device ID & device count 
    NSLog(@"\nDevice removed: %p\nDevice count: %ld", 
      (void *)inIOHIDDeviceRef, 
      USBDeviceCount(inSender)); 
    IOHIDDeviceRegisterInputValueCallback(inIOHIDDeviceRef, NULL, NULL); //Remove callback 

} 





// Counts the number of devices in the device set (incudes all USB devices that match our dictionary) 
static long USBDeviceCount(IOHIDManagerRef HIDManager){ 

    // The device set includes all USB devices that match our matching dictionary. Fetch it. 
    CFSetRef devSet = IOHIDManagerCopyDevices(HIDManager); 

    // The devSet will be NULL if there are 0 devices, so only try to count the devices if devSet exists 
    if(devSet) return CFSetGetCount(devSet); 

    // There were no matching devices (devSet was NULL), so return a count of 0 
    return 0; 
} 


- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    // Insert code here to initialize your application 
    SInt32 idVendor = 0x1D34;//0x062A;//0x1d34; //0x1AAD; //// set vendor id 
    SInt32 idProduct = 0x000D;//0x0000;//0x000d; //0x000F; //// set product id 

    // Create an HID Manager 
    IOHIDManagerRef HIDManager = IOHIDManagerCreate(kCFAllocatorDefault, 
                kIOHIDOptionsTypeNone); 

    // Create a Matching Dictionary 
    CFMutableDictionaryRef matchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 
                   2, 
                   &kCFTypeDictionaryKeyCallBacks, 
                   &kCFTypeDictionaryValueCallBacks); 

    // Specify a device manufacturer in the Matching Dictionary 

    CFDictionarySetValue(matchDict, 
         CFSTR(kIOHIDVendorIDKey), 
         CFNumberCreate(kCFAllocatorDefault, 
             kCFNumberSInt32Type, &idVendor)); 
    CFDictionarySetValue(matchDict, 
         CFSTR(kIOHIDProductKey), 
         CFNumberCreate(kCFAllocatorDefault, 
             kCFNumberSInt32Type, &idProduct)); 


    // Register the Matching Dictionary to the HID Manager 
    IOHIDManagerSetDeviceMatching(HIDManager, matchDict); 

    // Register a callback for USB device detection with the HID Manager 
    IOHIDManagerRegisterDeviceMatchingCallback(HIDManager, &Handle_DeviceMatchingCallback, NULL); 
    // Register a callback fro USB device removal with the HID Manager 
    IOHIDManagerRegisterDeviceRemovalCallback(HIDManager, &Handle_DeviceRemovalCallback, NULL); 

    // Register the HID Manager on our app’s run loop 
    IOHIDManagerScheduleWithRunLoop(HIDManager, CFRunLoopGetMain(), kCFRunLoopDefaultMode); 

    // Open the HID Manager 
    IOReturn IOReturn = IOHIDManagerOpen(HIDManager, kIOHIDOptionsTypeNone); 
    if(IOReturn) NSLog(@"IOHIDManagerOpen failed."); // Couldn't open the HID manager! TODO: proper error handling 
} 
@end 

मैं भी यकीन नहीं डिवाइस कुछ भी भेज रहा है कर रहा हूँ ... मैं, यूएसबी लॉगर का उपयोग लेवल 7 में प्रवेश करने का प्रयास है, लेकिन केवल बटन दबाने कुछ भी प्रदर्शित करने के लिए प्रतीत नहीं होता है ... मैं कैसे कर सकते हैं सुनिश्चित करें कि यह वास्तव में काम कर रहा है?

अपडेट: BigRedButton के लिए this Ruby Open Source project का उपयोग करके बटन प्रेस का पता लगाने में सक्षम था मैं इसे सीखने के लिए उपयोग कर रहा हूं। तो मुझे पता है कि यह वास्तव में काम करता है। मैंने अपने कोड को केवल वैल्यू चेंज के लिए पंजीकृत करने के लिए फिर से काम किया जब डिवाइस वास्तव में पता चला और डिवाइस को हटा दिए जाने पर इसे हटा दिया गया। इस बिंदु पर अभी भी कुछ नहीं।

अद्यतन 2: इसे काम करने के लिए मिला! दो मुद्दे ... मैं डिवाइस को पढ़ने के लिए नहीं खोल रहा था, और डिवाइस को खुद को वर्तमान रनलूप पर भी पंजीकृत नहीं कर रहा था, जिसकी भी आवश्यकता है। डब्ल्यूडब्ल्यूडीसी 2011 से यूजरलैंड डिवाइस एक्सेस पर एक महान डब्ल्यूडब्ल्यूडीसी वीडियो ने काफी मदद की। मुझे यह भी कहना है कि बिगरेडबटन मैं शायद एक मानक उपकरण नहीं था और कभी भी योजनाबद्ध के रूप में काम नहीं करता था, लेकिन वास्तविक उपकरण मैं काम के साथ काम करना चाहता था और मुझे इनपुट दे रहा था! तो अब यह सब अच्छा है, डब्ल्यूडब्ल्यूडीसी वीडियो के लिए धन्यवाद!

+0

मैं वास्तव में कोड के समान हिस्से का उपयोग कर रहा हूं जो आपके पास माइकल डॉलिनार्स ट्यूटोरियल से है। क्या आप पोस्ट कर सकते हैं या शायद मुझे कोड का हिस्सा भेज सकते हैं जिसमें आप डिवाइस खोलते हैं (केवल छिपा प्रबंधक नहीं) और फिर इसे रन लूप में जोड़ें? यह वह जगह है जहां मैं वर्तमान में अभी अटक गया हूं। –

+0

असल में खरोंच कि मैं देखता हूं कि क्या हुआ, आपके कोड ब्लॉक टूट रहे थे और इसके कुछ हिस्सों को सिर्फ टेक्स्ट की तरह दिख रहा था। –

उत्तर

4

अंत में, उपरोक्त कोड अब काम करता है कि मैंने डिवाइस खोल दिया है और डिवाइस को वर्तमान रनलोप पर निर्धारित किया है। इसके अलावा, बदलते उपकरणों ने मुझे किसी अन्य डिवाइस के साथ काम करने की इजाजत दी जो कि अपने मूल्यों को बदलने का एक और अनुमानित अनुभव प्रदान करता है। मैं सुझाव देता हूं कि डब्ल्यूडब्ल्यूडीसी 2011 से यूजरलैंड डिवाइस एक्सेस वीडियो देखने के लिए यह देखने के लिए कि यह कैसे काम करता है (वीडियो में लगभग 30 मिनट)

अद्यतन: डिवाइस अलग-अलग प्रतिक्रिया क्यों करते हैं, यह थोड़ा जटिल है। सबसे पहले, प्रत्येक यूएसबी एचआईडी डिवाइस में कई "कॉन्फ़िगरेशन" हो सकते हैं और एक डिफ़ॉल्ट एक सक्षम नहीं हो सकता है। आपको इसे स्पष्ट रूप से करना है।फिर, दूसरा भाग डिवाइस से भेजे गए मानों को समझने के बारे में है। यह "छुपा डिवाइस रिपोर्ट डिस्क्रिप्टर" को समझकर किया जाता है जो विवरण में वर्णित प्रत्येक प्रकार के मूल्य (रिपोर्ट कहा जाता है) और इसके बिट्स और बाइट्स की व्यवस्था कैसे की जाती है।

ओएस एक्स पर इसके लिए एक महान पढ़ने New HID Manager APIs for Mac OS X version 10.5 TechNote है। हालांकि यह 10.5 की तारीख है, यह इसका नवीनतम संस्करण है और इसमें सभी उचित कॉल शामिल हैं और यह सब कुछ कैसे काम करता है इसकी बेहतर समझ देता है।

इसके अलावा, वर्णनकर्ताओं के बारे में जानने के लिए, this tutorial सहायक था।

संबंधित मुद्दे