Update ControllerListener_mac.cpp to our style guidelines

This commit is contained in:
Micke Prag 2012-09-26 16:31:27 +02:00
parent bc22754f8c
commit c522173296

View file

@ -1,10 +1,17 @@
#include "ControllerListener.h" //
// Copyright (C) 2012 Telldus Technologies AB. All rights reserved.
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include "service/ControllerListener.h"
#include <CoreFoundation/CoreFoundation.h> #include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h> #include <IOKit/IOKitLib.h>
#include <IOKit/IOMessage.h> #include <IOKit/IOMessage.h>
#include <IOKit/IOCFPlugIn.h> #include <IOKit/IOCFPlugIn.h>
#include <IOKit/usb/IOUSBLib.h> #include <IOKit/usb/IOUSBLib.h>
#include <string>
class TellStickData { class TellStickData {
public: public:
@ -22,15 +29,14 @@ public:
io_iterator_t gAddedIter; io_iterator_t gAddedIter;
TelldusCore::EventRef event; TelldusCore::EventRef event;
bool running; bool running;
void addUsbFilter(int vid, int pid); void addUsbFilter(int vid, int pid);
static void DeviceAdded(void *refCon, io_iterator_t iterator); static void DeviceAdded(void *refCon, io_iterator_t iterator);
static void DeviceNotification(void *refCon, io_service_t service, natural_t messageType, void *messageArgument); static void DeviceNotification(void *refCon, io_service_t service, natural_t messageType, void *messageArgument);
}; };
ControllerListener::ControllerListener(TelldusCore::EventRef event) ControllerListener::ControllerListener(TelldusCore::EventRef event)
:Thread() :Thread() {
{
d = new PrivateData; d = new PrivateData;
d->event = event; d->event = event;
d->running = true; d->running = true;
@ -48,135 +54,134 @@ ControllerListener::~ControllerListener() {
} }
void ControllerListener::run() { void ControllerListener::run() {
CFRunLoopSourceRef runLoopSource; CFRunLoopSourceRef runLoopSource;
d->gNotifyPort = IONotificationPortCreate(kIOMasterPortDefault); d->gNotifyPort = IONotificationPortCreate(kIOMasterPortDefault);
runLoopSource = IONotificationPortGetRunLoopSource(d->gNotifyPort); runLoopSource = IONotificationPortGetRunLoopSource(d->gNotifyPort);
d->gRunLoop = CFRunLoopGetCurrent(); d->gRunLoop = CFRunLoopGetCurrent();
CFRunLoopAddSource(d->gRunLoop, runLoopSource, kCFRunLoopDefaultMode); CFRunLoopAddSource(d->gRunLoop, runLoopSource, kCFRunLoopDefaultMode);
d->addUsbFilter(0x1781, 0x0c30); d->addUsbFilter(0x1781, 0x0c30);
d->addUsbFilter(0x1781, 0x0c31); d->addUsbFilter(0x1781, 0x0c31);
// Race check, if destructor was called really close to thread init, // Race check, if destructor was called really close to thread init,
// running might have gone false. Make sure we don't get stuck // running might have gone false. Make sure we don't get stuck
if(d->running) if (d->running) {
CFRunLoopRun(); CFRunLoopRun();
}
} }
void ControllerListener::PrivateData::addUsbFilter(int vid, int pid) { void ControllerListener::PrivateData::addUsbFilter(int vid, int pid) {
CFNumberRef numberRef; CFNumberRef numberRef;
kern_return_t kr; kern_return_t kr;
CFMutableDictionaryRef matchingDict; CFMutableDictionaryRef matchingDict;
matchingDict = IOServiceMatching(kIOUSBDeviceClassName); // Interested in instances of class matchingDict = IOServiceMatching(kIOUSBDeviceClassName); // Interested in instances of class
// IOUSBDevice and its subclasses // IOUSBDevice and its subclasses
if (matchingDict == NULL) { if (matchingDict == NULL) {
return; return;
} }
// Create a CFNumber for the idVendor and set the value in the dictionary // Create a CFNumber for the idVendor and set the value in the dictionary
numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vid); numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vid);
CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), numberRef); CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), numberRef);
CFRelease(numberRef); CFRelease(numberRef);
// Create a CFNumber for the idProduct and set the value in the dictionary // Create a CFNumber for the idProduct and set the value in the dictionary
numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pid); numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pid);
CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), numberRef); CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), numberRef);
CFRelease(numberRef); CFRelease(numberRef);
// Now set up a notification to be called when a device is first matched by I/O Kit.
kr = IOServiceAddMatchingNotification(gNotifyPort, // notifyPort
kIOFirstMatchNotification, // notificationType
matchingDict, // matching
PrivateData::DeviceAdded, // callback
this, // refCon
&gAddedIter // notification
);
// Iterate once to get already-present devices and arm the notification
PrivateData::DeviceAdded(this, gAddedIter);
// Now set up a notification to be called when a device is first matched by I/O Kit.
kr = IOServiceAddMatchingNotification(gNotifyPort, // notifyPort
kIOFirstMatchNotification, // notificationType
matchingDict, // matching
PrivateData::DeviceAdded, // callback
this, // refCon
&gAddedIter // notification
);
// Iterate once to get already-present devices and arm the notification
PrivateData::DeviceAdded(this, gAddedIter);
} }
void ControllerListener::PrivateData::DeviceNotification(void *refCon, io_service_t service, natural_t messageType, void *messageArgument) { void ControllerListener::PrivateData::DeviceNotification(void *refCon, io_service_t service, natural_t messageType, void *messageArgument) {
kern_return_t kr; kern_return_t kr;
if (messageType != kIOMessageServiceIsTerminated) { if (messageType != kIOMessageServiceIsTerminated) {
return; return;
} }
TellStickData *tsd = reinterpret_cast<TellStickData*> (refCon); TellStickData *tsd = reinterpret_cast<TellStickData*> (refCon);
if (!tsd) { if (!tsd) {
return; return;
} }
CFIndex size = CFStringGetLength(tsd->serialNumber); CFIndex size = CFStringGetLength(tsd->serialNumber);
char *s = new char[size+1]; char *s = new char[size+1];
CFStringGetCString(tsd->serialNumber, s, size+1, kCFStringEncodingASCII); CFStringGetCString(tsd->serialNumber, s, size+1, kCFStringEncodingASCII);
std::string serial(s); //Copy the string to the stack std::string serial(s); // Copy the string to the stack
delete[] s; delete[] s;
ControllerChangeEventData *data = new ControllerChangeEventData; ControllerChangeEventData *data = new ControllerChangeEventData;
data->vid = tsd->vid; data->vid = tsd->vid;
data->pid = tsd->pid; data->pid = tsd->pid;
data->inserted = false; data->inserted = false;
tsd->event->signal(data); tsd->event->signal(data);
// Free the data we're no longer using now that the device is going away // Free the data we're no longer using now that the device is going away
CFRelease(tsd->serialNumber); CFRelease(tsd->serialNumber);
kr = IOObjectRelease(tsd->notification); kr = IOObjectRelease(tsd->notification);
delete tsd; delete tsd;
} }
void ControllerListener::PrivateData::DeviceAdded(void *refCon, io_iterator_t iterator) { void ControllerListener::PrivateData::DeviceAdded(void *refCon, io_iterator_t iterator) {
io_service_t usbDevice; io_service_t usbDevice;
kern_return_t kr; kern_return_t kr;
PrivateData *pd = reinterpret_cast<PrivateData*> (refCon); PrivateData *pd = reinterpret_cast<PrivateData*> (refCon);
while ((usbDevice = IOIteratorNext(iterator))) { while ((usbDevice = IOIteratorNext(iterator))) {
TellStickData *tsd = new TellStickData; TellStickData *tsd = new TellStickData;
tsd->event = pd->event; tsd->event = pd->event;
// Get the serial number // Get the serial number
CFStringRef serialRef = reinterpret_cast<CFStringRef>(IORegistryEntryCreateCFProperty( usbDevice, CFSTR("USB Serial Number" ), kCFAllocatorDefault, 0 )); CFStringRef serialRef = reinterpret_cast<CFStringRef>(IORegistryEntryCreateCFProperty( usbDevice, CFSTR("USB Serial Number" ), kCFAllocatorDefault, 0 ));
if (serialRef == NULL) { if (serialRef == NULL) {
//No serial number, we cannot continue. Sorry // No serial number, we cannot continue. Sorry
continue; continue;
} }
CFNumberRef vidRef = reinterpret_cast<CFNumberRef> (IORegistryEntryCreateCFProperty(usbDevice, CFSTR("idVendor"), kCFAllocatorDefault, 0)); CFNumberRef vidRef = reinterpret_cast<CFNumberRef> (IORegistryEntryCreateCFProperty(usbDevice, CFSTR("idVendor"), kCFAllocatorDefault, 0));
if (vidRef) { if (vidRef) {
CFNumberGetValue(vidRef, kCFNumberIntType, &(tsd->vid)); CFNumberGetValue(vidRef, kCFNumberIntType, &(tsd->vid));
CFRelease(vidRef); CFRelease(vidRef);
} }
CFNumberRef pidRef = reinterpret_cast<CFNumberRef> (IORegistryEntryCreateCFProperty(usbDevice, CFSTR("idProduct"), kCFAllocatorDefault, 0)); CFNumberRef pidRef = reinterpret_cast<CFNumberRef> (IORegistryEntryCreateCFProperty(usbDevice, CFSTR("idProduct"), kCFAllocatorDefault, 0));
if (pidRef) { if (pidRef) {
CFNumberGetValue(pidRef, kCFNumberIntType, &(tsd->pid)); CFNumberGetValue(pidRef, kCFNumberIntType, &(tsd->pid));
CFRelease(pidRef); CFRelease(pidRef);
} }
CFStringRef serialNumberAsCFString = CFStringCreateCopy(kCFAllocatorDefault, serialRef); CFStringRef serialNumberAsCFString = CFStringCreateCopy(kCFAllocatorDefault, serialRef);
tsd->serialNumber = serialNumberAsCFString; tsd->serialNumber = serialNumberAsCFString;
CFRelease(serialRef); CFRelease(serialRef);
// Register for an interest notification of this device being removed. Use a reference to our // Register for an interest notification of this device being removed. Use a reference to our
// private data as the refCon which will be passed to the notification callback. // private data as the refCon which will be passed to the notification callback.
kr = IOServiceAddInterestNotification(pd->gNotifyPort, usbDevice, kIOGeneralInterest, DeviceNotification, tsd, &(tsd->notification)); kr = IOServiceAddInterestNotification(pd->gNotifyPort, usbDevice, kIOGeneralInterest, DeviceNotification, tsd, &(tsd->notification));
CFIndex size = CFStringGetLength(serialNumberAsCFString); CFIndex size = CFStringGetLength(serialNumberAsCFString);
char *s = new char[size+1]; char *s = new char[size+1];
CFStringGetCString(serialNumberAsCFString, s, size+1, kCFStringEncodingASCII); CFStringGetCString(serialNumberAsCFString, s, size+1, kCFStringEncodingASCII);
std::string serial(s); //Copy the string to the stack std::string serial(s); // Copy the string to the stack
delete[] s; delete[] s;
kr = IOObjectRelease(usbDevice); kr = IOObjectRelease(usbDevice);
ControllerChangeEventData *data = new ControllerChangeEventData; ControllerChangeEventData *data = new ControllerChangeEventData;
data->vid = tsd->vid; data->vid = tsd->vid;
data->pid = tsd->pid; data->pid = tsd->pid;