|
|
@@ -1,829 +0,0 @@
|
|
|
-#include "USBMicroX.h"
|
|
|
-#define UNLESS(S) if(!(S))
|
|
|
-
|
|
|
-#define USBMX_ID_PRODUCT 0x01A5
|
|
|
-#define USBMX_ID_VENDOR 0x0DE7
|
|
|
-
|
|
|
-static long dict_get_long(CFDictionaryRef properties, CFStringRef key)
|
|
|
-{
|
|
|
- long number;
|
|
|
- CFTypeRef value = CFDictionaryGetValue(properties, key);
|
|
|
- if (!value) return 0;
|
|
|
- CFTypeID type = CFGetTypeID(value);
|
|
|
- if (type != CFNumberGetTypeID()) return 0 ;
|
|
|
- CFNumberGetValue((CFNumberRef)value, kCFNumberLongType, (void *)&number);
|
|
|
- return number;
|
|
|
-}
|
|
|
-
|
|
|
-static char* dict_get_string(CFDictionaryRef properties, CFStringRef key, CFStringEncoding encoding)
|
|
|
-{
|
|
|
- static char cstring[512];
|
|
|
- CFTypeRef value = CFDictionaryGetValue(properties, key);
|
|
|
- if (!value) return "";
|
|
|
- CFTypeID type = CFGetTypeID(value) ;
|
|
|
- if (type != CFStringGetTypeID()) return "";
|
|
|
- CFStringGetCString((CFStringRef)value, cstring, sizeof(cstring), encoding);
|
|
|
- return cstring; // WARNING: be sure to copy string after return
|
|
|
-}
|
|
|
-
|
|
|
-static void nsp(int L) {
|
|
|
- int i = 0;
|
|
|
- while(i++ < L) printf(" ");
|
|
|
-}
|
|
|
-
|
|
|
-static void cftype_dump(CFTypeRef o, int L);
|
|
|
-
|
|
|
-static void cftype_dump_arrayapply(const void *value, void *context) {
|
|
|
- int L = (int)context;
|
|
|
- nsp(L); printf("0x%08x\n", value);
|
|
|
- cftype_dump((CFTypeRef)value, L+1);
|
|
|
-}
|
|
|
-
|
|
|
-static void cftype_dump_dictapply (const void *key, const void *value, void *context) {
|
|
|
- int L = (int)context;
|
|
|
- nsp(L); printf("\"%s\" => 0x%08x\n",
|
|
|
- CFStringGetCStringPtr(key, CFStringGetSystemEncoding()), value);
|
|
|
- cftype_dump((CFTypeRef)value, L+1);
|
|
|
-}
|
|
|
-
|
|
|
-static void cftype_dump(CFTypeRef o, int L)
|
|
|
-{
|
|
|
- if(CFGetTypeID(o) == CFArrayGetTypeID()) {
|
|
|
- nsp(L); printf("[\n");
|
|
|
- CFArrayApplyFunction(
|
|
|
- o,
|
|
|
- CFRangeMake(0, CFArrayGetCount(o)),
|
|
|
- cftype_dump_arrayapply,
|
|
|
- (void*)(L+1));
|
|
|
- nsp(L); printf("]\n");
|
|
|
- } else if(CFGetTypeID(o) == CFDictionaryGetTypeID()) {
|
|
|
- nsp(L); printf("{\n");
|
|
|
- CFDictionaryApplyFunction(
|
|
|
- o,
|
|
|
- cftype_dump_dictapply,
|
|
|
- (void*)(L+1));
|
|
|
- nsp(L); printf("}\n");
|
|
|
- } else if(CFGetTypeID(o) == CFNumberGetTypeID()) {
|
|
|
- long number;
|
|
|
- CFNumberGetValue((CFNumberRef)o, kCFNumberLongType, (void*)&number);
|
|
|
- nsp(L); printf("number: 0x%08x\n", number);
|
|
|
- } else if(CFGetTypeID(o) == CFStringGetTypeID()) {
|
|
|
- const char *s = CFStringGetCStringPtr(o, CFStringGetSystemEncoding());
|
|
|
- nsp(L); printf("string: \"%s\"\n", s);
|
|
|
- } else if(CFGetTypeID(o) == CFBooleanGetTypeID()) {
|
|
|
- nsp(L); printf("boolean: %s\n", CFBooleanGetValue(o)?"TRUE":"FALSE");
|
|
|
- } else {
|
|
|
- nsp(L); printf("??? unknown type\n");
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_DeviceAddedHandler(
|
|
|
- USBmX_ContextRef ctx,
|
|
|
- USBmX_DeviceAddedProc proc,
|
|
|
- void *cookie)
|
|
|
-{
|
|
|
- ctx->deviceAdded = proc;
|
|
|
- ctx->deviceAdded_cookie = cookie;
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_DeviceRemovedHandler(
|
|
|
- USBmX_ContextRef ctx,
|
|
|
- USBmX_DeviceRemovedProc proc,
|
|
|
- void *cookie)
|
|
|
-{
|
|
|
- ctx->deviceRemoved = proc;
|
|
|
- ctx->deviceRemoved_cookie = cookie;
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_DeviceInfo(USBmX_DeviceRef dev)
|
|
|
-{
|
|
|
- if(!dev) goto err;
|
|
|
- cftype_dump(dev->properties, 0);
|
|
|
- return 0;
|
|
|
-err:
|
|
|
- return -1;
|
|
|
-}
|
|
|
-
|
|
|
-static void DumpBuffer(const u_char buf[], unsigned int buf_size)
|
|
|
-{
|
|
|
- const u_char *p = buf;
|
|
|
- while(buf_size--) printf("0x%02x ", *p++);
|
|
|
- printf("\n");
|
|
|
-}
|
|
|
-
|
|
|
-void USBmX_DumpCommand(u_char buf[])
|
|
|
-{
|
|
|
- DumpBuffer(buf, 8);
|
|
|
-}
|
|
|
-
|
|
|
-void DeviceAddedHandler(void *refCon, io_iterator_t iterator)
|
|
|
-{
|
|
|
- #if USBMX_DEBUG_LOG
|
|
|
- USBMX_LOG("Device added notification");
|
|
|
- #endif
|
|
|
- io_object_t o;
|
|
|
- USBmX_ContextRef ctx;
|
|
|
- // Must iterate in order to re-arm notification
|
|
|
- while(o = IOIteratorNext(iterator)) {
|
|
|
- IOObjectRelease(o);
|
|
|
- }
|
|
|
- ctx = (USBmX_ContextRef)refCon;
|
|
|
- #if USBMX_DEBUG_LOG
|
|
|
- USBMX_LOG("ctx = %x", ctx);
|
|
|
- #endif
|
|
|
- USBmX_ScanForDevices(ctx);
|
|
|
-}
|
|
|
-
|
|
|
-void DestroyDeviceRef(USBmX_DeviceRef d)
|
|
|
-{
|
|
|
- #if USBMX_DEBUG_LOG
|
|
|
- USBMX_LOG("Destroying: %x %x %x %x", d->properties, d->serialNumber, d->interface, d);
|
|
|
- #endif
|
|
|
- CFRelease(d->properties);
|
|
|
- free((void *)d->serialNumber);
|
|
|
- free((void *)d->deviceName);
|
|
|
- free((void *)d->manufacturer);
|
|
|
- (*d->interface)->close(d->interface);
|
|
|
- free(d);
|
|
|
-}
|
|
|
-
|
|
|
-void DeviceRemovedHandler(void *target, IOReturn result, void *refcon, void *sender)
|
|
|
-{
|
|
|
- USBmX_DeviceRef d = (USBmX_DeviceRef)refcon;
|
|
|
- USBmX_ContextRef ctx = d->ctx;
|
|
|
- #if USBMX_DEBUG_LOG
|
|
|
- USBMX_LOG("Device Removed (# %s)", d->serialNumber);
|
|
|
- #endif
|
|
|
-
|
|
|
- USBmX_DeviceRef p = ctx->deviceList;
|
|
|
- USBmX_DeviceRef pl = NULL;
|
|
|
- while(p) {
|
|
|
- if(p == d)
|
|
|
- {
|
|
|
- if(pl == NULL) ctx->deviceList = d->next;
|
|
|
- else pl->next = d->next;
|
|
|
- ////////////////////////////
|
|
|
- //USBMX_LOG("NEED TO CALL DEVICE REMOVED CALLBACK");
|
|
|
- if(ctx->deviceRemoved)
|
|
|
- {
|
|
|
- (*ctx->deviceRemoved)(d, ctx->deviceRemoved_cookie);
|
|
|
- }
|
|
|
- ////////////////////////////
|
|
|
- DestroyDeviceRef(d);
|
|
|
- break;
|
|
|
- }
|
|
|
- pl = p;
|
|
|
- p = p->next;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-static void InterruptReportHandler(
|
|
|
- void *target,
|
|
|
- IOReturn result,
|
|
|
- void *refcon,
|
|
|
- void *sender,
|
|
|
- UInt32 bufferSize)
|
|
|
-{
|
|
|
- USBmX_DeviceRef d = (USBmX_DeviceRef)target;
|
|
|
-
|
|
|
- #if USBMX_DEBUG_LOG
|
|
|
- printf("Response: ");
|
|
|
- DumpBuffer(d->response_buffer, bufferSize);
|
|
|
- #endif
|
|
|
-
|
|
|
- d->response_ready = 1;
|
|
|
-}
|
|
|
-
|
|
|
-static int SetReport(USBmX_DeviceRef d, const u_char *buf, unsigned int buf_size)
|
|
|
-{
|
|
|
- #if USBMX_DEBUG_LOG
|
|
|
- printf("Report: "); DumpBuffer(buf, buf_size);
|
|
|
- #endif
|
|
|
- d->response_ready = 0;
|
|
|
- IOReturn rc = (*d->interface)->setReport(
|
|
|
- d->interface,
|
|
|
- kIOHIDReportTypeFeature,
|
|
|
- 0, //reportID
|
|
|
- (void *)buf,
|
|
|
- buf_size,
|
|
|
- 1000, //timeout
|
|
|
- NULL,
|
|
|
- NULL,
|
|
|
- NULL
|
|
|
- );
|
|
|
- while(!d->response_ready) {
|
|
|
- SInt32 r = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.001, false);
|
|
|
- #if USBMX_DEBUG_LOG
|
|
|
- printf("wait r=%x\n", r);
|
|
|
- #endif
|
|
|
- }
|
|
|
- if(rc != kIOReturnSuccess) {
|
|
|
- USBMX_LOG("SetReport: (*interface)->setReport() Error %x", rc);
|
|
|
- return -1;
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_DeviceCount(USBmX_ContextRef ctx)
|
|
|
-{
|
|
|
- if(!ctx) return 0;
|
|
|
- USBmX_DeviceRef d = ctx->deviceList;
|
|
|
- int count = 0;
|
|
|
- while(d) {
|
|
|
- ++count;
|
|
|
- d = d->next;
|
|
|
- }
|
|
|
- return count;
|
|
|
-}
|
|
|
-
|
|
|
-USBmX_DeviceRef USBmX_DefaultDevice(USBmX_ContextRef ctx)
|
|
|
-{
|
|
|
- if(ctx) return ctx->deviceList;
|
|
|
- return NULL;
|
|
|
-}
|
|
|
-
|
|
|
-USBmX_DeviceRef USBmX_DeviceWithSerial(USBmX_ContextRef ctx, const char *serial)
|
|
|
-{
|
|
|
- if(!ctx || !serial) return NULL;
|
|
|
- USBmX_DeviceRef dev = ctx->deviceList;
|
|
|
- #if USBMX_DEBUG_LOG
|
|
|
- USBMX_LOG("Searching for device...");
|
|
|
- #endif
|
|
|
- while(dev) {
|
|
|
- if(!strcmp(serial, dev->serialNumber))
|
|
|
- {
|
|
|
- #if USBMX_DEBUG_LOG
|
|
|
- USBMX_LOG("Device found! %x (# %s)", dev, dev->serialNumber);
|
|
|
- #endif
|
|
|
- return dev;
|
|
|
- }
|
|
|
- dev = dev->next;
|
|
|
- }
|
|
|
- #if USBMX_DEBUG_LOG
|
|
|
- USBMX_LOG("Device not found");
|
|
|
- #endif
|
|
|
- return NULL;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_RawCommand(USBmX_DeviceRef dev,
|
|
|
- const u_char command[8],
|
|
|
- u_char response[8])
|
|
|
-{
|
|
|
- if(!dev) goto err;
|
|
|
- if(SetReport(dev, command, 8) < 0) goto err;
|
|
|
- if(response) {
|
|
|
- memcpy(response, dev->response_buffer, 8);
|
|
|
- }
|
|
|
- return 0;
|
|
|
-err:
|
|
|
- return -1;
|
|
|
-}
|
|
|
-
|
|
|
-static int CreateDeviceRef(USBmX_ContextRef ctx, io_object_t dev, USBmX_DeviceRef *dev_out)
|
|
|
-{
|
|
|
- IOReturn rc;
|
|
|
- kern_return_t result;
|
|
|
-
|
|
|
- USBmX_DeviceRef dr = USBMX_ALLOC(USBmX_Device);
|
|
|
- dr->next = NULL;
|
|
|
- dr->ctx = ctx;
|
|
|
- dr->userData = NULL;
|
|
|
-
|
|
|
- // Get device properties
|
|
|
- result = IORegistryEntryCreateCFProperties(
|
|
|
- dev, &dr->properties,
|
|
|
- kCFAllocatorDefault, kNilOptions);
|
|
|
- if(result != KERN_SUCCESS || !dr->properties) {
|
|
|
- USBMX_LOG("IORegistryEntryCreateCFProperties Error %x", result);
|
|
|
- goto err;
|
|
|
- }
|
|
|
-
|
|
|
- dr->serialNumber = strdup(
|
|
|
- dict_get_string(
|
|
|
- dr->properties,
|
|
|
- CFSTR(kIOHIDSerialNumberKey),
|
|
|
- CFStringGetSystemEncoding()));
|
|
|
- dr->deviceName = strdup(
|
|
|
- dict_get_string(
|
|
|
- dr->properties,
|
|
|
- CFSTR(kIOHIDProductKey),
|
|
|
- CFStringGetSystemEncoding()));
|
|
|
- dr->manufacturer = strdup(
|
|
|
- dict_get_string(
|
|
|
- dr->properties,
|
|
|
- CFSTR(kIOHIDManufacturerKey),
|
|
|
- CFStringGetSystemEncoding()));
|
|
|
-
|
|
|
- // Add device to head of list if we don't already have it
|
|
|
- if(USBmX_DeviceWithSerial(ctx, dr->serialNumber) == NULL)
|
|
|
- {
|
|
|
- #if USBMX_DEBUG_LOG
|
|
|
- USBMX_LOG("Adding device");
|
|
|
- #endif
|
|
|
- dr->next = ctx->deviceList;
|
|
|
- ctx->deviceList = dr;
|
|
|
- } else {
|
|
|
- #if USBMX_DEBUG_LOG
|
|
|
- USBMX_LOG("Already have device");
|
|
|
- #endif
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
- #if USBMX_DEBUG_LOG
|
|
|
- USBMX_LOG("Found Device (# %s)", dr->serialNumber);
|
|
|
- USBMX_LOG("kIOHIDManufacturerKey: \"%s\"",
|
|
|
- dict_get_string(dr->properties,
|
|
|
- CFSTR(kIOHIDManufacturerKey), CFStringGetSystemEncoding()));
|
|
|
- #endif
|
|
|
-
|
|
|
- { // Set up the device
|
|
|
- SInt32 score = 0;
|
|
|
- IOCFPlugInInterface **plugIn;
|
|
|
-
|
|
|
- if((rc = IOCreatePlugInInterfaceForService(
|
|
|
- dev,
|
|
|
- kIOHIDDeviceUserClientTypeID,
|
|
|
- kIOCFPlugInInterfaceID,
|
|
|
- &plugIn, &score)) != kIOReturnSuccess)
|
|
|
- {
|
|
|
- USBMX_LOG("IOCreatePlugInInterfaceForService Error %x", rc);
|
|
|
- goto err;
|
|
|
- }
|
|
|
-
|
|
|
- // Grab interface
|
|
|
- IOHIDDeviceInterface **interface;
|
|
|
- HRESULT prc;
|
|
|
- prc = (*plugIn)->QueryInterface(plugIn,
|
|
|
- CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID),
|
|
|
- (LPVOID)&interface);
|
|
|
- (*plugIn)->Release(plugIn);
|
|
|
- if(prc != S_OK) {
|
|
|
- USBMX_LOG("QueryInterface Error %x", prc);
|
|
|
- goto err;
|
|
|
- }
|
|
|
-
|
|
|
- dr->interface = interface;
|
|
|
-
|
|
|
- // Set up removal callback
|
|
|
- if((rc = (*interface)->setRemovalCallback(interface,
|
|
|
- DeviceRemovedHandler, NULL, (void *)dr)) != kIOReturnSuccess)
|
|
|
- {
|
|
|
- USBMX_LOG("(*interface)->setRemovalCallback() Error %x", rc);
|
|
|
- goto err1;
|
|
|
- }
|
|
|
-
|
|
|
- if((rc = (*interface)->open(interface, 0)) != kIOReturnSuccess)
|
|
|
- {
|
|
|
- USBMX_LOG("(*interface)->open() Error %x", rc);
|
|
|
- goto err1;
|
|
|
- }
|
|
|
-
|
|
|
- mach_port_t async_port;
|
|
|
- if((rc = (*interface)->createAsyncPort(interface, &async_port)) != kIOReturnSuccess)
|
|
|
- {
|
|
|
- USBMX_LOG("(*interface)->createAsyncPort() Error %x", rc);
|
|
|
- goto err1;
|
|
|
- }
|
|
|
-
|
|
|
- CFRunLoopSourceRef rl_source;
|
|
|
- if((rc = (*interface)->createAsyncEventSource(interface, &rl_source)) != kIOReturnSuccess)
|
|
|
- {
|
|
|
- USBMX_LOG("(*interface)->createAsyncEventSource() Error %x", rc);
|
|
|
- goto err1;
|
|
|
- }
|
|
|
-
|
|
|
- CFRunLoopAddSource(
|
|
|
- CFRunLoopGetCurrent(),
|
|
|
- rl_source,
|
|
|
- kCFRunLoopDefaultMode);
|
|
|
- if((rc = ((IOHIDDeviceInterface122*)*interface)->setInterruptReportHandlerCallback(
|
|
|
- interface,
|
|
|
- dr->response_buffer,
|
|
|
- USBMX_RESPONSE_BUFFER_SIZE,
|
|
|
- InterruptReportHandler,
|
|
|
- (void *)dr,
|
|
|
- NULL)) != kIOReturnSuccess)
|
|
|
- {
|
|
|
- USBMX_LOG("(*interface)->setInterruptReportHandlerCallback() Error %x", rc);
|
|
|
- goto err1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- *dev_out = dr;
|
|
|
- ////////////////
|
|
|
- //USBMX_LOG("NEED TO CALL DEVICE ADDED CALLBACK");
|
|
|
- if(ctx->deviceAdded)
|
|
|
- {
|
|
|
- (*ctx->deviceAdded)(dr, ctx->deviceAdded_cookie);
|
|
|
- }
|
|
|
- ////////////////
|
|
|
- return 0;
|
|
|
-err1:
|
|
|
- (*dr->interface)->Release(dr->interface);
|
|
|
-err:
|
|
|
- IOObjectRelease(dev);
|
|
|
- free(dr);
|
|
|
- return -1;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_ScanForDevices(USBmX_ContextRef ctx)
|
|
|
-{
|
|
|
- IOReturn rc;
|
|
|
- io_iterator_t iterator;
|
|
|
- io_object_t d;
|
|
|
- int n_devices = 0;
|
|
|
-
|
|
|
- CFRetain(ctx->matchingDict);
|
|
|
-
|
|
|
- // Narrow it down to devices matching vendor and product IDs
|
|
|
- if(rc = IOServiceGetMatchingServices(
|
|
|
- kIOMasterPortDefault,
|
|
|
- ctx->matchingDict,
|
|
|
- &iterator) != kIOReturnSuccess)
|
|
|
- {
|
|
|
- USBMX_LOG("IOServiceGetMatchingServices Error %x", rc);
|
|
|
- goto err;
|
|
|
- }
|
|
|
-
|
|
|
- // Iterate over each found device
|
|
|
- while(d = IOIteratorNext(iterator))
|
|
|
- {
|
|
|
- USBmX_DeviceRef dev;
|
|
|
- if(CreateDeviceRef(ctx, d, &dev) < 0) goto err1;
|
|
|
- n_devices++;
|
|
|
- }
|
|
|
-
|
|
|
- IOObjectRelease(iterator);
|
|
|
-
|
|
|
-noerr:
|
|
|
- return n_devices;
|
|
|
-err1:
|
|
|
- IOObjectRelease(iterator);
|
|
|
-err:
|
|
|
- USBMX_LOG("USBmX_FindDevices Failed!");
|
|
|
- return -1;
|
|
|
-}
|
|
|
-
|
|
|
-USBmX_ContextRef USBmX_Create(void)
|
|
|
-{
|
|
|
- USBmX_ContextRef ctx = NULL;
|
|
|
- if(ctx = USBMX_ALLOC(USBmX_Context))
|
|
|
- {
|
|
|
- ctx->deviceList = NULL;
|
|
|
- ctx->matchingDict = NULL;
|
|
|
- ctx->deviceAdded = NULL;
|
|
|
- ctx->deviceRemoved = NULL;
|
|
|
- ctx->deviceAdded_cookie = NULL;
|
|
|
- ctx->deviceRemoved_cookie = NULL;
|
|
|
- }
|
|
|
- return ctx;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_Begin(USBmX_ContextRef ctx)
|
|
|
-{
|
|
|
-// USBmX_ContextRef ctx = USBMX_ALLOC(USBmX_Context);
|
|
|
-// ctx->deviceList = NULL;
|
|
|
-// ctx->matchingDict = NULL;
|
|
|
- if(!ctx) return -1;
|
|
|
-
|
|
|
- // Grab root IOKit HID services
|
|
|
- UNLESS(ctx->matchingDict = IOServiceMatching(kIOHIDDeviceKey))
|
|
|
- {
|
|
|
- USBMX_LOG("IOServiceMatching(kIOHIDDeviceKey) Error");
|
|
|
- goto err;
|
|
|
- }
|
|
|
-
|
|
|
- { // Add product and vendor keys to matchingDict
|
|
|
- SInt32 product = USBMX_ID_PRODUCT;
|
|
|
- SInt32 vendor = USBMX_ID_VENDOR;
|
|
|
- CFNumberRef num = NULL;
|
|
|
- #define USBMX_DNA(NAME, VALUE) \
|
|
|
- UNLESS(num = CFNumberCreate( \
|
|
|
- kCFAllocatorDefault, \
|
|
|
- kCFNumberSInt32Type, \
|
|
|
- & VALUE )) { \
|
|
|
- USBMX_LOG("CFNumber Error"); \
|
|
|
- goto err; \
|
|
|
- } \
|
|
|
- CFDictionaryAddValue(ctx->matchingDict, CFSTR(NAME), num); \
|
|
|
- CFRelease(num);
|
|
|
- USBMX_DNA(kIOHIDVendorIDKey, vendor)
|
|
|
- USBMX_DNA(kIOHIDProductIDKey, product)
|
|
|
- #undef USBMX_DNA
|
|
|
- }
|
|
|
-
|
|
|
- { // Set up onPlug handler
|
|
|
- io_iterator_t plugIterator;
|
|
|
- IONotificationPortRef plugPort;
|
|
|
- //CFRunLoopSourceRef runLoopSource;
|
|
|
-
|
|
|
- //CFMutableDictionaryRef hd = IOServiceMatching(kIOHIDDeviceKey);
|
|
|
- CFRetain(ctx->matchingDict);
|
|
|
-
|
|
|
- UNLESS(plugPort = IONotificationPortCreate(kIOMasterPortDefault))
|
|
|
- {
|
|
|
- USBMX_LOG("IONotificationPortCreate error");
|
|
|
- }
|
|
|
-
|
|
|
- CFRunLoopAddSource(
|
|
|
- CFRunLoopGetCurrent(),
|
|
|
- IONotificationPortGetRunLoopSource(plugPort),
|
|
|
- kCFRunLoopDefaultMode);
|
|
|
- if(IOServiceAddMatchingNotification(
|
|
|
- plugPort,
|
|
|
- kIOFirstMatchNotification,
|
|
|
- ctx->matchingDict,
|
|
|
- DeviceAddedHandler,
|
|
|
- (void *)ctx,
|
|
|
- &plugIterator) != KERN_SUCCESS)
|
|
|
- {
|
|
|
- USBMX_LOG("IOServiceAddMatchingNotification error");
|
|
|
- }
|
|
|
- DeviceAddedHandler((void *)ctx, plugIterator);
|
|
|
- }
|
|
|
-
|
|
|
- //if(USBmX_ScanForDevices(ctx) < 0) goto err;
|
|
|
-noerr:
|
|
|
- //return ctx;
|
|
|
- return 0;
|
|
|
-err:
|
|
|
- USBMX_LOG("USBmX_Init Failed!");
|
|
|
- free(ctx);
|
|
|
- //return NULL;
|
|
|
- return -1;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_Destroy(USBmX_ContextRef ctx)
|
|
|
-{
|
|
|
- if(!ctx) return -1;
|
|
|
- free(ctx);
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_InitPorts(USBmX_DeviceRef dev)
|
|
|
-{
|
|
|
- int r;
|
|
|
- u_char res[8];
|
|
|
- static const u_char cmd[8] = {
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00
|
|
|
- };
|
|
|
- r = USBmX_RawCommand(dev, cmd, res);
|
|
|
- if(r < 0) return r;
|
|
|
- if(res[0] != cmd[0]) return -1;
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_WriteA(USBmX_DeviceRef dev, u_char value)
|
|
|
-{
|
|
|
- int r;
|
|
|
- u_char res[8];
|
|
|
- u_char cmd[8] = {
|
|
|
- 0x01,
|
|
|
- value,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00
|
|
|
- };
|
|
|
- r = USBmX_RawCommand(dev, cmd, res);
|
|
|
- if(r < 0) return r;
|
|
|
- if(res[0] != cmd[0]) return -1;
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_WriteB(USBmX_DeviceRef dev, u_char value)
|
|
|
-{
|
|
|
- int r;
|
|
|
- u_char res[8];
|
|
|
- u_char cmd[8] = {
|
|
|
- 0x02,
|
|
|
- value,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00
|
|
|
- };
|
|
|
- r = USBmX_RawCommand(dev, cmd, res);
|
|
|
- if(r < 0) return r;
|
|
|
- if(res[0] != cmd[0]) return -1;
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_WriteABit(USBmX_DeviceRef dev, u_char v_and, u_char v_or)
|
|
|
-{
|
|
|
- int r;
|
|
|
- u_char res[8];
|
|
|
- u_char cmd[8] = {
|
|
|
- 0x03,
|
|
|
- v_and,
|
|
|
- v_or,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00
|
|
|
- };
|
|
|
- r = USBmX_RawCommand(dev, cmd, res);
|
|
|
- if(r < 0) return r;
|
|
|
- if(res[0] != cmd[0]) return -1;
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_WriteBBit(USBmX_DeviceRef dev, u_char v_and, u_char v_or)
|
|
|
-{
|
|
|
- int r;
|
|
|
- u_char res[8];
|
|
|
- u_char cmd[8] = {
|
|
|
- 0x04,
|
|
|
- v_and,
|
|
|
- v_or,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00
|
|
|
- };
|
|
|
- r = USBmX_RawCommand(dev, cmd, res);
|
|
|
- if(r < 0) return r;
|
|
|
- if(res[0] != cmd[0]) return -1;
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_ReadA(USBmX_DeviceRef dev, u_char *value_out)
|
|
|
-{
|
|
|
- int r;
|
|
|
- u_char res[8];
|
|
|
- u_char cmd[8] = {
|
|
|
- 0x05,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00
|
|
|
- };
|
|
|
- r = USBmX_RawCommand(dev, cmd, res);
|
|
|
- if(value_out) *value_out = res[1];
|
|
|
- if(r < 0) return r;
|
|
|
- if(res[0] != cmd[0]) return -1;
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_ReadB(USBmX_DeviceRef dev, u_char *value_out)
|
|
|
-{
|
|
|
- int r;
|
|
|
- u_char res[8];
|
|
|
- u_char cmd[8] = {
|
|
|
- 0x06,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00
|
|
|
- };
|
|
|
- r = USBmX_RawCommand(dev, cmd, res);
|
|
|
- if(value_out) *value_out = res[1];
|
|
|
- if(r < 0) return r;
|
|
|
- if(res[0] != cmd[0]) return -1;
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_SetBit(USBmX_DeviceRef dev, u_char line)
|
|
|
-{
|
|
|
- int r;
|
|
|
- u_char res[8];
|
|
|
- u_char cmd[8] = {
|
|
|
- 0x07,
|
|
|
- line,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00
|
|
|
- };
|
|
|
- r = USBmX_RawCommand(dev, cmd, res);
|
|
|
- if(r < 0) return r;
|
|
|
- if(res[0] != cmd[0]) return -1;
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_ResetBit(USBmX_DeviceRef dev, u_char line)
|
|
|
-{
|
|
|
- int r;
|
|
|
- u_char res[8];
|
|
|
- u_char cmd[8] = {
|
|
|
- 0x08,
|
|
|
- line,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00
|
|
|
- };
|
|
|
- r = USBmX_RawCommand(dev, cmd, res);
|
|
|
- if(r < 0) return r;
|
|
|
- if(res[0] != cmd[0]) return -1;
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_DirectionA(USBmX_DeviceRef dev, u_char dir0, u_char dir1)
|
|
|
-{
|
|
|
- int r;
|
|
|
- u_char res[8];
|
|
|
- u_char cmd[8] = {
|
|
|
- 0x09,
|
|
|
- dir0,
|
|
|
- dir1,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00
|
|
|
- };
|
|
|
- r = USBmX_RawCommand(dev, cmd, res);
|
|
|
- if(r < 0) return r;
|
|
|
- if(res[0] != cmd[0]) return -1;
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_DirectionB(USBmX_DeviceRef dev, u_char dir0, u_char dir1)
|
|
|
-{
|
|
|
- int r;
|
|
|
- u_char res[8];
|
|
|
- u_char cmd[8] = {
|
|
|
- 0x0A,
|
|
|
- dir0,
|
|
|
- dir1,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00,
|
|
|
- 0x00
|
|
|
- };
|
|
|
- r = USBmX_RawCommand(dev, cmd, res);
|
|
|
- if(r < 0) return r;
|
|
|
- if(res[0] != cmd[0]) return -1;
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_StrobeWrite(USBmX_DeviceRef dev,
|
|
|
- u_char data,
|
|
|
- u_char port_select,
|
|
|
- u_char strobe_line,
|
|
|
- u_char pulse_length)
|
|
|
-{
|
|
|
- return -1;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_StrobeRead(USBmX_DeviceRef dev,
|
|
|
- u_char *data_out,
|
|
|
- u_char port_select,
|
|
|
- u_char strobe_line,
|
|
|
- u_char pulse_length)
|
|
|
-{
|
|
|
- return -1;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_StrobeWrites(USBmX_DeviceRef dev,
|
|
|
- u_char n_bytes,
|
|
|
- u_char bytes[])
|
|
|
-{
|
|
|
- return -1;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_InitLCD(USBmX_DeviceRef dev,
|
|
|
- u_char rw_select,
|
|
|
- u_char rs_select,
|
|
|
- u_char port_select,
|
|
|
- u_char e_select)
|
|
|
-{
|
|
|
- return -1;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_LCDCmd(USBmX_DeviceRef dev, u_char cmd)
|
|
|
-{
|
|
|
- return -1;
|
|
|
-}
|
|
|
-
|
|
|
-int USBmX_LCDData(USBmX_DeviceRef dev, u_char data)
|
|
|
-{
|
|
|
- return -1;
|
|
|
-}
|