Example #1
0
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;
}
Example #2
0
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);
}
Example #3
0
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;
}
Example #6
0
/* 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);

}
Example #7
0
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);
}
Example #8
0
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;
}
Example #9
0
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;
}
Example #10
0
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();
}
Example #11
0
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;
}
Example #12
0
/* 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);
}
Example #13
0
/* 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);
}