1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-19 09:54:15 +01:00

Merge remote-tracking branch 'origin/ed_mac_halt_bug' into next

This commit is contained in:
James Cotton 2011-10-11 10:23:19 -05:00
commit ef34f6b674
2 changed files with 78 additions and 48 deletions

View File

@ -37,7 +37,6 @@
#if defined( Q_OS_MAC)
// todo:
#elif defined(Q_OS_UNIX)
//#elif defined(Q_OS_LINUX)
@ -104,10 +103,12 @@ public:
void mytest(int num);
signals:
void deviceUnplugged(int);//just to make pips changes compile
private:
#if defined( Q_OS_MAC)
// todo:
#endif
private:
#if defined( Q_OS_MAC)
#elif defined(Q_OS_UNIX)
//#elif defined(Q_OS_LINUX)

View File

@ -44,6 +44,18 @@
#include <IOKit/hid/IOHIDLib.h>
#include <CoreFoundation/CFString.h>
#include <QString>
#include <QThread>
#include <QTimer>
#include <QCoreApplication>
class delay : public QThread
{
public:
static void msleep(unsigned long msecs)
{
QThread::msleep(msecs);
}
};
#define BUFFER_SIZE 64
@ -54,6 +66,8 @@ typedef struct hid_struct hid_t;
typedef struct buffer_struct buffer_t;
static hid_t *first_hid = NULL;
static hid_t *last_hid = NULL;
// Make sure we use the correct runloop
CFRunLoopRef the_correct_runloop = NULL;
struct hid_struct {
IOHIDDeviceRef ref;
int open;
@ -75,9 +89,10 @@ static void free_all_hid(void);
static void hid_close(hid_t *);
static void attach_callback(void *, IOReturn, void *, IOHIDDeviceRef);
static void detach_callback(void *, IOReturn, void *hid_mgr, IOHIDDeviceRef dev);
static void timeout_callback(CFRunLoopTimerRef, void *);
static void input_callback(void *, IOReturn, void *, IOHIDReportType, uint32_t, uint8_t *, CFIndex);
static void output_callback(hid_t *context, IOReturn ret, void *sender, IOHIDReportType type, uint32_t id, uint8_t *data, CFIndex len);
static void timeout_callback(CFRunLoopTimerRef, void *);
pjrc_rawhid::pjrc_rawhid()
{
@ -164,6 +179,8 @@ int pjrc_rawhid::open(int max, int vid, int pid, int usage_page, int usage)
CFRelease(hid_manager);
return 0;
}
// Set the run loop reference:
the_correct_runloop = CFRunLoopGetCurrent();
printf("run loop\n");
// let it do the callback for all devices
while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource) ;
@ -183,47 +200,56 @@ int pjrc_rawhid::open(int max, int vid, int pid, int usage_page, int usage)
//
int pjrc_rawhid::receive(int num, void *buf, int len, int timeout)
{
hid_t *hid;
buffer_t *b;
CFRunLoopTimerRef timer=NULL;
CFRunLoopTimerContext context;
int ret=0, timeout_occurred=0;
hid_t *hid;
buffer_t *b;
CFRunLoopTimerRef timer=NULL;
CFRunLoopTimerContext context;
int ret=0, timeout_occurred=0;
if (len < 1) return 0;
hid = get_hid(num);
if (!hid || !hid->open) return -1;
if ((b = hid->first_buffer) != NULL) {
if (len > b->len) len = b->len;
memcpy(buf, b->buf, len);
hid->first_buffer = b->next;
free(b);
return len;
}
memset(&context, 0, sizeof(context));
context.info = &timeout_occurred;
timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent() +
(double)timeout / 1000.0, 0, 0, 0, timeout_callback, &context);
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopDefaultMode);
while (1) {
CFRunLoopRun();
if ((b = hid->first_buffer) != NULL) {
if (len > b->len) len = b->len;
memcpy(buf, b->buf, len);
hid->first_buffer = b->next;
free(b);
ret = len;
if (len < 1) return 0;
hid = get_hid(num);
if (!hid || !hid->open) return -1;
if ((b = hid->first_buffer) != NULL) {
if (len > b->len) len = b->len;
memcpy(buf, b->buf, len);
hid->first_buffer = b->next;
free(b);
return len;
}
memset(&context, 0, sizeof(context));
context.info = &timeout_occurred;
timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent() +
(double)timeout / 1000.0, 0, 0, 0, timeout_callback, &context);
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopDefaultMode);
the_correct_runloop = CFRunLoopGetCurrent();
//qDebug("--");
while (1) {
//qDebug(".");
CFRunLoopRun(); // Found the problem: somehow the input_callback does not
// stop this CFRunLoopRun because it is hooked to a different run loop !!!
// Hence the use of the "correct_runloop" variable above.
//qDebug(" ..");
if ((b = hid->first_buffer) != NULL) {
if (len > b->len) len = b->len;
memcpy(buf, b->buf, len);
hid->first_buffer = b->next;
free(b);
ret = len;
//qDebug("*************");
break;
}
if (!hid->open) {
printf("pjrc_rawhid_recv, device not open\n");
ret = -1;
break;
}
if (timeout_occurred)
break;
}
if (!hid->open) {
printf("pjrc_rawhid_recv, device not open\n");
ret = -1;
break;
}
if (timeout_occurred) break;
}
CFRunLoopTimerInvalidate(timer);
CFRelease(timer);
return ret;
}
CFRunLoopTimerInvalidate(timer);
CFRelease(timer);
return ret;
}
// send - send a packet
@ -335,10 +361,11 @@ static void input_callback(void *context, IOReturn ret, void *sender, IOHIDRepor
buffer_t *n;
hid_t *hid;
printf("input_callback, report id: %i buf: %x %x, len: %d\n", id, data[0], data[1], len);
//qDebug("input_callback, ret: %i - report id: %i buf: %x %x, len: %d\n", ret, id, data[0], data[1], len);
if (ret != kIOReturnSuccess || len < 1) return;
hid = (hid_t*)context;
if (!hid || hid->ref != sender) return;
printf("Processing packet");
n = (buffer_t *)malloc(sizeof(buffer_t));
if (!n) return;
if (len > BUFFER_SIZE) len = BUFFER_SIZE;
@ -352,14 +379,16 @@ static void input_callback(void *context, IOReturn ret, void *sender, IOHIDRepor
hid->last_buffer->next = n;
hid->last_buffer = n;
}
CFRunLoopStop(CFRunLoopGetCurrent());
//qDebug() << "Stop CFRunLoop from input_callback" << CFRunLoopGetCurrent();
CFRunLoopStop(the_correct_runloop);
}
static void timeout_callback(CFRunLoopTimerRef timer, void *info)
{
printf("timeout_callback\n");
*(int *)info = 1;
CFRunLoopStop(CFRunLoopGetCurrent());
//qDebug("timeout_callback\n");
*(int *)info = 1;
//qDebug() << "Stop CFRunLoop from timeout_callback" << CFRunLoopGetCurrent();
CFRunLoopStop(CFRunLoopGetCurrent());
}
static void add_hid(hid_t *h)