diff --git a/plugins/mbim.c b/plugins/mbim.c index 13948d0f..f3109ab0 100644 --- a/plugins/mbim.c +++ b/plugins/mbim.c @@ -40,6 +40,8 @@ #include +#include +#include #include #include @@ -49,6 +51,13 @@ struct mbim_data { uint8_t max_outstanding; }; +static void mbim_debug(const char *str, void *user_data) +{ + const char *prefix = user_data; + + ofono_info("%s%s", prefix, str); +} + static int mbim_parse_descriptors(struct mbim_data *md, const char *file) { void *data; @@ -111,13 +120,87 @@ static void mbim_remove(struct ofono_modem *modem) DBG("%p", modem); + mbim_device_unref(data->device); + ofono_modem_set_data(modem, NULL); l_free(data); } +static void mbim_device_caps_info_cb(struct mbim_message *message, void *user) +{ + struct ofono_modem *modem = user; + struct mbim_data *md = ofono_modem_get_data(modem); + uint32_t device_type; + uint32_t cellular_class; + uint32_t voice_class; + uint32_t sim_class; + uint32_t data_class; + uint32_t sms_caps; + uint32_t control_caps; + uint32_t max_sessions; + char *custom_data_class; + char *device_id; + char *firmware_info; + char *hardware_info; + bool r; + + if (mbim_message_get_error(message) != 0) + goto error; + + r = mbim_message_get_arguments(message, "uuuuuuuussss", + &device_type, &cellular_class, + &voice_class, &sim_class, &data_class, + &sms_caps, &control_caps, &max_sessions, + &custom_data_class, &device_id, + &firmware_info, &hardware_info); + if (!r) + goto error; + + DBG("DeviceId: %s", device_id); + DBG("FirmwareInfo: %s", firmware_info); + DBG("HardwareInfo: %s", hardware_info); + + l_free(custom_data_class); + l_free(device_id); + l_free(firmware_info); + l_free(hardware_info); + + ofono_modem_set_powered(modem, TRUE); + return; + +error: + mbim_device_shutdown(md->device); +} + +static void mbim_device_closed(void *user_data) +{ + struct ofono_modem *modem = user_data; + struct mbim_data *md = ofono_modem_get_data(modem); + + mbim_device_unref(md->device); + md->device = NULL; + + ofono_modem_set_powered(modem, FALSE); +} + +static void mbim_device_ready(void *user_data) +{ + struct ofono_modem *modem = user_data; + struct mbim_data *md = ofono_modem_get_data(modem); + struct mbim_message *message = + mbim_message_new(mbim_uuid_basic_connect, + 1, MBIM_COMMAND_TYPE_QUERY); + + mbim_message_set_arguments(message, ""); + mbim_device_send(md->device, 0, message, + mbim_device_caps_info_cb, modem, NULL); +} + static int mbim_enable(struct ofono_modem *modem) { const char *device; + int fd; + struct mbim_data *md = ofono_modem_get_data(modem); DBG("%p", modem); @@ -126,15 +209,31 @@ static int mbim_enable(struct ofono_modem *modem) return -EINVAL; DBG("%p", device); + fd = open(device, O_EXCL | O_NONBLOCK | O_RDWR); + if (fd < 0) + return -EIO; - return -ENOTSUP; + md->device = mbim_device_new(fd, md->max_segment); + + mbim_device_set_close_on_unref(md->device, true); + mbim_device_set_max_outstanding(md->device, md->max_outstanding); + mbim_device_set_ready_handler(md->device, + mbim_device_ready, modem, NULL); + mbim_device_set_disconnect_handler(md->device, + mbim_device_closed, modem, NULL); + mbim_device_set_debug(md->device, mbim_debug, "MBIM:", NULL); + + return -EINPROGRESS; } static int mbim_disable(struct ofono_modem *modem) { + struct mbim_data *md = ofono_modem_get_data(modem); + DBG("%p", modem); - return -ENOTSUP; + mbim_device_shutdown(md->device); + return -EINPROGRESS; } static void mbim_set_online(struct ofono_modem *modem, ofono_bool_t online,