Пример #1
0
//  rawhid_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 rawhid_send(int num, void *buf, int len, int timeout)
{
	hid_t *hid;
	unsigned char tmpbuf[516];
	OVERLAPPED ov;
	DWORD n, r;

	if (sizeof(tmpbuf) < len + 1) return -1;
	hid = get_hid(num);
	if (!hid || !hid->open) return -1;
	EnterCriticalSection(&tx_mutex);
	ResetEvent(&tx_event);
	memset(&ov, 0, sizeof(ov));
	ov.hEvent = tx_event;
	tmpbuf[0] = 0;
	memcpy(tmpbuf + 1, buf, len);
	if (!WriteFile(hid->handle, tmpbuf, len + 1, NULL, &ov)) {
		if (GetLastError() != ERROR_IO_PENDING) goto return_error;
		r = WaitForSingleObject(tx_event, timeout);
		if (r == WAIT_TIMEOUT) goto return_timeout;
		if (r != WAIT_OBJECT_0) goto return_error;
	}
	if (!GetOverlappedResult(hid->handle, &ov, &n, FALSE)) goto return_error;
	LeaveCriticalSection(&tx_mutex);
	if (n <= 0) return -1;
	return n - 1;
return_timeout:
	CancelIo(hid->handle);
	LeaveCriticalSection(&tx_mutex);
	return 0;
return_error:
	print_win32_err();
	LeaveCriticalSection(&tx_mutex);
	return -1;
}
Пример #2
0
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);
}
Пример #3
0
//  rawhid_close - close a device
//
//    Inputs:
//	num = device to close (zero based)
//    Output
//	(nothing)
//
void rawhid_close(int num)
{
	hid_t *hid;

	hid = get_hid(num);
	if (!hid || !hid->open) return;
	hid_close(hid);
}
Пример #4
0
//  close - close a device
//
//    Inputs:
//	num = device to close (zero based)
//    Output
//	(nothing)
//
void pjrc_rawhid::close(int num)
{
    hid_t *hid;

    hid = get_hid(num);
    if (!hid || !hid->open) return;
    hid_close(hid);
    hid->open = 0;
}
Пример #5
0
//  rawhid_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 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, buf, len, timeout);
	} else {
		return usb_control_msg(hid->usb, 0x21, 9, 0, hid->iface, buf, len, timeout);
	}
}
Пример #6
0
//  rawhid_recv - 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 rawhid_recv(int num, void *buf, int len, int timeout)
{
	hid_t *hid;
	int r;

	hid = get_hid(num);
	if (!hid || !hid->open) return -1;
	r = usb_interrupt_read(hid->usb, hid->ep_in, buf, len, timeout);
	if (r >= 0) return r;
	if (r == -110) return 0;  // timeout
	return -1;
}
Пример #7
0
//  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)
{
   hid_t *hid;
   buffer_t *b;
   CFRunLoopTimerRef timer=NULL;
   CFRunLoopTimerContext context;
   int ret=0, timeout_occurred=0;

   if (len < 1) return 0;
   hid = get_hid(num);
   if (!hid || !hid->open) return -1;
   if ((b = hid->first_buffer) != NULL) {
       if (len > b->len) len = b->len;
       memcpy(buf, b->buf, len);
       hid->first_buffer = b->next;
       free(b);
       return len;
   }
   memset(&context, 0, sizeof(context));
   context.info = &timeout_occurred;
   timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent() +
                                (double)timeout / 1000.0, 0, 0, 0, timeout_callback, &context);
   CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopDefaultMode);
   the_correct_runloop = CFRunLoopGetCurrent();
   //qDebug("--");
   while (1) {
       //qDebug(".");
       CFRunLoopRun(); // Found the problem: somehow the input_callback does not
                       // stop this CFRunLoopRun because it is hooked to a different run loop !!!
                       // Hence the use of the "correct_runloop" variable above.
       //qDebug("  ..");

       if ((b = hid->first_buffer) != NULL) {
           if (len > b->len) len = b->len;
           memcpy(buf, b->buf, len);
           hid->first_buffer = b->next;
           free(b);
           ret = len;
           //qDebug("*************");
           break;
       }
       if (!hid->open) {
           printf("pjrc_rawhid_recv, device not open\n");
           ret = -1;
           break;
       }
       if (timeout_occurred)
            break;
   }
   CFRunLoopTimerInvalidate(timer);
   CFRelease(timer);
   return ret;
}
Пример #8
0
//  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;
    int result=-100;

    hid = get_hid(num);
    if (!hid || !hid->open) return -1;
#if 1
#warning "Send timeout not implemented on MACOSX"
    uint8_t *report_buf = (uint8_t *) malloc(len);
    memcpy(&report_buf[0], buf,len);
    // Note: packet processing done in OS indepdent code
    IOReturn ret = IOHIDDeviceSetReport(hid->ref, kIOHIDReportTypeOutput, 2, (uint8_t *)report_buf, len);
    result = (ret == kIOReturnSuccess) ? len : -1;
    if (err_get_system(ret) == err_get_system(sys_iokit))
    {

        // The error was in the I/O Kit system
        UInt32 codeValue = err_get_code(ret);
        qDebug("Returned: %x", codeValue);
        // Can now perform test on error code, display it to user, or whatever.
        usleep(1000000);
    }

#endif
#if 0
    // No matter what I tried this never actually sends an output
    // report and output_callback never gets called.  Why??
    // Did I miss something?  This is exactly the same params as
    // the sync call that works.  Is it an Apple bug?
    // (submitted to Apple on 22-sep-2009, problem ID 7245050)
    //
    IOHIDDeviceScheduleWithRunLoop(hid->ref, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
    // should already be scheduled with run loop by attach_callback,
    // sadly this doesn't make any difference either way
    //
    IOHIDDeviceSetReportWithCallback(hid->ref, kIOHIDReportTypeOutput,
                                     0, buf, len, (double)timeout / 1000.0, output_callback, &result);
    while (1) {
        printf("enter run loop (send)\n");
        CFRunLoopRun();
        printf("leave run loop (send)\n");
        if (result > -100) break;
        if (!hid->open) {
            result = -1;
            break;
        }
    }
#endif
    return result;
}
Пример #9
0
int rawhid_recv(int num, void *buf, int len, int timeout)
{
   //fprintf(stderr,"rawhid_recv start len: %d\n",len);
   //fprintf(stderr,"rawhid_recv start \n");
   hid_t *hid;
	buffer_t *b;
	CFRunLoopTimerRef timer=NULL;
	CFRunLoopTimerContext context;
	int ret=0, timeout_occurred=0;
   
	if (len < 1) return 0;
	hid = get_hid(num);
	if (!hid || !hid->open) return -1;
	if ((b = hid->first_buffer) != NULL)
   {
		if (len > b->len) len = b->len;
		memcpy(buf, b->buf, len);
		hid->first_buffer = b->next;
		free(b);
     // fprintf(stderr,"rawhid_recv A len: %d\n\n",len);
		return len;
	}
	memset(&context, 0, sizeof(context));
	context.info = &timeout_occurred;
	timer = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent() +
                                (double)timeout / 1000.0, 0, 0, 0, timeout_callback, &context);
	CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopDefaultMode);
	while (1) {
		CFRunLoopRun();
		if ((b = hid->first_buffer) != NULL) {
			if (len > b->len) len = b->len;
			memcpy(buf, b->buf, len);
			hid->first_buffer = b->next;
			free(b);
			ret = len;
			break;
		}
		if (!hid->open) {
			//printf("rawhid_recv, device not open\n");
			ret = -1;
			break;
		}
		if (timeout_occurred) break;
	}
	CFRunLoopTimerInvalidate(timer);
	CFRelease(timer);
   //fprintf(stderr,"rawhid_recv ret: %d\n",ret);
	return ret;
   
}
Пример #10
0
//  rawhid_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 rawhid_send(int num, void *buf, int len, int timeout)
{
   //fprintf(stderr,"rawhid_send num: %d\n",num);
	hid_t *hid;
	int result=-100;
   
	hid = get_hid(num);
	if (!hid || !hid->open) return -1;
   //fprintf(stderr,"rawhid_send A\n");
#if 1
#warning "Send timeout not implemented on MACOSX"
	IOReturn ret = IOHIDDeviceSetReport(hid->ref, kIOHIDReportTypeOutput, 0, buf, len);
	result = (ret == kIOReturnSuccess) ? len : -1;
   //fprintf(stderr,"rawhid_send B result: %d\n",result);
#endif
#if 0
	// No matter what I tried this never actually sends an output
	// report and output_callback never gets called.  Why??
	// Did I miss something?  This is exactly the same params as
	// the sync call that works.  Is it an Apple bug?
	// (submitted to Apple on 22-sep-2009, problem ID 7245050)
	//
   fprintf(stderr,"rawhid_send C\n");
	IOHIDDeviceScheduleWithRunLoop(hid->ref, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
	// should already be scheduled with run loop by attach_callback,
	// sadly this doesn't make any difference either way
	//
	IOHIDDeviceSetReportWithCallback(hid->ref, kIOHIDReportTypeOutput,
                                    0, buf, len, (double)timeout / 1000.0, output_callback, &result);
   //fprintf(stderr,"rawhid_send D\n");
	while (1) 
   {
		fprintf(stderr,"enter run loop (send)\n");
		CFRunLoopRun();
		fprintf(stderr,"leave run loop (send)\n");
		if (result > -100) break;
		if (!hid->open) 
      {
			result = -1;
			break;
		}
	}
#endif
   fprintf(stderr,"rawhid_send result: %d\n",result);
	return result;
}
Пример #11
0
const char* get_prod()
{
   hid_t * cnc = get_hid(0);
   if (cnc)
   {
      CFTypeRef prod= IOHIDDeviceGetProperty(cnc->ref,CFSTR(kIOHIDProductKey));
      //CFStringRef manu = (CFStringRef)prop;
      const char* prodstr = CFStringGetCStringPtr(prod, kCFStringEncodingMacRoman);
      //fprintf(stderr,"prodstr: %s\n",prodstr);
      
      return  prodstr; 
   }
   else 
   {
      return "*\n";
   }
}
Пример #12
0
const char* get_manu()
{
   hid_t * cnc = get_hid(0);
   if (cnc)
   {
      CFTypeRef manu= IOHIDDeviceGetProperty(cnc->ref,CFSTR(kIOHIDManufacturerKey));
      //CFStringRef manu = (CFStringRef)prop;
      
      const char* manustr = CFStringGetCStringPtr(manu, kCFStringEncodingMacRoman);
      //fprintf(stderr,"manustr: %s\n",manustr);   
      return  manustr; 
   }
   else 
   {
      return "Kein USB-Device vorhanden\n";
   }
   
}
Пример #13
0
QString pjrc_rawhid::getserial(int num) {
    hid_t *hid;
    char buf[128];

    hid = get_hid(num);

    if (!hid || !hid->open) return QString("Error");

    CFTypeRef serialnum = IOHIDDeviceGetProperty(hid->ref, 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 = (CFStringRef)serialnum;
        const char * buf = CFStringGetCStringPtr(str, kCFStringEncodingMacRoman);
        return QString(buf);
    }

    return QString("Error");
}
Пример #14
0
//  close - close a device
//
//    Inputs:
//      num = device to close (zero based)
//    Output
//      (nothing)
//
void pjrc_rawhid::close(int num)
{
        hid_close(get_hid(num));
}
Пример #15
0
//  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;
}
Пример #16
0
//  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;
}