diff --git a/flight/libraries/op_dfu.c b/flight/libraries/op_dfu.c index 882b106a8..e952a886c 100644 --- a/flight/libraries/op_dfu.c +++ b/flight/libraries/op_dfu.c @@ -245,7 +245,7 @@ void processComand(uint8_t *xReceive_Buffer) } break; case Remote_flash_via_spi: - result = false; // No support for this for the PipX + result = false; // No support for this for the OPLink Mini break; default: result = 0; @@ -476,7 +476,7 @@ bool flash_read(uint8_t *buffer, uint32_t adr, DFUProgType type) { switch (type) { case Remote_flash_via_spi: - return false; // We should not get this for the PipX + return false; // We should not get this for the OPLink Mini break; case Self_flash: diff --git a/flight/targets/boards/coptercontrol/bootloader/pios_board.c b/flight/targets/boards/coptercontrol/bootloader/pios_board.c index bd437df42..8071a3c32 100644 --- a/flight/targets/boards/coptercontrol/bootloader/pios_board.c +++ b/flight/targets/boards/coptercontrol/bootloader/pios_board.c @@ -3,7 +3,7 @@ * * @file pios_board.c * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @brief Defines board specific static initializers for hardware for the PipBee board. + * @brief Defines board specific static initializers for hardware for the CopterControl board. * @see The GNU Public License (GPL) Version 3 * *****************************************************************************/ diff --git a/flight/targets/boards/oplinkmini/board_hw_defs.c b/flight/targets/boards/oplinkmini/board_hw_defs.c index 42598b96c..cec0d3d51 100644 --- a/flight/targets/boards/oplinkmini/board_hw_defs.c +++ b/flight/targets/boards/oplinkmini/board_hw_defs.c @@ -1,3 +1,29 @@ +/** + ****************************************************************************** + * + * @file board_hw_defs.c.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013. + * @brief Defines board hardware for the OpenPilot OPLink Mini board. + * @see The GNU Public License (GPL) Version 3 + * + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + #if defined(PIOS_INCLUDE_LED) #include diff --git a/flight/targets/boards/oplinkmini/bootloader/pios_board.c b/flight/targets/boards/oplinkmini/bootloader/pios_board.c index 7bcd5ce8a..94a73e708 100644 --- a/flight/targets/boards/oplinkmini/bootloader/pios_board.c +++ b/flight/targets/boards/oplinkmini/bootloader/pios_board.c @@ -3,7 +3,7 @@ * * @file pios_board.c * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @brief Defines board specific static initializers for hardware for the PipBee board. + * @brief Defines board specific static initializers for hardware for the OPLink Mini board. * @see The GNU Public License (GPL) Version 3 * *****************************************************************************/ diff --git a/flight/targets/boards/oplinkmini/pios_board.h b/flight/targets/boards/oplinkmini/pios_board.h index bc0a9f321..9d2ae2b6e 100644 --- a/flight/targets/boards/oplinkmini/pios_board.h +++ b/flight/targets/boards/oplinkmini/pios_board.h @@ -2,8 +2,8 @@ ****************************************************************************** * * @file pios_board.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @brief Defines board hardware for the OpenPilot Version 1.1 hardware. + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2013. + * @brief Defines PiOS board hardware for the OpenPilot OPLink Mini board. * @see The GNU Public License (GPL) Version 3 * *****************************************************************************/ diff --git a/flight/targets/boards/oplinkmini/pios_usb_board_data.c b/flight/targets/boards/oplinkmini/pios_usb_board_data.c index 5aa5ab5f9..2f6a2753c 100644 --- a/flight/targets/boards/oplinkmini/pios_usb_board_data.c +++ b/flight/targets/boards/oplinkmini/pios_usb_board_data.c @@ -33,18 +33,19 @@ #include /* PIOS_USBHOOK_* */ #include /* PIOS_USB_UTIL_AsciiToUtf8 */ -static const uint8_t usb_product_id[20] = { +static const uint8_t usb_product_id[22] = { sizeof(usb_product_id), USB_DESC_TYPE_STRING, + 'O', 0, 'P', 0, + 'L', 0, + 'i', 0, + 'n', 0, + 'k', 0, + 'M', 0, + 'i', 0, + 'n', 0, 'i', 0, - 'p', 0, - 'X', 0, - 't', 0, - 'r', 0, - 'e', 0, - 'm', 0, - 'e', 0, }; static uint8_t usb_serial_number[2 + PIOS_SYS_SERIAL_NUM_ASCII_LEN * 2 + (sizeof(PIOS_USB_BOARD_SN_SUFFIX) - 1) * 2] = { diff --git a/flight/targets/common/bootloader_updater/pios_board.c b/flight/targets/common/bootloader_updater/pios_board.c index 8ef335e3f..1557c7b83 100644 --- a/flight/targets/common/bootloader_updater/pios_board.c +++ b/flight/targets/common/bootloader_updater/pios_board.c @@ -3,7 +3,7 @@ * * @file pios_board.c * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @brief Defines board specific static initializers for hardware for the PipBee board. + * @brief Defines board specific static initializers for hardware for the OPLink Mini board. * @see The GNU Public License (GPL) Version 3 * *****************************************************************************/ diff --git a/ground/openpilotgcs/src/plugins/ophid/inc/ophid_usbmon.h b/ground/openpilotgcs/src/plugins/ophid/inc/ophid_usbmon.h index 20ef05031..b39c74952 100644 --- a/ground/openpilotgcs/src/plugins/ophid/inc/ophid_usbmon.h +++ b/ground/openpilotgcs/src/plugins/ophid/inc/ophid_usbmon.h @@ -116,7 +116,7 @@ public: idVendor_OpenPilot = 0x20a0, idProduct_OpenPilot = 0x415a, idProduct_CopterControl = 0x415b, - idProduct_PipXtreme = 0x415c + idProduct_OPLinkMini = 0x415c }; static USBMonitor *instance(); diff --git a/ground/openpilotgcs/src/plugins/rawhid/RawHID.pluginspec b/ground/openpilotgcs/src/plugins/rawhid/RawHID.pluginspec deleted file mode 100644 index 7cb190038..000000000 --- a/ground/openpilotgcs/src/plugins/rawhid/RawHID.pluginspec +++ /dev/null @@ -1,10 +0,0 @@ - -The OpenPilot Project - (C) 2010 OpenPilot Project - GNU Public License (GPL) Version 3 - Connection to OpenPilot board using RawHID USB interface - http://www.openpilot.org - - - - diff --git a/ground/openpilotgcs/src/plugins/rawhid/pjrc_rawhid.h b/ground/openpilotgcs/src/plugins/rawhid/pjrc_rawhid.h deleted file mode 100644 index 486f88b92..000000000 --- a/ground/openpilotgcs/src/plugins/rawhid/pjrc_rawhid.h +++ /dev/null @@ -1,163 +0,0 @@ -/** - ****************************************************************************** - * - * @file pjrc_rawhid.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup RawHIDPlugin Raw HID Plugin - * @{ - * @brief Impliments a HID USB connection to the flight hardware as a QIODevice - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef PJRC_RAWHID_H -#define PJRC_RAWHID_H - -#include -#include -#include -#include -#include -#include -#include "rawhid_global.h" - -#if defined(Q_OS_MAC) - -#include -#include -#include - -#elif defined(Q_OS_UNIX) -// #elif defined(Q_OS_LINUX) -#include -#include -#include -#elif defined(Q_OS_WIN32) -#include -#include -#include -#include -#endif - -// ************ - -#if defined(Q_OS_MAC) - -// todo: - -#elif defined(Q_OS_UNIX) -// #elif defined(Q_OS_LINUX) - -typedef struct hid_struct hid_t; -struct hid_struct { - usb_dev_handle *usb; - int open; - int iface; - int ep_in; - int ep_out; - struct hid_struct *prev; - struct hid_struct *next; -}; - -#elif defined(Q_OS_WIN32) - -typedef struct hid_struct hid_t; - -struct hid_struct { - HANDLE handle; - int open; - struct hid_struct *prev; - struct hid_struct *next; -}; - -#endif // if defined(Q_OS_MAC) - - -class RAWHID_EXPORT pjrc_rawhid : public QObject { - Q_OBJECT - -public: - pjrc_rawhid(); - ~pjrc_rawhid(); - int open(int max, int vid, int pid, int usage_page, int usage); - int receive(int, void *buf, int len, int timeout); - void close(int num); - int send(int num, void *buf, int len, int timeout); - QString getserial(int num); -signals: - void deviceUnplugged(int); - -private: -#if defined(Q_OS_MAC) - - // Static callbacks called by the HID system with handles to the PJRC object - static void attach_callback(void *, IOReturn, void *, IOHIDDeviceRef); - static void dettach_callback(void *, IOReturn, void *hid_mgr, IOHIDDeviceRef dev); - static void input_callback(void *, IOReturn, void *, IOHIDReportType, uint32_t, uint8_t *, CFIndex); - static void timeout_callback(CFRunLoopTimerRef, void *); - - // Non static methods to call into - void attach(IOHIDDeviceRef dev); - void dettach(IOHIDDeviceRef dev); - void input(uint8_t *, CFIndex); - - // Platform specific handles for the USB device - IOHIDManagerRef hid_manager; - IOHIDDeviceRef dev; - CFRunLoopRef the_correct_runloop; - CFRunLoopRef received_runloop; - - static const int BUFFER_SIZE = 64; - uint8_t buffer[BUFFER_SIZE]; - int attach_count; - int buffer_count; - bool device_open; - bool unplugged; - - QMutex *m_writeMutex; - QMutex *m_readMutex; -#elif defined(Q_OS_UNIX) - - hid_t * first_hid; - hid_t *last_hid; - - void add_hid(hid_t *h); - hid_t *get_hid(int num); - void free_all_hid(void); - void hid_close(hid_t *hid); - int hid_parse_item(uint32_t *val, uint8_t * *data, const uint8_t *end); - -#elif defined(Q_OS_WIN32) - - hid_t * first_hid; - hid_t *last_hid; - HANDLE rx_event; - HANDLE tx_event; - CRITICAL_SECTION rx_mutex; - CRITICAL_SECTION tx_mutex; - - void add_hid(hid_t *h); - hid_t *get_hid(int num); - void free_all_hid(void); - void hid_close(hid_t *hid); - void print_win32_err(DWORD err); - -#endif // if defined(Q_OS_MAC) -}; - -#endif // ifndef PJRC_RAWHID_H diff --git a/ground/openpilotgcs/src/plugins/rawhid/pjrc_rawhid_mac.cpp b/ground/openpilotgcs/src/plugins/rawhid/pjrc_rawhid_mac.cpp deleted file mode 100644 index 1ca909ccd..000000000 --- a/ground/openpilotgcs/src/plugins/rawhid/pjrc_rawhid_mac.cpp +++ /dev/null @@ -1,423 +0,0 @@ -/* @file pjrc_rawhid_mac.cpp - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup RawHIDPlugin Raw HID Plugin - * @{ - * @brief Impliments a HID USB connection to the flight hardware as a QIODevice - *****************************************************************************/ - -/* Simple Raw HID functions for Linux - for use with Teensy RawHID example - * http://www.pjrc.com/teensy/rawhid.html - * Copyright (c) 2009 PJRC.COM, LLC - * - * rawhid_open - open 1 or more devices - * rawhid_recv - receive a packet - * rawhid_send - send a packet - * rawhid_close - close a device - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above description, website URL and copyright notice and this permission - * notice shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * Version 1.0: Initial Release - */ - - -#include "pjrc_rawhid.h" - -#include -#include -#include -#include -#include - -struct timeout_info { - CFRunLoopRef loopRef; - bool timed_out; -}; - -pjrc_rawhid::pjrc_rawhid() : - device_open(false), hid_manager(NULL), buffer_count(0), unplugged(false) -{ - m_writeMutex = new QMutex(); - m_readMutex = new QMutex(); -} - -pjrc_rawhid::~pjrc_rawhid() -{ - if (device_open) { - close(0); - } - - if (m_writeMutex) { - delete m_writeMutex; - m_writeMutex = NULL; - } - - if (m_readMutex) { - delete m_readMutex; - m_readMutex = NULL; - } -} - -/** - * @brief open - open 1 or more devices - * @param[in] max maximum number of devices to open - * @param[in] vid Vendor ID, or -1 if any - * @param[in] pid Product ID, or -1 if any - * @param[in] usage_page top level usage page, or -1 if any - * @param[in] usage top level usage number, or -1 if any - * @returns actual number of devices opened - */ -int pjrc_rawhid::open(int max, int vid, int pid, int usage_page, int usage) -{ - CFMutableDictionaryRef dict; - CFNumberRef num; - IOReturn ret; - - Q_ASSERT(hid_manager == NULL); - Q_ASSERT(device_open == false); - - attach_count = 0; - - // Start the HID Manager - hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); - if (hid_manager == NULL || CFGetTypeID(hid_manager) != IOHIDManagerGetTypeID()) { - if (hid_manager) { - CFRelease(hid_manager); - } - return 0; - } - - if (vid > 0 || pid > 0 || usage_page > 0 || usage > 0) { - // Tell the HID Manager what type of devices we want - dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, - &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - if (!dict) { - return 0; - } - if (vid > 0) { - num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &vid); - CFDictionarySetValue(dict, CFSTR(kIOHIDVendorIDKey), num); - CFRelease(num); - } - if (pid > 0) { - num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &pid); - CFDictionarySetValue(dict, CFSTR(kIOHIDProductIDKey), num); - CFRelease(num); - } - if (usage_page > 0) { - num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage_page); - CFDictionarySetValue(dict, CFSTR(kIOHIDPrimaryUsagePageKey), num); - CFRelease(num); - } - if (usage > 0) { - num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage); - CFDictionarySetValue(dict, CFSTR(kIOHIDPrimaryUsageKey), num); - CFRelease(num); - } - IOHIDManagerSetDeviceMatching(hid_manager, dict); - CFRelease(dict); - } else { - IOHIDManagerSetDeviceMatching(hid_manager, NULL); - } - - // Set the run loop reference before configuring the attach callback - the_correct_runloop = CFRunLoopGetCurrent(); - - // set up a callbacks for device attach & detach - IOHIDManagerScheduleWithRunLoop(hid_manager, CFRunLoopGetCurrent(), - kCFRunLoopDefaultMode); - IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, pjrc_rawhid::attach_callback, this); - IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, pjrc_rawhid::dettach_callback, this); - ret = IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone); - if (ret != kIOReturnSuccess) { - IOHIDManagerUnscheduleFromRunLoop(hid_manager, - CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); - CFRelease(hid_manager); - return 0; - } - - // let it do the callback for all devices - while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource) { - ; - } - - // count up how many were added by the callback - return attach_count; -} - -/** - * @brief receive - receive a packet - * @param[in] num device to receive from (unused now) - * @param[in] buf buffer to receive packet - * @param[in] len buffer's size - * @param[in] timeout = time to wait, in milliseconds - * @returns number of bytes received, or -1 on error - */ -int pjrc_rawhid::receive(int, void *buf, int len, int timeout) -{ - QMutexLocker locker(m_readMutex); - - Q_UNUSED(locker); - - if (!device_open) { - return -1; - } - - // Pass information to the callback to stop this run loop and signal if a timeout occurred - struct timeout_info info; - info.loopRef = CFRunLoopGetCurrent();; - info.timed_out = false; - CFRunLoopTimerContext context; - memset(&context, 0, sizeof(context)); - context.info = &info; - - // Set up the timer for the timeout - CFRunLoopTimerRef timer; - timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent() + (double)timeout / 1000.0, 0, 0, 0, timeout_callback, &context); - CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopDefaultMode); - - received_runloop = CFRunLoopGetCurrent(); - - // Run the CFRunLoop until either a timeout or data is available - while (1) { - if (buffer_count != 0) { - if (len > buffer_count) { - len = buffer_count; - } - memcpy(buf, buffer, len); - buffer_count = 0; - break; - } else if (info.timed_out) { - len = 0; - break; - } - CFRunLoopRun(); // Wait for data - } - - CFRunLoopTimerInvalidate(timer); - CFRelease(timer); - - received_runloop = NULL; - - return len; -} - -/** - * @brief Helper class that will workaround the fact - * that the HID send is broken on OSX - */ -class Sender : public QThread { -public: - Sender(IOHIDDeviceRef d, uint8_t *b, int l) : - dev(d), buf(b), len(l), result(-1) {} - - void run() - { - ret = IOHIDDeviceSetReport(dev, kIOHIDReportTypeOutput, 2, buf, len); - result = (ret == kIOReturnSuccess) ? len : -1; - } - - int result; - IOReturn ret; -private: - IOHIDDeviceRef dev; - uint8_t *buf; - int len; -}; - -/** - * @brief send - send a packet - * @param[in] num device to transmit to (zero based) - * @param[in] buf buffer containing packet to send - * @param[in] len number of bytes to transmit - * @param[in] timeout = time to wait, in milliseconds - * @returns number of bytes sent, or -1 on error - */ -int pjrc_rawhid::send(int, void *buf, int len, int timeout) -{ - // This lock ensures that when closing we don't do it until the - // write has terminated (and then the device_open flag is set to false) - QMutexLocker locker(m_writeMutex); - - Q_UNUSED(locker); - - if (!device_open || unplugged) { - return -1; - } - - uint8_t *report_buf = (uint8_t *)malloc(len); - memcpy(&report_buf[0], buf, len); - - QEventLoop el; - Sender sender(dev, report_buf, len); - connect(&sender, SIGNAL(finished()), &el, SLOT(quit())); - sender.start(); - QTimer::singleShot(timeout, &el, SLOT(quit())); - el.exec(); - - return sender.result; -} - -// ! Get the serial number for a HID device -QString pjrc_rawhid::getserial(int num) -{ - QMutexLocker locker(m_readMutex); - - Q_UNUSED(locker); - - if (!device_open || unplugged) { - return ""; - } - - CFTypeRef serialnum = IOHIDDeviceGetProperty(dev, CFSTR(kIOHIDSerialNumberKey)); - if (serialnum && CFGetTypeID(serialnum) == CFStringGetTypeID()) { - // Note: I'm not sure it will always succeed if encoded as MacRoman but that - // is a superset of UTF8 so I think this is fine - CFStringRef str = static_cast(serialnum); - int length = CFStringGetLength(str); - if (length == 0) { - return ""; - } - char *ptr = (char *)malloc(length + 1); - Boolean ret = CFStringGetCString(str, ptr, length + 1, kCFStringEncodingMacRoman); - QString strResult; - if (ret == true) { - strResult = ptr; - } - free(ptr); - return strResult; - } - - return QString("Error"); -} - -// ! Close the HID device -void pjrc_rawhid::close(int) -{ - // Make sure any pending locks are done - QMutexLocker lock(m_writeMutex); - - if (device_open) { - device_open = false; - CFRunLoopStop(the_correct_runloop); - - if (!unplugged) { - IOHIDDeviceUnscheduleFromRunLoop(dev, the_correct_runloop, kCFRunLoopDefaultMode); - IOHIDDeviceRegisterInputReportCallback(dev, buffer, sizeof(buffer), NULL, NULL); - IOHIDDeviceClose(dev, kIOHIDOptionsTypeNone); - } - - IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, NULL, NULL); - IOHIDManagerClose(hid_manager, 0); - - dev = NULL; - hid_manager = NULL; - } -} - -/** - * @brief input Called to add input data to the buffer - * @param[in] id Report id - * @param[in] data The data buffer - * @param[in] len The report length - */ -void pjrc_rawhid::input(uint8_t *data, CFIndex len) -{ - if (!device_open) { - return; - } - - if (len > BUFFER_SIZE) { - len = BUFFER_SIZE; - } - // Note: packet preprocessing done in OS independent code - memcpy(buffer, &data[0], len); - buffer_count = len; - - if (received_runloop) { - CFRunLoopStop(received_runloop); - } -} - -// ! Callback for the HID driver on an input report -void pjrc_rawhid::input_callback(void *c, IOReturn ret, void *sender, IOHIDReportType type, uint32_t id, uint8_t *data, CFIndex len) -{ - if (ret != kIOReturnSuccess || len < 1) { - return; - } - - pjrc_rawhid *context = (pjrc_rawhid *)c; - context->input(data, len); -} - -// ! Timeout used for the -void pjrc_rawhid::timeout_callback(CFRunLoopTimerRef, void *i) -{ - struct timeout_info *info = (struct timeout_info *)i; - - info->timed_out = true; - CFRunLoopStop(info->loopRef); -} - -// ! Called on a dettach event -void pjrc_rawhid::dettach(IOHIDDeviceRef d) -{ - unplugged = true; - if (d == dev) { - emit deviceUnplugged(0); - } -} - -// ! Called from the USB system and forwarded to the instance (context) -void pjrc_rawhid::dettach_callback(void *context, IOReturn, void *, IOHIDDeviceRef dev) -{ - pjrc_rawhid *p = (pjrc_rawhid *)context; - - p->dettach(dev); -} - -/** - * @brief Called by the USB system - * @param dev The device that was attached - */ -void pjrc_rawhid::attach(IOHIDDeviceRef d) -{ - // Store the device handle - dev = d; - - if (IOHIDDeviceOpen(dev, kIOHIDOptionsTypeNone) != kIOReturnSuccess) { - return; - } - // Disconnect the attach callback since we don't want to automatically reconnect - IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, NULL, NULL); - IOHIDDeviceScheduleWithRunLoop(dev, the_correct_runloop, kCFRunLoopDefaultMode); - IOHIDDeviceRegisterInputReportCallback(dev, buffer, sizeof(buffer), pjrc_rawhid::input_callback, this); - - attach_count++; - device_open = true; - unplugged = false; -} - -// ! Called from the USB system and forwarded to the instance (context) -void pjrc_rawhid::attach_callback(void *context, IOReturn r, void *hid_mgr, IOHIDDeviceRef dev) -{ - pjrc_rawhid *p = (pjrc_rawhid *)context; - - p->attach(dev); -} diff --git a/ground/openpilotgcs/src/plugins/rawhid/pjrc_rawhid_unix.cpp b/ground/openpilotgcs/src/plugins/rawhid/pjrc_rawhid_unix.cpp deleted file mode 100644 index f8f123c3a..000000000 --- a/ground/openpilotgcs/src/plugins/rawhid/pjrc_rawhid_unix.cpp +++ /dev/null @@ -1,421 +0,0 @@ -/* @file pjrc_rawhid_unix.cpp - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup RawHIDPlugin Raw HID Plugin - * @{ - * @brief Impliments a HID USB connection to the flight hardware as a QIODevice - *****************************************************************************/ - -/* Simple Raw HID functions for Linux - for use with Teensy RawHID example - * http://www.pjrc.com/teensy/rawhid.html - * Copyright (c) 2009 PJRC.COM, LLC - * - * rawhid_open - open 1 or more devices - * rawhid_recv - receive a packet - * rawhid_send - send a packet - * rawhid_close - close a device - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above description, website URL and copyright notice and this permission - * notice shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * Version 1.0: Initial Release - */ - -#include "pjrc_rawhid.h" - -#define printf qDebug - -pjrc_rawhid::pjrc_rawhid() -{ - first_hid = NULL; - last_hid = NULL; -} - -pjrc_rawhid::~pjrc_rawhid() -{} - -// open - open 1 or more devices -// -// Inputs: -// max = maximum number of devices to open -// vid = Vendor ID, or -1 if any -// pid = Product ID, or -1 if any -// usage_page = top level usage page, or -1 if any -// usage = top level usage number, or -1 if any -// Output: -// actual number of devices opened -// -int pjrc_rawhid::open(int max, int vid, int pid, int usage_page, int usage) -{ - struct usb_bus *bus; - struct usb_device *dev; - struct usb_interface *iface; - struct usb_interface_descriptor *desc; - struct usb_endpoint_descriptor *ep; - usb_dev_handle *u; - uint8_t buf[1024], *p; - int i, n, len, tag, ep_in, ep_out, count = 0, claimed; - uint32_t val = 0, parsed_usage, parsed_usage_page; - hid_t *hid; - - if (first_hid) { - free_all_hid(); - } - // printf("pjrc_rawhid_open, max=%d\n", max); - - if (max < 1) { - return 0; - } - - usb_init(); - usb_find_busses(); - usb_find_devices(); - - for (bus = usb_get_busses(); bus; bus = bus->next) { - for (dev = bus->devices; dev; dev = dev->next) { - if (vid > 0 && dev->descriptor.idVendor != vid) { - continue; - } - if (pid > 0 && dev->descriptor.idProduct != pid) { - continue; - } - if (!dev->config) { - continue; - } - if (dev->config->bNumInterfaces < 1) { - continue; - } - printf("device: vid=%04X, pic=%04X, with %d iface", - dev->descriptor.idVendor, - dev->descriptor.idProduct, - dev->config->bNumInterfaces); - iface = dev->config->interface; - u = NULL; - claimed = 0; - for (i = 0; i < dev->config->bNumInterfaces && iface; i++, iface++) { - desc = iface->altsetting; - if (!desc) { - continue; - } - - printf(" type %d, %d, %d", desc->bInterfaceClass, desc->bInterfaceSubClass, desc->bInterfaceProtocol); - - if (desc->bInterfaceClass != 3) { - continue; - } - if (desc->bInterfaceSubClass != 0) { - continue; - } - if (desc->bInterfaceProtocol != 0) { - continue; - } - - ep = desc->endpoint; - ep_in = ep_out = 0; - for (n = 0; n < desc->bNumEndpoints; n++, ep++) { - if (ep->bEndpointAddress & 0x80) { - if (!ep_in) { - ep_in = ep->bEndpointAddress & 0x7F; - } - qDebug() << " IN endpoint " << ep_in; - } else { - if (!ep_out) { - ep_out = ep->bEndpointAddress; - } - qDebug() << " OUT endpoint " << ep_out; - } - } - if (!ep_in) { - continue; - } - - if (!u) { - u = usb_open(dev); - if (!u) { - qDebug() << " unable to open device"; - break; - } - } - qDebug() << " hid interface (generic)"; - if (usb_get_driver_np(u, i, (char *)buf, sizeof(buf)) >= 0) { - printf(" in use by driver \"%s\"", buf); - if (usb_detach_kernel_driver_np(u, i) < 0) { - printf(" unable to detach from kernel"); - continue; - } - } - - if (usb_claim_interface(u, i) < 0) { - printf(" unable claim interface %d", i); - continue; - } - - len = usb_control_msg(u, 0x81, 6, 0x2200, i, (char *)buf, sizeof(buf), 250); - printf(" descriptor, len=%d", len); - if (len < 2) { - usb_release_interface(u, i); - continue; - } - - p = buf; - parsed_usage_page = parsed_usage = 0; - while ((tag = hid_parse_item(&val, &p, buf + len)) >= 0) { - printf(" tag: %X, val %X", tag, val); - if (tag == 4) { - parsed_usage_page = val; - } - if (tag == 8) { - parsed_usage = val; - } - if (parsed_usage_page && parsed_usage) { - break; - } - } - if ((!parsed_usage_page) || (!parsed_usage) || - (usage_page > 0 && parsed_usage_page != (uint32_t)usage_page) || - (usage > 0 && parsed_usage != (uint32_t)usage)) { - usb_release_interface(u, i); - continue; - } - - hid = (struct hid_struct *)malloc(sizeof(struct hid_struct)); - if (!hid) { - usb_release_interface(u, i); - continue; - } - - hid->usb = u; - hid->iface = i; - hid->ep_in = ep_in; - hid->ep_out = ep_out; - hid->open = 1; - add_hid(hid); - - claimed++; - count++; - if (count >= max) { - return count; - } - } - - if (u && !claimed) { - usb_close(u); - } - } - } - - return count; -} - -// recveive - receive a packet -// Inputs: -// num = device to receive from (zero based) -// buf = buffer to receive packet -// len = buffer's size -// timeout = time to wait, in milliseconds -// Output: -// number of bytes received, or -1 on error -// -int pjrc_rawhid::receive(int num, void *buf, int len, int timeout) -{ - if (!buf) { - return -1; - } - - hid_t *hid = get_hid(num); - if (!hid || !hid->open) { - return -1; - } - - int r = usb_interrupt_read(hid->usb, hid->ep_in, (char *)buf, len, timeout); - if (r >= 0) { - return r; - } - if (r == -110) { - return 0; // timeout - } - return -1; -} - -// send - send a packet -// Inputs: -// num = device to transmit to (zero based) -// buf = buffer containing packet to send -// len = number of bytes to transmit -// timeout = time to wait, in milliseconds -// Output: -// number of bytes sent, or -1 on error -// -int pjrc_rawhid::send(int num, void *buf, int len, int timeout) -{ - hid_t *hid; - - hid = get_hid(num); - if (!hid || !hid->open) { - return -1; - } - if (hid->ep_out) { - return usb_interrupt_write(hid->usb, hid->ep_out, (char *)buf, len, timeout); - } else { - return usb_control_msg(hid->usb, 0x21, 9, 0, hid->iface, (char *)buf, len, timeout); - } -} - -// getserial - get the serialnumber of the device -// -// Inputs: -// num = device to close (zero based) -// buf = buffer to read the serialnumber into -// Output -// number of bytes in found, or -1 on error -// -QString pjrc_rawhid::getserial(int num) -{ - hid_t *hid; - char buf[128]; - - hid = get_hid(num); - if (!hid || !hid->open) { - return QString(""); - } - - int retlen = usb_get_string_simple(hid->usb, 3, buf, 128); - return QString().fromAscii(buf, -1); -} - -// close - close a device -// -// Inputs: -// num = device to close (zero based) -// Output -// (nothing) -// -void pjrc_rawhid::close(int num) -{ - hid_close(get_hid(num)); -} - -// Chuck Robey wrote a real HID report parser -// (chuckr@telenix.org) chuckr@chuckr.org -// http://people.freebsd.org/~chuckr/code/python/uhidParser-0.2.tbz -// this tiny thing only needs to extract the top-level usage page -// and usage, and even then is may not be truly correct, but it does -// work with the Teensy Raw HID example. -int pjrc_rawhid::hid_parse_item(uint32_t *val, uint8_t * *data, const uint8_t *end) -{ - const uint8_t *p = *data; - uint8_t tag; - int table[4] = { 0, 1, 2, 4 }; - int len; - - if (p >= end) { - return -1; - } - if (p[0] == 0xFE) { - // long item, HID 1.11, 6.2.2.3, page 27 - if (p + 5 >= end || p + p[1] >= end) { - return -1; - } - tag = p[2]; - *val = 0; - len = p[1] + 5; - } else { - // short item, HID 1.11, 6.2.2.2, page 26 - tag = p[0] & 0xFC; - len = table[p[0] & 0x03]; - if (p + len + 1 >= end) { - return -1; - } - switch (p[0] & 0x03) { - case 3: *val = p[1] | (p[2] << 8) | (p[3] << 16) | (p[4] << 24); break; - case 2: *val = p[1] | (p[2] << 8); break; - case 1: *val = p[1]; break; - case 0: *val = 0; break; - } - } - *data += len + 1; - return tag; -} - -void pjrc_rawhid::add_hid(hid_t *h) -{ - if (!h) { - return; - } - - if (!first_hid || !last_hid) { - first_hid = last_hid = h; - h->next = h->prev = NULL; - return; - } - last_hid->next = h; - h->prev = last_hid; - h->next = NULL; - last_hid = h; -} - -hid_t *pjrc_rawhid::get_hid(int num) -{ - hid_t *p = NULL; - - for (p = first_hid; p && num > 0; p = p->next, num--) { - ; - } - return p; -} - -void pjrc_rawhid::free_all_hid(void) -{ - for (hid_t *p = first_hid; p; p = p->next) { - hid_close(p); - } - - hid_t *p = first_hid; - while (p) { - hid_t *q = p; - p = p->next; - free(q); - } - - first_hid = last_hid = NULL; -} - -void pjrc_rawhid::hid_close(hid_t *hid) -{ - if (!hid) { - return; - } - if (!hid->open) { - return; - } - - usb_release_interface(hid->usb, hid->iface); - - int others = 0; - for (hid_t *p = first_hid; p; p = p->next) { - if (p->open && p->usb == hid->usb) { - others++; - } - } - if (!others) { - usb_close(hid->usb); - } - - hid->usb = NULL; - hid->open = 0; -} diff --git a/ground/openpilotgcs/src/plugins/rawhid/pjrc_rawhid_win.cpp b/ground/openpilotgcs/src/plugins/rawhid/pjrc_rawhid_win.cpp deleted file mode 100644 index 37d4a9075..000000000 --- a/ground/openpilotgcs/src/plugins/rawhid/pjrc_rawhid_win.cpp +++ /dev/null @@ -1,483 +0,0 @@ -/* @file pjrc_rawhid_windows.cpp - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup RawHIDPlugin Raw HID Plugin - * @{ - * @brief Impliments a HID USB connection to the flight hardware as a QIODevice - *****************************************************************************/ - -/* Simple Raw HID functions for Windows - for use with Teensy RawHID example - * http://www.pjrc.com/teensy/rawhid.html - * Copyright (c) 2009 PJRC.COM, LLC - * - * rawhid_open - open 1 or more devices - * rawhid_recv - receive a packet - * rawhid_send - send a packet - * rawhid_close - close a device - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above description, website URL and copyright notice and this permission - * notice shall be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - * Version 1.0: Initial Release - */ -/* See: http://msdn.microsoft.com/en-us/library/ms794141.aspx */ - -#include "pjrc_rawhid.h" -#include -#define printf qDebug - -pjrc_rawhid::pjrc_rawhid() -{ - first_hid = NULL; - last_hid = NULL; - rx_event = NULL; - tx_event = NULL; -} - -pjrc_rawhid::~pjrc_rawhid() -{} - -// open - open 1 or more devices -// -// Inputs: -// max = maximum number of devices to open -// vid = Vendor ID, or -1 if any -// pid = Product ID, or -1 if any -// usage_page = top level usage page, or -1 if any -// usage = top level usage number, or -1 if any -// Output: -// actual number of devices opened -// -int pjrc_rawhid::open(int max, int vid, int pid, int usage_page, int usage) -{ - GUID guid; - HDEVINFO info; - DWORD index = 0, reqd_size; - SP_DEVICE_INTERFACE_DATA iface; - SP_DEVICE_INTERFACE_DETAIL_DATA *details; - HIDD_ATTRIBUTES attrib; - PHIDP_PREPARSED_DATA hid_data; - HIDP_CAPS capabilities; - HANDLE h; - BOOL ret; - hid_t *hid; - - int count = 0; - - if (first_hid) { - free_all_hid(); - } - - if (max < 1) { - return 0; - } - - if (!rx_event) { - rx_event = CreateEvent(NULL, TRUE, TRUE, NULL); - tx_event = CreateEvent(NULL, TRUE, TRUE, NULL); - InitializeCriticalSection(&rx_mutex); - InitializeCriticalSection(&tx_mutex); - } - - HidD_GetHidGuid(&guid); - - info = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); - if (info == INVALID_HANDLE_VALUE) { - return 0; - } - - for (index = 0; 1; index++) { - iface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); - ret = SetupDiEnumDeviceInterfaces(info, NULL, &guid, index, &iface); - if (!ret) { - return count; - } - - SetupDiGetInterfaceDeviceDetail(info, &iface, NULL, 0, &reqd_size, NULL); - details = (SP_DEVICE_INTERFACE_DETAIL_DATA *)malloc(reqd_size); - if (details == NULL) { - continue; - } - - memset(details, 0, reqd_size); - details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); - ret = SetupDiGetDeviceInterfaceDetail(info, &iface, details, reqd_size, NULL, NULL); - if (!ret) { - free(details); - continue; - } - - h = CreateFile(details->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); - if (h == INVALID_HANDLE_VALUE) { - DWORD err = GetLastError(); - - // I get ERROR_ACCESS_DENIED with most/all my input devices (mice/trackballs/tablet). - // Let's not log it :) - if (err == ERROR_ACCESS_DENIED) { - free(details); - continue; - } - - // qDebug wipes the GetLastError() it seems, so do that after print_win32_err(). - print_win32_err(err); - qDebug() << "Problem opening handle, path: " << QString().fromWCharArray(details->DevicePath); - - free(details); - continue; - } - - free(details); - - attrib.Size = sizeof(HIDD_ATTRIBUTES); - ret = HidD_GetAttributes(h, &attrib); - // printf("vid: %4x\n", attrib.VendorID); - if (!ret || (vid > 0 && attrib.VendorID != vid) || - (pid > 0 && attrib.ProductID != pid) || - !HidD_GetPreparsedData(h, &hid_data)) { - CloseHandle(h); - continue; - } - - if (!HidP_GetCaps(hid_data, &capabilities) || - (usage_page > 0 && capabilities.UsagePage != usage_page) || - (usage > 0 && capabilities.Usage != usage)) { - HidD_FreePreparsedData(hid_data); - CloseHandle(h); - continue; - } - - HidD_FreePreparsedData(hid_data); - - hid = (struct hid_struct *)malloc(sizeof(struct hid_struct)); - if (!hid) { - CloseHandle(h); - continue; - } - -// COMMTIMEOUTS CommTimeouts; -// CommTimeouts.ReadIntervalTimeout = 100; // 100ms -// CommTimeouts.ReadTotalTimeoutConstant = 5; // ms -// CommTimeouts.ReadTotalTimeoutMultiplier = 1; // -// CommTimeouts.WriteTotalTimeoutConstant = 5; // ms -// CommTimeouts.WriteTotalTimeoutMultiplier = 1; // -// if (!SetCommTimeouts(h, &CommTimeouts)) -// { -//// DWORD err = GetLastError(); -// -// } - - qDebug("Open: Handle address: %li for num: %i", (long int)h, count); - - hid->handle = h; - add_hid(hid); - - count++; - if (count >= max) { - return count; - } - } - - return count; -} - -// recveive - receive a packet -// Inputs: -// num = device to receive from (zero based) -// buf = buffer to receive packet -// len = buffer's size -// timeout = time to wait, in milliseconds -// Output: -// number of bytes received, or -1 on error -// -int pjrc_rawhid::receive(int num, void *buf, int len, int timeout) -{ - OVERLAPPED ov; - DWORD n; - - hid_t *hid = get_hid(num); - - if (!hid) { - return -1; - } - if (!hid->handle) { - return -1; - } - - EnterCriticalSection(&rx_mutex); - - ResetEvent(&rx_event); - - memset(&ov, 0, sizeof(ov)); - ov.hEvent = rx_event; - - if (!ReadFile(hid->handle, buf, len, NULL, &ov)) { - DWORD err = GetLastError(); - - if (err == ERROR_DEVICE_NOT_CONNECTED) { // the device has been unplugged - print_win32_err(err); - hid_close(hid); - LeaveCriticalSection(&rx_mutex); - emit deviceUnplugged(num); - return -1; - } - - if (err != ERROR_IO_PENDING) { - print_win32_err(err); - LeaveCriticalSection(&rx_mutex); - return -1; - } - - DWORD r = WaitForSingleObject(rx_event, timeout); - if (r == WAIT_TIMEOUT) { - CancelIo(hid->handle); - LeaveCriticalSection(&rx_mutex); - return 0; - } - if (r != WAIT_OBJECT_0) { - DWORD err = GetLastError(); - print_win32_err(err); - LeaveCriticalSection(&rx_mutex); - return -1; - } - } - - if (!GetOverlappedResult(hid->handle, &ov, &n, FALSE)) { - DWORD err = GetLastError(); - print_win32_err(err); - - if (err == ERROR_DEVICE_NOT_CONNECTED) { // the device has been unplugged - hid_close(hid); - LeaveCriticalSection(&rx_mutex); - emit deviceUnplugged(num); - return -1; - } - - LeaveCriticalSection(&rx_mutex); - return -1; - } - - LeaveCriticalSection(&rx_mutex); - - if (n <= 0) { - return -1; - } - -// qDebug("Received %i bytes, first %x, second %x", len, *((char *) buf),*((char *)buf + 1)); - - if ((int)n > len) { - n = len; - } - return n; -} - -// send - send a packet -// Inputs: -// num = device to transmit to (zero based) -// buf = buffer containing packet to send -// len = number of bytes to transmit -// timeout = time to wait, in milliseconds -// Output: -// number of bytes sent, or -1 on error -// -int pjrc_rawhid::send(int num, void *buf, int len, int timeout) -{ - OVERLAPPED ov; - DWORD n, r; - - hid_t *hid = get_hid(num); - - if (!hid) { - return -1; - } - if (!hid->handle) { - return -1; - } - -// qDebug("Send: Handle address: %li for num: %i", (long int) hid->handle, num); - - EnterCriticalSection(&tx_mutex); - - ResetEvent(&tx_event); - - memset(&ov, 0, sizeof(ov)); - ov.hEvent = tx_event; - -// qDebug("Trying to write %u bytes. First %x second %x",len, *((char *) buf), *((char *)buf + 1)); - - if (!WriteFile(hid->handle, buf, len, NULL, &ov)) { - DWORD err = GetLastError(); - - if (err == ERROR_DEVICE_NOT_CONNECTED) { // the device has been unplugged - hid_close(hid); - LeaveCriticalSection(&tx_mutex); - emit deviceUnplugged(num); - return -1; - } - - if (err == ERROR_SUCCESS || err == ERROR_IO_PENDING) { -// qDebug("Waiting for write to finish"); - r = WaitForSingleObject(tx_event, timeout); - if (r == WAIT_TIMEOUT) { - CancelIo(hid->handle); - LeaveCriticalSection(&tx_mutex); - return 0; - } - if (r != WAIT_OBJECT_0) { - DWORD err = GetLastError(); - print_win32_err(err); - LeaveCriticalSection(&tx_mutex); - return -1; - } - } else { -// qDebug("Error writing to file"); - print_win32_err(err); - LeaveCriticalSection(&tx_mutex); - return -1; - } - } - - if (!GetOverlappedResult(hid->handle, &ov, &n, FALSE)) { - DWORD err = GetLastError(); - - qDebug("Problem getting overlapped result"); - print_win32_err(err); - - if (err == ERROR_DEVICE_NOT_CONNECTED) { // the device has been unplugged - hid_close(hid); - LeaveCriticalSection(&tx_mutex); - emit deviceUnplugged(num); - return -1; - } - } - - LeaveCriticalSection(&tx_mutex); - - if (n <= 0) { - return -1; - } - return n; -} - -QString pjrc_rawhid::getserial(int num) -{ - hid_t *hid = get_hid(num); - - if (!hid) { - return ""; - } - if (!hid->handle) { - return ""; - } - - // Should we do some "critical section" stuff here?? - char temp[126]; - if (!HidD_GetSerialNumberString(hid->handle, temp, sizeof(temp))) { - DWORD err = GetLastError(); - print_win32_err(err); - - if (err == ERROR_DEVICE_NOT_CONNECTED) { // the device has been unplugged - hid_close(hid); - emit deviceUnplugged(num); - return ""; - } - - return QString("Error"); - } - - return QString().fromUtf16((ushort *)temp, -1); -} - -// close - close a device -// -// Inputs: -// num = device to close (zero based) -// Output -// (nothing) -// -void pjrc_rawhid::close(int num) -{ - hid_close(get_hid(num)); -} - -void pjrc_rawhid::add_hid(hid_t *h) -{ - if (!h) { - return; - } - - if (!first_hid || !last_hid) { - first_hid = last_hid = h; - h->next = h->prev = NULL; - return; - } - - last_hid->next = h; - h->prev = last_hid; - h->next = NULL; - last_hid = h; -} - -hid_t *pjrc_rawhid::get_hid(int num) -{ - hid_t *p; - - for (p = first_hid; p && num > 0; p = p->next, num--) { - ; - } - return p; -} - -void pjrc_rawhid::free_all_hid(void) -{ - for (hid_t *p = first_hid; p; p = p->next) { - hid_close(p); - } - - hid_t *p = first_hid; - while (p) { - hid_t *q = p; - p = p->next; - free(q); - } - - first_hid = last_hid = NULL; -} - -void pjrc_rawhid::hid_close(hid_t *hid) -{ - if (!hid) { - return; - } - if (!hid->handle) { - return; - } - - CloseHandle(hid->handle); - hid->handle = NULL; -} - -void pjrc_rawhid::print_win32_err(DWORD err) -{ - char buf[256]; - char temp[256]; - - // FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, (WCHAR*)buf, sizeof(buf), NULL); - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), (WCHAR *)buf, sizeof(buf), NULL); - WideCharToMultiByte(CP_ACP, 0, (WCHAR *)buf, sizeof(buf), temp, sizeof(temp), NULL, NULL); - printf("err %ld: %s\n", err, temp); -} diff --git a/ground/openpilotgcs/src/plugins/rawhid/rawhid.cpp b/ground/openpilotgcs/src/plugins/rawhid/rawhid.cpp deleted file mode 100644 index 3e3d8a4ad..000000000 --- a/ground/openpilotgcs/src/plugins/rawhid/rawhid.cpp +++ /dev/null @@ -1,465 +0,0 @@ -/** - ****************************************************************************** - * - * @file rawhid.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup RawHIDPlugin Raw HID Plugin - * @{ - * @brief Impliments a HID USB connection to the flight hardware as a QIODevice - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "rawhid.h" - -#include "rawhid_const.h" -#include "coreplugin/connectionmanager.h" -#include -#include -#include -#include -#include - -class IConnection; - -// timeout value used when we want to return directly without waiting -static const int READ_TIMEOUT = 200; -static const int READ_SIZE = 64; - -static const int WRITE_TIMEOUT = 1000; -static const int WRITE_SIZE = 64; - - -// ********************************************************************************* - -/** - * Thread to desynchronize reading from the device - */ -class RawHIDReadThread : public QThread { -public: - RawHIDReadThread(RawHID *hid); - virtual ~RawHIDReadThread(); - - /** Return the data read so far without waiting */ - int getReadData(char *data, int size); - - /** return the bytes buffered */ - qint64 getBytesAvailable(); - -public slots: - void terminate() - { - m_running = false; - } - -protected: - void run(); - - /** QByteArray might not be the most efficient way to implement - a circular buffer but it's good enough and very simple */ - QByteArray m_readBuffer; - - /** A mutex to protect read buffer */ - QMutex m_readBufMtx; - - RawHID *m_hid; - - pjrc_rawhid *hiddev; - int hidno; - - bool m_running; -}; - - -// ********************************************************************************* - -/** - * This class is nearly the same than RawHIDReadThread but for writing - */ -class RawHIDWriteThread : public QThread { -public: - RawHIDWriteThread(RawHID *hid); - virtual ~RawHIDWriteThread(); - - /** Add some data to be written without waiting */ - int pushDataToWrite(const char *data, int size); - - /** Return the number of bytes buffered */ - qint64 getBytesToWrite(); - -public slots: - void terminate() - { - m_running = false; - } - -protected: - void run(); - - /** QByteArray might not be the most efficient way to implement - a circular buffer but it's good enough and very simple */ - QByteArray m_writeBuffer; - - /** A mutex to protect read buffer */ - QMutex m_writeBufMtx; - - /** Synchronize task with data arival */ - QWaitCondition m_newDataToWrite; - - RawHID *m_hid; - - pjrc_rawhid *hiddev; - int hidno; - - bool m_running; -}; - -// ********************************************************************************* - -RawHIDReadThread::RawHIDReadThread(RawHID *hid) - : m_hid(hid), - hiddev(&hid->dev), - hidno(hid->m_deviceNo), - m_running(true) -{ - hid->m_startedMutex->lock(); -} - -RawHIDReadThread::~RawHIDReadThread() -{ - m_running = false; - // wait for the thread to terminate - if (wait(10000) == false) { - qDebug() << "Cannot terminate RawHIDReadThread"; - } -} - -void RawHIDReadThread::run() -{ - m_running = m_hid->openDevice(); - while (m_running) { - // here we use a temporary buffer so we don't need to lock - // the mutex while we are reading from the device - - // Want to read in regular chunks that match the packet size the device - // is using. In this case it is 64 bytes (the interrupt packet limit) - // although it would be nice if the device had a different report to - // configure this - char buffer[READ_SIZE] = { 0 }; - - int ret = hiddev->receive(hidno, buffer, READ_SIZE, READ_TIMEOUT); - - if (ret > 0) { // read some data - QMutexLocker lock(&m_readBufMtx); - // Note: Preprocess the USB packets in this OS independent code - // First byte is report ID, second byte is the number of valid bytes - m_readBuffer.append(&buffer[2], buffer[1]); - - emit m_hid->readyRead(); - } else if (ret == 0) { // nothing read - } else { // < 0 => error - // TODO! make proper error handling, this only quick hack for unplug freeze - m_running = false; - } - } - m_hid->closeDevice(); -} - -int RawHIDReadThread::getReadData(char *data, int size) -{ - QMutexLocker lock(&m_readBufMtx); - - size = qMin(size, m_readBuffer.size()); - - memcpy(data, m_readBuffer.constData(), size); - m_readBuffer.remove(0, size); - - return size; -} - -qint64 RawHIDReadThread::getBytesAvailable() -{ - QMutexLocker lock(&m_readBufMtx); - - return m_readBuffer.size(); -} - -RawHIDWriteThread::RawHIDWriteThread(RawHID *hid) - : m_hid(hid), - hiddev(&hid->dev), - hidno(hid->m_deviceNo), - m_running(true) -{} - -// ********************************************************************************* - -RawHIDWriteThread::~RawHIDWriteThread() -{ - m_running = false; - // wait for the thread to terminate - if (wait(10000) == false) { - qDebug() << "Cannot terminate RawHIDReadThread"; - } -} - -void RawHIDWriteThread::run() -{ - while (m_running) { - char buffer[WRITE_SIZE] = { 0 }; - - m_writeBufMtx.lock(); - int size = qMin(WRITE_SIZE - 2, m_writeBuffer.size()); - while (size <= 0) { - // wait on new data to write condition, the timeout - // enable the thread to shutdown properly - m_newDataToWrite.wait(&m_writeBufMtx, 200); - if (!m_running) { - return; - } - - size = m_writeBuffer.size(); - } - - // NOTE: data size is limited to 2 bytes less than the - // usb packet size (64 bytes for interrupt) to make room - // for the reportID and valid data length - size = qMin(WRITE_SIZE - 2, m_writeBuffer.size()); - memcpy(&buffer[2], m_writeBuffer.constData(), size); - buffer[1] = size; // valid data length - buffer[0] = 2; // reportID - m_writeBufMtx.unlock(); - - // must hold lock through the send to know how much was sent - int ret = hiddev->send(hidno, buffer, WRITE_SIZE, WRITE_TIMEOUT); - - if (ret > 0) { - // only remove the size actually written to the device - QMutexLocker lock(&m_writeBufMtx); - m_writeBuffer.remove(0, size); - - emit m_hid->bytesWritten(ret - 2); - } else if (ret < 0) { // < 0 => error - // TODO! make proper error handling, this only quick hack for unplug freeze - m_running = false; - qDebug() << "Error writing to device"; - } else { - qDebug() << "No data written to device ??"; - } - } -} - -int RawHIDWriteThread::pushDataToWrite(const char *data, int size) -{ - QMutexLocker lock(&m_writeBufMtx); - - m_writeBuffer.append(data, size); - m_newDataToWrite.wakeOne(); // signal that new data arrived - - return size; -} - -qint64 RawHIDWriteThread::getBytesToWrite() -{ - // QMutexLocker lock(&m_writeBufMtx); - return m_writeBuffer.size(); -} - -// ********************************************************************************* - -RawHID::RawHID(const QString &deviceName) - : QIODevice(), - serialNumber(deviceName), - m_deviceNo(-1), - m_readThread(NULL), - m_writeThread(NULL), - m_mutex(NULL) -{ - m_mutex = new QMutex(QMutex::Recursive); - m_startedMutex = new QMutex(); - - // detect if the USB device is unplugged - QObject::connect(&dev, SIGNAL(deviceUnplugged(int)), this, SLOT(onDeviceUnplugged(int))); - - m_writeThread = new RawHIDWriteThread(this); - - // Starting the read thread will lock the m_startexMutex until the - // device is opened (which happens in that thread). - m_readThread = new RawHIDReadThread(this); - m_readThread->start(); - - m_startedMutex->lock(); -} - -/** - * @brief RawHID::openDevice This method opens the USB connection - * It is uses as a callback from the read thread so that the USB - * system code is registered in that thread instead of the calling - * thread (usually UI) - */ -bool RawHID::openDevice() -{ - int opened = dev.open(USB_MAX_DEVICES, USBMonitor::idVendor_OpenPilot, -1, USB_USAGE_PAGE, USB_USAGE); - - for (int i = 0; i < opened; i++) { - if (serialNumber == dev.getserial(i)) { - m_deviceNo = i; - } else { - dev.close(i); - } - } - - // Now things are opened or not (from read thread) allow the constructor to complete - m_startedMutex->unlock(); - - // didn't find the device we are trying to open (shouldnt happen) - device_open = opened >= 0; - if (opened < 0) { - return false; - } - - m_writeThread->start(); - - return true; -} - -/** - * @brief RawHID::closeDevice This method closes the USB connection - * It is uses as a callback from the read thread so that the USB - * system code is unregistered from that thread\ - */ -bool RawHID::closeDevice() -{ - dev.close(m_deviceNo); -} - -RawHID::~RawHID() -{ - // If the read thread exists then the device is open - if (m_readThread) { - close(); - } -} - -void RawHID::onDeviceUnplugged(int num) -{ - if (num != m_deviceNo) { - return; - } - - // the USB device has been unplugged - close(); -} - -bool RawHID::open(OpenMode mode) -{ - QMutexLocker locker(m_mutex); - - if (m_deviceNo < 0) { - return false; - } - - QIODevice::open(mode); - - Q_ASSERT(m_readThread); - Q_ASSERT(m_writeThread); - if (m_readThread) { - m_readThread->start(); - } - if (m_writeThread) { - m_writeThread->start(); - } - - return true; -} - -void RawHID::close() -{ - qDebug() << "RawHID::close()"; - emit aboutToClose(); - if (m_writeThread) { - qDebug() << "About to terminate write thread"; - m_writeThread->terminate(); - delete m_writeThread; - m_writeThread = NULL; - qDebug() << "Write thread terminated"; - } - - - if (m_readThread) { - qDebug() << "About to terminate read thread"; - m_readThread->terminate(); - delete m_readThread; // calls wait - m_readThread = NULL; - qDebug() << "Read thread terminated"; - } - - emit closed(); - - QIODevice::close(); -} - -bool RawHID::isSequential() const -{ - return true; -} - -qint64 RawHID::bytesAvailable() const -{ - QMutexLocker locker(m_mutex); - - if (!m_readThread) { - return -1; - } - - return m_readThread->getBytesAvailable() + QIODevice::bytesAvailable(); -} - -qint64 RawHID::bytesToWrite() const -{ - QMutexLocker locker(m_mutex); - - if (!m_writeThread) { - return -1; - } - - return m_writeThread->getBytesToWrite() + QIODevice::bytesToWrite(); -} - -qint64 RawHID::readData(char *data, qint64 maxSize) -{ - QMutexLocker locker(m_mutex); - - if (!m_readThread || !data) { - return -1; - } - - return m_readThread->getReadData(data, maxSize); -} - -qint64 RawHID::writeData(const char *data, qint64 maxSize) -{ - QMutexLocker locker(m_mutex); - - if (!m_writeThread || !data) { - return -1; - } - - return m_writeThread->pushDataToWrite(data, maxSize); -} - -// ********************************************************************************* diff --git a/ground/openpilotgcs/src/plugins/rawhid/rawhid.h b/ground/openpilotgcs/src/plugins/rawhid/rawhid.h deleted file mode 100644 index 72275b4b4..000000000 --- a/ground/openpilotgcs/src/plugins/rawhid/rawhid.h +++ /dev/null @@ -1,95 +0,0 @@ -/** - ****************************************************************************** - * - * @file rawhid.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup RawHIDPlugin Raw HID Plugin - * @{ - * @brief Impliments a HID USB connection to the flight hardware as a QIODevice - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef RAWHID_H -#define RAWHID_H - -#include "rawhid_global.h" - -#include -#include -#include -#include - -#include "pjrc_rawhid.h" -#include "usbmonitor.h" - -// helper classes -class RawHIDReadThread; -class RawHIDWriteThread; - -/** - * The actual IO device that will be used to communicate - * with the board. - */ -class RAWHID_EXPORT RawHID : public QIODevice { - Q_OBJECT - - friend class RawHIDReadThread; - friend class RawHIDWriteThread; - -public: - RawHID(); - RawHID(const QString &deviceName); - virtual ~RawHID(); - - virtual bool open(OpenMode mode); - virtual void close(); - virtual bool isSequential() const; - -signals: - void closed(); - -public slots: - void onDeviceUnplugged(int num); - -protected: - virtual qint64 readData(char *data, qint64 maxSize); - virtual qint64 writeData(const char *data, qint64 maxSize); - virtual qint64 bytesAvailable() const; - virtual qint64 bytesToWrite() const; - - // ! Callback from the read thread to open the device - bool openDevice(); - - // ! Callback from teh read thread to close the device - bool closeDevice(); - - QString serialNumber; - - int m_deviceNo; - pjrc_rawhid dev; - bool device_open; - - RawHIDReadThread *m_readThread; - RawHIDWriteThread *m_writeThread; - - QMutex *m_mutex; - QMutex *m_startedMutex; -}; - -#endif // RAWHID_H diff --git a/ground/openpilotgcs/src/plugins/rawhid/rawhid.pri b/ground/openpilotgcs/src/plugins/rawhid/rawhid.pri deleted file mode 100644 index 4982d3408..000000000 --- a/ground/openpilotgcs/src/plugins/rawhid/rawhid.pri +++ /dev/null @@ -1,3 +0,0 @@ -include(rawhid_dependencies.pri) - -LIBS *= -l$$qtLibraryName(RawHID) diff --git a/ground/openpilotgcs/src/plugins/rawhid/rawhid.pro b/ground/openpilotgcs/src/plugins/rawhid/rawhid.pro deleted file mode 100644 index f857ef72a..000000000 --- a/ground/openpilotgcs/src/plugins/rawhid/rawhid.pro +++ /dev/null @@ -1,52 +0,0 @@ -TEMPLATE = lib -TARGET = RawHID -include(../../openpilotgcsplugin.pri) -include(rawhid_dependencies.pri) -HEADERS += rawhid_global.h \ - rawhidplugin.h \ - rawhid.h \ - pjrc_rawhid.h \ - rawhid_const.h \ - usbmonitor.h \ - usbsignalfilter.h -SOURCES += rawhidplugin.cpp \ - rawhid.cpp \ - usbsignalfilter.cpp -FORMS += -RESOURCES += -DEFINES += RAWHID_LIBRARY -OTHER_FILES += RawHID.pluginspec - -# Platform Specific USB HID Stuff -win32 { - SOURCES += pjrc_rawhid_win.cpp \ - usbmonitor_win.cpp - LIBS += -lhid \ - -lsetupapi -} -macx { - SOURCES += pjrc_rawhid_mac.cpp \ - usbmonitor_mac.cpp - SDK = /Developer/SDKs/MacOSX10.5.sdk - ARCH = -mmacosx-version-min=10.5 \ - -arch \ - ppc \ - -arch \ - i386 - LIBS += $(ARCH) \ - -Wl,-syslibroot,$(SDK) \ - -framework \ - IOKit \ - -framework \ - CoreFoundation -} -linux-g++ { - SOURCES += pjrc_rawhid_unix.cpp \ - usbmonitor_linux.cpp - LIBS += -lusb -ludev -} -linux-g++-64 { - SOURCES += pjrc_rawhid_unix.cpp \ - usbmonitor_linux.cpp - LIBS += -lusb -ludev -} diff --git a/ground/openpilotgcs/src/plugins/rawhid/rawhid_const.h b/ground/openpilotgcs/src/plugins/rawhid/rawhid_const.h deleted file mode 100644 index 9e58720cf..000000000 --- a/ground/openpilotgcs/src/plugins/rawhid/rawhid_const.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - ****************************************************************************** - * - * @file rawhid_const.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup RawHIDPlugin Raw HID Plugin - * @{ - * @brief Impliments a HID USB connection to the flight hardware as a QIODevice - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef RAWHID_CONST_H -#define RAWHID_CONST_H - -static const int USB_MAX_DEVICES = 10; - -static const int USB_VID = 0x20A0; -static const int USB_PID = 0x4117; - -static const int USB_USAGE_PAGE = 0xFF9C; -static const int USB_USAGE = 0x0001; - -static const int USB_DEV_SERIAL_LEN = 24; - -#endif // RAWHID_CONST_H diff --git a/ground/openpilotgcs/src/plugins/rawhid/rawhid_dependencies.pri b/ground/openpilotgcs/src/plugins/rawhid/rawhid_dependencies.pri deleted file mode 100644 index 0e063b82b..000000000 --- a/ground/openpilotgcs/src/plugins/rawhid/rawhid_dependencies.pri +++ /dev/null @@ -1 +0,0 @@ -include(../../plugins/coreplugin/coreplugin.pri) \ No newline at end of file diff --git a/ground/openpilotgcs/src/plugins/rawhid/rawhid_global.h b/ground/openpilotgcs/src/plugins/rawhid/rawhid_global.h deleted file mode 100644 index 84ab9c0e0..000000000 --- a/ground/openpilotgcs/src/plugins/rawhid/rawhid_global.h +++ /dev/null @@ -1,39 +0,0 @@ -/** - ****************************************************************************** - * - * @file rawhid_global.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup RawHIDPlugin Raw HID Plugin - * @{ - * @brief Impliments a HID USB connection to the flight hardware as a QIODevice - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef RAWHID_GLOBAL_H -#define RAWHID_GLOBAL_H - -#include - -#if defined(RAWHID_LIBRARY) -# define RAWHID_EXPORT Q_DECL_EXPORT -#else -# define RAWHID_EXPORT Q_DECL_IMPORT -#endif - -#endif // RAWHID_GLOBAL_H diff --git a/ground/openpilotgcs/src/plugins/rawhid/rawhidplugin.cpp b/ground/openpilotgcs/src/plugins/rawhid/rawhidplugin.cpp deleted file mode 100644 index 4dd682758..000000000 --- a/ground/openpilotgcs/src/plugins/rawhid/rawhidplugin.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/** - ****************************************************************************** - * - * @file rawhidplugin.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup RawHIDPlugin Raw HID Plugin - * @{ - * @brief Impliments a HID USB connection to the flight hardware as a QIODevice - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "rawhidplugin.h" -#include "rawhid.h" -#include - -#include -#include - -#include "pjrc_rawhid.h" - -#include "rawhid_const.h" - - -// ********************************************************************** - -RawHIDConnection::RawHIDConnection() -{ - // added by andrew - RawHidHandle = NULL; - enablePolling = true; - - m_usbMonitor = USBMonitor::instance(); - - connect(m_usbMonitor, SIGNAL(deviceDiscovered(USBPortInfo)), this, SLOT(onDeviceConnected())); - connect(m_usbMonitor, SIGNAL(deviceRemoved(USBPortInfo)), this, SLOT(onDeviceDisconnected())); -} - -RawHIDConnection::~RawHIDConnection() -{ - if (RawHidHandle) { - if (RawHidHandle->isOpen()) { - RawHidHandle->close(); - } - } -} - -/** - The USB monitor tells us a new device appeared - */ -void RawHIDConnection::onDeviceConnected() -{ - emit availableDevChanged(this); -} - -/** - The USB monitor tells us a device disappeard - */ -void RawHIDConnection::onDeviceDisconnected() -{ - qDebug() << "onDeviceDisconnected()"; - if (enablePolling) { - emit availableDevChanged(this); - } -} - -/** - Returns the list of all currently available devices - */ -QList < Core::IConnection::device> RawHIDConnection::availableDevices() -{ - QList < Core::IConnection::device> devices; - - QList portsList = m_usbMonitor->availableDevices(USBMonitor::idVendor_OpenPilot, -1, -1, USBMonitor::Running); - // We currently list devices by their serial number - device dev; - foreach(USBPortInfo prt, portsList) { - dev.name = prt.serialNumber; - dev.displayName = prt.product; - devices.append(dev); - } - return devices; -} - -QIODevice *RawHIDConnection::openDevice(const QString &deviceName) -{ - // added by andrew - if (RawHidHandle) { - closeDevice(deviceName); - } - // end added by andrew - - // return new RawHID(deviceName); - RawHidHandle = new RawHID(deviceName); - return RawHidHandle; -} - - -void RawHIDConnection::closeDevice(const QString &deviceName) -{ - Q_UNUSED(deviceName); - if (RawHidHandle) { - qDebug() << "Closing the device here"; - RawHidHandle->close(); - delete RawHidHandle; - RawHidHandle = NULL; - } -} - -QString RawHIDConnection::connectionName() -{ - return QString("Raw HID USB"); -} - -QString RawHIDConnection::shortName() -{ - return QString("USB"); -} - -/** - Tells the Raw HID plugin to stop polling for USB devices - */ -void RawHIDConnection::suspendPolling() -{ - enablePolling = false; -} - -/** - Tells the Raw HID plugin to resume polling for USB devices - */ -void RawHIDConnection::resumePolling() -{ - enablePolling = true; -} - -// ********************************************************************** - -RawHIDPlugin::RawHIDPlugin() -{ - hidConnection = NULL; // Pip -} - -RawHIDPlugin::~RawHIDPlugin() -{ - m_usbMonitor->quit(); - m_usbMonitor->wait(500); -} - -void RawHIDPlugin::extensionsInitialized() -{ - hidConnection = new RawHIDConnection(); - addAutoReleasedObject(hidConnection); - - // temp for test - // addAutoReleasedObject(new RawHIDTestThread); -} - -bool RawHIDPlugin::initialize(const QStringList & arguments, QString *errorString) -{ - Q_UNUSED(arguments); - Q_UNUSED(errorString); - - // We have to create the USB Monitor here: - m_usbMonitor = new USBMonitor(this); - - return true; -} - -Q_EXPORT_PLUGIN(RawHIDPlugin) - -// ********************************************************************** diff --git a/ground/openpilotgcs/src/plugins/rawhid/rawhidplugin.h b/ground/openpilotgcs/src/plugins/rawhid/rawhidplugin.h deleted file mode 100644 index 3b241c6e5..000000000 --- a/ground/openpilotgcs/src/plugins/rawhid/rawhidplugin.h +++ /dev/null @@ -1,99 +0,0 @@ -/** - ****************************************************************************** - * - * @file rawhid.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup RawHIDPlugin Raw HID Plugin - * @{ - * @brief Impliments a HID USB connection to the flight hardware as a QIODevice - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef RAWHIDPLUGIN_H -#define RAWHIDPLUGIN_H - -#include "rawhid_global.h" -#include "rawhid.h" -#include "usbmonitor.h" -#include "coreplugin/iconnection.h" -#include - -#include -#include - -class IConnection; -class RawHIDConnection; - - -/** - * Define a connection via the IConnection interface - * Plugin will add a instance of this class to the pool, - * so the connection manager can use it. - */ -class RAWHID_EXPORT RawHIDConnection - : public Core::IConnection { - Q_OBJECT -public: - RawHIDConnection(); - virtual ~RawHIDConnection(); - - virtual QList < Core::IConnection::device> availableDevices(); - virtual QIODevice *openDevice(const QString &deviceName); - virtual void closeDevice(const QString &deviceName); - - virtual QString connectionName(); - virtual QString shortName(); - virtual void suspendPolling(); - virtual void resumePolling(); - - bool deviceOpened() - { - return RawHidHandle != NULL; - } // Pip - -protected slots: - void onDeviceConnected(); - void onDeviceDisconnected(); - -private: - RawHID *RawHidHandle; - bool enablePolling; - -protected: - QMutex m_enumMutex; - USBMonitor *m_usbMonitor; - bool m_deviceOpened; -}; - -class RAWHID_EXPORT RawHIDPlugin - : public ExtensionSystem::IPlugin { - Q_OBJECT - -public: - RawHIDPlugin(); - ~RawHIDPlugin(); - - virtual bool initialize(const QStringList &arguments, QString *error_message); - virtual void extensionsInitialized(); -private: - RawHIDConnection *hidConnection; - USBMonitor *m_usbMonitor; -}; - -#endif // RAWHIDPLUGIN_H diff --git a/ground/openpilotgcs/src/plugins/rawhid/usbmonitor.h b/ground/openpilotgcs/src/plugins/rawhid/usbmonitor.h deleted file mode 100644 index 9dde7e1ec..000000000 --- a/ground/openpilotgcs/src/plugins/rawhid/usbmonitor.h +++ /dev/null @@ -1,202 +0,0 @@ -/** - ****************************************************************************** - * - * @file usbmonitor.h - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup RawHIDPlugin Raw HID Plugin - * @{ - * @brief Monitors the USB bus for devince insertion/removal - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef USBMONITOR_H -#define USBMONITOR_H - -#include "rawhid_global.h" - -#include -#include - -// Depending on the OS, we'll need different things: -#if defined(Q_OS_MAC) -#include -#include -#elif defined(Q_OS_UNIX) - -#include -#include - -#elif defined(Q_OS_WIN32) -#ifndef _WIN32_WINNT - #define _WIN32_WINNT 0x0500 -#endif -#ifndef _WIN32_WINDOWS - #define _WIN32_WINDOWS 0x0500 -#endif -#ifndef WINVER - #define WINVER 0x0500 -#endif -#include -#include -#include -#include -#include -#endif // if defined(Q_OS_MAC) - - -#ifdef Q_OS_WIN -#ifdef QT_GUI_LIB -#include -class USBMonitor; - -class USBRegistrationWidget : public QWidget { - Q_OBJECT -public: - USBRegistrationWidget(USBMonitor *qese) - { - this->qese = qese; - } - ~USBRegistrationWidget() {} - -protected: - USBMonitor *qese; - bool winEvent(MSG *message, long *result); -}; -#endif -#endif - -struct USBPortInfo { - // QString friendName; ///< Friendly name. - // QString physName; - // QString enumName; ///< It seems its the only one with meaning - QString serialNumber; // As a string as it can be anything, really... - QString manufacturer; - QString product; -#if defined(Q_OS_WIN32) - QString devicePath; // only has meaning on windows -#elif defined(Q_OS_MAC) - IOHIDDeviceRef dev_handle; -#endif - int UsagePage; - int Usage; - int vendorID; ///< Vendor ID. - int productID; ///< Product ID - int bcdDevice; -}; - -/** - * A monitoring thread which will wait for device events. - */ - -class RAWHID_EXPORT USBMonitor : public QThread { - Q_OBJECT - -public: - enum RunState { - Bootloader = 0x01, - Running = 0x02 - }; - - enum USBConstants { - idVendor_OpenPilot = 0x20a0, - idProduct_OpenPilot = 0x415a, - idProduct_CopterControl = 0x415b, - idProduct_PipXtreme = 0x415c - }; - - static USBMonitor *instance(); - - USBMonitor(QObject *parent = 0); - ~USBMonitor(); - QList availableDevices(); - QList availableDevices(int vid, int pid, int boardModel, int runState); - #if defined(Q_OS_WIN32) - LRESULT onDeviceChangeWin(WPARAM wParam, LPARAM lParam); - #endif -signals: - /*! - A new device has been connected to the system. - - setUpNotifications() must be called first to enable event-driven device notifications. - Currently only implemented on Windows and OS X. - \param info The device that has been discovered. - */ - void deviceDiscovered(const USBPortInfo & info); - /*! - A device has been disconnected from the system. - - setUpNotifications() must be called first to enable event-driven device notifications. - Currently only implemented on Windows and OS X. - \param info The device that was disconnected. - */ - void deviceRemoved(const USBPortInfo & info); - -private slots: - /** - Callback available for whenever the system that is put in place gets - an event - */ - void deviceEventReceived(); - -private: - - // ! Mutex for modifying the list of available devices - QMutex *listMutex; - - // ! List of known devices maintained by callbacks - QList knowndevices; - - Q_DISABLE_COPY(USBMonitor) - static USBMonitor * m_instance; - - - // Depending on the OS, we'll need different things: -#if defined(Q_OS_MAC) - static void attach_callback(void *context, IOReturn r, void *hid_mgr, IOHIDDeviceRef dev); - static void detach_callback(void *context, IOReturn r, void *hid_mgr, IOHIDDeviceRef dev); - void addDevice(USBPortInfo info); - void removeDevice(IOHIDDeviceRef dev); - IOHIDManagerRef hid_manager; -#elif defined(Q_OS_UNIX) - struct udev *context; - struct udev_monitor *monitor; - QSocketNotifier *monitorNotifier; - USBPortInfo makePortInfo(struct udev_device *dev); -#elif defined(Q_OS_WIN32) - GUID guid_hid; - void setUpNotifications(); - /*! - * Get specific property from registry. - * \param devInfo pointer to the device information set that contains the interface - * and its underlying device. Returned by SetupDiGetClassDevs() function. - * \param devData pointer to an SP_DEVINFO_DATA structure that defines the device instance. - * this is returned by SetupDiGetDeviceInterfaceDetail() function. - * \param property registry property. One of defined SPDRP_* constants. - * \return property string. - */ - static QString getDeviceProperty(HDEVINFO devInfo, PSP_DEVINFO_DATA devData, DWORD property); - static int infoFromHandle(const GUID & guid, USBPortInfo & info, HDEVINFO & devInfo, DWORD & index); - static void enumerateDevicesWin(const GUID & guidDev, QList *infoList); - bool matchAndDispatchChangedDevice(const QString & deviceID, const GUID & guid, WPARAM wParam); -#ifdef QT_GUI_LIB - USBRegistrationWidget *notificationWidget; -#endif -#endif // if defined(Q_OS_MAC) -}; -#endif // USBMONITOR_H diff --git a/ground/openpilotgcs/src/plugins/rawhid/usbmonitor_linux.cpp b/ground/openpilotgcs/src/plugins/rawhid/usbmonitor_linux.cpp deleted file mode 100644 index 7fc9d77c8..000000000 --- a/ground/openpilotgcs/src/plugins/rawhid/usbmonitor_linux.cpp +++ /dev/null @@ -1,201 +0,0 @@ -/** - ****************************************************************************** - * - * @file usbmonitor_linux.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup RawHIDPlugin Raw HID Plugin - * @{ - * @brief Implements the USB monitor on Linux using libudev - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - Need help wihth udev ? - There is a great tuturial at: http://www.signal11.us/oss/udev/ - */ - -#include "usbmonitor.h" -#include - -#define printf qDebug - - -void printPortInfo(struct udev_device *dev) -{ - printf(" Node: %s", udev_device_get_devnode(dev)); - printf(" Subsystem: %s", udev_device_get_subsystem(dev)); - printf(" Devtype: %s", udev_device_get_devtype(dev)); - printf(" Action: %s", udev_device_get_action(dev)); - /* From here, we can call get_sysattr_value() for each file - in the device's /sys entry. The strings passed into these - functions (idProduct, idVendor, serial, etc.) correspond - directly to the files in the directory which represents - the USB device. Note that USB strings are Unicode, UCS2 - encoded, but the strings returned from - udev_device_get_sysattr_value() are UTF-8 encoded. */ - printf(" VID/PID/bcdDevice : %s %s %s", - udev_device_get_sysattr_value(dev, "idVendor"), - udev_device_get_sysattr_value(dev, "idProduct"), - udev_device_get_sysattr_value(dev, "bcdDevice")); - printf(" %s - %s", - udev_device_get_sysattr_value(dev, "manufacturer"), - udev_device_get_sysattr_value(dev, "product")); - printf(" serial: %s", - udev_device_get_sysattr_value(dev, "serial")); -} - - -void USBMonitor::deviceEventReceived() -{ - qDebug() << "Device event"; - struct udev_device *dev; - - dev = udev_monitor_receive_device(this->monitor); - if (dev) { - printf("------- Got Device Event"); - QString action = QString(udev_device_get_action(dev)); - QString devtype = QString(udev_device_get_devtype(dev)); - if (action == "add" && devtype == "usb_device") { - printPortInfo(dev); - emit deviceDiscovered(makePortInfo(dev)); - } else if (action == "remove" && devtype == "usb_device") { - printPortInfo(dev); - emit deviceRemoved(makePortInfo(dev)); - } - - udev_device_unref(dev); - } else { - printf("No Device from receive_device(). An error occured."); - } -} - - -USBMonitor *USBMonitor::instance() -{ - return m_instance; -} - -USBMonitor *USBMonitor::m_instance = 0; - -/** - Initialize the udev monitor here - */ -USBMonitor::USBMonitor(QObject *parent) : QThread(parent) -{ - m_instance = this; - - this->context = udev_new(); - - this->monitor = udev_monitor_new_from_netlink(this->context, "udev"); - udev_monitor_filter_add_match_subsystem_devtype( - this->monitor, "usb", NULL); - udev_monitor_enable_receiving(this->monitor); - this->monitorNotifier = new QSocketNotifier( - udev_monitor_get_fd(this->monitor), QSocketNotifier::Read, this); - connect(this->monitorNotifier, SIGNAL(activated(int)), - this, SLOT(deviceEventReceived())); - qDebug() << "Starting the Udev client"; - - start(); // Start the thread event loop so that the socketnotifier works -} - -USBMonitor::~USBMonitor() -{ - quit(); -} - -/** - Returns a list of all currently available devices - */ -QList USBMonitor::availableDevices() -{ - QList devicesList; - struct udev_list_entry *devices, *dev_list_entry; - struct udev_enumerate *enumerate; - struct udev_device *dev; - - enumerate = udev_enumerate_new(this->context); - udev_enumerate_add_match_subsystem(enumerate, "usb"); -// udev_enumerate_add_match_sysattr(enumerate, "idVendor", "20a0"); - udev_enumerate_scan_devices(enumerate); - devices = udev_enumerate_get_list_entry(enumerate); - // Will use the 'native' udev functions to loop: - udev_list_entry_foreach(dev_list_entry, devices) { - const char *path; - - /* Get the filename of the /sys entry for the device - and create a udev_device object (dev) representing it */ - path = udev_list_entry_get_name(dev_list_entry); - dev = udev_device_new_from_syspath(this->context, path); - if (QString(udev_device_get_devtype(dev)) == "usb_device") { - devicesList.append(makePortInfo(dev)); - } - udev_device_unref(dev); - } - /* free the enumerator object */ - udev_enumerate_unref(enumerate); - - return devicesList; -} - -/** - Be a bit more picky and ask only for a specific type of device: - On OpenPilot, the bcdDeviceLSB indicates the run state: bootloader or running. - bcdDeviceMSB indicates the board model. - */ -QList USBMonitor::availableDevices(int vid, int pid, int bcdDeviceMSB, int bcdDeviceLSB) -{ - QList allPorts = availableDevices(); - QList thePortsWeWant; - - foreach(USBPortInfo port, allPorts) { - if ((port.vendorID == vid || vid == -1) && (port.productID == pid || pid == -1) && ((port.bcdDevice >> 8) == bcdDeviceMSB || bcdDeviceMSB == -1) && - ((port.bcdDevice & 0x00ff) == bcdDeviceLSB || bcdDeviceLSB == -1)) { - thePortsWeWant.append(port); - } - } - return thePortsWeWant; -} - - -USBPortInfo USBMonitor::makePortInfo(struct udev_device *dev) -{ - USBPortInfo prtInfo; - - ////////// - // Debug info - ////////// -#ifdef DEBUG - printPortInfo(dev); -#endif - - - bool ok; - prtInfo.vendorID = QString(udev_device_get_sysattr_value(dev, "idVendor")).toInt(&ok, 16); - prtInfo.productID = QString(udev_device_get_sysattr_value(dev, "idProduct")).toInt(&ok, 16); - prtInfo.serialNumber = QString(udev_device_get_sysattr_value(dev, "serial")); - prtInfo.manufacturer = QString(udev_device_get_sysattr_value(dev, "manufacturer")); - prtInfo.product = QString(udev_device_get_sysattr_value(dev, "product")); -// prtInfo.UsagePage = QString(udev_device_get_sysattr_value(dev,"")); -// prtInfo.Usage = QString(udev_device_get_sysattr_value(dev,"")); - prtInfo.bcdDevice = QString(udev_device_get_sysattr_value(dev, "bcdDevice")).toInt(&ok, 16); - - - return prtInfo; -} diff --git a/ground/openpilotgcs/src/plugins/rawhid/usbmonitor_mac.cpp b/ground/openpilotgcs/src/plugins/rawhid/usbmonitor_mac.cpp deleted file mode 100644 index 19aac0a47..000000000 --- a/ground/openpilotgcs/src/plugins/rawhid/usbmonitor_mac.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/** - ****************************************************************************** - * - * @file usbmonitor_mac.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup RawHIDPlugin Raw HID Plugin - * @{ - * @brief Implements the USB monitor on Mac using XXXXX - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - -#include "usbmonitor.h" -#include -#include -#include -#include -#include -#include - -#define printf qDebug - -// ! Local helper functions -static bool HID_GetIntProperty(IOHIDDeviceRef dev, CFStringRef property, int *value); -static bool HID_GetStrProperty(IOHIDDeviceRef dev, CFStringRef property, QString & value); - -/** - Initialize the USB monitor here - */ -USBMonitor::USBMonitor(QObject *parent) : QThread(parent) -{ - hid_manager = NULL; - IOReturn ret; - - m_instance = this; - - listMutex = new QMutex(); - knowndevices.clear(); - - hid_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone); - if (hid_manager == NULL || CFGetTypeID(hid_manager) != IOHIDManagerGetTypeID()) { - if (hid_manager) { - CFRelease(hid_manager); - } - Q_ASSERT(0); - } - - // No matching filter - IOHIDManagerSetDeviceMatching(hid_manager, NULL); - - // set up a callbacks for device attach & detach - IOHIDManagerScheduleWithRunLoop(hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); - IOHIDManagerRegisterDeviceMatchingCallback(hid_manager, attach_callback, NULL); - IOHIDManagerRegisterDeviceRemovalCallback(hid_manager, detach_callback, NULL); - ret = IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone); - if (ret != kIOReturnSuccess) { - IOHIDManagerUnscheduleFromRunLoop(hid_manager, - CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); - CFRelease(hid_manager); - return; - } - - start(); -} - -USBMonitor::~USBMonitor() -{ - // if(hid_manager != NULL) - // IOHIDManagerUnscheduleFromRunLoop(hid_manager, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); - quit(); -} - -void USBMonitor::deviceEventReceived() -{ - qDebug() << "Device event"; -} - -USBMonitor *USBMonitor::instance() -{ - return m_instance; -} - -USBMonitor *USBMonitor::m_instance = 0; - - -void USBMonitor::removeDevice(IOHIDDeviceRef dev) -{ - for (int i = 0; i < knowndevices.length(); i++) { - USBPortInfo port = knowndevices.at(i); - if (port.dev_handle == dev) { - QMutexLocker locker(listMutex); - knowndevices.removeAt(i); - emit deviceRemoved(port); - return; - } - } -} - -/** - * @brief Static callback for the USB driver to indicate device removed - */ -void USBMonitor::detach_callback(void *context, IOReturn r, void *hid_mgr, IOHIDDeviceRef dev) -{ - Q_UNUSED(context); - Q_UNUSED(r); - Q_UNUSED(hid_mgr); - - qDebug() << "USBMonitor: Device detached event"; - instance()->removeDevice(dev); -} - -void USBMonitor::addDevice(USBPortInfo info) -{ - QMutexLocker locker(listMutex); - - knowndevices.append(info); - emit deviceDiscovered(info); -} - -void USBMonitor::attach_callback(void *context, IOReturn r, void *hid_mgr, IOHIDDeviceRef dev) -{ - Q_UNUSED(context); - Q_UNUSED(r); - Q_UNUSED(hid_mgr); - - bool got_properties = true; - - USBPortInfo deviceInfo; - - deviceInfo.dev_handle = dev; - - qDebug() << "USBMonitor: Device attached event"; - - // Populate the device info structure - got_properties &= HID_GetIntProperty(dev, CFSTR(kIOHIDVendorIDKey), &deviceInfo.vendorID); - got_properties &= HID_GetIntProperty(dev, CFSTR(kIOHIDProductIDKey), &deviceInfo.productID); - got_properties &= HID_GetIntProperty(dev, CFSTR(kIOHIDVersionNumberKey), &deviceInfo.bcdDevice); - got_properties &= HID_GetStrProperty(dev, CFSTR(kIOHIDSerialNumberKey), deviceInfo.serialNumber); - got_properties &= HID_GetStrProperty(dev, CFSTR(kIOHIDProductKey), deviceInfo.product); - got_properties &= HID_GetStrProperty(dev, CFSTR(kIOHIDManufacturerKey), deviceInfo.manufacturer); - // TOOD: Eventually want to take array of usages if devices start needing that - got_properties &= HID_GetIntProperty(dev, CFSTR(kIOHIDPrimaryUsageKey), &deviceInfo.Usage); - got_properties &= HID_GetIntProperty(dev, CFSTR(kIOHIDPrimaryUsagePageKey), &deviceInfo.UsagePage); - - // Currently only enumerating objects that have the complete list of properties - if (got_properties) { - qDebug() << "USBMonitor: Adding device"; - instance()->addDevice(deviceInfo); - } -} - -/** - Returns a list of all currently available devices - */ -QList USBMonitor::availableDevices() -{ - // QMutexLocker locker(listMutex); - return knowndevices; -} - -/** - * @brief Be a bit more picky and ask only for a specific type of device: - * @param[in] vid VID to screen or -1 to ignore - * @param[in] pid PID to screen or -1 to ignore - * @param[in] bcdDeviceMSB MSB of bcdDevice to screen or -1 to ignore - * @param[in] bcdDeviceLSB LSB of bcdDevice to screen or -1 to ignore - * @return List of USBPortInfo that meet this criterion - * @note - * On OpenPilot, the bcdDeviceLSB indicates the run state: bootloader or running. - * bcdDeviceMSB indicates the board model. - */ -QList USBMonitor::availableDevices(int vid, int pid, int bcdDeviceMSB, int bcdDeviceLSB) -{ - QList allPorts = availableDevices(); - QList thePortsWeWant; - - foreach(USBPortInfo port, allPorts) { - if ((port.vendorID == vid || vid == -1) && (port.productID == pid || pid == -1) && ((port.bcdDevice >> 8) == bcdDeviceMSB || bcdDeviceMSB == -1) && - ((port.bcdDevice & 0x00ff) == bcdDeviceLSB || bcdDeviceLSB == -1)) { - thePortsWeWant.append(port); - } - } - - return thePortsWeWant; -} - -/** - * @brief Helper function get get a HID integer property - * @param[in] dev Device reference - * @param[in] property The property to get (constants defined in IOKIT) - * @param[out] value Pointer to integer to set - * @return True if successful, false otherwise - */ -static bool HID_GetIntProperty(IOHIDDeviceRef dev, CFStringRef property, int *value) -{ - CFTypeRef prop = IOHIDDeviceGetProperty(dev, property); - - if (prop) { - if (CFNumberGetTypeID() == CFGetTypeID(prop)) { // if a number - CFNumberGetValue((CFNumberRef)prop, kCFNumberSInt32Type, value); - return true; - } - } - return false; -} - -/** - * @brief Helper function get get a HID string property - * @param[in] dev Device reference - * @param[in] property The property to get (constants defined in IOKIT) - * @param[out] value The QString to set - * @return True if successful, false otherwise - */ -static bool HID_GetStrProperty(IOHIDDeviceRef dev, CFStringRef property, QString & value) -{ - CFTypeRef prop = IOHIDDeviceGetProperty(dev, property); - - if (prop) { - if (CFStringGetTypeID() == CFGetTypeID(prop)) { // if a string - char buffer[2550]; - bool success = CFStringGetCString((CFStringRef)prop, buffer, sizeof(buffer), kCFStringEncodingMacRoman); - value = QString(buffer); - return success; - } - } - return false; -} diff --git a/ground/openpilotgcs/src/plugins/rawhid/usbmonitor_win.cpp b/ground/openpilotgcs/src/plugins/rawhid/usbmonitor_win.cpp deleted file mode 100644 index 04f5c8154..000000000 --- a/ground/openpilotgcs/src/plugins/rawhid/usbmonitor_win.cpp +++ /dev/null @@ -1,376 +0,0 @@ -/** - ****************************************************************************** - * - * @file usbmonitor_win.cpp - * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. - * @addtogroup GCSPlugins GCS Plugins - * @{ - * @addtogroup RawHIDPlugin Raw HID Plugin - * @{ - * @brief Implements the USB monitor on Windows using system API - *****************************************************************************/ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include "usbmonitor.h" -#include -#define printf qDebug - -void USBMonitor::deviceEventReceived() -{ - qDebug() << "Device event"; - // Dispatch and emit the signals here... -} - -USBMonitor *USBMonitor::instance() -{ - return m_instance; -} - -USBMonitor *USBMonitor::m_instance = 0; - - -USBMonitor::USBMonitor(QObject *parent) : QThread(parent) -{ - HidD_GetHidGuid(&guid_hid); - if (!QMetaType::isRegistered(QMetaType::type("USBPortInfo"))) { - qRegisterMetaType("USBPortInfo"); - } -#if (defined QT_GUI_LIB) - notificationWidget = 0; -#endif // Q_OS_WIN - setUpNotifications(); - m_instance = this; -} - -USBMonitor::~USBMonitor() -{ -#if (defined QT_GUI_LIB) - if (notificationWidget) { - delete notificationWidget; - } -#endif - quit(); -} - -/** - Be a bit more picky and ask only for a specific type of device: - On OpenPilot, the bcdDeviceLSB indicates the run state: bootloader or running. - bcdDeviceMSB indicates the board model. - */ -QList USBMonitor::availableDevices(int vid, int pid, int bcdDeviceMSB, int bcdDeviceLSB) -{ - QList allPorts = availableDevices(); - qDebug() << "USBMonitor::availableDevices list off all ports:"; - qDebug() << "USBMonitor::availableDevices total ports:" << allPorts.length(); - foreach(USBPortInfo info, allPorts) { - qDebug() << "----------"; - qDebug() << "bcdDevice:" << info.bcdDevice; - qDebug() << "devicePath:" << info.devicePath; - qDebug() << "product:" << info.product; - } - qDebug() << "END OF LIST"; - QList thePortsWeWant; - qDebug() << "USBMonitor::availableDevices bcdLSB=" << bcdDeviceLSB; - foreach(USBPortInfo port, allPorts) { - qDebug() << "USBMonitorWin:Port VID=" << port.vendorID << "PID=" << port.productID << "bcddevice=" << port.bcdDevice; - if ((port.vendorID == vid || vid == -1) && (port.productID == pid || pid == -1) && ((port.bcdDevice >> 8) == bcdDeviceMSB || bcdDeviceMSB == -1) && - ((port.bcdDevice & 0x00ff) == bcdDeviceLSB || bcdDeviceLSB == -1)) { - thePortsWeWant.append(port); - } - } - qDebug() << "USBMonitor::availableDevices list off matching ports vid pid bcdMSD bcdLSD:" << vid << pid << bcdDeviceMSB << bcdDeviceLSB; - qDebug() << "USBMonitor::availableDevices total matching ports:" << thePortsWeWant.length(); - foreach(USBPortInfo info, thePortsWeWant) { - qDebug() << "----------"; - qDebug() << "bcdDevice:" << info.bcdDevice; - qDebug() << "devicePath:" << info.devicePath; - qDebug() << "product:" << info.product; - } - qDebug() << "END OF LIST"; - return thePortsWeWant; -} - - -// see http://msdn.microsoft.com/en-us/library/ms791134.aspx for list of GUID classes -/*#ifndef GUID_DEVCLASS_PORTS - DEFINE_GUID(GUID_DEVCLASS_PORTS, //0x4d1e55b2, 0xf16f, 0x11cf, 0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30); - //0x745a17a0, 0x74d3, 0x11d0, 0xb6, 0xfe, 0x00, 0xa0, 0xc9, 0x0f, 0x57, 0xda); - 0xA5DCBF10, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED); - #endif - */ -/* Gordon Schumacher's macros for TCHAR -> QString conversions and vice versa */ -#ifdef UNICODE -#define QStringToTCHAR(x) (wchar_t *)x.utf16() -#define PQStringToTCHAR(x) (wchar_t *)x->utf16() -#define TCHARToQString(x) QString::fromUtf16((ushort *)(x)) -#define TCHARToQStringN(x, y) QString::fromUtf16((ushort *)(x), (y)) -#else -#define QStringToTCHAR(x) x.local8Bit().constData() -#define PQStringToTCHAR(x) x->local8Bit().constData() -#define TCHARToQString(x) QString::fromLocal8Bit((x)) -#define TCHARToQStringN(x, y) QString::fromLocal8Bit((x), (y)) -#endif /*UNICODE*/ - -void USBMonitor::setUpNotifications() -{ -#ifdef QT_GUI_LIB - if (notificationWidget) { - return; - } - notificationWidget = new USBRegistrationWidget(this); - - DEV_BROADCAST_DEVICEINTERFACE dbh; - ZeroMemory(&dbh, sizeof(dbh)); - dbh.dbcc_size = sizeof(dbh); - dbh.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; - CopyMemory(&dbh.dbcc_classguid, &guid_hid, sizeof(GUID)); - if (RegisterDeviceNotification(notificationWidget->winId(), &dbh, DEVICE_NOTIFY_WINDOW_HANDLE) == NULL) { - qWarning() << "RegisterDeviceNotification failed:" << GetLastError(); - } - // setting up notifications doesn't tell us about devices already connected - // so get those manually - foreach(USBPortInfo port, availableDevices()) - emit deviceDiscovered(port); -#else - qWarning("GUI not enabled - can't register for device notifications."); -#endif // QT_GUI_LIB -} -LRESULT USBMonitor::onDeviceChangeWin(WPARAM wParam, LPARAM lParam) -{ - if (DBT_DEVICEARRIVAL == wParam || DBT_DEVICEREMOVECOMPLETE == wParam) { - PDEV_BROADCAST_HDR pHdr = (PDEV_BROADCAST_HDR)lParam; - if (pHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { - PDEV_BROADCAST_DEVICEINTERFACE pDevInf = (PDEV_BROADCAST_DEVICEINTERFACE)pHdr; - // delimiters are different across APIs...change to backslash. ugh. - QString deviceID = TCHARToQString(pDevInf->dbcc_name).toUpper().replace("#", "\\"); - matchAndDispatchChangedDevice(deviceID, guid_hid, wParam); - } - } - return 0; -} -#ifdef QT_GUI_LIB -bool USBRegistrationWidget::winEvent(MSG *message, long *result) -{ - if (message->message == WM_DEVICECHANGE) { - qese->onDeviceChangeWin(message->wParam, message->lParam); - *result = 1; - return true; - } - return false; -} -#endif -bool USBMonitor::matchAndDispatchChangedDevice(const QString & deviceID, const GUID & guid, WPARAM wParam) -{ - qDebug() << "USB_MONITOR matchAndDispatchChangedDevice deviceID=" << deviceID; - bool rv = false; - DWORD dwFlag = (DBT_DEVICEARRIVAL == wParam) ? DIGCF_PRESENT : DIGCF_ALLCLASSES; - HDEVINFO devInfo; - if ((devInfo = SetupDiGetClassDevs(&guid, NULL, NULL, dwFlag | DIGCF_DEVICEINTERFACE)) != INVALID_HANDLE_VALUE) { - SP_DEVINFO_DATA spDevInfoData; - spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); - for (DWORD i = 0; SetupDiEnumDeviceInfo(devInfo, i, &spDevInfoData); i++) { - DWORD nSize = 0; - TCHAR buf[MAX_PATH]; - if (SetupDiGetDeviceInstanceId(devInfo, &spDevInfoData, buf, MAX_PATH, &nSize) && - deviceID.contains(TCHARToQString(buf))) { // we found a match - USBPortInfo info; - info.devicePath = deviceID; - if (wParam == DBT_DEVICEARRIVAL) { - qDebug() << "USB_MONITOR INSERTION"; - if (infoFromHandle(guid, info, devInfo, i) != 1) { - qDebug() << "USB_MONITOR infoFromHandle failed on matchAndDispatchChangedDevice"; - break; - } - bool m_break = false; - foreach(USBPortInfo m_info, knowndevices) { - if (m_info.serialNumber == info.serialNumber && m_info.productID == info.productID && m_info.bcdDevice == info.bcdDevice && m_info.devicePath == info.devicePath) { - qDebug() << "USB_MONITOR device already present don't emit signal"; - m_break = true; - } - } - if (m_break) { - break; - } - if (info.bcdDevice == 0 || info.product.isEmpty()) { - qDebug() << "USB_MONITOR empty information on device not emiting signal"; - break; - } - knowndevices.append(info); - qDebug() << "USB_MONITOR emit device discovered on device:" << info.product << info.bcdDevice; - emit deviceDiscovered(info); - break; - } else if (wParam == DBT_DEVICEREMOVECOMPLETE) { - bool found = false; - for (int x = 0; x < knowndevices.count(); ++x) { - if (knowndevices[x].devicePath == deviceID) { - USBPortInfo temp = knowndevices.at(x); - knowndevices.removeAt(x); - qDebug() << "USB_MONITOR emit device removed on device:" << temp.product << temp.bcdDevice; - emit deviceRemoved(temp); - found = true; - break; - } - } - if (!found) { - qDebug() << "USB_MONITOR emit device removed on unknown device"; - emit deviceRemoved(info); - } - } - break; - } - } - SetupDiDestroyDeviceInfoList(devInfo); - } - return rv; -} - -QString USBMonitor::getDeviceProperty(HDEVINFO devInfo, PSP_DEVINFO_DATA devData, DWORD property) -{ - DWORD buffSize = 0; - - SetupDiGetDeviceRegistryProperty(devInfo, devData, property, NULL, NULL, 0, &buffSize); - BYTE *buff = new BYTE[buffSize]; - SetupDiGetDeviceRegistryProperty(devInfo, devData, property, NULL, buff, buffSize, NULL); - QString result = TCHARToQString(buff); - delete[] buff; - return result; -} -/** - Returns a list of all currently available devices - */ -QList USBMonitor::availableDevices() -{ - QList ports; - enumerateDevicesWin(guid_hid, &ports); - // qDebug()<<"USBMonitorWin availabledevices="< *infoList) -{ - HDEVINFO devInfo; - USBPortInfo info; - - // qDebug()<<"enumerateDevicesWin1"; - if ((devInfo = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)) != INVALID_HANDLE_VALUE) { - // qDebug()<<"enumerateDevicesWin2"; - SP_DEVINFO_DATA devInfoData; - devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); - for (DWORD i = 0; SetupDiEnumDeviceInfo(devInfo, i, &devInfoData); i++) { - int r = infoFromHandle(guid, info, devInfo, i); - if (r == 1) { - infoList->append(info); - } else if (r == 0) { - break; - } - } - - SetupDiDestroyDeviceInfoList(devInfo); - } -} - -int USBMonitor::infoFromHandle(const GUID & guid, USBPortInfo & info, HDEVINFO & devInfo, DWORD & index) -{ - // qDebug()<<"index0="<DevicePath); - - free(details); - return 2; - } - // qDebug()<<"index4="<DevicePath).toUpper().replace("#", "\\"); - attrib.Size = sizeof(HIDD_ATTRIBUTES); - ret = HidD_GetAttributes(h, &attrib); - info.vendorID = attrib.VendorID; - info.productID = attrib.ProductID; - info.bcdDevice = attrib.VersionNumber; - - - if (!ret || !HidD_GetPreparsedData(h, &hid_data)) { - CloseHandle(h); - return 2; - } - // qDebug()<<"index5="< -void USBSignalFilter::m_deviceDiscovered(USBPortInfo port) -{ - if ((port.vendorID == m_vid || m_vid == -1) && (port.productID == m_pid || m_pid == -1) && ((port.bcdDevice >> 8) == m_boardModel || m_boardModel == -1) && - ((port.bcdDevice & 0x00ff) == m_runState || m_runState == -1)) { - qDebug() << "USBSignalFilter emit device discovered"; - emit deviceDiscovered(); - } -} - -USBSignalFilter::USBSignalFilter(int vid, int pid, int boardModel, int runState) : - m_vid(vid), - m_pid(pid), - m_boardModel(boardModel), - m_runState(runState) -{ - connect(USBMonitor::instance(), SIGNAL(deviceDiscovered(USBPortInfo)), this, SLOT(m_deviceDiscovered(USBPortInfo))); -} diff --git a/ground/openpilotgcs/src/plugins/rawhid/usbsignalfilter.h b/ground/openpilotgcs/src/plugins/rawhid/usbsignalfilter.h deleted file mode 100644 index a3eafa131..000000000 --- a/ground/openpilotgcs/src/plugins/rawhid/usbsignalfilter.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef USBSIGNALFILTER_H -#define USBSIGNALFILTER_H -#include -#include "usbmonitor.h" - -class RAWHID_EXPORT USBSignalFilter : public QObject { - Q_OBJECT -private: - int m_vid; - int m_pid; - int m_boardModel; - int m_runState; -signals: - void deviceDiscovered(); -private slots: - void m_deviceDiscovered(USBPortInfo port); -public: - USBSignalFilter(int vid, int pid, int boardModel, int runState); -}; -#endif // USBSIGNALFILTER_H diff --git a/package/linux/45-openpilot-permissions.rules b/package/linux/45-openpilot-permissions.rules index d04d31b7f..74e415c39 100644 --- a/package/linux/45-openpilot-permissions.rules +++ b/package/linux/45-openpilot-permissions.rules @@ -3,7 +3,7 @@ SUBSYSTEM=="usb", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="415a", MODE="0664", GROUP="plugdev" # OpenPilot coptercontrol flight control board SUBSYSTEM=="usb", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="415b", MODE="0664", GROUP="plugdev" - # OpenPilot Pipx radio modem board + # OpenPilot OPLink Mini radio modem board SUBSYSTEM=="usb", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="415c", MODE="0664", GROUP="plugdev" # unprogrammed openpilot flight control board SUBSYSTEM=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5750", MODE="0664", GROUP="plugdev" diff --git a/package/linux/deb_common/openpilot.udev b/package/linux/deb_common/openpilot.udev index 3d84dd426..a7852b192 100644 --- a/package/linux/deb_common/openpilot.udev +++ b/package/linux/deb_common/openpilot.udev @@ -4,7 +4,7 @@ SUBSYSTEM=="usb", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="415a", MODE="0664", GROUP="plugdev" # OpenPilot CopterControl flight control board SUBSYSTEM=="usb", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="415b", MODE="0664", GROUP="plugdev" - # OpenPilot Pipx radio modem board + # OpenPilot OPlink Mini radio modem board SUBSYSTEM=="usb", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="415c", MODE="0664", GROUP="plugdev" # OpenPilot CopterControl3D flight control board SUBSYSTEM=="usb", ATTRS{idVendor}=="20a0", ATTRS{idProduct}=="415d", MODE="0664", GROUP="plugdev"