send_control_packet(data, type, LIBUSB_REQUEST_SET_FEATURE, 1, 0, 0);
}
+static void handle_huaweinew(struct usbdev_data *data, struct blob_attr **tb)
+{
+ static struct msg_entry msgs[] = {
+ {
+ "\x55\x53\x42\x43\x12\x34\x56\x78\x00\x00\x00\x00\x00\x00\x00\x11"
+ "\x06\x20\x00\x00\x01\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00", 31
+ }
+ };
+
+ detach_driver(data);
+ data->need_response = false;
+ send_messages(data, msgs, ARRAY_SIZE(msgs));
+}
+
+static void handle_standardeject(struct usbdev_data *data, struct blob_attr **tb)
+{
+ static struct msg_entry msgs[] = {
+ {
+ "\x55\x53\x42\x43\x12\x34\x56\x78\x00\x00\x00\x00\x00\x00\x06\x1e"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 31
+ }, {
+ "\x55\x53\x42\x43\x12\x34\x56\x79\x00\x00\x00\x00\x00\x00\x06\x1b"
+ "\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 31
+ }
+ };
+
+ detach_driver(data);
+ data->need_response = true;
+ send_messages(data, msgs, ARRAY_SIZE(msgs));
+}
+
static void handle_sierra(struct usbdev_data *data, struct blob_attr **tb)
{
int type = LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE;
send_messages(data, msgs, ARRAY_SIZE(msgs));
}
+static void handle_mbim(struct usbdev_data *data, struct blob_attr **tb)
+{
+ int j;
+
+ if (data->desc.bNumConfigurations < 2)
+ return;
+
+ for (j = 0; j < data->desc.bNumConfigurations; j++) {
+ struct libusb_config_descriptor *config;
+ int i;
+
+ libusb_get_config_descriptor(data->dev, j, &config);
+
+ for (i = 0; i < config->bNumInterfaces; i++) {
+ if (config->interface[i].altsetting[0].bInterfaceClass == 2) {
+ if (config->interface[i].altsetting[0].bInterfaceSubClass == 0x0e) {
+ struct libusb_config_descriptor *active;
+ int count = 5;
+
+ libusb_get_active_config_descriptor(data->dev, &active);
+ if (active->bConfigurationValue == config->bConfigurationValue)
+ return;
+ while ((libusb_set_configuration(data->devh, config->bConfigurationValue) < 0) && --count)
+ libusb_detach_kernel_driver(data->devh, active->interface[0].altsetting[0].bInterfaceNumber);
+
+ libusb_free_config_descriptor(config);
+ return;
+ }
+ }
+ }
+
+ libusb_free_config_descriptor(config);
+ }
+}
+
static void set_alt_setting(struct usbdev_data *data, int setting)
{
if (libusb_claim_interface(data->devh, data->interface))
enum {
MODE_GENERIC,
MODE_HUAWEI,
+ MODE_HUAWEINEW,
MODE_SIERRA,
+ MODE_STDEJECT,
MODE_SONY,
MODE_QISDA,
MODE_GCT,
MODE_SEQUANS,
MODE_MOBILE_ACTION,
MODE_CISCO,
+ MODE_MBIM,
__MODE_MAX
};
void (*cb)(struct usbdev_data *data, struct blob_attr **tb);
} modeswitch_cb[__MODE_MAX] = {
[MODE_GENERIC] = { "Generic", handle_generic },
+ [MODE_STDEJECT] = { "StandardEject", handle_standardeject },
[MODE_HUAWEI] = { "Huawei", handle_huawei },
+ [MODE_HUAWEINEW] = { "HuaweiNew", handle_huaweinew },
[MODE_SIERRA] = { "Sierra", handle_sierra },
[MODE_SONY] = { "Sony", handle_sony },
[MODE_QISDA] = { "Qisda", handle_qisda },
[MODE_SEQUANS] = { "Sequans", handle_sequans },
[MODE_MOBILE_ACTION] = { "MobileAction", handle_mobile_action },
[MODE_CISCO] = { "Cisco", handle_cisco },
+ [MODE_MBIM] = { "MBIM", handle_mbim },
};
void handle_switch(struct usbdev_data *data)
[DATA_INTERFACE] = { .name = "interface", .type = BLOBMSG_TYPE_INT32 },
[DATA_MSG_EP] = { .name = "msg_endpoint", .type = BLOBMSG_TYPE_INT32 },
[DATA_RES_EP] = { .name = "response_endpoint", .type = BLOBMSG_TYPE_INT32 },
- [DATA_RESPONSE] = { .name = "response", .type = BLOBMSG_TYPE_INT32 },
+ [DATA_RESPONSE] = { .name = "response", .type = BLOBMSG_TYPE_BOOL },
[DATA_CONFIG] = { .name = "config", .type = BLOBMSG_TYPE_INT32 },
[DATA_ALT] = { .name = "alt", .type = BLOBMSG_TYPE_INT32 },
};