detach the kernel driver before mode switch
[project/usbmode.git] / switch.c
index 80613221e257d1bbb1d83418a3f026240df2cbc6..15933d4eb2ccf45c55156c0835c1b78cb1a0ad95 100644 (file)
--- a/switch.c
+++ b/switch.c
@@ -1,8 +1,20 @@
 #include "switch.h"
 
+enum {
+       DATA_MODE,
+       DATA_MSG,
+       DATA_INTERFACE,
+       __DATA_MAX
+};
+
+static void detach_driver(struct usbdev_data *data)
+{
+       libusb_detach_kernel_driver(data->devh, data->interface);
+}
+
 static void handle_generic(struct usbdev_data *data, struct blob_attr **tb)
 {
-       fprintf(stderr, "Do generic switch!\n");
+       detach_driver(data);
 }
 
 static void handle_huawei(struct usbdev_data *data, struct blob_attr **tb)
@@ -27,11 +39,13 @@ static void handle_qisda(struct usbdev_data *data, struct blob_attr **tb)
 
 static void handle_gct(struct usbdev_data *data, struct blob_attr **tb)
 {
+       detach_driver(data);
        /* TODO */
 }
 
 static void handle_kobil(struct usbdev_data *data, struct blob_attr **tb)
 {
+       detach_driver(data);
        /* TODO */
 }
 
@@ -47,6 +61,7 @@ static void handle_mobile_action(struct usbdev_data *data, struct blob_attr **tb
 
 static void handle_cisco(struct usbdev_data *data, struct blob_attr **tb)
 {
+       detach_driver(data);
        /* TODO */
 }
 
@@ -84,15 +99,17 @@ void handle_switch(struct usbdev_data *data)
 {
        static const struct blobmsg_policy data_policy[__DATA_MAX] = {
                [DATA_MODE] = { .name = "mode", .type = BLOBMSG_TYPE_STRING },
-               [DATA_MSG] = { .name = "msg", .type = BLOBMSG_TYPE_INT32 },
-               [DATA_MSG2] = { .name = "msg2", .type = BLOBMSG_TYPE_INT32 },
-               [DATA_MSG3] = { .name = "msg3", .type = BLOBMSG_TYPE_INT32 },
+               [DATA_MSG] = { .name = "msg", .type = BLOBMSG_TYPE_ARRAY },
+               [DATA_INTERFACE] = { .name = "interface", .type = BLOBMSG_TYPE_INT32 },
        };
        struct blob_attr *tb[__DATA_MAX];
        int mode = MODE_GENERIC;
 
        blobmsg_parse(data_policy, __DATA_MAX, tb, blobmsg_data(data->info), blobmsg_data_len(data->info));
 
+       if (tb[DATA_INTERFACE])
+               data->interface = blobmsg_get_u32(tb[DATA_INTERFACE]);
+
        if (tb[DATA_MODE]) {
                const char *modestr;
                int i;
@@ -109,5 +126,3 @@ void handle_switch(struct usbdev_data *data)
 
        modeswitch_cb[mode].cb(data, tb);
 }
-
-