summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjørn Mork <bjorn@mork.no>2015-11-26 13:18:49 +0100
committerBjørn Mork <bjorn@mork.no>2015-11-26 13:18:49 +0100
commit4f760a0d62d23b9b5fbee4500102bc950ff02033 (patch)
tree1345aa3f20107a78e2b2c6514deb6ee1b1957d29
parent9074e037f97d117e607e9895898918eb23459312 (diff)
flush-wdm: force flushing a wdm(-like) function
Signed-off-by: Bjørn Mork <bjorn@mork.no>
-rw-r--r--src/Makefile8
-rw-r--r--src/flush-wdm.c127
2 files changed, 134 insertions, 1 deletions
diff --git a/src/Makefile b/src/Makefile
index 664e992..0f4b0b4 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -2,7 +2,7 @@ CC=gcc
CFLAGS_FUSE=$(shell pkg-config fuse --cflags)
LDLIBS_FUSE=$(shell pkg-config fuse --libs)
LDFLAGS=-Wall
-BINARIES=wwan_ctl qcqmifs
+BINARIES=wwan_ctl qcqmifs flush-wdm
CFLAGS_USB=$(shell pkg-config libusb-1.0 --cflags)
LDLIBS_USB=$(shell pkg-config libusb-1.0 --libs)
@@ -25,3 +25,9 @@ qcqmifs: qcqmifs.c
cuseqmi: cuseqmi.c
$(CC) $(CFLAGS) $(CFLAGS_FUSE) $(LDFLAGS) -lpthread -o $@ $^ $(LDLIBS) $(LDLIBS_FUSE)
+
+swi-firmware: swi-firmware.c
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LDLIBS)
+
+flush-wdm: flush-wdm.c
+ $(CC) $(CFLAGS_USB) $(LDFLAGS) -o $@ $^ $(LDLIBS_USB)
diff --git a/src/flush-wdm.c b/src/flush-wdm.c
new file mode 100644
index 0000000..7471c57
--- /dev/null
+++ b/src/flush-wdm.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2012 Bjørn Mork <bjorn@mork.no>
+ *
+ * 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 2 of the License.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <string.h>
+#include <libusb.h>
+#include <linux/types.h>
+
+/* dump device info */
+static void print_usb_device(libusb_device_handle *handle)
+{
+ libusb_device *dev;
+ struct libusb_device_descriptor desc;
+ int err;
+
+ dev = libusb_get_device(handle);
+ if (dev == NULL)
+ return;
+
+ err = libusb_get_device_descriptor(dev, &desc);
+ if (err)
+ return;
+
+ printf("bLength=%d\nbDescriptorType=%d\nbDeviceClass=%x\nidVendor=%04x\nidProduct=%04x\n",
+ desc.bLength, desc.bDescriptorType, desc.bDeviceClass, desc.idVendor, desc.idProduct);
+}
+
+/* open the given device */
+static libusb_device_handle *open_device(char *device)
+{
+ uint16_t vendor_id = 0, product_id = 0;
+
+ if ((sscanf(device, " %hx : %hx ", &vendor_id, &product_id) != 2) || (vendor_id == 0) || (product_id == 0))
+ return NULL;
+
+ return libusb_open_device_with_vid_pid(NULL, vendor_id, product_id);
+}
+
+static int read_reply(libusb_device_handle *handle, int interface, unsigned char *buf, int size)
+{
+ int ret;
+
+ ret = libusb_control_transfer(handle,
+ LIBUSB_ENDPOINT_IN + LIBUSB_REQUEST_TYPE_CLASS + LIBUSB_RECIPIENT_INTERFACE, /* 0xa1 */
+ 1, /* CDC GET_ENCAPSULATED_RESPONSE */
+ 0, /* zero */
+ interface, /* wIndex = interface */
+ buf,
+ size,
+ 1000);
+
+ fprintf(stderr, "%s: libusb_control_transfer() returned %d\n", __FUNCTION__, ret);
+ return ret;
+}
+
+static struct option main_options[] = {
+ { "help", 0, 0, 'h' },
+ { "device", 1, 0, 'd' },
+ { "interface", 1, 0, 'i' },
+ { 0, 0, 0, 0 }
+};
+
+
+void usage(char *prog)
+{
+ fprintf(stderr, "Usage: %s --device vid:pid [--interface N]\n\n", prog);
+}
+
+int main(int argc, char *argv[])
+{
+ char *prog, *device = NULL;
+ int i, opt, ret, interface = 0;
+ libusb_device_handle *handle;
+ unsigned char buf[500];
+ int size = sizeof(buf);
+
+ prog = argv[0];
+ while ((opt = getopt_long(argc, argv, "d:i:h", main_options, NULL)) != -1) {
+ switch(opt) {
+ case 'd':
+ device = strdup(optarg);
+ break;
+ case 'i':
+ interface = atoi(optarg);
+ break;
+ case 'h':
+ usage(prog);
+ exit(0);
+ }
+ }
+
+ if (!device) {
+ usage(prog);
+ exit(0);
+ }
+
+ if ((ret = libusb_init(NULL))) {
+ fprintf(stderr, "libusb_init() failed: %d\n", ret);
+ exit(1);
+ }
+
+ if ((handle = open_device(device))) {
+ print_usb_device(handle);
+ ret = libusb_claim_interface (handle, interface);
+
+ /* flush pending messages */
+ i = 1;
+ while (i > 0)
+ i = read_reply(handle, interface, buf, size);
+ ret = libusb_release_interface(handle, interface);
+ } else {
+ fprintf(stderr, "failed to open device \"%s\"\n", device);
+ }
+
+ libusb_exit(NULL);
+
+ return ret;
+}