aboutsummaryrefslogtreecommitdiffstats
path: root/src/usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/usb.c')
-rw-r--r--src/usb.c170
1 files changed, 170 insertions, 0 deletions
diff --git a/src/usb.c b/src/usb.c
new file mode 100644
index 0000000..8e87474
--- /dev/null
+++ b/src/usb.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2016 Paul Kocialkowski <contact@paulk.fr>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <libusb.h>
+
+#include "lg-downloader.h"
+#include "usb.h"
+
+int usb_open(struct context *context)
+{
+ struct libusb_device_handle *handle;
+ int rc;
+
+ if (context == NULL)
+ return -1;
+
+ rc = libusb_init(NULL);
+ if (rc < 0) {
+ fprintf(stderr, "Initializing libusb failed\n");
+ return -1;
+ }
+
+ handle = libusb_open_device_with_vid_pid(NULL, USB_VENDOR_LG, USB_DEVICE_DOWNLOAD);
+ if (handle == NULL) {
+ fprintf(stderr, "Finding and opening USB device failed\n");
+ fprintf(stderr, "\nDevice might be missing or you may not have the rights to do this\n");
+ goto error;
+ }
+
+ libusb_detach_kernel_driver(handle, USB_INTERFACE);
+
+ rc = libusb_set_configuration(handle, USB_CONFIGURATION);
+ if (rc < 0) {
+ fprintf(stderr, "Setting USB configuration failed\n");
+ goto error;
+ }
+
+ rc = libusb_claim_interface(handle, USB_INTERFACE);
+ if (rc < 0) {
+ fprintf(stderr, "Claiming USB interface failed\n");
+ goto error;
+ }
+
+ context->usb_handle = handle;
+
+ rc = 0;
+ goto complete;
+
+error:
+ rc = -1;
+
+ if (handle != NULL)
+ libusb_close(handle);
+
+ libusb_exit(NULL);
+
+complete:
+ return rc;
+}
+
+void usb_close(struct context *context)
+{
+ if (context == NULL)
+ return;
+
+ if (context->usb_handle != NULL) {
+ libusb_release_interface(context->usb_handle, USB_INTERFACE);
+ libusb_close(context->usb_handle);
+
+ context->usb_handle = NULL;
+
+ libusb_exit(NULL);
+ }
+}
+
+int usb_send(struct context *context, const void *data, unsigned int size)
+{
+ unsigned int count;
+ unsigned int chunk;
+ unsigned char *p;
+ int transferred;
+ int rc;
+
+ if (context == NULL)
+ return -1;
+
+ count = 0;
+ p = (unsigned char *) data;
+
+ while (count < size) {
+ chunk = (size - count) < USB_SEND_CHUNK ? (size - count) : USB_SEND_CHUNK;
+
+ rc = libusb_bulk_transfer(context->usb_handle, USB_ENDPOINT_OUT, p, chunk, &transferred, USB_TIMEOUT);
+ if (rc < 0 || transferred <= 0) {
+ fprintf(stderr, "sBulk USB transfer failed\n");
+ return -1;
+ }
+
+ count += transferred;
+ p += transferred;
+ }
+
+ return 0;
+}
+
+int usb_recv(struct context *context, void *data, unsigned int size)
+{
+ unsigned int count;
+ unsigned int chunk;
+ unsigned char *p;
+ int transferred;
+ int rc;
+
+ if (context == NULL)
+ return -1;
+
+ count = 0;
+ p = (unsigned char *) data;
+
+ while (count < size) {
+ chunk = (size - count) < USB_RECV_CHUNK ? (size - count) : USB_RECV_CHUNK;
+
+ rc = libusb_bulk_transfer(context->usb_handle, USB_ENDPOINT_IN, p, chunk, &transferred, USB_TIMEOUT);
+ if (rc < 0 || transferred <= 0) {
+ fprintf(stderr, "Bulk USB transfer failed\n");
+ return -1;
+ }
+
+ count += transferred;
+ p += transferred;
+ }
+
+ return 0;
+}
+
+int usb_recv_available(struct context *context, void *data, unsigned int size)
+{
+ unsigned int chunk;
+ int transferred;
+ int rc;
+
+ if (context == NULL)
+ return -1;
+
+ chunk = size < USB_RECV_CHUNK ? size : USB_RECV_CHUNK;
+
+ rc = libusb_bulk_transfer(context->usb_handle, USB_ENDPOINT_IN, data, chunk, &transferred, USB_TIMEOUT);
+ if (rc < 0 || transferred <= 0) {
+ fprintf(stderr, "Bulk USB transfer failed\n");
+ return -1;
+ }
+
+ return transferred;
+}