24 #include <libusb-1.0/libusb.h> 47 int errorcode = libusb_init(&(*context).usb_link);
48 if (errorcode != LIBUSB_SUCCESS) {
49 printf(
"[liblabpro FATAL] Error initializing liblabpro: %s\n", libusb_strerror(errorcode));
52 libusb_set_debug((*context).usb_link, LIBUSB_LOG_LEVEL_DEBUG);
54 libusb_set_debug((*context).usb_link, LIBUSB_LOG_LEVEL_WARNING);
60 libusb_exit((*context).usb_link);
64 libusb_device** usb_list;
68 cnt = libusb_get_device_list((*context).usb_link, &usb_list);
74 struct libusb_device_descriptor desc;
76 for (ssize_t i = 0; i < cnt && lp_list.
num < 5; ++i) {
77 libusb_get_device_descriptor(usb_list[i], &desc);
78 if (desc.idVendor == 0x08f7 && desc.idProduct == 1) {
80 libusb_device_handle *dev_handle = NULL;
82 if ((open_err = libusb_open(usb_list[i], &dev_handle)) != LIBUSB_SUCCESS) {
83 printf(
"[liblabpro ERR] Unable to open libusb device: %s\n", libusb_strerror(open_err));
87 if (libusb_kernel_driver_active(dev_handle, 0) == 1) {
88 int detach_error = libusb_detach_kernel_driver(dev_handle, 0);
89 if (detach_error != 0) {
90 printf(
"[liblabpro ERR] Unable to detach kernel driver from interface 0 of LabPro %d: %s\n", lp_list.
num, libusb_strerror(detach_error));
91 libusb_close(dev_handle);
95 printf(
"[liblabpro MSG] Successfully detached kernel driver.\n");
103 int config_setting_err = libusb_set_configuration(dev_handle, 1);
104 if (config_setting_err != 0) {
105 printf(
"[liblabpro ERR] Unable to set configuration to 1 on LabPro %d: %s\n", lp_list.
num, libusb_strerror(config_setting_err));
106 libusb_close(dev_handle);
111 int interface_claim_error;
112 if ((interface_claim_error = libusb_claim_interface(dev_handle, 1)) != 0) {
113 printf(
"[liblabpro ERR] Unable to claim interface 0 of LabPro %d: %s\n", lp_list.
num, libusb_strerror(interface_claim_error));
114 libusb_close(dev_handle);
119 struct libusb_config_descriptor* config;
121 if ((config_desc_err = libusb_get_config_descriptor(usb_list[i], 0, &config)) != 0) {
122 printf(
"[liblabpro ERR] Unable to get descriptor of first configuration of LabPro %d: %s\n", lp_list.
num, libusb_strerror(config_desc_err));
123 libusb_close(dev_handle);
126 struct libusb_endpoint_descriptor ep_desc;
127 unsigned char in_addr;
128 unsigned char out_addr;
129 bool in_endpt_found =
false;
130 bool out_endpt_found =
false;
131 for (uint8_t i = 1; i <= config->interface[0].altsetting[0].bNumEndpoints; ++i) {
132 ep_desc = config->interface[0].altsetting[0].endpoint[i];
135 if ((ep_desc.bmAttributes & 0b00000011) != LIBUSB_TRANSFER_TYPE_BULK)
137 printf(
"[liblabpro ERR] LabPro %d had unexpected non-bulk endpoint.\n", lp_list.
num);
147 unsigned char address = ep_desc.bEndpointAddress & 0b00001111;
148 if ((ep_desc.bEndpointAddress & 0b10000000) == LIBUSB_ENDPOINT_IN) {
150 in_endpt_found =
true;
154 out_endpt_found =
true;
157 if (!in_endpt_found && !out_endpt_found) {
158 printf(
"[liblabpro ERR] No bulk endpoints found for LabPro %d.\n", lp_list.
num);
159 libusb_close(dev_handle);
176 libusb_free_device_list(usb_list, 1);
196 unsigned char *cmd_str = (
unsigned char *)malloc(6);
206 int *found_errors = (
int *)calloc(5,
sizeof(
int));
221 *errors = found_errors;
229 if ((command = realloc(command, strlen(command) + 2)) == NULL)
232 char* real_command = strcat(command,
"\r");
233 *length_transferred = 0;
234 int len = strlen(real_command);
239 int numpackets = len / 64;
243 for (
int i = 1; i <= numpackets; ++i) {
246 if (i == numpackets && len % 64 != 0)
251 status = libusb_bulk_transfer(
254 (
unsigned char *)real_command + (64 * (i - 1)),
259 *length_transferred += transferred;
261 if (status == LIBUSB_ERROR_NO_DEVICE) {
263 return LIBUSB_ERROR_NO_DEVICE;
266 if (status != LIBUSB_SUCCESS) {
268 printf(
"[liblabpro ERR] Error writing to USB: %s", libusb_strerror(status));
269 printf(
"[liblabpro WARN] There have been %d errors for this write function so far.", numerrors);
272 printf(
"[liblabpro ERR] LabPro_send_raw: Error limit reached; aborting.");
291 unsigned char* data = malloc(64 *
sizeof(
char));
297 status = libusb_bulk_transfer(
300 data + (64 * (numpackets - 1)),
306 if (status == LIBUSB_ERROR_NO_DEVICE) {
308 memset(data + (64 * numpackets), 0, 64);
309 retval = LIBUSB_ERROR_NO_DEVICE;
313 if (status != LIBUSB_SUCCESS && status != LIBUSB_ERROR_TIMEOUT) {
315 printf(
"[liblabpro ERR] Error reading from USB: %s", libusb_strerror(status));
316 printf(
"[liblabpro WARN] There have been %d errors for this read function call so far.", numerrors);
319 printf(
"[liblabpro ERR] LabPro_read_raw: error limit reached; aborting.");
320 memset(data + (64 * numpackets), 0, 64);
326 else if (status == LIBUSB_ERROR_TIMEOUT) {
327 memset(data + (64 * numpackets), 0, 64);
332 *length += transferred;
335 unsigned char* previous_data = data;
336 data = realloc(data, 64 * numpackets);
338 data = previous_data;
343 }
while (transferred == 64 && status == LIBUSB_SUCCESS);
345 *
string = (
char*)data;
351 char* cr = strstr(
string,
"\r");
360 printf(
"[liblabpro WARN] LabPro_handle_device_disconnect(): stub\n");
unsigned int timeout
How long libusb waits before timing out on a transfer. Default is 5000.
unsigned short num
Number of available LabPros. Max is 5.
void LabPro_exit(LabPro_Context *context)
De-initialize liblabpro.
int LabPro_init(LabPro_Context *context)
Initialize liblabpro. Currently just a wrapper around libusb_init().
bool is_collecting_data
Whether data is currently being collected. This doesn't determine whether we should be sending comman...
libusb_device_handle * device_handle
enum LabPro_Sonic_Chan_Operations sonic_op
The type of data to collect (sonic channels). I do NOT recommend using anything but LABPRO_DISTANCE_A...
The underlying libusb_device is not open.
Struct acting as an array of LabPros.
Clear RAM and reset the LabPro.
void LabPro_close_labpro(LabPro *labpro)
Close the LabPro.
Have the LabPro send datapoints as they're collected without storing them.
LabPro_List LabPro_list_labpros(LabPro_Context *context)
Obtain a list connected LabPro devices.
bool is_busy
Whether there is a pending transfer request. Some commands do not return data so it's OK to send them...
enum LabPro_Channels channel
The channel to use.
The post-processing was set to a nonzero value on a realtime capture. This is not allowed...
enum LabPro_Analog_PostProc postproc
Post processing LabPro can perform the first and second derivatives with respect to time for you...
The LabPro is transferring data, so we cannot send a command that requires a response from the LabPro...
int LabPro_trim_response(char *string)
Trim trailing junk that the LabPro sent Since the LabPro always returns data in multiples of 64 bytes...
int LabPro_reset(LabPro *labpro, bool force)
Send a reset command to the specified LabPro.
liblabpro couldn't allocate memory.
Struct representing a LabPro device.
int LabPro_send_raw(LabPro *labpro, char *command, int *length_transferred)
Send a raw command to the LabPro.
enum LabPro_Analog_Chan_Operations analog_op
The type of data to collect (analog channels). For most analog sensors you should use LABPRO_CHANOP_A...
Thin wrapper around libusb_context.
void LabPro_sleep(unsigned int milliseconds)
unsigned char out_endpt_addr
The USB "out" endpoint address.
int LabPro_check_data_session(LabPro_Data_Session *session, int **errors)
Check a data session for problems before running it on the LabPro.
bool is_open
Whether the underlying USB device handle is open.
Struct representing a "data session" Data sessions are an abstraction over the LabPro's command-orien...
enum LabPro_Sampling_Modes sampling_mode
Sampling mode: realtime or non-realtime. The names are a bit misleading, because LabPro itself will a...
void LabPro_handle_device_disconnect(LabPro *labpro)
LabPro * labpros[5]
Array of LabPro.
unsigned char in_endpt_addr
The USB "in" endpoint address.
The post-processing was set to a nonzero value for a sonic data capture. For sonic data like from mot...
int LabPro_read_raw(LabPro *labpro, char **string, int *length)
Read raw bytes from the LabPro.