| /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
| /* |
| * mbimcli -- Command line interface to control MBIM devices |
| * |
| * 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, 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/>. |
| * |
| * Copyright (C) 2013 - 2014 Aleksander Morgado <aleksander@aleksander.es> |
| */ |
| |
| #include "config.h" |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <locale.h> |
| #include <string.h> |
| #include <errno.h> |
| |
| #include <glib.h> |
| #include <gio/gio.h> |
| |
| #include <libmbim-glib.h> |
| |
| #include "mbim-common.h" |
| #include "mbimcli.h" |
| #include "mbimcli-helpers.h" |
| |
| /* Context */ |
| typedef struct { |
| MbimDevice *device; |
| GCancellable *cancellable; |
| } Context; |
| static Context *ctx; |
| |
| /* Options */ |
| static gboolean query_device_caps_flag; |
| static gboolean query_subscriber_ready_status_flag; |
| static gboolean query_radio_state_flag; |
| static gchar *set_radio_state_str; |
| static gboolean query_device_services_flag; |
| static gboolean query_pin_flag; |
| static gchar *set_pin_enter_str; |
| static gchar *set_pin_change_str; |
| static gchar *set_pin_enable_str; |
| static gchar *set_pin_disable_str; |
| static gchar *set_pin_enter_puk_str; |
| static gboolean query_pin_list_flag; |
| static gboolean query_home_provider_flag; |
| static gboolean query_preferred_providers_flag; |
| static gboolean query_visible_providers_flag; |
| static gboolean query_register_state_flag; |
| static gboolean set_register_state_automatic_flag; |
| static gboolean query_signal_state_flag; |
| static gboolean query_packet_service_flag; |
| static gboolean set_packet_service_attach_flag; |
| static gboolean set_packet_service_detach_flag; |
| static gchar *query_connect_str; |
| static gchar *set_connect_activate_str; |
| static gchar *query_ip_configuration_str; |
| static gchar *set_connect_deactivate_str; |
| static gboolean query_packet_statistics_flag; |
| static gchar *query_ip_packet_filters_str; |
| |
| static gboolean query_connection_state_arg_parse (const char *option_name, |
| const char *value, |
| gpointer user_data, |
| GError **error); |
| |
| static gboolean query_ip_configuration_arg_parse (const char *option_name, |
| const char *value, |
| gpointer user_data, |
| GError **error); |
| |
| static gboolean disconnect_arg_parse (const char *option_name, |
| const char *value, |
| gpointer user_data, |
| GError **error); |
| |
| static gboolean query_ip_packet_filters_arg_parse (const char *option_name, |
| const char *value, |
| gpointer user_data, |
| GError **error); |
| |
| static GOptionEntry entries[] = { |
| { "query-device-caps", 0, 0, G_OPTION_ARG_NONE, &query_device_caps_flag, |
| "Query device capabilities", |
| NULL |
| }, |
| { "query-subscriber-ready-status", 0, 0, G_OPTION_ARG_NONE, &query_subscriber_ready_status_flag, |
| "Query subscriber ready status", |
| NULL |
| }, |
| { "query-radio-state", 0, 0, G_OPTION_ARG_NONE, &query_radio_state_flag, |
| "Query radio state", |
| NULL |
| }, |
| { "set-radio-state", 0, 0, G_OPTION_ARG_STRING, &set_radio_state_str, |
| "Set radio state", |
| "[(on|off)]" |
| }, |
| { "query-device-services", 0, 0, G_OPTION_ARG_NONE, &query_device_services_flag, |
| "Query device services", |
| NULL |
| }, |
| { "query-pin-state", 0, 0, G_OPTION_ARG_NONE, &query_pin_flag, |
| "Query PIN state", |
| NULL |
| }, |
| { "enter-pin", 0, 0, G_OPTION_ARG_STRING, &set_pin_enter_str, |
| "Enter PIN", |
| "[(current PIN)]" |
| }, |
| { "change-pin", 0, 0, G_OPTION_ARG_STRING, &set_pin_change_str, |
| "Change PIN", |
| "[(current PIN),(new PIN)]" |
| }, |
| { "enable-pin", 0, 0, G_OPTION_ARG_STRING, &set_pin_enable_str, |
| "Enable PIN", |
| "[(current PIN)]" |
| }, |
| { "disable-pin", 0, 0, G_OPTION_ARG_STRING, &set_pin_disable_str, |
| "Disable PIN", |
| "[(current PIN)]" |
| }, |
| { "enter-puk", 0, 0, G_OPTION_ARG_STRING, &set_pin_enter_puk_str, |
| "Enter PUK", |
| "[(PUK),(new PIN)]" |
| }, |
| { "query-pin-list", 0, 0, G_OPTION_ARG_NONE, &query_pin_list_flag, |
| "Query PIN list", |
| NULL |
| }, |
| { "query-home-provider", 0, 0, G_OPTION_ARG_NONE, &query_home_provider_flag, |
| "Query home provider", |
| NULL |
| }, |
| { "query-preferred-providers", 0, 0, G_OPTION_ARG_NONE, &query_preferred_providers_flag, |
| "Query preferred providers", |
| NULL |
| }, |
| { "query-visible-providers", 0, 0, G_OPTION_ARG_NONE, &query_visible_providers_flag, |
| "Query visible providers", |
| NULL |
| }, |
| { "query-registration-state", 0, 0, G_OPTION_ARG_NONE, &query_register_state_flag, |
| "Query registration state", |
| NULL |
| }, |
| { "register-automatic", 0, 0, G_OPTION_ARG_NONE, &set_register_state_automatic_flag, |
| "Launch automatic registration", |
| NULL |
| }, |
| { "query-signal-state", 0, 0, G_OPTION_ARG_NONE, &query_signal_state_flag, |
| "Query signal state", |
| NULL |
| }, |
| { "query-packet-service-state", 0, 0, G_OPTION_ARG_NONE, &query_packet_service_flag, |
| "Query packet service state", |
| NULL |
| }, |
| { "attach-packet-service", 0, 0, G_OPTION_ARG_NONE, &set_packet_service_attach_flag, |
| "Attach to the packet service", |
| NULL |
| }, |
| { "detach-packet-service", 0, 0, G_OPTION_ARG_NONE, &set_packet_service_detach_flag, |
| "Detach from the packet service", |
| NULL |
| }, |
| { "query-connection-state", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, G_CALLBACK (query_connection_state_arg_parse), |
| "Query connection state (SessionID is optional, defaults to 0)", |
| "[SessionID]" |
| }, |
| { "connect", 0, 0, G_OPTION_ARG_STRING, &set_connect_activate_str, |
| "Connect (allowed keys: session-id, apn, auth (PAP|CHAP|MSCHAPV2), username, password)", |
| "[\"key=value,...\"]" |
| }, |
| { "query-ip-configuration", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, G_CALLBACK (query_ip_configuration_arg_parse), |
| "Query IP configuration (SessionID is optional, defaults to 0)", |
| "[SessionID]" |
| }, |
| { "disconnect", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, G_CALLBACK (disconnect_arg_parse), |
| "Disconnect (SessionID is optional, defaults to 0)", |
| "[SessionID]" |
| }, |
| { "query-packet-statistics", 0, 0, G_OPTION_ARG_NONE, &query_packet_statistics_flag, |
| "Query packet statistics", |
| NULL |
| }, |
| { "query-ip-packet-filters", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, G_CALLBACK (query_ip_packet_filters_arg_parse), |
| "Query IP packet filters (SessionID is optional, defaults to 0)", |
| "[SessionID]" |
| }, |
| { NULL } |
| }; |
| |
| GOptionGroup * |
| mbimcli_basic_connect_get_option_group (void) |
| { |
| GOptionGroup *group; |
| |
| group = g_option_group_new ("basic-connect", |
| "Basic Connect options", |
| "Show Basic Connect Service options", |
| NULL, |
| NULL); |
| g_option_group_add_entries (group, entries); |
| |
| return group; |
| } |
| |
| static gboolean |
| query_connection_state_arg_parse (const char *option_name, |
| const char *value, |
| gpointer user_data, |
| GError **error) |
| { |
| query_connect_str = g_strdup (value ? value : "0"); |
| return TRUE; |
| } |
| |
| static gboolean |
| query_ip_configuration_arg_parse (const char *option_name, |
| const char *value, |
| gpointer user_data, |
| GError **error) |
| { |
| query_ip_configuration_str = g_strdup (value ? value : "0"); |
| return TRUE; |
| } |
| |
| static gboolean |
| disconnect_arg_parse (const char *option_name, |
| const char *value, |
| gpointer user_data, |
| GError **error) |
| { |
| set_connect_deactivate_str = g_strdup (value ? value : "0"); |
| return TRUE; |
| } |
| |
| static gboolean |
| query_ip_packet_filters_arg_parse (const char *option_name, |
| const char *value, |
| gpointer user_data, |
| GError **error) |
| { |
| query_ip_packet_filters_str = g_strdup (value ? value : "0"); |
| return TRUE; |
| } |
| |
| gboolean |
| mbimcli_basic_connect_options_enabled (void) |
| { |
| static guint n_actions = 0; |
| static gboolean checked = FALSE; |
| |
| if (checked) |
| return !!n_actions; |
| |
| n_actions = (query_device_caps_flag + |
| query_subscriber_ready_status_flag + |
| query_radio_state_flag + |
| !!set_radio_state_str + |
| query_device_services_flag + |
| query_pin_flag + |
| !!set_pin_enter_str + |
| !!set_pin_change_str + |
| !!set_pin_enable_str + |
| !!set_pin_disable_str + |
| !!set_pin_enter_puk_str + |
| query_pin_list_flag + |
| query_register_state_flag + |
| query_home_provider_flag + |
| query_preferred_providers_flag + |
| query_visible_providers_flag + |
| set_register_state_automatic_flag + |
| query_signal_state_flag + |
| query_packet_service_flag + |
| set_packet_service_attach_flag + |
| set_packet_service_detach_flag + |
| !!query_connect_str + |
| !!set_connect_activate_str + |
| !!query_ip_configuration_str + |
| !!set_connect_deactivate_str + |
| query_packet_statistics_flag + |
| !!query_ip_packet_filters_str); |
| |
| if (n_actions > 1) { |
| g_printerr ("error: too many Basic Connect actions requested\n"); |
| exit (EXIT_FAILURE); |
| } |
| |
| checked = TRUE; |
| return !!n_actions; |
| } |
| |
| static void |
| context_free (Context *context) |
| { |
| if (!context) |
| return; |
| |
| if (context->cancellable) |
| g_object_unref (context->cancellable); |
| if (context->device) |
| g_object_unref (context->device); |
| g_slice_free (Context, context); |
| } |
| |
| static void |
| shutdown (gboolean operation_status) |
| { |
| /* Cleanup context and finish async operation */ |
| context_free (ctx); |
| mbimcli_async_operation_done (operation_status); |
| } |
| |
| static void |
| query_device_caps_ready (MbimDevice *device, |
| GAsyncResult *res) |
| { |
| MbimMessage *response; |
| GError *error = NULL; |
| MbimDeviceType device_type; |
| const gchar *device_type_str; |
| MbimCellularClass cellular_class; |
| gchar *cellular_class_str; |
| MbimVoiceClass voice_class; |
| const gchar *voice_class_str; |
| MbimSimClass sim_class; |
| gchar *sim_class_str; |
| MbimDataClass data_class; |
| gchar *data_class_str; |
| MbimSmsCaps sms_caps; |
| gchar *sms_caps_str; |
| MbimCtrlCaps ctrl_caps; |
| gchar *ctrl_caps_str; |
| guint32 max_sessions; |
| gchar *custom_data_class; |
| gchar *device_id; |
| gchar *firmware_info; |
| gchar *hardware_info; |
| |
| response = mbim_device_command_finish (device, res, &error); |
| if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) { |
| g_printerr ("error: operation failed: %s\n", error->message); |
| g_error_free (error); |
| if (response) |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| if (!mbim_message_device_caps_response_parse ( |
| response, |
| &device_type, |
| &cellular_class, |
| &voice_class, |
| &sim_class, |
| &data_class, |
| &sms_caps, |
| &ctrl_caps, |
| &max_sessions, |
| &custom_data_class, |
| &device_id, |
| &firmware_info, |
| &hardware_info, |
| &error)) { |
| g_printerr ("error: couldn't parse response message: %s\n", error->message); |
| g_error_free (error); |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| device_type_str = mbim_device_type_get_string (device_type); |
| cellular_class_str = mbim_cellular_class_build_string_from_mask (cellular_class); |
| voice_class_str = mbim_voice_class_get_string (voice_class); |
| sim_class_str = mbim_sim_class_build_string_from_mask (sim_class); |
| data_class_str = mbim_data_class_build_string_from_mask (data_class); |
| sms_caps_str = mbim_sms_caps_build_string_from_mask (sms_caps); |
| ctrl_caps_str = mbim_ctrl_caps_build_string_from_mask (ctrl_caps); |
| |
| g_print ("[%s] Device capabilities retrieved:\n" |
| "\t Device type: '%s'\n" |
| "\t Cellular class: '%s'\n" |
| "\t Voice class: '%s'\n" |
| "\t SIM class: '%s'\n" |
| "\t Data class: '%s'\n" |
| "\t SMS caps: '%s'\n" |
| "\t Ctrl caps: '%s'\n" |
| "\t Max sessions: '%u'\n" |
| "\tCustom data class: '%s'\n" |
| "\t Device ID: '%s'\n" |
| "\t Firmware info: '%s'\n" |
| "\t Hardware info: '%s'\n", |
| mbim_device_get_path_display (device), |
| VALIDATE_UNKNOWN (device_type_str), |
| VALIDATE_UNKNOWN (cellular_class_str), |
| VALIDATE_UNKNOWN (voice_class_str), |
| VALIDATE_UNKNOWN (sim_class_str), |
| VALIDATE_UNKNOWN (data_class_str), |
| VALIDATE_UNKNOWN (sms_caps_str), |
| VALIDATE_UNKNOWN (ctrl_caps_str), |
| max_sessions, |
| VALIDATE_UNKNOWN (custom_data_class), |
| VALIDATE_UNKNOWN (device_id), |
| VALIDATE_UNKNOWN (firmware_info), |
| VALIDATE_UNKNOWN (hardware_info)); |
| |
| g_free (cellular_class_str); |
| g_free (sim_class_str); |
| g_free (data_class_str); |
| g_free (sms_caps_str); |
| g_free (ctrl_caps_str); |
| g_free (custom_data_class); |
| g_free (device_id); |
| g_free (firmware_info); |
| g_free (hardware_info); |
| |
| mbim_message_unref (response); |
| shutdown (TRUE); |
| } |
| |
| static void |
| query_subscriber_ready_status_ready (MbimDevice *device, |
| GAsyncResult *res) |
| { |
| MbimMessage *response; |
| GError *error = NULL; |
| MbimSubscriberReadyState ready_state; |
| const gchar *ready_state_str; |
| gchar *subscriber_id; |
| gchar *sim_iccid; |
| MbimReadyInfoFlag ready_info; |
| gchar *ready_info_str; |
| guint32 telephone_numbers_count; |
| gchar **telephone_numbers; |
| gchar *telephone_numbers_str; |
| |
| response = mbim_device_command_finish (device, res, &error); |
| if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) { |
| g_printerr ("error: operation failed: %s\n", error->message); |
| g_error_free (error); |
| if (response) |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| if (!mbim_message_subscriber_ready_status_response_parse ( |
| response, |
| &ready_state, |
| &subscriber_id, |
| &sim_iccid, |
| &ready_info, |
| &telephone_numbers_count, |
| &telephone_numbers, |
| &error)) { |
| g_printerr ("error: couldn't parse response message: %s\n", error->message); |
| g_error_free (error); |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| telephone_numbers_str = (telephone_numbers ? g_strjoinv (", ", telephone_numbers) : NULL); |
| ready_state_str = mbim_subscriber_ready_state_get_string (ready_state); |
| ready_info_str = mbim_ready_info_flag_build_string_from_mask (ready_info); |
| |
| g_print ("[%s] Subscriber ready status retrieved:\n" |
| "\t Ready state: '%s'\n" |
| "\t Subscriber ID: '%s'\n" |
| "\t SIM ICCID: '%s'\n" |
| "\t Ready info: '%s'\n" |
| "\tTelephone numbers: (%u) '%s'\n", |
| mbim_device_get_path_display (device), |
| VALIDATE_UNKNOWN (ready_state_str), |
| VALIDATE_UNKNOWN (subscriber_id), |
| VALIDATE_UNKNOWN (sim_iccid), |
| VALIDATE_UNKNOWN (ready_info_str), |
| telephone_numbers_count, VALIDATE_UNKNOWN (telephone_numbers_str)); |
| |
| g_free (subscriber_id); |
| g_free (sim_iccid); |
| g_free (ready_info_str); |
| g_strfreev (telephone_numbers); |
| g_free (telephone_numbers_str); |
| |
| mbim_message_unref (response); |
| shutdown (TRUE); |
| } |
| |
| static void |
| query_radio_state_ready (MbimDevice *device, |
| GAsyncResult *res) |
| { |
| MbimMessage *response; |
| GError *error = NULL; |
| MbimRadioSwitchState hardware_radio_state; |
| const gchar *hardware_radio_state_str; |
| MbimRadioSwitchState software_radio_state; |
| const gchar *software_radio_state_str; |
| |
| response = mbim_device_command_finish (device, res, &error); |
| if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) { |
| g_printerr ("error: operation failed: %s\n", error->message); |
| g_error_free (error); |
| if (response) |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| if (!mbim_message_radio_state_response_parse ( |
| response, |
| &hardware_radio_state, |
| &software_radio_state, |
| &error)) { |
| g_printerr ("error: couldn't parse response message: %s\n", error->message); |
| g_error_free (error); |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| hardware_radio_state_str = mbim_radio_switch_state_get_string (hardware_radio_state); |
| software_radio_state_str = mbim_radio_switch_state_get_string (software_radio_state); |
| |
| g_print ("[%s] Radio state retrieved:\n" |
| "\t Hardware radio state: '%s'\n" |
| "\t Software radio state: '%s'\n", |
| mbim_device_get_path_display (device), |
| VALIDATE_UNKNOWN (hardware_radio_state_str), |
| VALIDATE_UNKNOWN (software_radio_state_str)); |
| |
| mbim_message_unref (response); |
| shutdown (TRUE); |
| } |
| |
| static void |
| query_device_services_ready (MbimDevice *device, |
| GAsyncResult *res) |
| { |
| MbimMessage *response; |
| GError *error = NULL; |
| MbimDeviceServiceElement **device_services; |
| guint32 device_services_count; |
| guint32 max_dss_sessions; |
| |
| response = mbim_device_command_finish (device, res, &error); |
| if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) { |
| g_printerr ("error: operation failed: %s\n", error->message); |
| g_error_free (error); |
| if (response) |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| if (!mbim_message_device_services_response_parse ( |
| response, |
| &device_services_count, |
| &max_dss_sessions, |
| &device_services, |
| &error)) { |
| g_printerr ("error: couldn't parse response message: %s\n", error->message); |
| g_error_free (error); |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| g_print ("[%s] Device services retrieved:\n" |
| "\tMax DSS sessions: '%u'\n", |
| mbim_device_get_path_display (device), |
| max_dss_sessions); |
| if (device_services_count == 0) |
| g_print ("\t Services: None\n"); |
| else { |
| guint32 i; |
| |
| g_print ("\t Services: (%u)\n", device_services_count); |
| for (i = 0; i < device_services_count; i++) { |
| MbimService service; |
| gchar *uuid_str; |
| GString *cids; |
| guint32 j; |
| |
| service = mbim_uuid_to_service (&device_services[i]->device_service_id); |
| uuid_str = mbim_uuid_get_printable (&device_services[i]->device_service_id); |
| |
| cids = g_string_new (""); |
| for (j = 0; j < device_services[i]->cids_count; j++) { |
| if (service == MBIM_SERVICE_INVALID) { |
| g_string_append_printf (cids, "%u", device_services[i]->cids[j]); |
| if (j < device_services[i]->cids_count - 1) |
| g_string_append (cids, ", "); |
| } else { |
| g_string_append_printf (cids, "%s%s (%u)", |
| j == 0 ? "" : "\t\t ", |
| VALIDATE_UNKNOWN (mbim_cid_get_printable (service, device_services[i]->cids[j])), |
| device_services[i]->cids[j]); |
| if (j < device_services[i]->cids_count - 1) |
| g_string_append (cids, ",\n"); |
| } |
| } |
| |
| g_print ("\n" |
| "\t\t Service: '%s'\n" |
| "\t\t UUID: [%s]:\n" |
| "\t\t DSS payload: %u\n" |
| "\t\tMax DSS instances: %u\n" |
| "\t\t CIDs: %s\n", |
| service == MBIM_SERVICE_INVALID ? "unknown" : mbim_service_get_string (service), |
| uuid_str, |
| device_services[i]->dss_payload, |
| device_services[i]->max_dss_instances, |
| cids->str); |
| |
| g_string_free (cids, TRUE); |
| g_free (uuid_str); |
| } |
| } |
| |
| mbim_device_service_element_array_free (device_services); |
| |
| mbim_message_unref (response); |
| shutdown (TRUE); |
| } |
| |
| static void |
| pin_ready (MbimDevice *device, |
| GAsyncResult *res, |
| gpointer user_data) |
| { |
| MbimMessage *response; |
| GError *error = NULL; |
| MbimPinType pin_type; |
| MbimPinState pin_state; |
| const gchar *pin_state_str; |
| guint32 remaining_attempts; |
| |
| response = mbim_device_command_finish (device, res, &error); |
| if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) { |
| g_printerr ("error: operation failed: %s\n", error->message); |
| g_error_free (error); |
| if (response) |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| if (!mbim_message_pin_response_parse ( |
| response, |
| &pin_type, |
| &pin_state, |
| &remaining_attempts, |
| &error)) { |
| g_printerr ("error: couldn't parse response message: %s\n", error->message); |
| g_error_free (error); |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| if (GPOINTER_TO_UINT (user_data)) |
| g_print ("[%s] PIN operation successful\n\n", |
| mbim_device_get_path_display (device)); |
| |
| pin_state_str = mbim_pin_state_get_string (pin_state); |
| |
| g_print ("[%s] PIN info:\n" |
| "\t PIN state: '%s'\n", |
| mbim_device_get_path_display (device), |
| VALIDATE_UNKNOWN (pin_state_str)); |
| if (pin_type != MBIM_PIN_TYPE_UNKNOWN) { |
| const gchar *pin_type_str; |
| |
| pin_type_str = mbim_pin_type_get_string (pin_type); |
| g_print ("\t PIN type: '%s'\n" |
| "\tRemaining attempts: '%u'\n", |
| VALIDATE_UNKNOWN (pin_type_str), |
| remaining_attempts); |
| } |
| |
| mbim_message_unref (response); |
| shutdown (TRUE); |
| } |
| |
| static gboolean |
| set_pin_input_parse (guint n_expected, |
| const gchar *str, |
| gchar **pin, |
| gchar **new_pin) |
| { |
| gchar **split; |
| |
| g_assert (n_expected == 1 || n_expected == 2); |
| g_assert (pin != NULL); |
| g_assert (new_pin != NULL); |
| |
| /* Format of the string is: |
| * "[(current PIN)]" |
| * or: |
| * "[(current PIN),(new PIN)]" |
| */ |
| split = g_strsplit (str, ",", -1); |
| |
| if (g_strv_length (split) > n_expected) { |
| g_printerr ("error: couldn't parse input string, too many arguments\n"); |
| g_strfreev (split); |
| return FALSE; |
| } |
| |
| if (g_strv_length (split) < n_expected) { |
| g_printerr ("error: couldn't parse input string, missing arguments\n"); |
| g_strfreev (split); |
| return FALSE; |
| } |
| |
| *pin = g_strdup (split[0]); |
| *new_pin = g_strdup (split[1]); |
| |
| g_strfreev (split); |
| return TRUE; |
| } |
| |
| enum { |
| CONNECTION_STATUS, |
| CONNECT, |
| DISCONNECT |
| }; |
| |
| static void |
| print_pin_desc (const gchar *pin_name, |
| const MbimPinDesc *pin_desc) |
| { |
| g_print ("\t%s:\n" |
| "\t\t Mode: '%s'\n" |
| "\t\t Format: '%s'\n" |
| "\t\tMin length: '%d'\n" |
| "\t\tMax length: '%d'\n" |
| "\n", |
| pin_name, |
| VALIDATE_UNKNOWN (mbim_pin_mode_get_string (pin_desc->pin_mode)), |
| VALIDATE_UNKNOWN (mbim_pin_format_get_string (pin_desc->pin_format)), |
| pin_desc->pin_length_min, |
| pin_desc->pin_length_max); |
| } |
| |
| static void |
| pin_list_ready (MbimDevice *device, |
| GAsyncResult *res, |
| gpointer user_data) |
| { |
| MbimMessage *response; |
| GError *error = NULL; |
| MbimPinDesc *pin_desc_pin1; |
| MbimPinDesc *pin_desc_pin2; |
| MbimPinDesc *pin_desc_device_sim_pin; |
| MbimPinDesc *pin_desc_device_first_sim_pin; |
| MbimPinDesc *pin_desc_network_pin; |
| MbimPinDesc *pin_desc_network_subset_pin; |
| MbimPinDesc *pin_desc_service_provider_pin; |
| MbimPinDesc *pin_desc_corporate_pin; |
| MbimPinDesc *pin_desc_subsidy_lock; |
| MbimPinDesc *pin_desc_custom; |
| |
| response = mbim_device_command_finish (device, res, &error); |
| if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) { |
| g_printerr ("error: operation failed: %s\n", error->message); |
| g_error_free (error); |
| if (response) |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| if (!mbim_message_pin_list_response_parse ( |
| response, |
| &pin_desc_pin1, |
| &pin_desc_pin2, |
| &pin_desc_device_sim_pin, |
| &pin_desc_device_first_sim_pin, |
| &pin_desc_network_pin, |
| &pin_desc_network_subset_pin, |
| &pin_desc_service_provider_pin, |
| &pin_desc_corporate_pin, |
| &pin_desc_subsidy_lock, |
| &pin_desc_custom, |
| &error)) { |
| g_printerr ("error: couldn't parse response message: %s\n", error->message); |
| g_error_free (error); |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| g_print ("[%s] PIN list:\n\n", |
| mbim_device_get_path_display (device)); |
| |
| print_pin_desc ("PIN1", pin_desc_pin1); |
| print_pin_desc ("PIN2", pin_desc_pin2); |
| print_pin_desc ("Device SIM PIN", pin_desc_device_sim_pin); |
| print_pin_desc ("Device first SIM PIN", pin_desc_device_first_sim_pin); |
| print_pin_desc ("Network PIN", pin_desc_network_pin); |
| print_pin_desc ("Network subset PIN", pin_desc_network_subset_pin); |
| print_pin_desc ("Service provider PIN", pin_desc_service_provider_pin); |
| print_pin_desc ("Corporate PIN", pin_desc_corporate_pin); |
| print_pin_desc ("Subsidy lock", pin_desc_subsidy_lock); |
| print_pin_desc ("Custom", pin_desc_custom); |
| |
| mbim_pin_desc_free (pin_desc_pin1); |
| mbim_pin_desc_free (pin_desc_pin2); |
| mbim_pin_desc_free (pin_desc_device_sim_pin); |
| mbim_pin_desc_free (pin_desc_device_first_sim_pin); |
| mbim_pin_desc_free (pin_desc_network_pin); |
| mbim_pin_desc_free (pin_desc_network_subset_pin); |
| mbim_pin_desc_free (pin_desc_service_provider_pin); |
| mbim_pin_desc_free (pin_desc_corporate_pin); |
| mbim_pin_desc_free (pin_desc_subsidy_lock); |
| mbim_pin_desc_free (pin_desc_custom); |
| |
| mbim_message_unref (response); |
| shutdown (TRUE); |
| } |
| |
| static void |
| ip_configuration_query_ready (MbimDevice *device, |
| GAsyncResult *res, |
| gpointer unused) |
| { |
| GError *error = NULL; |
| MbimMessage *response; |
| gboolean success = FALSE; |
| |
| response = mbim_device_command_finish (device, res, &error); |
| if (!response || |
| !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) { |
| g_printerr ("error: couldn't get IP configuration response message: %s\n", error->message); |
| } else { |
| success = mbimcli_print_ip_config (device, response, &error); |
| if (!success) |
| g_printerr ("error: couldn't parse IP configuration response message: %s\n", error->message); |
| } |
| |
| g_clear_error (&error); |
| if (response) |
| mbim_message_unref (response); |
| shutdown (success); |
| } |
| |
| static void |
| ip_configuration_query (MbimDevice *device, |
| GCancellable *cancellable, |
| guint32 session_id) |
| { |
| MbimMessage *message; |
| GError *error = NULL; |
| |
| message = (mbim_message_ip_configuration_query_new ( |
| session_id, |
| MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_NONE, /* ipv4configurationavailable */ |
| MBIM_IP_CONFIGURATION_AVAILABLE_FLAG_NONE, /* ipv6configurationavailable */ |
| 0, /* ipv4addresscount */ |
| NULL, /* ipv4address */ |
| 0, /* ipv6addresscount */ |
| NULL, /* ipv6address */ |
| NULL, /* ipv4gateway */ |
| NULL, /* ipv6gateway */ |
| 0, /* ipv4dnsservercount */ |
| NULL, /* ipv4dnsserver */ |
| 0, /* ipv6dnsservercount */ |
| NULL, /* ipv6dnsserver */ |
| 0, /* ipv4mtu */ |
| 0, /* ipv6mtu */ |
| &error)); |
| if (!message) { |
| g_printerr ("error: couldn't create IP config request: %s\n", error->message); |
| g_error_free (error); |
| shutdown (FALSE); |
| return; |
| } |
| |
| mbim_device_command (device, |
| message, |
| 60, |
| cancellable, |
| (GAsyncReadyCallback)ip_configuration_query_ready, |
| NULL); |
| mbim_message_unref (message); |
| } |
| |
| static void |
| connect_ready (MbimDevice *device, |
| GAsyncResult *res, |
| gpointer user_data) |
| { |
| MbimMessage *response; |
| GError *error = NULL; |
| guint32 session_id; |
| MbimActivationState activation_state; |
| MbimVoiceCallState voice_call_state; |
| MbimContextIpType ip_type; |
| const MbimUuid *context_type; |
| guint32 nw_error; |
| |
| response = mbim_device_command_finish (device, res, &error); |
| if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) { |
| g_printerr ("error: operation failed: %s\n", error->message); |
| g_error_free (error); |
| if (response) |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| if (!mbim_message_connect_response_parse ( |
| response, |
| &session_id, |
| &activation_state, |
| &voice_call_state, |
| &ip_type, |
| &context_type, |
| &nw_error, |
| &error)) { |
| g_printerr ("error: couldn't parse response message: %s\n", error->message); |
| g_error_free (error); |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| mbim_message_unref (response); |
| |
| switch (GPOINTER_TO_UINT (user_data)) { |
| case CONNECT: |
| g_print ("[%s] Successfully connected\n\n", |
| mbim_device_get_path_display (device)); |
| break; |
| case DISCONNECT: |
| g_print ("[%s] Successfully disconnected\n\n", |
| mbim_device_get_path_display (device)); |
| break; |
| default: |
| break; |
| } |
| |
| g_print ("[%s] Connection status:\n" |
| "\t Session ID: '%u'\n" |
| "\tActivation state: '%s'\n" |
| "\tVoice call state: '%s'\n" |
| "\t IP type: '%s'\n" |
| "\t Context type: '%s'\n" |
| "\t Network error: '%s'\n", |
| mbim_device_get_path_display (device), |
| session_id, |
| VALIDATE_UNKNOWN (mbim_activation_state_get_string (activation_state)), |
| VALIDATE_UNKNOWN (mbim_voice_call_state_get_string (voice_call_state)), |
| VALIDATE_UNKNOWN (mbim_context_ip_type_get_string (ip_type)), |
| VALIDATE_UNKNOWN (mbim_context_type_get_string (mbim_uuid_to_context_type (context_type))), |
| VALIDATE_UNKNOWN (mbim_nw_error_get_string (nw_error))); |
| |
| if (GPOINTER_TO_UINT (user_data) == CONNECT) { |
| ip_configuration_query (device, NULL, session_id); |
| return; |
| } |
| |
| shutdown (TRUE); |
| } |
| |
| static void |
| ip_packet_filters_ready (MbimDevice *device, |
| GAsyncResult *res, |
| gpointer unused) |
| { |
| MbimMessage *response; |
| GError *error = NULL; |
| MbimPacketFilter **filters; |
| guint32 filters_count, i; |
| |
| response = mbim_device_command_finish (device, res, &error); |
| if (!response || |
| !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) { |
| g_printerr ("error: operation failed: %s\n", error->message); |
| g_error_free (error); |
| if (response) |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| if (!mbim_message_ip_packet_filters_response_parse ( |
| response, |
| NULL, /* sessionid */ |
| &filters_count, |
| &filters, |
| &error)) { |
| g_printerr ("error: couldn't parse response message: %s\n", error->message); |
| g_error_free (error); |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| g_print ("\n[%s] IP packet filters: (%u)\n", mbim_device_get_path_display (device), filters_count); |
| |
| for (i = 0; i < filters_count; i++) { |
| gchar *bytes; |
| |
| g_print ("\n"); |
| g_print ("\tFilter size: %u\n", filters[i]->filter_size); |
| |
| bytes = mbim_common_str_hex (filters[i]->packet_filter, filters[i]->filter_size, ' '); |
| g_print ("\tPacket filter: %s\n", VALIDATE_UNKNOWN (bytes)); |
| g_free (bytes); |
| |
| bytes = mbim_common_str_hex (filters[i]->packet_mask, filters[i]->filter_size, ' '); |
| g_print ("\tPacket mask: %s\n", VALIDATE_UNKNOWN (bytes)); |
| g_free (bytes); |
| } |
| |
| mbim_packet_filter_array_free (filters); |
| |
| mbim_message_unref (response); |
| shutdown (TRUE); |
| } |
| |
| static gboolean |
| mbim_auth_protocol_from_string (const gchar *str, |
| MbimAuthProtocol *auth_protocol) |
| { |
| if (g_ascii_strcasecmp (str, "PAP") == 0) { |
| *auth_protocol = MBIM_AUTH_PROTOCOL_PAP; |
| return TRUE; |
| } else if (g_ascii_strcasecmp (str, "CHAP") == 0) { |
| *auth_protocol = MBIM_AUTH_PROTOCOL_CHAP; |
| return TRUE; |
| } else if (g_ascii_strcasecmp (str, "MSCHAPV2") == 0) { |
| *auth_protocol = MBIM_AUTH_PROTOCOL_MSCHAPV2; |
| return TRUE; |
| } |
| |
| return FALSE; |
| } |
| |
| static gboolean |
| connect_session_id_parse (const gchar *str, |
| gboolean allow_empty, |
| guint32 *session_id, |
| GError **error) |
| { |
| gchar *endptr = NULL; |
| gint64 n; |
| |
| g_assert (str != NULL); |
| g_assert (session_id != NULL); |
| |
| if (!str[0]) { |
| if (allow_empty) { |
| *session_id = 0; |
| return TRUE; |
| } |
| g_set_error_literal (error, |
| MBIM_CORE_ERROR, |
| MBIM_CORE_ERROR_FAILED, |
| "missing session ID (must be 0 - 255)"); |
| return FALSE; |
| } |
| |
| errno = 0; |
| n = g_ascii_strtoll (str, &endptr, 10); |
| if (errno || n < 0 || n > 255 || ((endptr - str) < strlen (str))) { |
| g_set_error (error, |
| MBIM_CORE_ERROR, |
| MBIM_CORE_ERROR_FAILED, |
| "couldn't parse session ID '%s' (must be 0 - 255)", |
| str); |
| return FALSE; |
| } |
| *session_id = (guint32) n; |
| |
| return TRUE; |
| } |
| |
| typedef struct { |
| guint32 session_id; |
| gchar *apn; |
| MbimAuthProtocol auth_protocol; |
| gchar *username; |
| gchar *password; |
| } ConnectActivateProperties; |
| |
| static gboolean connect_activate_properties_handle (const gchar *key, |
| const gchar *value, |
| GError **error, |
| gpointer user_data) |
| { |
| ConnectActivateProperties *props = user_data; |
| |
| /* APN may be empty */ |
| if ((g_ascii_strcasecmp (key, "apn") != 0) && (!value || !value[0])) { |
| g_set_error (error, |
| MBIM_CORE_ERROR, |
| MBIM_CORE_ERROR_FAILED, |
| "key '%s' required a value", |
| key); |
| return FALSE; |
| } |
| |
| if (g_ascii_strcasecmp (key, "session-id") == 0) { |
| if (!connect_session_id_parse (value, FALSE, &props->session_id, error)) |
| return FALSE; |
| } else if (g_ascii_strcasecmp (key, "apn") == 0 && !props->apn) { |
| props->apn = g_strdup (value); |
| } else if (g_ascii_strcasecmp (key, "auth") == 0) { |
| if (!mbim_auth_protocol_from_string (value, &props->auth_protocol)) { |
| g_set_error (error, |
| MBIM_CORE_ERROR, |
| MBIM_CORE_ERROR_FAILED, |
| "unknown auth protocol '%s'", |
| value); |
| return FALSE; |
| } |
| } else if (g_ascii_strcasecmp (key, "username") == 0 && !props->username) { |
| props->username = g_strdup (value); |
| } else if (g_ascii_strcasecmp (key, "password") == 0 && !props->password) { |
| props->password = g_strdup (value); |
| } else { |
| g_set_error (error, |
| MBIM_CORE_ERROR, |
| MBIM_CORE_ERROR_FAILED, |
| "unrecognized or duplicate option '%s'", |
| key); |
| return FALSE; |
| } |
| |
| return TRUE; |
| } |
| |
| static gboolean |
| set_connect_activate_parse (const gchar *str, |
| guint32 *session_id, |
| gchar **apn, |
| MbimAuthProtocol *auth_protocol, |
| gchar **username, |
| gchar **password) |
| { |
| ConnectActivateProperties props = { |
| .session_id = 0, |
| .apn = NULL, |
| .auth_protocol = MBIM_AUTH_PROTOCOL_NONE, |
| .username = NULL, |
| .password = NULL |
| }; |
| gchar **split = NULL; |
| |
| g_assert (session_id != NULL); |
| g_assert (apn != NULL); |
| g_assert (auth_protocol != NULL); |
| g_assert (username != NULL); |
| g_assert (password != NULL); |
| |
| if (strchr (str, '=')) { |
| GError *error = NULL; |
| |
| /* New key=value format */ |
| if (!mbimcli_parse_key_value_string (str, |
| &error, |
| connect_activate_properties_handle, |
| &props)) { |
| g_printerr ("error: couldn't parse input string: %s\n", error->message); |
| g_error_free (error); |
| goto error; |
| } |
| } else { |
| /* Old non key=value format, like this: |
| * "[(APN),(PAP|CHAP|MSCHAPV2),(Username),(Password)]" |
| */ |
| split = g_strsplit (str, ",", -1); |
| |
| if (g_strv_length (split) > 4) { |
| g_printerr ("error: couldn't parse input string, too many arguments\n"); |
| goto error; |
| } |
| |
| if (g_strv_length (split) > 0) { |
| /* APN */ |
| props.apn = g_strdup (split[0]); |
| |
| /* Use authentication method */ |
| if (split[1]) { |
| if (!mbim_auth_protocol_from_string (split[1], &props.auth_protocol)) { |
| g_printerr ("error: couldn't parse input string, unknown auth protocol '%s'\n", split[1]); |
| goto error; |
| } |
| /* Username */ |
| if (split[2]) { |
| props.username = g_strdup (split[2]); |
| /* Password */ |
| props.password = g_strdup (split[3]); |
| } |
| } |
| } |
| } |
| |
| if (props.auth_protocol == MBIM_AUTH_PROTOCOL_NONE) { |
| if (props.username || props.password) { |
| g_printerr ("error: username or password requires an auth protocol\n"); |
| goto error; |
| } |
| } else { |
| if (!props.username) { |
| g_printerr ("error: auth protocol requires a username\n"); |
| goto error; |
| } |
| } |
| |
| *session_id = props.session_id; |
| *apn = props.apn; |
| *auth_protocol = props.auth_protocol; |
| *username = props.username; |
| *password = props.password; |
| |
| if (split) |
| g_strfreev (split); |
| |
| return TRUE; |
| |
| error: |
| if (split) |
| g_strfreev (split); |
| g_free (props.apn); |
| g_free (props.username); |
| g_free (props.password); |
| return FALSE; |
| } |
| |
| static void |
| home_provider_ready (MbimDevice *device, |
| GAsyncResult *res, |
| gpointer user_data) |
| { |
| MbimMessage *response; |
| GError *error = NULL; |
| MbimProvider *provider; |
| gchar *provider_state_str; |
| gchar *cellular_class_str; |
| |
| response = mbim_device_command_finish (device, res, &error); |
| if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) { |
| g_printerr ("error: operation failed: %s\n", error->message); |
| g_error_free (error); |
| if (response) |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| if (!mbim_message_home_provider_response_parse (response, |
| &provider, |
| &error)) { |
| g_printerr ("error: couldn't parse response message: %s\n", error->message); |
| g_error_free (error); |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| provider_state_str = mbim_provider_state_build_string_from_mask (provider->provider_state); |
| cellular_class_str = mbim_cellular_class_build_string_from_mask (provider->cellular_class); |
| |
| g_print ("[%s] Home provider:\n" |
| "\t Provider ID: '%s'\n" |
| "\t Provider name: '%s'\n" |
| "\t State: '%s'\n" |
| "\tCellular class: '%s'\n" |
| "\t RSSI: '%u'\n" |
| "\t Error rate: '%u'\n", |
| mbim_device_get_path_display (device), |
| VALIDATE_UNKNOWN (provider->provider_id), |
| VALIDATE_UNKNOWN (provider->provider_name), |
| VALIDATE_UNKNOWN (provider_state_str), |
| VALIDATE_UNKNOWN (cellular_class_str), |
| provider->rssi, |
| provider->error_rate); |
| |
| g_free (cellular_class_str); |
| g_free (provider_state_str); |
| |
| mbim_provider_free (provider); |
| mbim_message_unref (response); |
| shutdown (TRUE); |
| } |
| |
| static void |
| preferred_providers_ready (MbimDevice *device, |
| GAsyncResult *res, |
| gpointer user_data) |
| { |
| MbimMessage *response; |
| GError *error = NULL; |
| MbimProvider **providers; |
| guint n_providers; |
| guint i; |
| |
| response = mbim_device_command_finish (device, res, &error); |
| if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) { |
| g_printerr ("error: operation failed: %s\n", error->message); |
| g_error_free (error); |
| if (response) |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| if (!mbim_message_preferred_providers_response_parse (response, |
| &n_providers, |
| &providers, |
| &error)) { |
| g_printerr ("error: couldn't parse response message: %s\n", error->message); |
| g_error_free (error); |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| if (!n_providers) |
| g_print ("[%s] No preferred providers given\n", |
| mbim_device_get_path_display (device)); |
| else |
| g_print ("[%s] Preferred providers (%u):\n", |
| mbim_device_get_path_display (device), |
| n_providers); |
| |
| for (i = 0; i < n_providers; i++) { |
| gchar *provider_state_str; |
| gchar *cellular_class_str; |
| |
| provider_state_str = mbim_provider_state_build_string_from_mask (providers[i]->provider_state); |
| cellular_class_str = mbim_cellular_class_build_string_from_mask (providers[i]->cellular_class); |
| |
| g_print ("\tProvider [%u]:\n" |
| "\t\t Provider ID: '%s'\n" |
| "\t\t Provider name: '%s'\n" |
| "\t\t State: '%s'\n" |
| "\t\t Cellular class: '%s'\n" |
| "\t\t RSSI: '%u'\n" |
| "\t\t Error rate: '%u'\n", |
| i, |
| VALIDATE_UNKNOWN (providers[i]->provider_id), |
| VALIDATE_UNKNOWN (providers[i]->provider_name), |
| VALIDATE_UNKNOWN (provider_state_str), |
| VALIDATE_UNKNOWN (cellular_class_str), |
| providers[i]->rssi, |
| providers[i]->error_rate); |
| |
| g_free (cellular_class_str); |
| g_free (provider_state_str); |
| } |
| |
| mbim_provider_array_free (providers); |
| mbim_message_unref (response); |
| shutdown (TRUE); |
| } |
| |
| static void |
| visible_providers_ready (MbimDevice *device, |
| GAsyncResult *res, |
| gpointer user_data) |
| { |
| MbimMessage *response; |
| GError *error = NULL; |
| MbimProvider **providers; |
| guint n_providers; |
| guint i; |
| |
| response = mbim_device_command_finish (device, res, &error); |
| if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) { |
| g_printerr ("error: operation failed: %s\n", error->message); |
| g_error_free (error); |
| if (response) |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| if (!mbim_message_visible_providers_response_parse (response, |
| &n_providers, |
| &providers, |
| &error)) { |
| g_printerr ("error: couldn't parse response message: %s\n", error->message); |
| g_error_free (error); |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| if (!n_providers) |
| g_print ("[%s] No visible providers given\n", |
| mbim_device_get_path_display (device)); |
| else |
| g_print ("[%s] Visible providers (%u):\n", |
| mbim_device_get_path_display (device), |
| n_providers); |
| |
| for (i = 0; i < n_providers; i++) { |
| gchar *provider_state_str; |
| gchar *cellular_class_str; |
| |
| provider_state_str = mbim_provider_state_build_string_from_mask (providers[i]->provider_state); |
| cellular_class_str = mbim_cellular_class_build_string_from_mask (providers[i]->cellular_class); |
| |
| g_print ("\tProvider [%u]:\n" |
| "\t\t Provider ID: '%s'\n" |
| "\t\t Provider name: '%s'\n" |
| "\t\t State: '%s'\n" |
| "\t\t Cellular class: '%s'\n" |
| "\t\t RSSI: '%u'\n" |
| "\t\t Error rate: '%u'\n", |
| i, |
| VALIDATE_UNKNOWN (providers[i]->provider_id), |
| VALIDATE_UNKNOWN (providers[i]->provider_name), |
| VALIDATE_UNKNOWN (provider_state_str), |
| VALIDATE_UNKNOWN (cellular_class_str), |
| providers[i]->rssi, |
| providers[i]->error_rate); |
| |
| g_free (cellular_class_str); |
| g_free (provider_state_str); |
| } |
| |
| mbim_provider_array_free (providers); |
| mbim_message_unref (response); |
| shutdown (TRUE); |
| } |
| |
| static void |
| register_state_ready (MbimDevice *device, |
| GAsyncResult *res, |
| gpointer user_data) |
| { |
| MbimMessage *response; |
| GError *error = NULL; |
| MbimNwError nw_error; |
| MbimRegisterState register_state; |
| MbimRegisterMode register_mode; |
| MbimDataClass available_data_classes; |
| gchar *available_data_classes_str; |
| MbimCellularClass cellular_class; |
| gchar *cellular_class_str; |
| gchar *provider_id; |
| gchar *provider_name; |
| gchar *roaming_text; |
| MbimRegistrationFlag registration_flag; |
| gchar *registration_flag_str; |
| |
| response = mbim_device_command_finish (device, res, &error); |
| if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) { |
| g_printerr ("error: operation failed: %s\n", error->message); |
| g_error_free (error); |
| if (response) |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| if (!mbim_message_register_state_response_parse (response, |
| &nw_error, |
| ®ister_state, |
| ®ister_mode, |
| &available_data_classes, |
| &cellular_class, |
| &provider_id, |
| &provider_name, |
| &roaming_text, |
| ®istration_flag, |
| &error)) { |
| g_printerr ("error: couldn't parse response message: %s\n", error->message); |
| g_error_free (error); |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| if (GPOINTER_TO_UINT (user_data)) |
| g_print ("[%s] Successfully launched automatic registration\n\n", |
| mbim_device_get_path_display (device)); |
| |
| available_data_classes_str = mbim_data_class_build_string_from_mask (available_data_classes); |
| cellular_class_str = mbim_cellular_class_build_string_from_mask (cellular_class); |
| registration_flag_str = mbim_registration_flag_build_string_from_mask (registration_flag); |
| |
| g_print ("[%s] Registration status:\n" |
| "\t Network error: '%s'\n" |
| "\t Register state: '%s'\n" |
| "\t Register mode: '%s'\n" |
| "\tAvailable data classes: '%s'\n" |
| "\tCurrent cellular class: '%s'\n" |
| "\t Provider ID: '%s'\n" |
| "\t Provider name: '%s'\n" |
| "\t Roaming text: '%s'\n" |
| "\t Registration flags: '%s'\n", |
| mbim_device_get_path_display (device), |
| VALIDATE_UNKNOWN (mbim_nw_error_get_string (nw_error)), |
| VALIDATE_UNKNOWN (mbim_register_state_get_string (register_state)), |
| VALIDATE_UNKNOWN (mbim_register_mode_get_string (register_mode)), |
| VALIDATE_UNKNOWN (available_data_classes_str), |
| VALIDATE_UNKNOWN (cellular_class_str), |
| VALIDATE_UNKNOWN (provider_id), |
| VALIDATE_UNKNOWN (provider_name), |
| VALIDATE_UNKNOWN (roaming_text), |
| VALIDATE_UNKNOWN (registration_flag_str)); |
| |
| g_free (available_data_classes_str); |
| g_free (cellular_class_str); |
| g_free (registration_flag_str); |
| g_free (provider_name); |
| g_free (provider_id); |
| g_free (roaming_text); |
| |
| mbim_message_unref (response); |
| shutdown (TRUE); |
| } |
| |
| static void |
| signal_state_ready (MbimDevice *device, |
| GAsyncResult *res, |
| gpointer user_data) |
| { |
| MbimMessage *response; |
| GError *error = NULL; |
| guint32 rssi; |
| guint32 error_rate; |
| guint32 signal_strength_interval; |
| guint32 rssi_threshold; |
| guint32 error_rate_threshold; |
| |
| response = mbim_device_command_finish (device, res, &error); |
| if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) { |
| g_printerr ("error: operation failed: %s\n", error->message); |
| g_error_free (error); |
| if (response) |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| if (!mbim_message_signal_state_response_parse (response, |
| &rssi, |
| &error_rate, |
| &signal_strength_interval, |
| &rssi_threshold, |
| &error_rate_threshold, |
| &error)) { |
| g_printerr ("error: couldn't parse response message: %s\n", error->message); |
| g_error_free (error); |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| g_print ("[%s] Signal state:\n" |
| "\t RSSI [0-31,99]: '%u'\n" |
| "\t Error rate [0-7,99]: '%u'\n" |
| "\tSignal strength interval: '%u'\n" |
| "\t RSSI threshold: '%u'\n", |
| mbim_device_get_path_display (device), |
| rssi, |
| error_rate, |
| signal_strength_interval, |
| rssi_threshold); |
| |
| if (error_rate_threshold == 0xFFFFFFFF) |
| g_print ("\t Error rate threshold: 'unspecified'\n"); |
| else |
| g_print ("\t Error rate threshold: '%u'\n", error_rate_threshold); |
| |
| mbim_message_unref (response); |
| shutdown (TRUE); |
| } |
| |
| enum { |
| PACKET_SERVICE_STATUS, |
| PACKET_SERVICE_ATTACH, |
| PACKET_SERVICE_DETACH |
| }; |
| |
| static void |
| packet_service_ready (MbimDevice *device, |
| GAsyncResult *res, |
| gpointer user_data) |
| { |
| MbimMessage *response; |
| GError *error = NULL; |
| guint32 nw_error; |
| MbimPacketServiceState packet_service_state; |
| MbimDataClass highest_available_data_class; |
| gchar *highest_available_data_class_str; |
| guint64 uplink_speed; |
| guint64 downlink_speed; |
| |
| response = mbim_device_command_finish (device, res, &error); |
| if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) { |
| g_printerr ("error: operation failed: %s\n", error->message); |
| g_error_free (error); |
| if (response) |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| if (!mbim_message_packet_service_response_parse (response, |
| &nw_error, |
| &packet_service_state, |
| &highest_available_data_class, |
| &uplink_speed, |
| &downlink_speed, |
| &error)) { |
| g_printerr ("error: couldn't parse response message: %s\n", error->message); |
| g_error_free (error); |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| switch (GPOINTER_TO_UINT (user_data)) { |
| case PACKET_SERVICE_ATTACH: |
| g_print ("[%s] Successfully attached to packet service\n\n", |
| mbim_device_get_path_display (device)); |
| break; |
| case PACKET_SERVICE_DETACH: |
| g_print ("[%s] Successfully detached from packet service\n\n", |
| mbim_device_get_path_display (device)); |
| break; |
| default: |
| break; |
| } |
| |
| highest_available_data_class_str = mbim_data_class_build_string_from_mask (highest_available_data_class); |
| |
| g_print ("[%s] Packet service status:\n" |
| "\t Network error: '%s'\n" |
| "\t Packet service state: '%s'\n" |
| "\tAvailable data classes: '%s'\n" |
| "\t Uplink speed: '%" G_GUINT64_FORMAT " bps'\n" |
| "\t Downlink speed: '%" G_GUINT64_FORMAT " bps'\n", |
| mbim_device_get_path_display (device), |
| VALIDATE_UNKNOWN (mbim_nw_error_get_string (nw_error)), |
| VALIDATE_UNKNOWN (mbim_packet_service_state_get_string (packet_service_state)), |
| VALIDATE_UNKNOWN (highest_available_data_class_str), |
| uplink_speed, |
| downlink_speed); |
| |
| g_free (highest_available_data_class_str); |
| |
| mbim_message_unref (response); |
| shutdown (TRUE); |
| } |
| |
| static void |
| packet_statistics_ready (MbimDevice *device, |
| GAsyncResult *res) |
| { |
| MbimMessage *response; |
| GError *error = NULL; |
| guint32 in_discards; |
| guint32 in_errors; |
| guint64 in_octets; |
| guint64 in_packets; |
| guint64 out_octets; |
| guint64 out_packets; |
| guint32 out_errors; |
| guint32 out_discards; |
| |
| response = mbim_device_command_finish (device, res, &error); |
| if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) { |
| g_printerr ("error: operation failed: %s\n", error->message); |
| g_error_free (error); |
| if (response) |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| if (!mbim_message_packet_statistics_response_parse (response, |
| &in_discards, |
| &in_errors, |
| &in_octets, |
| &in_packets, |
| &out_octets, |
| &out_packets, |
| &out_errors, |
| &out_discards, |
| &error)) { |
| g_printerr ("error: couldn't parse response message: %s\n", error->message); |
| g_error_free (error); |
| mbim_message_unref (response); |
| shutdown (FALSE); |
| return; |
| } |
| |
| g_print ("[%s] Packet statistics:\n" |
| "\t Octets (in): '%" G_GUINT64_FORMAT "'\n" |
| "\t Packets (in): '%" G_GUINT64_FORMAT "'\n" |
| "\t Discards (in): '%u'\n" |
| "\t Errors (in): '%u'\n" |
| "\t Octets (out): '%" G_GUINT64_FORMAT "'\n" |
| "\t Packets (out): '%" G_GUINT64_FORMAT "'\n" |
| "\tDiscards (out): '%u'\n" |
| "\t Errors (out): '%u'\n", |
| mbim_device_get_path_display (device), |
| in_octets, |
| in_packets, |
| in_discards, |
| in_errors, |
| out_octets, |
| out_packets, |
| out_discards, |
| out_errors); |
| |
| mbim_message_unref (response); |
| shutdown (TRUE); |
| } |
| |
| void |
| mbimcli_basic_connect_run (MbimDevice *device, |
| GCancellable *cancellable) |
| { |
| /* Initialize context */ |
| ctx = g_slice_new (Context); |
| ctx->device = g_object_ref (device); |
| ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL; |
| |
| /* Request to get capabilities? */ |
| if (query_device_caps_flag) { |
| MbimMessage *request; |
| |
| g_debug ("Asynchronously querying device capabilities..."); |
| request = (mbim_message_device_caps_query_new (NULL)); |
| mbim_device_command (ctx->device, |
| request, |
| 10, |
| ctx->cancellable, |
| (GAsyncReadyCallback)query_device_caps_ready, |
| NULL); |
| mbim_message_unref (request); |
| return; |
| } |
| |
| /* Request to get subscriber ready status? */ |
| if (query_subscriber_ready_status_flag) { |
| MbimMessage *request; |
| |
| g_debug ("Asynchronously querying subscriber ready status..."); |
| request = (mbim_message_subscriber_ready_status_query_new (NULL)); |
| mbim_device_command (ctx->device, |
| request, |
| 10, |
| ctx->cancellable, |
| (GAsyncReadyCallback)query_subscriber_ready_status_ready, |
| NULL); |
| mbim_message_unref (request); |
| return; |
| } |
| |
| /* Request to get radio state? */ |
| if (query_radio_state_flag) { |
| MbimMessage *request; |
| |
| g_debug ("Asynchronously querying radio state..."); |
| request = (mbim_message_radio_state_query_new (NULL)); |
| mbim_device_command (ctx->device, |
| request, |
| 10, |
| ctx->cancellable, |
| (GAsyncReadyCallback)query_radio_state_ready, |
| NULL); |
| mbim_message_unref (request); |
| return; |
| } |
| |
| /* Request to set radio state? */ |
| if (set_radio_state_str) { |
| MbimMessage *request; |
| MbimRadioSwitchState radio_state; |
| |
| if (g_ascii_strcasecmp (set_radio_state_str, "on") == 0) { |
| radio_state = MBIM_RADIO_SWITCH_STATE_ON; |
| } else if (g_ascii_strcasecmp (set_radio_state_str, "off") == 0) { |
| radio_state = MBIM_RADIO_SWITCH_STATE_OFF; |
| } else { |
| g_printerr ("error: invalid radio state: '%s'\n", set_radio_state_str); |
| shutdown (FALSE); |
| return; |
| } |
| |
| g_debug ("Asynchronously setting radio state to %s...", |
| radio_state == MBIM_RADIO_SWITCH_STATE_ON ? "on" : "off"); |
| request = mbim_message_radio_state_set_new (radio_state, NULL); |
| mbim_device_command (ctx->device, |
| request, |
| 10, |
| ctx->cancellable, |
| (GAsyncReadyCallback)query_radio_state_ready, |
| NULL); |
| mbim_message_unref (request); |
| return; |
| } |
| |
| /* Request to query device services? */ |
| if (query_device_services_flag) { |
| MbimMessage *request; |
| |
| g_debug ("Asynchronously querying device services..."); |
| request = (mbim_message_device_services_query_new (NULL)); |
| mbim_device_command (ctx->device, |
| request, |
| 10, |
| ctx->cancellable, |
| (GAsyncReadyCallback)query_device_services_ready, |
| NULL); |
| mbim_message_unref (request); |
| return; |
| } |
| |
| /* Query PIN state? */ |
| if (query_pin_flag) { |
| MbimMessage *request; |
| |
| g_debug ("Asynchronously querying PIN state..."); |
| request = (mbim_message_pin_query_new (NULL)); |
| mbim_device_command (ctx->device, |
| request, |
| 10, |
| ctx->cancellable, |
| (GAsyncReadyCallback)pin_ready, |
| GUINT_TO_POINTER (FALSE)); |
| mbim_message_unref (request); |
| return; |
| } |
| |
| /* Set PIN? */ |
| if (set_pin_enter_str || |
| set_pin_change_str || |
| set_pin_enable_str || |
| set_pin_disable_str || |
| set_pin_enter_puk_str) { |
| MbimMessage *request; |
| guint n_expected; |
| MbimPinType pin_type; |
| MbimPinOperation pin_operation; |
| gchar *pin; |
| gchar *new_pin; |
| const gchar *input = NULL; |
| GError *error = NULL; |
| |
| if (set_pin_enter_puk_str) { |
| g_debug ("Asynchronously entering PUK..."); |
| pin_type = MBIM_PIN_TYPE_PUK1; |
| input = set_pin_enter_puk_str; |
| n_expected = 2; |
| pin_operation = MBIM_PIN_OPERATION_ENTER; |
| } else { |
| pin_type = MBIM_PIN_TYPE_PIN1; |
| if (set_pin_change_str) { |
| g_debug ("Asynchronously changing PIN..."); |
| input = set_pin_change_str; |
| n_expected = 2; |
| pin_operation = MBIM_PIN_OPERATION_CHANGE; |
| } else if (set_pin_enable_str) { |
| g_debug ("Asynchronously enabling PIN..."); |
| input = set_pin_enable_str; |
| n_expected = 1; |
| pin_operation = MBIM_PIN_OPERATION_ENABLE; |
| } else if (set_pin_disable_str) { |
| g_debug ("Asynchronously disabling PIN..."); |
| input = set_pin_disable_str; |
| n_expected = 1; |
| pin_operation = MBIM_PIN_OPERATION_DISABLE; |
| } else if (set_pin_enter_str) { |
| g_debug ("Asynchronously entering PIN..."); |
| input = set_pin_enter_str; |
| n_expected = 1; |
| pin_operation = MBIM_PIN_OPERATION_ENTER; |
| } else |
| g_assert_not_reached (); |
| } |
| |
| if (!set_pin_input_parse (n_expected, input, &pin, &new_pin)) { |
| shutdown (FALSE); |
| return; |
| } |
| |
| request = (mbim_message_pin_set_new (pin_type, |
| pin_operation, |
| pin, |
| new_pin, |
| &error)); |
| g_free (pin); |
| g_free (new_pin); |
| |
| if (!request) { |
| g_printerr ("error: couldn't create request: %s\n", error->message); |
| g_error_free (error); |
| shutdown (FALSE); |
| return; |
| } |
| |
| mbim_device_command (ctx->device, |
| request, |
| 10, |
| ctx->cancellable, |
| (GAsyncReadyCallback)pin_ready, |
| GUINT_TO_POINTER (TRUE)); |
| mbim_message_unref (request); |
| return; |
| } |
| |
| /* Query PIN list? */ |
| if (query_pin_list_flag) { |
| MbimMessage *request; |
| |
| g_debug ("Asynchronously querying PIN list..."); |
| request = (mbim_message_pin_list_query_new (NULL)); |
| mbim_device_command (ctx->device, |
| request, |
| 10, |
| ctx->cancellable, |
| (GAsyncReadyCallback)pin_list_ready, |
| GUINT_TO_POINTER (FALSE)); |
| mbim_message_unref (request); |
| return; |
| } |
| |
| /* Query home provider? */ |
| if (query_home_provider_flag) { |
| MbimMessage *request; |
| |
| request = mbim_message_home_provider_query_new (NULL); |
| mbim_device_command (ctx->device, |
| request, |
| 10, |
| ctx->cancellable, |
| (GAsyncReadyCallback)home_provider_ready, |
| NULL); |
| mbim_message_unref (request); |
| return; |
| } |
| |
| /* Query preferred providers? */ |
| if (query_preferred_providers_flag) { |
| MbimMessage *request; |
| |
| request = mbim_message_preferred_providers_query_new (NULL); |
| mbim_device_command (ctx->device, |
| request, |
| 10, |
| ctx->cancellable, |
| (GAsyncReadyCallback)preferred_providers_ready, |
| NULL); |
| mbim_message_unref (request); |
| return; |
| } |
| |
| /* Query visible providers? */ |
| if (query_visible_providers_flag) { |
| MbimMessage *request; |
| |
| request = mbim_message_visible_providers_query_new (MBIM_VISIBLE_PROVIDERS_ACTION_FULL_SCAN, NULL); |
| mbim_device_command (ctx->device, |
| request, |
| 120, /* longer timeout, needs to scan */ |
| ctx->cancellable, |
| (GAsyncReadyCallback)visible_providers_ready, |
| NULL); |
| mbim_message_unref (request); |
| return; |
| } |
| |
| /* Query registration status? */ |
| if (query_register_state_flag) { |
| MbimMessage *request; |
| |
| request = mbim_message_register_state_query_new (NULL); |
| mbim_device_command (ctx->device, |
| request, |
| 10, |
| ctx->cancellable, |
| (GAsyncReadyCallback)register_state_ready, |
| GUINT_TO_POINTER (FALSE)); |
| mbim_message_unref (request); |
| return; |
| } |
| |
| /* Launch automatic registration? */ |
| if (set_register_state_automatic_flag) { |
| MbimMessage *request; |
| GError *error = NULL; |
| |
| request = mbim_message_register_state_set_new (NULL, |
| MBIM_REGISTER_ACTION_AUTOMATIC, |
| 0, |
| &error); |
| if (!request) { |
| g_printerr ("error: couldn't create request: %s\n", error->message); |
| g_error_free (error); |
| shutdown (FALSE); |
| return; |
| } |
| |
| mbim_device_command (ctx->device, |
| request, |
| 120, /* longer timeout, needs to look for the home network */ |
| ctx->cancellable, |
| (GAsyncReadyCallback)register_state_ready, |
| GUINT_TO_POINTER (TRUE)); |
| mbim_message_unref (request); |
| return; |
| } |
| |
| /* Query signal status? */ |
| if (query_signal_state_flag) { |
| MbimMessage *request; |
| |
| request = mbim_message_signal_state_query_new (NULL); |
| mbim_device_command (ctx->device, |
| request, |
| 10, |
| ctx->cancellable, |
| (GAsyncReadyCallback)signal_state_ready, |
| NULL); |
| mbim_message_unref (request); |
| return; |
| } |
| |
| /* Query packet service status? */ |
| if (query_packet_service_flag) { |
| MbimMessage *request; |
| |
| request = mbim_message_packet_service_query_new (NULL); |
| mbim_device_command (ctx->device, |
| request, |
| 10, |
| ctx->cancellable, |
| (GAsyncReadyCallback)packet_service_ready, |
| GUINT_TO_POINTER (PACKET_SERVICE_STATUS)); |
| mbim_message_unref (request); |
| return; |
| } |
| |
| /* Launch packet attach or detach? */ |
| if (set_packet_service_attach_flag || |
| set_packet_service_detach_flag) { |
| MbimMessage *request; |
| MbimPacketServiceAction action; |
| GError *error = NULL; |
| |
| if (set_packet_service_attach_flag) |
| action = MBIM_PACKET_SERVICE_ACTION_ATTACH; |
| else if (set_packet_service_detach_flag) |
| action = MBIM_PACKET_SERVICE_ACTION_DETACH; |
| else |
| g_assert_not_reached (); |
| |
| request = mbim_message_packet_service_set_new (action, &error); |
| if (!request) { |
| g_printerr ("error: couldn't create request: %s\n", error->message); |
| g_error_free (error); |
| shutdown (FALSE); |
| return; |
| } |
| |
| mbim_device_command (ctx->device, |
| request, |
| 120, |
| ctx->cancellable, |
| (GAsyncReadyCallback)packet_service_ready, |
| GUINT_TO_POINTER (set_packet_service_attach_flag ? |
| PACKET_SERVICE_ATTACH : |
| PACKET_SERVICE_DETACH)); |
| mbim_message_unref (request); |
| return; |
| } |
| |
| /* Query connection status? */ |
| if (query_connect_str) { |
| MbimMessage *request; |
| GError *error = NULL; |
| guint32 session_id = 0; |
| |
| if (!connect_session_id_parse (query_connect_str, TRUE, &session_id, &error)) { |
| g_printerr ("error: couldn't parse session ID: %s\n", error->message); |
| g_error_free (error); |
| shutdown (FALSE); |
| return; |
| } |
| |
| request = mbim_message_connect_query_new (session_id, |
| MBIM_ACTIVATION_STATE_UNKNOWN, |
| MBIM_VOICE_CALL_STATE_NONE, |
| MBIM_CONTEXT_IP_TYPE_DEFAULT, |
| mbim_uuid_from_context_type (MBIM_CONTEXT_TYPE_INTERNET), |
| 0, |
| &error); |
| if (!request) { |
| g_printerr ("error: couldn't create request: %s\n", error->message); |
| g_error_free (error); |
| shutdown (FALSE); |
| return; |
| } |
| |
| mbim_device_command (ctx->device, |
| request, |
| 10, |
| ctx->cancellable, |
| (GAsyncReadyCallback)connect_ready, |
| GUINT_TO_POINTER (CONNECTION_STATUS)); |
| mbim_message_unref (request); |
| return; |
| } |
| |
| /* Connect? */ |
| if (set_connect_activate_str) { |
| MbimMessage *request; |
| GError *error = NULL; |
| guint32 session_id = 0; |
| gchar *apn; |
| MbimAuthProtocol auth_protocol; |
| gchar *username = NULL; |
| gchar *password = NULL; |
| |
| if (!set_connect_activate_parse (set_connect_activate_str, |
| &session_id, |
| &apn, |
| &auth_protocol, |
| &username, |
| &password)) { |
| shutdown (FALSE); |
| return; |
| } |
| |
| request = mbim_message_connect_set_new (session_id, |
| MBIM_ACTIVATION_COMMAND_ACTIVATE, |
| apn, |
| username, |
| password, |
| MBIM_COMPRESSION_NONE, |
| auth_protocol, |
| MBIM_CONTEXT_IP_TYPE_DEFAULT, |
| mbim_uuid_from_context_type (MBIM_CONTEXT_TYPE_INTERNET), |
| &error); |
| g_free (apn); |
| g_free (username); |
| g_free (password); |
| |
| if (!request) { |
| g_printerr ("error: couldn't create request: %s\n", error->message); |
| g_error_free (error); |
| shutdown (FALSE); |
| return; |
| } |
| |
| mbim_device_command (ctx->device, |
| request, |
| 120, |
| ctx->cancellable, |
| (GAsyncReadyCallback)connect_ready, |
| GUINT_TO_POINTER (CONNECT)); |
| mbim_message_unref (request); |
| return; |
| } |
| |
| /* Query IP configuration? */ |
| if (query_ip_configuration_str) { |
| GError *error = NULL; |
| guint32 session_id = 0; |
| |
| if (!connect_session_id_parse (query_ip_configuration_str, TRUE, &session_id, &error)) { |
| g_printerr ("error: couldn't parse session ID: %s\n", error->message); |
| g_error_free (error); |
| shutdown (FALSE); |
| return; |
| } |
| |
| ip_configuration_query (ctx->device, ctx->cancellable, session_id); |
| return; |
| } |
| |
| /* Disconnect? */ |
| if (set_connect_deactivate_str) { |
| MbimMessage *request; |
| GError *error = NULL; |
| guint32 session_id = 0; |
| |
| if (!connect_session_id_parse (set_connect_deactivate_str, TRUE, &session_id, &error)) { |
| g_printerr ("error: couldn't parse session ID: %s\n", error->message); |
| g_error_free (error); |
| shutdown (FALSE); |
| return; |
| } |
| |
| request = mbim_message_connect_set_new (session_id, |
| MBIM_ACTIVATION_COMMAND_DEACTIVATE, |
| NULL, |
| NULL, |
| NULL, |
| MBIM_COMPRESSION_NONE, |
| MBIM_AUTH_PROTOCOL_NONE, |
| MBIM_CONTEXT_IP_TYPE_DEFAULT, |
| mbim_uuid_from_context_type (MBIM_CONTEXT_TYPE_INTERNET), |
| &error); |
| if (!request) { |
| g_printerr ("error: couldn't create request: %s\n", error->message); |
| g_error_free (error); |
| shutdown (FALSE); |
| return; |
| } |
| |
| mbim_device_command (ctx->device, |
| request, |
| 10, |
| ctx->cancellable, |
| (GAsyncReadyCallback)connect_ready, |
| GUINT_TO_POINTER (DISCONNECT)); |
| mbim_message_unref (request); |
| return; |
| } |
| |
| /* Packet statistics? */ |
| if (query_packet_statistics_flag) { |
| MbimMessage *request; |
| |
| request = mbim_message_packet_statistics_query_new (NULL); |
| mbim_device_command (ctx->device, |
| request, |
| 10, |
| ctx->cancellable, |
| (GAsyncReadyCallback)packet_statistics_ready, |
| NULL); |
| mbim_message_unref (request); |
| return; |
| } |
| |
| /* Query IP packet filters? */ |
| if (query_ip_packet_filters_str) { |
| MbimMessage *request; |
| GError *error = NULL; |
| guint32 session_id = 0; |
| |
| if (!connect_session_id_parse (query_ip_packet_filters_str, TRUE, &session_id, &error)) { |
| g_printerr ("error: couldn't parse session ID: %s\n", error->message); |
| g_error_free (error); |
| shutdown (FALSE); |
| return; |
| } |
| |
| request = (mbim_message_ip_packet_filters_query_new ( |
| session_id, |
| 0, /* packet_filters_count */ |
| NULL, /* packet_filters */ |
| &error)); |
| if (!request) { |
| g_printerr ("error: couldn't create IP packet filters request: %s\n", error->message); |
| g_error_free (error); |
| shutdown (FALSE); |
| return; |
| } |
| |
| mbim_device_command (ctx->device, |
| request, |
| 10, |
| ctx->cancellable, |
| (GAsyncReadyCallback)ip_packet_filters_ready, |
| NULL); |
| mbim_message_unref (request); |
| return; |
| } |
| |
| g_warn_if_reached (); |
| } |