int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds) { int bytes_read = -1; #if 0 int transferred; int res = libusb_interrupt_transfer(dev->device_handle, dev->input_endpoint, data, length, &transferred, 5000); LOG("transferred: %d\n", transferred); return transferred; #endif pthread_mutex_lock(&dev->mutex); /* There's an input report queued up. Return it. */ if (dev->input_reports) { /* Return the first one */ bytes_read = return_data(dev, data, length); goto ret; } if (dev->shutdown_thread) { /* This means the device has been disconnected. An error code of -1 should be returned. */ bytes_read = -1; goto ret; } if (milliseconds == -1) { /* Blocking */ pthread_cond_wait(&dev->condition, &dev->mutex); bytes_read = return_data(dev, data, length); } else if (milliseconds > 0) { /* Non-blocking, but called with timeout. */ int res; struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += milliseconds / 1000; ts.tv_nsec += (milliseconds % 1000) * 1000000; if (ts.tv_nsec >= 1000000000L) { ts.tv_sec++; ts.tv_nsec -= 1000000000L; } res = pthread_cond_timedwait(&dev->condition, &dev->mutex, &ts); if (res == 0) bytes_read = return_data(dev, data, length) ; else bytes_read = 0; } else { /* Purely non-blocking */ bytes_read = 0; } ret: pthread_mutex_unlock(&dev->mutex); return bytes_read; }
void HID_API_EXPORT hid_close(hid_device *dev) { if (!dev) return; /* Cause read_thread() to stop. */ dev->shutdown_thread = 1; libusb_cancel_transfer(dev->transfer); /* Wait for read_thread() to end. */ pthread_join(dev->thread, NULL); /* Clean up the Transfer objects allocated in read_thread(). */ free(dev->transfer->buffer); libusb_free_transfer(dev->transfer); /* release the interface */ libusb_release_interface(dev->device_handle, dev->interface); /* Close the handle */ libusb_close(dev->device_handle); /* Clear out the queue of received reports. */ pthread_mutex_lock(&dev->mutex); while (dev->input_reports) { return_data(dev, NULL, 0); } pthread_mutex_unlock(&dev->mutex); free_hid_device(dev); }
static void read_callback(struct libusb_transfer *transfer) { hid_device *dev = transfer->user_data; if (transfer->status == LIBUSB_TRANSFER_COMPLETED) { struct input_report *rpt = malloc(sizeof(*rpt)); rpt->data = malloc(transfer->actual_length); memcpy(rpt->data, transfer->buffer, transfer->actual_length); rpt->len = transfer->actual_length; rpt->next = NULL; pthread_mutex_lock(&dev->mutex); /* Attach the new report object to the end of the list. */ if (dev->input_reports == NULL) { /* The list is empty. Put it at the root. */ dev->input_reports = rpt; pthread_cond_signal(&dev->condition); } else { /* Find the end of the list and attach. */ struct input_report *cur = dev->input_reports; int num_queued = 0; while (cur->next != NULL) { cur = cur->next; num_queued++; } cur->next = rpt; /* Pop one off if we've reached 30 in the queue. This way we don't grow forever if the user never reads anything from the device. */ if (num_queued > 30) { return_data(dev, NULL, 0); } } pthread_mutex_unlock(&dev->mutex); } else if (transfer->status == LIBUSB_TRANSFER_CANCELLED) { dev->shutdown_thread = 1; return; } else if (transfer->status == LIBUSB_TRANSFER_NO_DEVICE) { dev->shutdown_thread = 1; return; } else if (transfer->status == LIBUSB_TRANSFER_TIMED_OUT) { //LOG("Timeout (normal)\n"); } else { LOG("Unknown transfer code: %d\n", transfer->status); } /* Re-submit the transfer object. */ libusb_submit_transfer(transfer); }
/* response handler */ int asynch_response(int operation, struct snmp_session *sp, int reqid, struct snmp_pdu *pdu, void *magic) { SNMP_INFO *snmpinfo = (SNMP_INFO*)magic; #if 0 static int count = 0; printf("Response:%d\n", count++); #endif if ((operation == NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE)) { return_data(STAT_SUCCESS, snmpinfo->sess, pdu); } else { return_data(STAT_TIMEOUT, snmpinfo->sess, pdu); } /* something went wrong (or end of variables) * this host not active any more */ hosts--; return 1; }
int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length, unsigned int timeout) { int bytes_read = -1; #if 0 int transferred; int res = libusb_interrupt_transfer(dev->device_handle, dev->input_endpoint, data, length, &transferred, timeout); LOG("transferred: %d\n", transferred); return transferred; #endif pthread_mutex_lock(&dev->mutex); /* There's an input report queued up. Return it. */ if (dev->input_reports) { /* Return the first one */ bytes_read = return_data(dev, data, length); goto ret; } if (dev->shutdown_thread) { /* This means the device has been disconnected. An error code of -1 should be returned. */ bytes_read = -1; goto ret; } if (dev->blocking) { pthread_cond_wait(&dev->condition, &dev->mutex); bytes_read = return_data(dev, data, length); } else { bytes_read = 0; } ret: pthread_mutex_unlock(&dev->mutex); return bytes_read; }
/* The Run Loop calls this function for each input report received. This function puts the data into a linked list to be picked up by hid_read(). */ static void hid_report_callback(void *context, IOReturn result, void *sender, IOHIDReportType report_type, uint32_t report_id, uint8_t *report, CFIndex report_length) { struct input_report *rpt; hid_device *dev = context; (void) result; (void) sender; (void) report_type; (void) report_id; /* Make a new Input Report object */ rpt = calloc(1, sizeof(struct input_report)); rpt->data = calloc(1, report_length); memcpy(rpt->data, report, report_length); rpt->len = report_length; rpt->next = NULL; /* Lock this section */ pthread_mutex_lock(&dev->mutex); /* Attach the new report object to the end of the list. */ if (dev->input_reports == NULL) { /* The list is empty. Put it at the root. */ dev->input_reports = rpt; } else { /* Find the end of the list and attach. */ struct input_report *cur = dev->input_reports; int num_queued = 0; while (cur->next != NULL) { cur = cur->next; num_queued++; } cur->next = rpt; /* Pop one off if we've reached 30 in the queue. This way we don't grow forever if the user never reads anything from the device. */ if (num_queued > 30) { return_data(dev, NULL, 0); } } /* Signal a waiting thread that there is data. */ pthread_cond_signal(&dev->condition); /* Unlock */ pthread_mutex_unlock(&dev->mutex); }
void HID_API_EXPORT hid_close(hid_device *dev) { if ( !dev ) { return; } /* Disconnect the report callback before close. */ if (!dev->disconnected) { IOHIDDeviceRegisterInputReportCallback( dev->device_handle, dev->input_report_buf, dev->max_input_report_len, NULL, dev); IOHIDManagerRegisterDeviceRemovalCallback(hid_mgr, NULL, dev); IOHIDDeviceUnscheduleFromRunLoop(dev->device_handle, dev->run_loop, dev->run_loop_mode); IOHIDDeviceScheduleWithRunLoop(dev->device_handle, CFRunLoopGetMain(), kCFRunLoopDefaultMode); } /* Cause read_thread() to stop. */ dev->shutdown_thread = 1; /* Wake up the run thread's event loop so that the thread can exit. */ CFRunLoopSourceSignal(dev->source); CFRunLoopWakeUp(dev->run_loop); /* Notify the read thread that it can shut down now. */ pthread_barrier_wait(&dev->shutdown_barrier); /* Wait for read_thread() to end. */ pthread_join(dev->thread, NULL); /* Close the OS handle to the device, but only if it's not been unplugged. If it's been unplugged, then calling IOHIDDeviceClose() will crash. */ if (!dev->disconnected) { IOHIDDeviceClose(dev->device_handle, kIOHIDOptionsTypeNone); } /* Clear out the queue of received reports. */ pthread_mutex_lock(&dev->mutex); while (dev->input_reports) { return_data(dev, NULL, 0); } pthread_mutex_unlock(&dev->mutex); free_hid_device(dev); }
int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds) { int bytes_read = -1; #if 0 int transferred; int res = libusb_interrupt_transfer(dev->device_handle, dev->input_endpoint, data, length, &transferred, 5000); LOG("transferred: %d\n", transferred); return transferred; #endif pthread_mutex_lock(&dev->mutex); pthread_cleanup_push(&cleanup_mutex, dev); /* There's an input report queued up. Return it. */ if (dev->input_reports) { /* Return the first one */ bytes_read = return_data(dev, data, length); goto ret; } if (dev->shutdown_thread) { /* This means the device has been disconnected. An error code of -1 should be returned. */ bytes_read = -1; goto ret; } if (milliseconds == -1) { /* Blocking */ while (!dev->input_reports && !dev->shutdown_thread) { pthread_cond_wait(&dev->condition, &dev->mutex); } if (dev->input_reports) { bytes_read = return_data(dev, data, length); } } else if (milliseconds > 0) { /* Non-blocking, but called with timeout. */ int res; struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += milliseconds / 1000; ts.tv_nsec += (milliseconds % 1000) * 1000000; if (ts.tv_nsec >= 1000000000L) { ts.tv_sec++; ts.tv_nsec -= 1000000000L; } while (!dev->input_reports && !dev->shutdown_thread) { res = pthread_cond_timedwait(&dev->condition, &dev->mutex, &ts); if (res == 0) { if (dev->input_reports) { bytes_read = return_data(dev, data, length); break; } /* If we're here, there was a spurious wake up or the read thread was shutdown. Run the loop again (ie: don't break). */ } else if (res == ETIMEDOUT) { /* Timed out. */ bytes_read = 0; break; } else { /* Error. */ bytes_read = -1; break; } } } else { /* Purely non-blocking */ bytes_read = 0; } ret: pthread_mutex_unlock(&dev->mutex); pthread_cleanup_pop(0); return bytes_read; }
int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds) { int bytes_read = -1; /* Lock the access to the report list. */ pthread_mutex_lock(&dev->mutex); /* There's an input report queued up. Return it. */ if (dev->input_reports) { /* Return the first one */ bytes_read = return_data(dev, data, length); goto ret; } /* Return if the device has been disconnected. */ if (dev->disconnected) { bytes_read = -1; goto ret; } if (dev->shutdown_thread) { /* This means the device has been closed (or there has been an error. An error code of -1 should be returned. */ bytes_read = -1; goto ret; } /* There is no data. Go to sleep and wait for data. */ if (milliseconds == -1) { /* Blocking */ int res; res = cond_wait(dev, &dev->condition, &dev->mutex); if (res == 0) bytes_read = return_data(dev, data, length); else { /* There was an error, or a device disconnection. */ bytes_read = -1; } } else if (milliseconds > 0) { /* Non-blocking, but called with timeout. */ int res; struct timespec ts; struct timeval tv; gettimeofday(&tv, NULL); TIMEVAL_TO_TIMESPEC(&tv, &ts); ts.tv_sec += milliseconds / 1000; ts.tv_nsec += (milliseconds % 1000) * 1000000; if (ts.tv_nsec >= 1000000000L) { ts.tv_sec++; ts.tv_nsec -= 1000000000L; } res = cond_timedwait(dev, &dev->condition, &dev->mutex, &ts); if (res == 0) bytes_read = return_data(dev, data, length); else if (res == ETIMEDOUT) bytes_read = 0; else bytes_read = -1; } else { /* Purely non-blocking */ bytes_read = 0; } ret: /* Unlock */ pthread_mutex_unlock(&dev->mutex); return bytes_read; }
void Cconditions_list_box::edit_condition(quint32 i) { Cconditions_list_boxItemDialog* dg= new Cconditions_list_boxItemDialog( this, this->projectPath ); QObject::connect( dg, SIGNAL(return_data(QString)), this->entries[i], SLOT(setData(QString)) ); //setting existing data //-> parsinf code to line QString line = this->entries[i]->btn_value_edit->text(); line.remove( "|" ); if ( line.contains( "swi" ) ) { //now we now it must be radio case 1 or 2 line.remove("swi"); //case 1 if ( line.contains( "ON" ) ) { //case1::1-ON dg->bool1_0rad->click(); line.remove("ON"); dg->bool1_2state->setCurrentIndex( 1 ); line = line.simplified(); dg->bool1_1boolIndex_box->setCurrentIndex( line.toInt() ); } else if ( line.contains( "OFF" ) ) { //case1::2-OFF dg->bool1_0rad->click(); line.remove("OFF"); dg->bool1_2state->setCurrentIndex( 0 ); line = line.simplified(); dg->bool1_1boolIndex_box->setCurrentIndex( line.toInt() ); } //case2 else if ( line.contains( "!=" ) ) { //case2::1-NotEqual dg->bool2_0rad->click(); QStringList iz = line.split( "!=" ); dg->bool2_1bool1Index_box->setCurrentIndex( iz[0].toInt() ); dg->bool2_2comperator_box->setCurrentIndex( 0 ); dg->bool2_3bool2Index_box->setCurrentIndex( iz[1].toInt() ); } else if ( line.contains( "==" ) ) { //case2::2-Equal dg->bool2_0rad->click(); QStringList iz = line.split( "==" ); dg->bool2_1bool1Index_box->setCurrentIndex( iz[0].toInt() ); dg->bool2_2comperator_box->setCurrentIndex( 1 ); dg->bool2_3bool2Index_box->setCurrentIndex( iz[1].toInt() ); } else { /*Apocalypse code here*/ } } else if ( line.contains( "var" ) ) { //now we now it must be radio case 3 or 4 line.remove("var"); if ( line.contains( "const" ) ) { //case3 dg->var1_0rad->click(); line.remove("const"); //get values per dividor QStringList iz; if (line.contains("!=") ) { iz = line.split( "!=" ); dg->var1_2comperator->setCurrentIndex( 0 ); } else if ( line.contains("==") ) { iz = line.split("=="); dg->var1_2comperator->setCurrentIndex( 1 ); } else if ( line.contains(">") ) { iz = line.split( ">" ); dg->var1_2comperator->setCurrentIndex( 2 ); } else { iz = line.split( "<" ); dg->var1_2comperator->setCurrentIndex( 3 ); } dg->var1_1varIndex_box->setCurrentIndex( iz[0].toInt() ); dg->var1_3const_value_spinbox->setValue( iz[1].toInt() ); } else { //case4 dg->var2_0rad->click(); line.remove("var"); //get values per dividor QStringList iz; if (line.contains("!=") ) { iz = line.split( "!=" ); dg->var2_2comperator_box->setCurrentIndex( 0 ); } else if ( line.contains("==") ) { iz = line.split("=="); dg->var2_2comperator_box->setCurrentIndex( 1 ); } else if ( line.contains(">") ) { iz = line.split( ">" ); dg->var2_2comperator_box->setCurrentIndex( 2 ); } else { iz = line.split( "<" ); dg->var2_2comperator_box->setCurrentIndex( 3 ); } dg->var2_1var1Index_box->setCurrentIndex( iz[0].toInt() ); dg->var2_3var2Index_box->setCurrentIndex( iz[1].toInt() ); } } else{ /*Apocalypse here*/ } dg->exec(); }
int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length) { int ret_val = -1; /* Lock this function */ pthread_mutex_lock(&dev->mutex); /* There's an input report queued up. Return it. */ if (dev->input_reports) { /* Return the first one */ ret_val = return_data(dev, data, length); goto ret; } /* Return if the device has been disconnected. */ if (dev->disconnected) { ret_val = -1; goto ret; } /* There are no input reports queued up. Need to get some from the OS. */ /* Move the device's run loop to this thread. */ IOHIDDeviceScheduleWithRunLoop(dev->device_handle, CFRunLoopGetCurrent(), dev->run_loop_mode); if (dev->blocking) { /* Run the Run Loop until it stops timing out. In other words, until something happens. This is necessary because there is no INFINITE timeout value. */ SInt32 code; while (1) { code = CFRunLoopRunInMode(dev->run_loop_mode, 1000, TRUE); /* Return if the device has been disconnected */ if (code == kCFRunLoopRunFinished) { dev->disconnected = 1; ret_val = -1; goto ret; } /* Return if some data showed up. */ if (dev->input_reports) break; /* Break if The Run Loop returns Finished or Stopped. */ if (code != kCFRunLoopRunTimedOut && code != kCFRunLoopRunHandledSource) break; } /* See if the run loop and callback gave us any reports. */ if (dev->input_reports) { ret_val = return_data(dev, data, length); goto ret; } else { dev->disconnected = 1; ret_val = -1; /* An error occured (maybe CTRL-C?). */ goto ret; } } else { /* Non-blocking. See if the OS has any reports to give. */ SInt32 code; code = CFRunLoopRunInMode(dev->run_loop_mode, 0, TRUE); if (code == kCFRunLoopRunFinished) { /* The run loop is finished, indicating an error or the device had been disconnected. */ dev->disconnected = 1; ret_val = -1; goto ret; } if (dev->input_reports) { /* Return the first one */ ret_val = return_data(dev, data, length); goto ret; } else { ret_val = 0; /* No data*/ goto ret; } } ret: /* Unlock */ pthread_mutex_unlock(&dev->mutex); return ret_val; }
/* Return a list of file names for input devices being used, separated by null characters. This call is optional; clients should not depend on it. */ error_t S_login_get_input_devices(file_t utmp, char **buf, unsigned *len) { return return_data(devices, devices_len, buf, len); }
/* Return a human-readable string describing the user's physical location. */ error_t S_login_get_location(file_t utmp, char **buf, unsigned *len) { return return_data(location, strlen(location) + 1, buf, len); }