diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2018-10-27 14:46:38 +0200 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2018-11-26 16:51:35 +0000 |
commit | b0fba14b1e122522a1db2581779ffb94ee7cfa37 (patch) | |
tree | f0ab362f9e124b7f01f8c7e1b97a84d0c40f3edc | |
parent | cafc40245d2007ad3a9a33875fc6b71d25e6a254 (diff) | |
download | ModemManager-b0fba14b1e122522a1db2581779ffb94ee7cfa37.tar.gz |
cli: allow multiple output format types
In addition to the standard human-friendly output, we now allow a
machine-friendly key-value pair output, much easier to parse and use
by programs that look at the mmcli output.
This new key-value pair output should be treated as API from now on, so
third-party programs can assume the output is compatible from one
release to another.
-rw-r--r-- | cli/Makefile.am | 4 | ||||
-rw-r--r-- | cli/mmcli-bearer.c | 248 | ||||
-rw-r--r-- | cli/mmcli-call.c | 51 | ||||
-rw-r--r-- | cli/mmcli-manager.c | 66 | ||||
-rw-r--r-- | cli/mmcli-modem-3gpp.c | 68 | ||||
-rw-r--r-- | cli/mmcli-modem-firmware.c | 46 | ||||
-rw-r--r-- | cli/mmcli-modem-location.c | 185 | ||||
-rw-r--r-- | cli/mmcli-modem-messaging.c | 63 | ||||
-rw-r--r-- | cli/mmcli-modem-oma.c | 50 | ||||
-rw-r--r-- | cli/mmcli-modem-signal.c | 106 | ||||
-rw-r--r-- | cli/mmcli-modem-time.c | 36 | ||||
-rw-r--r-- | cli/mmcli-modem-voice.c | 40 | ||||
-rw-r--r-- | cli/mmcli-modem.c | 358 | ||||
-rw-r--r-- | cli/mmcli-output.c | 1099 | ||||
-rw-r--r-- | cli/mmcli-output.h | 324 | ||||
-rw-r--r-- | cli/mmcli-sim.c | 25 | ||||
-rw-r--r-- | cli/mmcli-sms.c | 117 | ||||
-rw-r--r-- | cli/mmcli.c | 16 |
18 files changed, 1994 insertions, 908 deletions
diff --git a/cli/Makefile.am b/cli/Makefile.am index 6c2d79123..76ef4a9f3 100644 --- a/cli/Makefile.am +++ b/cli/Makefile.am @@ -13,8 +13,8 @@ mmcli_CPPFLAGS = \ mmcli_SOURCES = \ mmcli.h \ mmcli.c \ - mmcli-common.h \ - mmcli-common.c \ + mmcli-common.h mmcli-common.c \ + mmcli-output.h mmcli-output.c \ mmcli-manager.c \ mmcli-modem.c \ mmcli-modem-3gpp.c \ diff --git a/cli/mmcli-bearer.c b/cli/mmcli-bearer.c index 8b053136a..bc32cdd8c 100644 --- a/cli/mmcli-bearer.c +++ b/cli/mmcli-bearer.c @@ -15,7 +15,7 @@ * 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) 2011 Aleksander Morgado <aleksander@gnu.org> + * Copyright (C) 2011-2018 Aleksander Morgado <aleksander@aleksander.es> */ #include "config.h" @@ -33,6 +33,7 @@ #include "mmcli.h" #include "mmcli-common.h" +#include "mmcli-output.h" /* Context */ typedef struct { @@ -132,148 +133,143 @@ mmcli_bearer_shutdown (void) static void print_bearer_info (MMBearer *bearer) { - MMBearerIpConfig *ipv4_config; - MMBearerIpConfig *ipv6_config; + MMBearerIpConfig *ipv4_config; + MMBearerIpConfig *ipv6_config; MMBearerProperties *properties; - MMBearerStats *stats; + MMBearerStats *stats; ipv4_config = mm_bearer_get_ipv4_config (bearer); ipv6_config = mm_bearer_get_ipv6_config (bearer); - properties = mm_bearer_get_properties (bearer); - stats = mm_bearer_get_stats (bearer); - - /* Not the best thing to do, as we may be doing _get() calls twice, but - * easiest to maintain */ -#undef VALIDATE_UNKNOWN -#define VALIDATE_UNKNOWN(str) (str ? str : "unknown") -#undef VALIDATE_NONE -#define VALIDATE_NONE(str) (str ? str : "none") - - g_print ("Bearer '%s'\n", - mm_bearer_get_path (bearer)); - g_print (" -------------------------\n" - " Status | connected: '%s'\n" - " | suspended: '%s'\n" - " | interface: '%s'\n" - " | IP timeout: '%u'\n", - mm_bearer_get_connected (bearer) ? "yes" : "no", - mm_bearer_get_suspended (bearer) ? "yes" : "no", - VALIDATE_UNKNOWN (mm_bearer_get_interface (bearer)), - mm_bearer_get_ip_timeout (bearer)); - - if (properties) { - gchar *ip_family_str; - - ip_family_str = (mm_bearer_ip_family_build_string_from_mask ( - mm_bearer_properties_get_ip_type (properties))); - g_print (" -------------------------\n" - " Properties | apn: '%s'\n" - " | roaming: '%s'\n" - " | IP type: '%s'\n" - " | user: '%s'\n" - " | password: '%s'\n" - " | number: '%s'\n" - " | Rm protocol: '%s'\n", - VALIDATE_NONE (mm_bearer_properties_get_apn (properties)), - mm_bearer_properties_get_allow_roaming (properties) ? "allowed" : "forbidden", - VALIDATE_UNKNOWN (ip_family_str), - VALIDATE_NONE (mm_bearer_properties_get_user (properties)), - VALIDATE_NONE (mm_bearer_properties_get_password (properties)), - VALIDATE_NONE (mm_bearer_properties_get_number (properties)), - VALIDATE_UNKNOWN (mm_modem_cdma_rm_protocol_get_string ( - mm_bearer_properties_get_rm_protocol (properties)))); - g_free (ip_family_str); - } - - /* IPv4 */ - g_print (" -------------------------\n" - " IPv4 configuration | method: '%s'\n", - (ipv4_config ? - mm_bearer_ip_method_get_string (mm_bearer_ip_config_get_method (ipv4_config)) : - "none")); - if (ipv4_config && - mm_bearer_ip_config_get_method (ipv4_config) != MM_BEARER_IP_METHOD_UNKNOWN) { - const gchar **dns = mm_bearer_ip_config_get_dns (ipv4_config); - guint i, mtu; - - g_print (" | address: '%s'\n" - " | prefix: '%u'\n" - " | gateway: '%s'\n", - VALIDATE_UNKNOWN (mm_bearer_ip_config_get_address (ipv4_config)), - mm_bearer_ip_config_get_prefix (ipv4_config), - VALIDATE_UNKNOWN (mm_bearer_ip_config_get_gateway (ipv4_config))); - - if (dns && dns[0]) { - g_print ( - " | DNS: '%s'", dns[0]); - /* Additional DNS addresses */ - for (i = 1; dns[i]; i++) - g_print (", '%s'", dns[i]); - } else { - g_print ( - " | DNS: none"); + properties = mm_bearer_get_properties (bearer); + stats = mm_bearer_get_stats (bearer); + + mmcli_output_string (MMC_F_BEARER_GENERAL_DBUS_PATH, mm_bearer_get_path (bearer)); + + mmcli_output_string (MMC_F_BEARER_STATUS_CONNECTED, mm_bearer_get_connected (bearer) ? "yes" : "no"); + mmcli_output_string (MMC_F_BEARER_STATUS_SUSPENDED, mm_bearer_get_suspended (bearer) ? "yes" : "no"); + mmcli_output_string (MMC_F_BEARER_STATUS_INTERFACE, mm_bearer_get_interface (bearer)); + mmcli_output_string_take (MMC_F_BEARER_STATUS_IP_TIMEOUT, g_strdup_printf ("%u", mm_bearer_get_ip_timeout (bearer))); + + /* Properties */ + { + const gchar *apn = NULL; + const gchar *roaming = NULL; + gchar *ip_family_str = NULL; + const gchar *user = NULL; + const gchar *password = NULL; + const gchar *number = NULL; + const gchar *rm_protocol = NULL; + + if (properties) { + apn = mm_bearer_properties_get_apn (properties); + roaming = mm_bearer_properties_get_allow_roaming (properties) ? "allowed" : "forbidden"; + ip_family_str = (properties ? mm_bearer_ip_family_build_string_from_mask (mm_bearer_properties_get_ip_type (properties)) : NULL); + user = mm_bearer_properties_get_user (properties); + password = mm_bearer_properties_get_password (properties); + number = mm_bearer_properties_get_number (properties); + rm_protocol = mm_modem_cdma_rm_protocol_get_string (mm_bearer_properties_get_rm_protocol (properties)); } - g_print ("\n"); - mtu = mm_bearer_ip_config_get_mtu (ipv4_config); - if (mtu) - g_print (" | MTU: '%u'\n", mtu); + mmcli_output_string (MMC_F_BEARER_PROPERTIES_APN, apn); + mmcli_output_string (MMC_F_BEARER_PROPERTIES_ROAMING, roaming); + mmcli_output_string_take (MMC_F_BEARER_PROPERTIES_IP_TYPE, ip_family_str); + mmcli_output_string (MMC_F_BEARER_PROPERTIES_USER, user); + mmcli_output_string (MMC_F_BEARER_PROPERTIES_PASSWORD, password); + mmcli_output_string (MMC_F_BEARER_PROPERTIES_NUMBER, number); + mmcli_output_string (MMC_F_BEARER_PROPERTIES_RM_PROTOCOL, rm_protocol); } - /* IPv6 */ - g_print (" -------------------------\n" - " IPv6 configuration | method: '%s'\n", - (ipv6_config ? - mm_bearer_ip_method_get_string (mm_bearer_ip_config_get_method (ipv6_config)) : - "none")); - if (ipv6_config && - mm_bearer_ip_config_get_method (ipv6_config) != MM_BEARER_IP_METHOD_UNKNOWN) { - const gchar **dns = mm_bearer_ip_config_get_dns (ipv6_config); - guint i, mtu; - - g_print (" | address: '%s'\n" - " | prefix: '%u'\n" - " | gateway: '%s'\n", - VALIDATE_UNKNOWN(mm_bearer_ip_config_get_address (ipv6_config)), - mm_bearer_ip_config_get_prefix (ipv6_config), - VALIDATE_UNKNOWN(mm_bearer_ip_config_get_gateway (ipv6_config))); - - if (dns && dns[0]) { - g_print ( - " | DNS: '%s'", dns[0]); - /* Additional DNS addresses */ - for (i = 1; dns[i]; i++) - g_print (", '%s'", dns[i]); - } else { - g_print ( - " | DNS: none"); + /* IPv4 config */ + { + const gchar *method = NULL; + const gchar *address = NULL; + gchar *prefix = NULL; + const gchar *gateway = NULL; + const gchar **dns = NULL; + gchar *mtu = NULL; + + if (ipv4_config) { + method = mm_bearer_ip_method_get_string (mm_bearer_ip_config_get_method (ipv4_config)); + if (mm_bearer_ip_config_get_method (ipv4_config) != MM_BEARER_IP_METHOD_UNKNOWN) { + guint mtu_n; + + address = mm_bearer_ip_config_get_address (ipv4_config); + prefix = g_strdup_printf ("%u", mm_bearer_ip_config_get_prefix (ipv4_config)); + gateway = mm_bearer_ip_config_get_gateway (ipv4_config); + dns = mm_bearer_ip_config_get_dns (ipv4_config); + mtu_n = mm_bearer_ip_config_get_mtu (ipv4_config); + if (mtu_n) + mtu = g_strdup_printf ("%u", mtu_n); + } } - g_print ("\n"); - mtu = mm_bearer_ip_config_get_mtu (ipv6_config); - if (mtu) - g_print (" | MTU: '%u'\n", mtu); + mmcli_output_string (MMC_F_BEARER_IPV4_CONFIG_METHOD, method); + mmcli_output_string (MMC_F_BEARER_IPV4_CONFIG_ADDRESS, address); + mmcli_output_string_take (MMC_F_BEARER_IPV4_CONFIG_PREFIX, prefix); + mmcli_output_string (MMC_F_BEARER_IPV4_CONFIG_GATEWAY, gateway); + mmcli_output_string_array (MMC_F_BEARER_IPV4_CONFIG_DNS, dns, FALSE); + mmcli_output_string_take (MMC_F_BEARER_IPV4_CONFIG_MTU, mtu); } - if (stats) { - guint64 val; + /* IPv6 config */ + { + const gchar *method = NULL; + const gchar *address = NULL; + gchar *prefix = NULL; + const gchar *gateway = NULL; + const gchar **dns = NULL; + gchar *mtu = NULL; + + if (ipv6_config) { + method = mm_bearer_ip_method_get_string (mm_bearer_ip_config_get_method (ipv6_config)); + if (mm_bearer_ip_config_get_method (ipv6_config) != MM_BEARER_IP_METHOD_UNKNOWN) { + guint mtu_n; + + address = mm_bearer_ip_config_get_address (ipv6_config); + prefix = g_strdup_printf ("%u", mm_bearer_ip_config_get_prefix (ipv6_config)); + gateway = mm_bearer_ip_config_get_gateway (ipv6_config); + dns = mm_bearer_ip_config_get_dns (ipv6_config); + mtu_n = mm_bearer_ip_config_get_mtu (ipv6_config); + if (mtu_n) + mtu = g_strdup_printf ("%u", mtu_n); + } + } - g_print (" -------------------------\n" - " Stats | Duration: '%u'\n", mm_bearer_stats_get_duration (stats)); + mmcli_output_string (MMC_F_BEARER_IPV6_CONFIG_METHOD, method); + mmcli_output_string (MMC_F_BEARER_IPV6_CONFIG_ADDRESS, address); + mmcli_output_string_take (MMC_F_BEARER_IPV6_CONFIG_PREFIX, prefix); + mmcli_output_string (MMC_F_BEARER_IPV6_CONFIG_GATEWAY, gateway); + mmcli_output_string_array (MMC_F_BEARER_IPV6_CONFIG_DNS, dns, FALSE); + mmcli_output_string_take (MMC_F_BEARER_IPV6_CONFIG_MTU, mtu); + } - val = mm_bearer_stats_get_rx_bytes (stats); - if (val > 0) - g_print (" | Bytes received: '%" G_GUINT64_FORMAT "'\n", val); - else - g_print (" | Bytes received: 'n/a'\n"); + /* Stats */ + { + gchar *duration = NULL; + gchar *bytes_rx = NULL; + gchar *bytes_tx = NULL; + + if (stats) { + guint64 val; + + val = mm_bearer_stats_get_duration (stats); + if (val) + duration = g_strdup_printf ("%" G_GUINT64_FORMAT, val); + val = mm_bearer_stats_get_rx_bytes (stats); + if (val) + bytes_rx = g_strdup_printf ("%" G_GUINT64_FORMAT, val); + val = mm_bearer_stats_get_tx_bytes (stats); + if (val) + bytes_tx = g_strdup_printf ("%" G_GUINT64_FORMAT, val); + } - val = mm_bearer_stats_get_tx_bytes (stats); - if (val > 0) - g_print (" | Bytes transmitted: '%" G_GUINT64_FORMAT "'\n", val); - else - g_print (" | Bytes transmitted: 'n/a'\n"); + mmcli_output_string_take (MMC_F_BEARER_STATS_DURATION, duration); + mmcli_output_string_take (MMC_F_BEARER_STATS_BYTES_RX, bytes_rx); + mmcli_output_string_take (MMC_F_BEARER_STATS_BYTES_TX, bytes_tx); } + mmcli_output_dump (); + g_clear_object (&stats); g_clear_object (&properties); g_clear_object (&ipv4_config); diff --git a/cli/mmcli-call.c b/cli/mmcli-call.c index 09cf08717..d49302856 100644 --- a/cli/mmcli-call.c +++ b/cli/mmcli-call.c @@ -34,6 +34,7 @@ #include "mmcli.h" #include "mmcli-common.h" +#include "mmcli-output.h" /* Context */ typedef struct { @@ -145,45 +146,31 @@ mmcli_call_shutdown (void) static void print_call_info (MMCall *call) { - const gchar *audio_port; MMCallAudioFormat *audio_format; + const gchar *encoding = NULL; + const gchar *resolution = NULL; + gchar *rate = NULL; - audio_port = mm_call_get_audio_port (call); audio_format = mm_call_peek_audio_format (call); - /* Not the best thing to do, as we may be doing _get() calls twice, but - * easiest to maintain */ -#undef VALIDATE -#define VALIDATE(str) (str ? str : "unknown") - - g_print ("CALL '%s'\n", mm_call_get_path (call)); - g_print (" -------------------------------\n" - " Global | number: '%s'\n", VALIDATE (mm_call_get_number (call))); - g_print (" | direction: '%s'\n", mm_call_direction_get_string (mm_call_get_direction (call)) ); - - g_print (" -------------------------------\n" - " Properties | state: '%s'\n", mm_call_state_get_string (mm_call_get_state (call))); - - if (mm_call_get_state_reason(call) != MM_CALL_STATE_REASON_UNKNOWN) - g_print (" | state reason: '%s'\n", - mm_call_state_reason_get_string(mm_call_get_state_reason (call))); - - if (audio_port) - g_print (" | audio port: '%s'\n", VALIDATE (audio_port)); + mmcli_output_string (MMC_F_CALL_GENERAL_DBUS_PATH, mm_call_get_path (call)); + mmcli_output_string (MMC_F_CALL_PROPERTIES_NUMBER, mm_call_get_number (call)); + mmcli_output_string (MMC_F_CALL_PROPERTIES_DIRECTION, mm_call_direction_get_string (mm_call_get_direction (call))); + mmcli_output_string (MMC_F_CALL_PROPERTIES_STATE, mm_call_state_get_string (mm_call_get_state (call))); + mmcli_output_string (MMC_F_CALL_PROPERTIES_STATE_REASON, mm_call_state_get_string (mm_call_get_state_reason (call))); + mmcli_output_string (MMC_F_CALL_PROPERTIES_AUDIO_PORT, mm_call_get_audio_port (call)); if (audio_format) { - guint rate = mm_call_audio_format_get_rate (audio_format); - gchar *rate_str = rate ? g_strdup_printf ("%u", rate) : NULL; - - g_print (" -------------------------\n" - " Audio Format | encoding: '%s'\n" - " | resolution: '%s'\n" - " | rate: '%s'\n", - VALIDATE (mm_call_audio_format_get_encoding (audio_format)), - VALIDATE (mm_call_audio_format_get_resolution (audio_format)), - VALIDATE (rate_str)); - g_free (rate_str); + rate = g_strdup_printf ("%u", mm_call_audio_format_get_rate (audio_format)); + encoding = mm_call_audio_format_get_encoding (audio_format); + resolution = mm_call_audio_format_get_resolution (audio_format); } + + mmcli_output_string (MMC_F_CALL_AUDIO_FORMAT_ENCODING, encoding); + mmcli_output_string (MMC_F_CALL_AUDIO_FORMAT_RESOLUTION, resolution); + mmcli_output_string_take (MMC_F_CALL_AUDIO_FORMAT_RATE, rate); + + mmcli_output_dump (); } static void diff --git a/cli/mmcli-manager.c b/cli/mmcli-manager.c index ed8a9926b..41bda2112 100644 --- a/cli/mmcli-manager.c +++ b/cli/mmcli-manager.c @@ -38,6 +38,7 @@ #include "mmcli.h" #include "mmcli-common.h" +#include "mmcli-output.h" /* Context */ typedef struct { @@ -130,8 +131,13 @@ mmcli_manager_options_enabled (void) exit (EXIT_FAILURE); } - if (monitor_modems_flag) + if (monitor_modems_flag) { + if (mmcli_output_get () != MMC_OUTPUT_TYPE_HUMAN) { + g_printerr ("error: modem monitoring not available in keyvalue output\n"); + exit (EXIT_FAILURE); + } mmcli_force_async_operation (); + } #if defined WITH_UDEV if (report_kernel_event_auto_scan) @@ -265,58 +271,56 @@ scan_devices_ready (MMManager *manager, mmcli_async_operation_done (); } +#define FOUND_ACTION_PREFIX " " +#define ADDED_ACTION_PREFIX "(+) " +#define REMOVED_ACTION_PREFIX "(-) " + static void -print_modem_short_info (MMObject *modem) +output_modem_info (MMObject *obj, + const gchar *prefix) { - const gchar *manufacturer, *model; - - manufacturer = mm_modem_get_manufacturer (mm_object_peek_modem (modem)); - model = mm_modem_get_model (mm_object_peek_modem (modem)); - - g_print ("\t%s [%s] %s\n", - mm_object_get_path (modem), - manufacturer ? manufacturer : "unknown", - model ? model : "unknown"); + gchar *extra; + const gchar *manufacturer; + const gchar *model; + + manufacturer = mm_modem_get_manufacturer (mm_object_peek_modem (obj)); + model = mm_modem_get_model (mm_object_peek_modem (obj)); + extra = g_strdup_printf ("[%s] %s", + manufacturer ? manufacturer : "manufacturer unknown", + model ? model : "model unknown"); + mmcli_output_listitem (MMC_F_MODEM_LIST_DBUS_PATH, + prefix, + mm_object_get_path (obj), + extra); + g_free (extra); } static void device_added (MMManager *manager, MMObject *modem) { - g_print ("Added modem:\n"); - print_modem_short_info (modem); - fflush (stdout); + output_modem_info (modem, ADDED_ACTION_PREFIX); + mmcli_output_list_dump (MMC_F_MODEM_LIST_DBUS_PATH); } static void device_removed (MMManager *manager, MMObject *modem) { - g_print ("Removed modem:\n"); - print_modem_short_info (modem); - fflush (stdout); + output_modem_info (modem, REMOVED_ACTION_PREFIX); + mmcli_output_list_dump (MMC_F_MODEM_LIST_DBUS_PATH); } static void list_current_modems (MMManager *manager) { GList *modems; + GList *l; modems = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (ctx->manager)); - - g_print ("\n"); - if (!modems) - g_print ("No modems were found\n"); - else { - GList *l; - - g_print ("Found %u modems:\n", g_list_length (modems)); - for (l = modems; l; l = g_list_next (l)) { - print_modem_short_info (MM_OBJECT (l->data)); - } - g_list_free_full (modems, g_object_unref); - } - g_print ("\n"); + for (l = modems; l; l = g_list_next (l)) + output_modem_info ((MMObject *)(l->data), FOUND_ACTION_PREFIX); + mmcli_output_list_dump (MMC_F_MODEM_LIST_DBUS_PATH); } static void diff --git a/cli/mmcli-modem-3gpp.c b/cli/mmcli-modem-3gpp.c index b687d88d4..18ff955c0 100644 --- a/cli/mmcli-modem-3gpp.c +++ b/cli/mmcli-modem-3gpp.c @@ -34,6 +34,7 @@ #include "mmcli.h" #include "mmcli-common.h" +#include "mmcli-output.h" /* Context */ typedef struct { @@ -204,34 +205,6 @@ mmcli_modem_3gpp_shutdown (void) } static void -print_network_info (MMModem3gppNetwork *network) -{ - const gchar *name; - gchar *access_technologies; - - /* Not the best thing to do, as we may be doing _get() calls twice, but - * easiest to maintain */ -#undef VALIDATE -#define VALIDATE(str) (str ? str : "unknown") - - access_technologies = (mm_modem_access_technology_build_string_from_mask ( - mm_modem_3gpp_network_get_access_technology (network))); - - /* Prefer long name */ - name = mm_modem_3gpp_network_get_operator_long (network); - if (!name) - name = mm_modem_3gpp_network_get_operator_short (network); - - g_print ("%s - %s (%s, %s)\n", - VALIDATE (mm_modem_3gpp_network_get_operator_code (network)), - VALIDATE (name), - access_technologies, - mm_modem_3gpp_network_availability_get_string ( - mm_modem_3gpp_network_get_availability (network))); - g_free (access_technologies); -} - -static void scan_process_reply (GList *result, const GError *error) { @@ -241,19 +214,10 @@ scan_process_reply (GList *result, exit (EXIT_FAILURE); } - g_print ("\n"); - if (!result) - g_print ("No networks were found\n"); - else { - GList *l; - - g_print ("Found %u networks:\n", g_list_length (result)); - for (l = result; l; l = g_list_next (l)) { - print_network_info ((MMModem3gppNetwork *)(l->data)); - } - g_list_free_full (result, (GDestroyNotify) mm_modem_3gpp_network_free); - } - g_print ("\n"); + mmcli_output_scan_networks (result); + mmcli_output_dump (); + + g_list_free_full (result, (GDestroyNotify) mm_modem_3gpp_network_free); } static void @@ -339,22 +303,12 @@ parse_eps_ue_mode_operation (MMModem3gppEpsUeModeOperation *uemode) static void print_ussd_status (void) { - /* Not the best thing to do, as we may be doing _get() calls twice, but - * easiest to maintain */ -#undef VALIDATE -#define VALIDATE(str) (str ? str : "none") - - g_print ("\n" - "%s\n" - " ----------------------------\n" - " USSD | status: '%s'\n" - " | network request: '%s'\n" - " | network notification: '%s'\n", - mm_modem_3gpp_ussd_get_path (ctx->modem_3gpp_ussd), - mm_modem_3gpp_ussd_session_state_get_string ( - mm_modem_3gpp_ussd_get_state (ctx->modem_3gpp_ussd)), - VALIDATE (mm_modem_3gpp_ussd_get_network_request (ctx->modem_3gpp_ussd)), - VALIDATE (mm_modem_3gpp_ussd_get_network_notification (ctx->modem_3gpp_ussd))); + mmcli_output_string (MMC_F_GENERAL_DBUS_PATH, mm_modem_3gpp_ussd_get_path (ctx->modem_3gpp_ussd)); + mmcli_output_string (MMC_F_3GPP_USSD_STATUS, mm_modem_3gpp_ussd_session_state_get_string ( + mm_modem_3gpp_ussd_get_state (ctx->modem_3gpp_ussd))); + mmcli_output_string (MMC_F_3GPP_USSD_NETWORK_REQUEST, mm_modem_3gpp_ussd_get_network_request (ctx->modem_3gpp_ussd)); + mmcli_output_string (MMC_F_3GPP_USSD_NETWORK_NOTIFICATION, mm_modem_3gpp_ussd_get_network_notification (ctx->modem_3gpp_ussd)); + mmcli_output_dump (); } static void diff --git a/cli/mmcli-modem-firmware.c b/cli/mmcli-modem-firmware.c index 0905a00c6..008de8dea 100644 --- a/cli/mmcli-modem-firmware.c +++ b/cli/mmcli-modem-firmware.c @@ -33,6 +33,7 @@ #include "mmcli.h" #include "mmcli-common.h" +#include "mmcli-output.h" /* Context */ typedef struct { @@ -143,48 +144,11 @@ list_process_reply (MMFirmwareProperties *selected, exit (EXIT_FAILURE); } - g_print ("\n"); - if (!result) { - g_print ("No firmware images were found\n"); - } else { - GList *l; - guint i; - - g_print ("Found %u firmware images:\n", g_list_length (result)); - for (l = result, i = 0; l; l = g_list_next (l), i++) { - MMFirmwareProperties *props = MM_FIRMWARE_PROPERTIES (l->data); - - g_print ("\t[%u] %s%s\n" - "\t\tType: '%s'\n", - i, - mm_firmware_properties_get_unique_id (props), - ((selected && - g_str_equal (mm_firmware_properties_get_unique_id (props), - mm_firmware_properties_get_unique_id (selected))) ? - " (CURRENT)" : ""), - mm_firmware_image_type_get_string ( - mm_firmware_properties_get_image_type (props))); - - if (mm_firmware_properties_get_image_type (props) == MM_FIRMWARE_IMAGE_TYPE_GOBI) { - g_print ("\t\t[Gobi] PRI version: '%s'\n" - "\t\t[Gobi] PRI info: '%s'\n" - "\t\t[Gobi] Boot version: '%s'\n" - "\t\t[Gobi] PRI Unique ID: '%s'\n" - "\t\t[Gobi] Modem Unique ID: '%s'\n", - VALIDATE_UNKNOWN (mm_firmware_properties_get_gobi_pri_version (props)), - VALIDATE_UNKNOWN (mm_firmware_properties_get_gobi_pri_info (props)), - VALIDATE_UNKNOWN (mm_firmware_properties_get_gobi_boot_version (props)), - VALIDATE_UNKNOWN (mm_firmware_properties_get_gobi_pri_unique_id (props)), - VALIDATE_UNKNOWN (mm_firmware_properties_get_gobi_modem_unique_id (props))); - } - - g_object_unref (props); - } - g_list_free (result); - } + mmcli_output_firmware_list (result, selected); + mmcli_output_dump (); - if (selected) - g_object_unref (selected); + g_list_free_full (result, g_object_unref); + g_clear_object (&selected); } static void diff --git a/cli/mmcli-modem-location.c b/cli/mmcli-modem-location.c index 6dcfaf0bb..6e7185c89 100644 --- a/cli/mmcli-modem-location.c +++ b/cli/mmcli-modem-location.c @@ -34,6 +34,7 @@ #include "mmcli.h" #include "mmcli-common.h" +#include "mmcli-output.h" /* Context */ typedef struct { @@ -258,74 +259,46 @@ mmcli_modem_location_shutdown (void) static void print_location_status (void) { - gchar *capabilities_str; - gchar *enabled_str; - - capabilities_str = (mm_modem_location_source_build_string_from_mask ( - mm_modem_location_get_capabilities (ctx->modem_location))); - enabled_str = (mm_modem_location_source_build_string_from_mask ( - mm_modem_location_get_enabled (ctx->modem_location))); - g_print ("\n" - "%s\n" - " ----------------------------\n" - " Location | capabilities: '%s'\n" - " | enabled: '%s'\n" - " | signals: '%s'\n", - mm_modem_location_get_path (ctx->modem_location), - capabilities_str, - enabled_str, - mm_modem_location_signals_location (ctx->modem_location) ? "yes" : "no"); + gchar *capabilities; + gchar *enabled; + gchar *gps_refresh_rate = NULL; + const gchar *gps_supl_server = NULL; + gchar *gps_assistance = NULL; + const gchar **gps_assistance_servers = NULL; + + capabilities = (mm_modem_location_source_build_string_from_mask ( + mm_modem_location_get_capabilities (ctx->modem_location))); + enabled = (mm_modem_location_source_build_string_from_mask ( + mm_modem_location_get_enabled (ctx->modem_location))); /* If GPS supported, show GPS refresh rate and supported assistance data */ - if (mm_modem_location_get_capabilities (ctx->modem_location) & (MM_MODEM_LOCATION_SOURCE_GPS_RAW | - MM_MODEM_LOCATION_SOURCE_GPS_NMEA)) { + if (mm_modem_location_get_capabilities (ctx->modem_location) & (MM_MODEM_LOCATION_SOURCE_GPS_RAW | MM_MODEM_LOCATION_SOURCE_GPS_NMEA)) { guint rate; MMModemLocationAssistanceDataType mask; - gchar *mask_str; rate = mm_modem_location_get_gps_refresh_rate (ctx->modem_location); - g_print (" ----------------------------\n"); - if (rate > 0) - g_print (" GPS | refresh rate: '%u'\n", rate); - else - g_print (" GPS | refresh rate: disabled\n"); + gps_refresh_rate = g_strdup_printf ("%u", rate); /* If A-GPS supported, show SUPL server setup */ - if (mm_modem_location_get_capabilities (ctx->modem_location) & MM_MODEM_LOCATION_SOURCE_AGPS) { - const gchar *supl_server; - - supl_server = mm_modem_location_get_supl_server (ctx->modem_location); - g_print (" | A-GPS SUPL server: '%s'\n", - supl_server ? supl_server : "unset"); - } + if (mm_modem_location_get_capabilities (ctx->modem_location) & MM_MODEM_LOCATION_SOURCE_AGPS) + gps_supl_server = mm_modem_location_get_supl_server (ctx->modem_location); mask = mm_modem_location_get_supported_assistance_data (ctx->modem_location); - mask_str = mm_modem_location_assistance_data_type_build_string_from_mask (mask); - g_print (" | supported assistance data: '%s'\n", mask_str); - g_free (mask_str); + gps_assistance = mm_modem_location_assistance_data_type_build_string_from_mask (mask); /* If any assistance data supported, show server list */ - if (mask != MM_MODEM_LOCATION_ASSISTANCE_DATA_TYPE_NONE) { - const gchar **servers; - - servers = mm_modem_location_get_assistance_data_servers (ctx->modem_location); - if (!servers) - g_print (" | assistance data servers: 'n/a'\n"); - else { - guint server_i; - - for (server_i = 0; servers[server_i]; server_i++) { - if (server_i == 0) - g_print (" | assistance data servers: '%s'\n", servers[server_i]); - else - g_print (" | '%s'\n", servers[server_i]); - } - } - } + if (mask != MM_MODEM_LOCATION_ASSISTANCE_DATA_TYPE_NONE) + gps_assistance_servers = mm_modem_location_get_assistance_data_servers (ctx->modem_location); } - g_free (capabilities_str); - g_free (enabled_str); + mmcli_output_string_list_take (MMC_F_LOCATION_CAPABILITIES, capabilities); + mmcli_output_string_list_take (MMC_F_LOCATION_ENABLED, enabled); + mmcli_output_string (MMC_F_LOCATION_SIGNALS, mm_modem_location_signals_location (ctx->modem_location) ? "yes" : "no"); + mmcli_output_string_take_typed (MMC_F_LOCATION_GPS_REFRESH_RATE, gps_refresh_rate, "seconds"); + mmcli_output_string (MMC_F_LOCATION_GPS_SUPL_SERVER, gps_supl_server); + mmcli_output_string_list_take (MMC_F_LOCATION_GPS_ASSISTANCE, gps_assistance); + mmcli_output_string_array (MMC_F_LOCATION_GPS_ASSISTANCE_SERVERS, gps_assistance_servers, TRUE); + mmcli_output_dump (); } static void @@ -523,7 +496,18 @@ get_location_process_reply (MMLocation3gpp *location_3gpp, MMLocationCdmaBs *location_cdma_bs, const GError *error) { - gchar *full = NULL; + gchar *nmea = NULL; + gchar *mcc = NULL; + gchar *mnc = NULL; + gchar *lac = NULL; + gchar *tac = NULL; + gchar *cid = NULL; + const gchar *gps_utc = NULL; + gchar *gps_longitude = NULL; + gchar *gps_latitude = NULL; + gchar *gps_altitude = NULL; + gchar *cdma_bs_longitude = NULL; + gchar *cdma_bs_latitude = NULL; if (error) { g_printerr ("error: couldn't get location from the modem: '%s'\n", @@ -531,65 +515,42 @@ get_location_process_reply (MMLocation3gpp *location_3gpp, exit (EXIT_FAILURE); } - g_print ("\n" - "%s\n", - mm_modem_location_get_path (ctx->modem_location)); - - if (location_3gpp) - g_print (" -------------------------\n" - " 3GPP location | Mobile country code: '%u'\n" - " | Mobile network code: '%u'\n" - " | Location area code: '%04lX'\n" - " | Tracking area code: '%04lX'\n" - " | Cell ID: '%08lX'\n", - mm_location_3gpp_get_mobile_country_code (location_3gpp), - mm_location_3gpp_get_mobile_network_code (location_3gpp), - mm_location_3gpp_get_location_area_code (location_3gpp), - mm_location_3gpp_get_tracking_area_code (location_3gpp), - mm_location_3gpp_get_cell_id (location_3gpp)); - else - g_print (" -------------------------\n" - " 3GPP location | Not available\n"); + if (location_3gpp) { + mcc = g_strdup_printf ("%u", mm_location_3gpp_get_mobile_country_code (location_3gpp)); + mnc = g_strdup_printf ("%u", mm_location_3gpp_get_mobile_network_code (location_3gpp)); + lac = g_strdup_printf ("%04lX", mm_location_3gpp_get_location_area_code (location_3gpp)); + tac = g_strdup_printf ("%04lX", mm_location_3gpp_get_tracking_area_code (location_3gpp)); + cid = g_strdup_printf ("%08lX", mm_location_3gpp_get_cell_id (location_3gpp)); + } if (location_gps_nmea) - full = mm_location_gps_nmea_build_full (location_gps_nmea); - - if (full) { - gchar *prefixed; - - prefixed = mmcli_prefix_newlines (" | ", full); - g_print (" -------------------------\n" - " GPS NMEA traces | %s\n", - prefixed); - g_free (prefixed); - g_free (full); - } else - g_print (" -------------------------\n" - " GPS NMEA traces | Not available\n"); - - if (location_gps_raw) - g_print (" -------------------------\n" - " Raw GPS | UTC time: '%s'\n" - " | Longitude: '%lf'\n" - " | Latitude: '%lf'\n" - " | Altitude: '%lf'\n", - mm_location_gps_raw_get_utc_time (location_gps_raw), - mm_location_gps_raw_get_longitude (location_gps_raw), - mm_location_gps_raw_get_latitude (location_gps_raw), - mm_location_gps_raw_get_altitude (location_gps_raw)); - else - g_print (" -------------------------\n" - " Raw GPS | Not available\n"); - - if (location_cdma_bs) - g_print (" -------------------------\n" - " CDMA BS | Longitude: '%lf'\n" - " | Latitude: '%lf'\n", - mm_location_cdma_bs_get_longitude (location_cdma_bs), - mm_location_cdma_bs_get_latitude (location_cdma_bs)); - else - g_print (" -------------------------\n" - " CDMA BS | Not available\n"); + nmea = mm_location_gps_nmea_build_full (location_gps_nmea); + + if (location_gps_raw) { + gps_utc = mm_location_gps_raw_get_utc_time (location_gps_raw); + gps_longitude = g_strdup_printf ("%lf", mm_location_gps_raw_get_longitude (location_gps_raw)); + gps_latitude = g_strdup_printf ("%lf", mm_location_gps_raw_get_latitude (location_gps_raw)); + gps_altitude = g_strdup_printf ("%lf", mm_location_gps_raw_get_altitude (location_gps_raw)); + } + + if (location_cdma_bs) { + cdma_bs_longitude = g_strdup_printf ("%lf", mm_location_cdma_bs_get_longitude (location_cdma_bs)); + cdma_bs_latitude = g_strdup_printf ("%lf", mm_location_cdma_bs_get_latitude (location_cdma_bs)); + } + + mmcli_output_string_take (MMC_F_LOCATION_3GPP_MCC, mcc); + mmcli_output_string_take (MMC_F_LOCATION_3GPP_MNC, mnc); + mmcli_output_string_take (MMC_F_LOCATION_3GPP_LAC, lac); + mmcli_output_string_take (MMC_F_LOCATION_3GPP_TAC, tac); + mmcli_output_string_take (MMC_F_LOCATION_3GPP_CID, cid); + mmcli_output_string_multiline_take (MMC_F_LOCATION_GPS_NMEA, nmea); + mmcli_output_string (MMC_F_LOCATION_GPS_UTC, gps_utc); + mmcli_output_string_take (MMC_F_LOCATION_GPS_LONG, gps_longitude); + mmcli_output_string_take (MMC_F_LOCATION_GPS_LAT, gps_latitude); + mmcli_output_string_take (MMC_F_LOCATION_GPS_ALT, gps_altitude); + mmcli_output_string_take (MMC_F_LOCATION_CDMABS_LONG, cdma_bs_longitude); + mmcli_output_string_take (MMC_F_LOCATION_CDMABS_LAT, cdma_bs_latitude); + mmcli_output_dump (); g_clear_object (&location_3gpp); g_clear_object (&location_gps_nmea); diff --git a/cli/mmcli-modem-messaging.c b/cli/mmcli-modem-messaging.c index c424eac0f..0f38e972d 100644 --- a/cli/mmcli-modem-messaging.c +++ b/cli/mmcli-modem-messaging.c @@ -33,6 +33,7 @@ #include "mmcli.h" #include "mmcli-common.h" +#include "mmcli-output.h" /* Context */ typedef struct { @@ -208,64 +209,47 @@ static void print_messaging_status (void) { MMSmsStorage *supported = NULL; - guint supported_len = 0; - gchar *supported_str = NULL; + guint supported_len = 0; + gchar *supported_str = NULL; - mm_modem_messaging_get_supported_storages (ctx->modem_messaging, - &supported, - &supported_len); + mm_modem_messaging_get_supported_storages (ctx->modem_messaging, &supported, &supported_len); if (supported) supported_str = mm_common_build_sms_storages_string (supported, supported_len); -#undef VALIDATE_UNKNOWN -#define VALIDATE_UNKNOWN(str) (str ? str : "unknown") - - g_print ("\n" - "%s\n" - " ----------------------------\n" - " Messaging | supported storages: '%s'\n" - " | default storage: '%s'\n", - mm_modem_messaging_get_path (ctx->modem_messaging), - VALIDATE_UNKNOWN (supported_str), - VALIDATE_UNKNOWN (mm_sms_storage_get_string ( - mm_modem_messaging_get_default_storage ( - ctx->modem_messaging)))); - g_free (supported_str); + mmcli_output_string_take (MMC_F_MESSAGING_SUPPORTED_STORAGES, supported_str); + mmcli_output_string (MMC_F_MESSAGING_DEFAULT_STORAGES, mm_sms_storage_get_string ( + mm_modem_messaging_get_default_storage (ctx->modem_messaging))); + mmcli_output_dump (); } static void -print_sms_short_info (MMSms *sms) +output_sms_info (MMSms *sms) { - g_print ("\t%s (%s)\n", - mm_sms_get_path (sms), - mm_sms_state_get_string (mm_sms_get_state (sms))); + gchar *extra; + + extra = g_strdup_printf ("(%s)", mm_sms_state_get_string (mm_sms_get_state (sms))); + mmcli_output_listitem (MMC_F_SMS_LIST_DBUS_PATH, + " ", + mm_sms_get_path (sms), + extra); + g_free (extra); } static void list_process_reply (GList *result, const GError *error) { + GList *l; + if (error) { g_printerr ("error: couldn't list SMS: '%s'\n", error->message); exit (EXIT_FAILURE); } - g_print ("\n"); - if (!result) { - g_print ("No SMS messages were found\n"); - } else { - GList *l; - - g_print ("Found %u SMS messages:\n", g_list_length (result)); - for (l = result; l; l = g_list_next (l)) { - MMSms *sms = MM_SMS (l->data); - - print_sms_short_info (sms); - g_object_unref (sms); - } - g_list_free (result); - } + for (l = result; l; l = g_list_next (l)) + output_sms_info (MM_SMS (l->data)); + mmcli_output_list_dump (MMC_F_SMS_LIST_DBUS_PATH); } static void @@ -292,8 +276,7 @@ create_process_reply (MMSms *sms, exit (EXIT_FAILURE); } - g_print ("Successfully created new SMS:\n"); - print_sms_short_info (sms); + g_print ("Successfully created new SMS: %s\n", mm_sms_get_path (sms)); g_object_unref (sms); } diff --git a/cli/mmcli-modem-oma.c b/cli/mmcli-modem-oma.c index 63e23aeb1..0c6153031 100644 --- a/cli/mmcli-modem-oma.c +++ b/cli/mmcli-modem-oma.c @@ -33,6 +33,7 @@ #include "mmcli.h" #include "mmcli-common.h" +#include "mmcli-output.h" /* Context */ typedef struct { @@ -160,32 +161,19 @@ mmcli_modem_oma_shutdown (void) static void print_oma_status (void) { - gchar *features_str; + gchar *features_str; const MMOmaPendingNetworkInitiatedSession *pending_sessions; - guint n_pending_sessions; - -#undef VALIDATE_UNKNOWN -#define VALIDATE_UNKNOWN(str) (str ? str : "unknown") + guint n_pending_sessions; + const gchar *current_session_type = NULL; + const gchar *current_session_state = NULL; + GPtrArray *aux = NULL; features_str = mm_oma_feature_build_string_from_mask (mm_modem_oma_get_features (ctx->modem_oma)); - /* Global IDs */ - g_print ("\n" - "%s\n", - VALIDATE_UNKNOWN (mm_modem_oma_get_path (ctx->modem_oma))); - - /* Overall setup */ - g_print (" -------------------------\n" - " Setup | features: '%s'\n", - VALIDATE_UNKNOWN (features_str)); - /* Current session */ if (mm_modem_oma_get_session_type (ctx->modem_oma) != MM_OMA_SESSION_TYPE_UNKNOWN) { - g_print (" -------------------------\n" - " Current session | type: '%s'\n" - " | state: '%s'\n", - VALIDATE_UNKNOWN (mm_oma_session_type_get_string (mm_modem_oma_get_session_type (ctx->modem_oma))), - VALIDATE_UNKNOWN (mm_oma_session_state_get_string (mm_modem_oma_get_session_state (ctx->modem_oma)))); + current_session_type = mm_oma_session_type_get_string (mm_modem_oma_get_session_type (ctx->modem_oma)); + current_session_state = mm_oma_session_state_get_string (mm_modem_oma_get_session_state (ctx->modem_oma)); } /* If 1 or more pending sessions... */ @@ -193,18 +181,24 @@ print_oma_status (void) n_pending_sessions > 0) { guint i; - g_print (" -------------------------\n" - " Pending sessions |\n"); + aux = g_ptr_array_new (); + for (i = 0; i < n_pending_sessions; i++) { - g_print (" [%u] | type: '%s'\n" - " | id: '%u'\n", - i, - VALIDATE_UNKNOWN (mm_oma_session_type_get_string (pending_sessions[i].session_type)), - pending_sessions[i].session_id); + gchar *info; + + info = g_strdup_printf ("id: %u, type: %s", + pending_sessions[i].session_id, + mm_oma_session_type_get_string (pending_sessions[i].session_type)); + g_ptr_array_add (aux, info); } + g_ptr_array_add (aux, NULL); } - g_free (features_str); + mmcli_output_string_take (MMC_F_OMA_FEATURES, features_str); + mmcli_output_string (MMC_F_OMA_CURRENT_TYPE, current_session_type); + mmcli_output_string (MMC_F_OMA_CURRENT_STATE, current_session_state); + mmcli_output_string_array_take (MMC_F_OMA_PENDING_SESSIONS, aux ? (gchar **) g_ptr_array_free (aux, FALSE) : NULL, TRUE); + mmcli_output_dump (); } static void diff --git a/cli/mmcli-modem-signal.c b/cli/mmcli-modem-signal.c index bb64517d3..fa45f1022 100644 --- a/cli/mmcli-modem-signal.c +++ b/cli/mmcli-modem-signal.c @@ -33,6 +33,7 @@ #include "mmcli.h" #include "mmcli-common.h" +#include "mmcli-output.h" /* Context */ typedef struct { @@ -133,71 +134,92 @@ mmcli_modem_signal_shutdown (void) } static void -print_signal_value (const gchar *prefix, - gdouble value, - const gchar *units) -{ - if (value != MM_SIGNAL_UNKNOWN) - g_print ("%s'%.2lf' %s\n", prefix, value, units); - else - g_print ("%s'n/a'\n", prefix); -} - -static void print_signal_info (void) { MMSignal *signal; + gdouble value; + gchar *refresh_rate; + gchar *cdma1x_rssi = NULL; + gchar *cdma1x_ecio = NULL; + gchar *evdo_rssi = NULL; + gchar *evdo_ecio = NULL; + gchar *evdo_sinr = NULL; + gchar *evdo_io = NULL; + gchar *gsm_rssi = NULL; + gchar *umts_rssi = NULL; + gchar *umts_rscp = NULL; + gchar *umts_ecio = NULL; + gchar *lte_rssi = NULL; + gchar *lte_rsrp = NULL; + gchar *lte_rsrq = NULL; + gchar *lte_snr = NULL; + + refresh_rate = g_strdup_printf ("%u", mm_modem_signal_get_rate (ctx->modem_signal)); - g_print ("\n" - "%s\n" - " -------------------------\n" - " Signal | Refresh rate: '%u' seconds\n", - mm_modem_signal_get_path (ctx->modem_signal), - mm_modem_signal_get_rate (ctx->modem_signal)); - - /* CDMA */ signal = mm_modem_signal_peek_cdma (ctx->modem_signal); if (signal) { - g_print (" -------------------------\n"); - print_signal_value (" CDMA1x | RSSI: ", mm_signal_get_rssi (signal), "dBm"); - print_signal_value (" | EcIo: ", mm_signal_get_ecio (signal), "dBm"); + if ((value = mm_signal_get_rssi (signal)) != MM_SIGNAL_UNKNOWN) + cdma1x_rssi = g_strdup_printf ("%.2lf", value); + if ((value = mm_signal_get_ecio (signal)) != MM_SIGNAL_UNKNOWN) + cdma1x_ecio = g_strdup_printf ("%.2lf", value); } - /* EVDO */ signal = mm_modem_signal_peek_evdo (ctx->modem_signal); if (signal) { - g_print (" -------------------------\n"); - print_signal_value (" EV-DO | RSSI: ", mm_signal_get_rssi (signal), "dBm"); - print_signal_value (" | EcIo: ", mm_signal_get_ecio (signal), "dB"); - print_signal_value (" | SINR: ", mm_signal_get_sinr (signal), "dB"); - print_signal_value (" | Io: ", mm_signal_get_io (signal), "dBm"); + if ((value = mm_signal_get_rssi (signal)) != MM_SIGNAL_UNKNOWN) + evdo_rssi = g_strdup_printf ("%.2lf", value); + if ((value = mm_signal_get_ecio (signal)) != MM_SIGNAL_UNKNOWN) + evdo_ecio = g_strdup_printf ("%.2lf", value); + if ((value = mm_signal_get_sinr (signal)) != MM_SIGNAL_UNKNOWN) + evdo_sinr = g_strdup_printf ("%.2lf", value); + if ((value = mm_signal_get_io (signal)) != MM_SIGNAL_UNKNOWN) + evdo_io = g_strdup_printf ("%.2lf", value); } - /* GSM */ signal = mm_modem_signal_peek_gsm (ctx->modem_signal); if (signal) { - g_print (" -------------------------\n"); - print_signal_value (" GSM | RSSI: ", mm_signal_get_rssi (signal), "dBm"); + if ((value = mm_signal_get_rssi (signal)) != MM_SIGNAL_UNKNOWN) + gsm_rssi = g_strdup_printf ("%.2lf", value); } - /* UMTS */ signal = mm_modem_signal_peek_umts (ctx->modem_signal); if (signal) { - g_print (" -------------------------\n"); - print_signal_value (" UMTS | RSSI: ", mm_signal_get_rssi (signal), "dBm"); - print_signal_value (" | RSCP: ", mm_signal_get_rscp (signal), "dBm"); - print_signal_value (" | EcIo: ", mm_signal_get_ecio (signal), "dB"); + if ((value = mm_signal_get_rssi (signal)) != MM_SIGNAL_UNKNOWN) + umts_rssi = g_strdup_printf ("%.2lf", value); + if ((value = mm_signal_get_rscp (signal)) != MM_SIGNAL_UNKNOWN) + umts_rscp = g_strdup_printf ("%.2lf", value); + if ((value = mm_signal_get_ecio (signal)) != MM_SIGNAL_UNKNOWN) + umts_ecio = g_strdup_printf ("%.2lf", value); } - /* LTE */ signal = mm_modem_signal_peek_lte (ctx->modem_signal); if (signal) { - g_print (" -------------------------\n"); - print_signal_value (" LTE | RSSI: ", mm_signal_get_rssi (signal), "dBm"); - print_signal_value (" | RSRQ: ", mm_signal_get_rsrq (signal), "dB"); - print_signal_value (" | RSRP: ", mm_signal_get_rsrp (signal), "dBm"); - print_signal_value (" | S/N: ", mm_signal_get_snr (signal), "dB"); + if ((value = mm_signal_get_rssi (signal)) != MM_SIGNAL_UNKNOWN) + lte_rssi = g_strdup_printf ("%.2lf", value); + if ((value = mm_signal_get_rsrq (signal)) != MM_SIGNAL_UNKNOWN) + lte_rsrq = g_strdup_printf ("%.2lf", value); + if ((value = mm_signal_get_rsrp (signal)) != MM_SIGNAL_UNKNOWN) + lte_rsrp = g_strdup_printf ("%.2lf", value); + if ((value = mm_signal_get_snr (signal)) != MM_SIGNAL_UNKNOWN) + lte_snr = g_strdup_printf ("%.2lf", value); } + + mmcli_output_string_take_typed (MMC_F_SIGNAL_REFRESH_RATE, refresh_rate, "seconds"); + mmcli_output_string_take_typed (MMC_F_SIGNAL_CDMA1X_RSSI, cdma1x_rssi, "dBm"); + mmcli_output_string_take_typed (MMC_F_SIGNAL_CDMA1X_ECIO, cdma1x_ecio, "dBm"); + mmcli_output_string_take_typed (MMC_F_SIGNAL_EVDO_RSSI, evdo_rssi, "dBm"); + mmcli_output_string_take_typed (MMC_F_SIGNAL_EVDO_ECIO, evdo_ecio, "dB"); + mmcli_output_string_take_typed (MMC_F_SIGNAL_EVDO_SINR, evdo_sinr, "dB"); + mmcli_output_string_take_typed (MMC_F_SIGNAL_EVDO_IO, evdo_io, "dBm"); + mmcli_output_string_take_typed (MMC_F_SIGNAL_GSM_RSSI, gsm_rssi, "dBm"); + mmcli_output_string_take_typed (MMC_F_SIGNAL_UMTS_RSSI, umts_rssi, "dBm"); + mmcli_output_string_take_typed (MMC_F_SIGNAL_UMTS_RSCP, umts_rscp, "dBm"); + mmcli_output_string_take_typed (MMC_F_SIGNAL_UMTS_ECIO, umts_ecio, "dB"); + mmcli_output_string_take_typed (MMC_F_SIGNAL_LTE_RSSI, lte_rssi, "dBm"); + mmcli_output_string_take_typed (MMC_F_SIGNAL_LTE_RSRQ, lte_rsrq, "dB"); + mmcli_output_string_take_typed (MMC_F_SIGNAL_LTE_RSRP, lte_rsrp, "dBm"); + mmcli_output_string_take_typed (MMC_F_SIGNAL_LTE_SNR, lte_snr, "dB"); + mmcli_output_dump (); } static void diff --git a/cli/mmcli-modem-time.c b/cli/mmcli-modem-time.c index 206ca599d..b210e53da 100644 --- a/cli/mmcli-modem-time.c +++ b/cli/mmcli-modem-time.c @@ -33,6 +33,7 @@ #include "mmcli.h" #include "mmcli-common.h" +#include "mmcli-output.h" /* Context */ typedef struct { @@ -137,14 +138,11 @@ get_network_time_process_reply (gchar *time_string, gchar *dst_offset = NULL; gchar *leap_seconds = NULL; - if (error) + if (error) { g_printerr ("error: couldn't get current network time: '%s'\n", error->message); - - /* Not the best thing to do, as we may be doing _get() calls twice, but - * easiest to maintain */ -#undef VALIDATE -#define VALIDATE(str) (str ? str : "not available") + exit (EXIT_FAILURE); + } if (timezone) { if (mm_network_timezone_get_offset (timezone) != MM_NETWORK_TIMEZONE_OFFSET_UNKNOWN) @@ -157,27 +155,11 @@ get_network_time_process_reply (gchar *time_string, leap_seconds = g_strdup_printf ("%" G_GINT32_FORMAT, mm_network_timezone_get_leap_seconds (timezone)); } - g_print ("\n" - "%s\n" - " ----------------------------\n" - " Time | Current: '%s'\n" - " ----------------------------\n" - " Timezone | Offset: '%s'\n" - " | DST offset: '%s'\n" - " | Leap seconds: '%s'\n", - mm_modem_time_get_path (ctx->modem_time), - VALIDATE (time_string), - VALIDATE (offset), - VALIDATE (dst_offset), - VALIDATE (leap_seconds)); - - g_free (offset); - g_free (dst_offset); - g_free (leap_seconds); - g_free (time_string); - - if (error) - exit (EXIT_FAILURE); + mmcli_output_string_take (MMC_F_TIME_CURRENT, time_string); + mmcli_output_string_take (MMC_F_TIMEZONE_CURRENT, offset); + mmcli_output_string_take (MMC_F_TIMEZONE_DST_OFFSET, dst_offset); + mmcli_output_string_take (MMC_F_TIMEZONE_LEAP_SECONDS, leap_seconds); + mmcli_output_dump (); } static void diff --git a/cli/mmcli-modem-voice.c b/cli/mmcli-modem-voice.c index e5bb81d2e..089523ef5 100644 --- a/cli/mmcli-modem-voice.c +++ b/cli/mmcli-modem-voice.c @@ -34,6 +34,7 @@ #include "mmcli.h" #include "mmcli-common.h" +#include "mmcli-output.h" /* Context */ typedef struct { @@ -160,39 +161,35 @@ build_call_properties_from_input (const gchar *properties_string) } static void -print_call_short_info (MMCall *call) +output_call_info (MMCall *call) { - g_print ("\t%s %s (%s)\n", - mm_call_get_path (call), - mm_call_direction_get_string (mm_call_get_direction (call)), - mm_call_state_get_string (mm_call_get_state (call))); + gchar *extra; + + extra = g_strdup_printf ("%s (%s)", + mm_call_direction_get_string (mm_call_get_direction (call)), + mm_call_state_get_string (mm_call_get_state (call))); + mmcli_output_listitem (MMC_F_CALL_LIST_DBUS_PATH, + " ", + mm_call_get_path (call), + extra); + g_free (extra); } static void list_process_reply (GList *result, const GError *error) { + GList *l; + if (error) { g_printerr ("error: couldn't list call: '%s'\n", error->message); exit (EXIT_FAILURE); } - g_print ("\n"); - if (!result) { - g_print ("No calls were found\n"); - } else { - GList *l; - - g_print ("Found %u calls:\n", g_list_length (result)); - for (l = result; l; l = g_list_next (l)) { - MMCall *call = MM_CALL (l->data); - - print_call_short_info (call); - g_object_unref (call); - } - g_list_free (result); - } + for (l = result; l; l = g_list_next (l)) + output_call_info (MM_CALL (l->data)); + mmcli_output_list_dump (MMC_F_CALL_LIST_DBUS_PATH); } static void @@ -219,8 +216,7 @@ create_process_reply (MMCall *call, exit (EXIT_FAILURE); } - g_print ("Successfully created new call:\n"); - print_call_short_info (call); + g_print ("Successfully created new call: %s\n", mm_call_get_path (call)); g_object_unref (call); } diff --git a/cli/mmcli-modem.c b/cli/mmcli-modem.c index 5fde013b6..582322bdf 100644 --- a/cli/mmcli-modem.c +++ b/cli/mmcli-modem.c @@ -15,7 +15,7 @@ * 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) 2011 Aleksander Morgado <aleksander@gnu.org> + * Copyright (C) 2011-2018 Aleksander Morgado <aleksander@aleksander.es> */ #include "config.h" @@ -32,6 +32,7 @@ #include "mmcli.h" #include "mmcli-common.h" +#include "mmcli-output.h" /* Context */ typedef struct { @@ -242,9 +243,6 @@ print_bearer_short_info (MMBearer *bearer) static void print_modem_info (void) { - gchar *drivers_string; - gchar *prefixed_revision; - gchar *prefixed_hardware_revision; gchar *supported_capabilities_string; MMModemCapability *capabilities = NULL; guint n_capabilities = 0; @@ -261,7 +259,6 @@ print_modem_info (void) gchar *current_bands_string; gchar *supported_ip_families_string; gchar *unlock_retries_string; - gchar *own_numbers_string; MMModemBand *bands = NULL; guint n_bands = 0; MMModemPortInfo *ports = NULL; @@ -270,14 +267,8 @@ print_modem_info (void) MMUnlockRetries *unlock_retries; guint signal_quality = 0; gboolean signal_quality_recent = FALSE; - gchar *bearer_paths_string; - - /* Not the best thing to do, as we may be doing _get() calls twice, but - * easiest to maintain */ -#undef VALIDATE_UNKNOWN -#define VALIDATE_UNKNOWN(str) (str ? str : "unknown") -#undef VALIDATE_PATH -#define VALIDATE_PATH(str) ((str && !g_str_equal (str, "/")) ? str : "none") + const gchar *sim_path; + const gchar **bearer_paths; /* Strings in heap */ mm_modem_get_supported_capabilities (ctx->modem, &capabilities, &n_capabilities); @@ -310,252 +301,118 @@ print_modem_info (void) unlock_retries_string = mm_unlock_retries_build_string (unlock_retries); g_object_unref (unlock_retries); - if (mm_modem_get_own_numbers (ctx->modem)) { - own_numbers_string = g_strjoinv (", ", (gchar **)mm_modem_get_own_numbers (ctx->modem)); - if (!own_numbers_string[0]) { - g_free (own_numbers_string); - own_numbers_string = NULL; - } - } else - own_numbers_string = NULL; - - if (mm_modem_get_drivers (ctx->modem)) { - drivers_string = g_strjoinv (", ", (gchar **)mm_modem_get_drivers (ctx->modem)); - if (!drivers_string[0]) { - g_free (drivers_string); - drivers_string = NULL; + signal_quality = mm_modem_get_signal_quality (ctx->modem, &signal_quality_recent); + + mmcli_output_string (MMC_F_GENERAL_DBUS_PATH, mm_modem_get_path (ctx->modem)); + mmcli_output_string (MMC_F_GENERAL_DEVICE_ID, mm_modem_get_device_identifier (ctx->modem)); + + mmcli_output_string (MMC_F_HARDWARE_MANUFACTURER, mm_modem_get_manufacturer (ctx->modem)); + mmcli_output_string (MMC_F_HARDWARE_MODEL, mm_modem_get_model (ctx->modem)); + mmcli_output_string (MMC_F_HARDWARE_REVISION, mm_modem_get_revision (ctx->modem)); + mmcli_output_string (MMC_F_HARDWARE_HW_REVISION, mm_modem_get_hardware_revision (ctx->modem)); + mmcli_output_string_multiline (MMC_F_HARDWARE_SUPPORTED_CAPABILITIES, supported_capabilities_string); + mmcli_output_string_multiline (MMC_F_HARDWARE_CURRENT_CAPABILITIES, current_capabilities_string); + mmcli_output_string (MMC_F_HARDWARE_EQUIPMENT_ID, mm_modem_get_equipment_identifier (ctx->modem)); + + mmcli_output_string (MMC_F_SYSTEM_DEVICE, mm_modem_get_device (ctx->modem)); + mmcli_output_string_array (MMC_F_SYSTEM_DRIVERS, (const gchar **) mm_modem_get_drivers (ctx->modem), FALSE); + mmcli_output_string (MMC_F_SYSTEM_PLUGIN, mm_modem_get_plugin (ctx->modem)); + mmcli_output_string (MMC_F_SYSTEM_PRIMARY_PORT, mm_modem_get_primary_port (ctx->modem)); + mmcli_output_string_list (MMC_F_SYSTEM_PORTS, ports_string); + + mmcli_output_string_array (MMC_F_NUMBERS_OWN, (const gchar **) mm_modem_get_own_numbers (ctx->modem), FALSE); + + mmcli_output_string (MMC_F_STATUS_LOCK, mm_modem_lock_get_string (mm_modem_get_unlock_required (ctx->modem))); + mmcli_output_string_list (MMC_F_STATUS_UNLOCK_RETRIES, unlock_retries_string); + mmcli_output_state (mm_modem_get_state (ctx->modem), mm_modem_get_state_failed_reason (ctx->modem)); + mmcli_output_string (MMC_F_STATUS_POWER_STATE, mm_modem_power_state_get_string (mm_modem_get_power_state (ctx->modem))); + mmcli_output_string_list (MMC_F_STATUS_ACCESS_TECH, access_technologies_string); + mmcli_output_signal_quality (signal_quality, signal_quality_recent); + + mmcli_output_string_multiline (MMC_F_MODES_SUPPORTED, supported_modes_string); + mmcli_output_string_take (MMC_F_MODES_CURRENT, g_strdup_printf ("allowed: %s; preferred: %s", + allowed_modes_string, preferred_mode_string)); + + mmcli_output_string_list (MMC_F_BANDS_SUPPORTED, supported_bands_string); + mmcli_output_string_list (MMC_F_BANDS_CURRENT, current_bands_string); + + mmcli_output_string_list (MMC_F_IP_SUPPORTED, supported_ip_families_string); + + /* 3GPP */ + { + const gchar *imei = NULL; + gchar *facility_locks = NULL; + const gchar *operator_code = NULL; + const gchar *operator_name = NULL; + const gchar *registration = NULL; + const gchar *eps_ue_mode = NULL; + GList *pco_list = NULL; + + if (ctx->modem_3gpp) { + imei = mm_modem_3gpp_get_imei (ctx->modem_3gpp); + facility_locks = (mm_modem_3gpp_facility_build_string_from_mask (mm_modem_3gpp_get_enabled_facility_locks (ctx->modem_3gpp))); + operator_code = mm_modem_3gpp_get_operator_code (ctx->modem_3gpp); + operator_name = mm_modem_3gpp_get_operator_name (ctx->modem_3gpp); + registration = mm_modem_3gpp_registration_state_get_string (mm_modem_3gpp_get_registration_state (ctx->modem_3gpp)); + eps_ue_mode = mm_modem_3gpp_eps_ue_mode_operation_get_string (mm_modem_3gpp_get_eps_ue_mode_operation (ctx->modem_3gpp)); + pco_list = mm_modem_3gpp_get_pco (ctx->modem_3gpp); } - } else - drivers_string = NULL; - - /* Rework possible multiline strings */ - if (mm_modem_get_revision (ctx->modem)) - prefixed_revision = mmcli_prefix_newlines (" | ", - mm_modem_get_revision (ctx->modem)); - else - prefixed_revision = NULL; - - if (mm_modem_get_hardware_revision (ctx->modem)) - prefixed_hardware_revision = mmcli_prefix_newlines (" | ", - mm_modem_get_hardware_revision (ctx->modem)); - else - prefixed_hardware_revision = NULL; - - if (supported_modes_string) { - gchar *prefixed; - - prefixed = mmcli_prefix_newlines (" | ", - supported_modes_string); - g_free (supported_modes_string); - supported_modes_string = prefixed; - } - if (supported_capabilities_string) { - gchar *prefixed; + mmcli_output_string (MMC_F_3GPP_IMEI, imei); + mmcli_output_string_list (MMC_F_3GPP_ENABLED_LOCKS, facility_locks); + mmcli_output_string (MMC_F_3GPP_OPERATOR_ID, operator_code); + mmcli_output_string (MMC_F_3GPP_OPERATOR_NAME, operator_name); + mmcli_output_string (MMC_F_3GPP_REGISTRATION, registration); + mmcli_output_string (MMC_F_3GPP_EPS_UE_MODE, eps_ue_mode); + mmcli_output_pco_list (pco_list); - prefixed = mmcli_prefix_newlines (" | ", - supported_capabilities_string); - g_free (supported_capabilities_string); - supported_capabilities_string = prefixed; + g_free (facility_locks); + mm_pco_list_free (pco_list); } - /* Get signal quality info */ - signal_quality = mm_modem_get_signal_quality (ctx->modem, &signal_quality_recent); - - if (mm_modem_get_bearer_paths (ctx->modem)) { - bearer_paths_string = g_strjoinv (", ", (gchar **)mm_modem_get_bearer_paths (ctx->modem)); - if (!bearer_paths_string[0]) { - g_free (bearer_paths_string); - bearer_paths_string = NULL; + /* CDMA */ + { + const gchar *meid = NULL; + const gchar *esn = NULL; + gchar *sid = NULL; + gchar *nid = NULL; + const gchar *registration_cdma1x = NULL; + const gchar *registration_evdo = NULL; + const gchar *activation = NULL; + + if (ctx->modem_cdma) { + guint sid_n; + guint nid_n; + + meid = mm_modem_cdma_get_meid (ctx->modem_cdma); + esn = mm_modem_cdma_get_esn (ctx->modem_cdma); + sid_n = mm_modem_cdma_get_sid (ctx->modem_cdma); + if (sid_n != MM_MODEM_CDMA_SID_UNKNOWN) + sid = g_strdup_printf ("%u", sid_n); + nid_n = mm_modem_cdma_get_nid (ctx->modem_cdma); + if (nid_n != MM_MODEM_CDMA_NID_UNKNOWN) + nid = g_strdup_printf ("%u", nid_n); + registration_cdma1x = mm_modem_cdma_registration_state_get_string (mm_modem_cdma_get_cdma1x_registration_state (ctx->modem_cdma)); + registration_evdo = mm_modem_cdma_registration_state_get_string (mm_modem_cdma_get_evdo_registration_state (ctx->modem_cdma)); + activation = mm_modem_cdma_activation_state_get_string (mm_modem_cdma_get_activation_state (ctx->modem_cdma)); } - } else - bearer_paths_string = NULL; - - /* Global IDs */ - g_print ("\n" - "%s (device id '%s')\n", - VALIDATE_UNKNOWN (mm_modem_get_path (ctx->modem)), - VALIDATE_UNKNOWN (mm_modem_get_device_identifier (ctx->modem))); - - /* Hardware related stuff */ - g_print (" -------------------------\n" - " Hardware | manufacturer: '%s'\n" - " | model: '%s'\n" - " | revision: '%s'\n" - " | H/W revision: '%s'\n" - " | supported: '%s'\n" - " | current: '%s'\n" - " | equipment id: '%s'\n", - VALIDATE_UNKNOWN (mm_modem_get_manufacturer (ctx->modem)), - VALIDATE_UNKNOWN (mm_modem_get_model (ctx->modem)), - VALIDATE_UNKNOWN (prefixed_revision), - VALIDATE_UNKNOWN (prefixed_hardware_revision), - VALIDATE_UNKNOWN (supported_capabilities_string), - VALIDATE_UNKNOWN (current_capabilities_string), - VALIDATE_UNKNOWN (mm_modem_get_equipment_identifier (ctx->modem))); - - /* System related stuff */ - g_print (" -------------------------\n" - " System | device: '%s'\n" - " | drivers: '%s'\n" - " | plugin: '%s'\n" - " | primary port: '%s'\n" - " | ports: '%s'\n", - VALIDATE_UNKNOWN (mm_modem_get_device (ctx->modem)), - VALIDATE_UNKNOWN (drivers_string), - VALIDATE_UNKNOWN (mm_modem_get_plugin (ctx->modem)), - VALIDATE_UNKNOWN (mm_modem_get_primary_port (ctx->modem)), - VALIDATE_UNKNOWN (ports_string)); - - /* Numbers related stuff */ - g_print (" -------------------------\n" - " Numbers | own : '%s'\n", - VALIDATE_UNKNOWN (own_numbers_string)); - - /* Status related stuff */ - g_print (" -------------------------\n" - " Status | lock: '%s'\n" - " | unlock retries: '%s'\n" - " | state: '%s'\n", - mm_modem_lock_get_string (mm_modem_get_unlock_required (ctx->modem)), - VALIDATE_UNKNOWN (unlock_retries_string), - VALIDATE_UNKNOWN (mm_modem_state_get_string (mm_modem_get_state (ctx->modem)))); - - if (mm_modem_get_state (ctx->modem) == MM_MODEM_STATE_FAILED) - g_print (" | failed reason: '%s'\n", - VALIDATE_UNKNOWN (mm_modem_state_failed_reason_get_string (mm_modem_get_state_failed_reason (ctx->modem)))); - - g_print (" | power state: '%s'\n" - " | access tech: '%s'\n" - " | signal quality: '%u' (%s)\n", - VALIDATE_UNKNOWN (mm_modem_power_state_get_string (mm_modem_get_power_state (ctx->modem))), - VALIDATE_UNKNOWN (access_technologies_string), - signal_quality, signal_quality_recent ? "recent" : "cached"); - - /* Modes */ - g_print (" -------------------------\n" - " Modes | supported: '%s'\n" - " | current: 'allowed: %s; preferred: %s'\n", - VALIDATE_UNKNOWN (supported_modes_string), - VALIDATE_UNKNOWN (allowed_modes_string), - VALIDATE_UNKNOWN (preferred_mode_string)); - - /* Band related stuff */ - g_print (" -------------------------\n" - " Bands | supported: '%s'\n" - " | current: '%s'\n", - VALIDATE_UNKNOWN (supported_bands_string), - VALIDATE_UNKNOWN (current_bands_string)); - - /* IP families */ - g_print (" -------------------------\n" - " IP | supported: '%s'\n", - VALIDATE_UNKNOWN (supported_ip_families_string)); - - /* If available, 3GPP related stuff */ - if (ctx->modem_3gpp) { - gchar *facility_locks; - GList *pco_list; - - facility_locks = (mm_modem_3gpp_facility_build_string_from_mask ( - mm_modem_3gpp_get_enabled_facility_locks (ctx->modem_3gpp))); - pco_list = mm_modem_3gpp_get_pco (ctx->modem_3gpp); - g_print (" -------------------------\n" - " 3GPP | imei: '%s'\n" - " | enabled locks: '%s'\n" - " | operator id: '%s'\n" - " | operator name: '%s'\n" - " | subscription: '%s'\n" - " | registration: '%s'\n" - " | EPS UE mode: '%s'\n", - VALIDATE_UNKNOWN (mm_modem_3gpp_get_imei (ctx->modem_3gpp)), - facility_locks, - VALIDATE_UNKNOWN (mm_modem_3gpp_get_operator_code (ctx->modem_3gpp)), - VALIDATE_UNKNOWN (mm_modem_3gpp_get_operator_name (ctx->modem_3gpp)), - mm_modem_3gpp_subscription_state_get_string ( - mm_modem_3gpp_get_subscription_state (ctx->modem_3gpp)), - mm_modem_3gpp_registration_state_get_string ( - mm_modem_3gpp_get_registration_state (ctx->modem_3gpp)), - mm_modem_3gpp_eps_ue_mode_operation_get_string ( - mm_modem_3gpp_get_eps_ue_mode_operation (ctx->modem_3gpp))); - - if (pco_list) { - GList *l; - - g_print (" | PCO:\n"); - for (l = pco_list; l; l = g_list_next (l)) { - MMPco *pco = MM_PCO (l->data); - gchar *pco_data_hex = NULL; - const guint8 *pco_data; - gsize pco_data_size; - - pco_data = mm_pco_get_data (pco, &pco_data_size); - if (pco_data) - pco_data_hex = mm_utils_bin2hexstr (pco_data, pco_data_size); - - g_print (" | %u: (%s) '%s'\n", - mm_pco_get_session_id (pco), - mm_pco_is_complete (pco) ? "complete" : "partial", - pco_data_hex ? pco_data_hex : ""); - g_free (pco_data_hex); - } - mm_pco_list_free (pco_list); - } else - g_print (" | PCO: 'n/a'\n"); - g_free (facility_locks); + mmcli_output_string (MMC_F_CDMA_MEID, meid); + mmcli_output_string (MMC_F_CDMA_ESN, esn); + mmcli_output_string_take (MMC_F_CDMA_SID, sid); + mmcli_output_string_take (MMC_F_CDMA_NID, nid); + mmcli_output_string (MMC_F_CDMA_REGISTRATION_CDMA1X, registration_cdma1x); + mmcli_output_string (MMC_F_CDMA_REGISTRATION_EVDO, registration_evdo); + mmcli_output_string (MMC_F_CDMA_ACTIVATION, activation); } - /* If available, CDMA related stuff */ - if (ctx->modem_cdma) { - guint sid; - guint nid; - gchar *sid_str; - gchar *nid_str; - - sid = mm_modem_cdma_get_sid (ctx->modem_cdma); - sid_str = (sid != MM_MODEM_CDMA_SID_UNKNOWN ? - g_strdup_printf ("%u", sid) : - NULL); - nid = mm_modem_cdma_get_nid (ctx->modem_cdma); - nid_str = (nid != MM_MODEM_CDMA_NID_UNKNOWN ? - g_strdup_printf ("%u", nid) : - NULL); - - g_print (" -------------------------\n" - " CDMA | meid: '%s'\n" - " | esn: '%s'\n" - " | sid: '%s'\n" - " | nid: '%s'\n" - " | registration: CDMA1x '%s'\n" - " | EV-DO '%s'\n" - " | activation: '%s'\n", - VALIDATE_UNKNOWN (mm_modem_cdma_get_meid (ctx->modem_cdma)), - VALIDATE_UNKNOWN (mm_modem_cdma_get_esn (ctx->modem_cdma)), - VALIDATE_UNKNOWN (sid_str), - VALIDATE_UNKNOWN (nid_str), - mm_modem_cdma_registration_state_get_string ( - mm_modem_cdma_get_cdma1x_registration_state (ctx->modem_cdma)), - mm_modem_cdma_registration_state_get_string ( - mm_modem_cdma_get_evdo_registration_state (ctx->modem_cdma)), - mm_modem_cdma_activation_state_get_string ( - mm_modem_cdma_get_activation_state (ctx->modem_cdma))); - - g_free (sid_str); - g_free (nid_str); - } + sim_path = mm_modem_get_sim_path (ctx->modem); + mmcli_output_string (MMC_F_SIM_PATH, g_strcmp0 (sim_path, "/") != 0 ? sim_path : NULL); - /* SIM */ - g_print (" -------------------------\n" - " SIM | path: '%s'\n", - VALIDATE_PATH (mm_modem_get_sim_path (ctx->modem))); - g_print ("\n"); + bearer_paths = (const gchar **) mm_modem_get_bearer_paths (ctx->modem); + mmcli_output_string_array (MMC_F_BEARER_PATHS, (bearer_paths && bearer_paths[0]) ? bearer_paths : NULL, TRUE); - /* Bearers */ - g_print (" -------------------------\n" - " Bearers | paths: '%s'\n", - VALIDATE_PATH (bearer_paths_string)); - g_print ("\n"); + mmcli_output_dump (); g_free (ports_string); g_free (supported_ip_families_string); @@ -564,15 +421,10 @@ print_modem_info (void) g_free (access_technologies_string); g_free (supported_capabilities_string); g_free (current_capabilities_string); - g_free (prefixed_revision); - g_free (prefixed_hardware_revision); g_free (allowed_modes_string); g_free (preferred_mode_string); g_free (supported_modes_string); g_free (unlock_retries_string); - g_free (own_numbers_string); - g_free (drivers_string); - g_free (bearer_paths_string); } static void diff --git a/cli/mmcli-output.c b/cli/mmcli-output.c new file mode 100644 index 000000000..245aeed1e --- /dev/null +++ b/cli/mmcli-output.c @@ -0,0 +1,1099 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * mmcli -- Control modem status & access information from the command line + * + * 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) 2018 Aleksander Morgado <aleksander@aleksander.es> + */ + +#include <stdio.h> + +#include <libmm-glib.h> +#include "mm-common-helpers.h" +#include "mmcli-output.h" + +/******************************************************************************/ +/* List of sections (grouped fields) displayed in the human-friendly output */ + +typedef struct { + const gchar *name; +} SectionInfo; + +static SectionInfo section_infos[] = { + [MMC_S_MODEM_GENERAL] = { "General" }, + [MMC_S_MODEM_HARDWARE] = { "Hardware" }, + [MMC_S_MODEM_SYSTEM] = { "System" }, + [MMC_S_MODEM_NUMBERS] = { "Numbers" }, + [MMC_S_MODEM_STATUS] = { "Status" }, + [MMC_S_MODEM_MODES] = { "Modes" }, + [MMC_S_MODEM_BANDS] = { "Bands" }, + [MMC_S_MODEM_IP] = { "IP" }, + [MMC_S_MODEM_3GPP] = { "3GPP" }, + [MMC_S_MODEM_3GPP_SCAN] = { "3GPP scan" }, + [MMC_S_MODEM_3GPP_USSD] = { "3GPP USSD" }, + [MMC_S_MODEM_CDMA] = { "CDMA" }, + [MMC_S_MODEM_SIM] = { "SIM" }, + [MMC_S_MODEM_BEARER] = { "Bearer" }, + [MMC_S_MODEM_TIME] = { "Time" }, + [MMC_S_MODEM_TIMEZONE] = { "Timezone" }, + [MMC_S_MODEM_MESSAGING] = { "Messaging" }, + [MMC_S_MODEM_SIGNAL] = { "Signal" }, + [MMC_S_MODEM_SIGNAL_CDMA1X] = { "CDMA1x" }, + [MMC_S_MODEM_SIGNAL_EVDO] = { "EV-DO" }, + [MMC_S_MODEM_SIGNAL_GSM] = { "GSM" }, + [MMC_S_MODEM_SIGNAL_UMTS] = { "UMTS" }, + [MMC_S_MODEM_SIGNAL_LTE] = { "LTE" }, + [MMC_S_MODEM_OMA] = { "OMA" }, + [MMC_S_MODEM_OMA_CURRENT] = { "Current session" }, + [MMC_S_MODEM_OMA_PENDING] = { "Pending sessions" }, + [MMC_S_MODEM_LOCATION] = { "Location" }, + [MMC_S_MODEM_LOCATION_3GPP] = { "3GPP" }, + [MMC_S_MODEM_LOCATION_GPS] = { "GPS" }, + [MMC_S_MODEM_LOCATION_CDMABS] = { "CDMA BS" }, + [MMC_S_MODEM_FIRMWARE] = { "Firmware" }, + [MMC_S_BEARER_GENERAL] = { "General" }, + [MMC_S_BEARER_STATUS] = { "Status" }, + [MMC_S_BEARER_PROPERTIES] = { "Properties" }, + [MMC_S_BEARER_IPV4_CONFIG] = { "IPv4 configuration" }, + [MMC_S_BEARER_IPV6_CONFIG] = { "IPv6 configuration" }, + [MMC_S_BEARER_STATS] = { "Statistics" }, + [MMC_S_CALL_GENERAL] = { "General" }, + [MMC_S_CALL_PROPERTIES] = { "Properties" }, + [MMC_S_CALL_AUDIO_FORMAT] = { "Audio format" }, + [MMC_S_SMS_GENERAL] = { "General" }, + [MMC_S_SMS_CONTENT] = { "Content" }, + [MMC_S_SMS_PROPERTIES] = { "Properties" }, + [MMC_S_SIM_GENERAL] = { "General" }, + [MMC_S_SIM_PROPERTIES] = { "Properties" }, +}; + +/******************************************************************************/ +/* List of fields */ + +typedef struct { + const gchar *key; + const gchar *name; + MmcS section; +} FieldInfo; + +static FieldInfo field_infos[] = { + [MMC_F_GENERAL_DBUS_PATH] = { "modem.dbus-path", "dbus path", MMC_S_MODEM_GENERAL, }, + [MMC_F_GENERAL_DEVICE_ID] = { "modem.generic.device-identifier", "device id", MMC_S_MODEM_GENERAL, }, + [MMC_F_HARDWARE_MANUFACTURER] = { "modem.generic.manufacturer", "manufacturer", MMC_S_MODEM_HARDWARE, }, + [MMC_F_HARDWARE_MODEL] = { "modem.generic.model", "model", MMC_S_MODEM_HARDWARE, }, + [MMC_F_HARDWARE_REVISION] = { "modem.generic.revision", "revision", MMC_S_MODEM_HARDWARE, }, + [MMC_F_HARDWARE_HW_REVISION] = { "modem.generic.hardware-revision", "h/w revision", MMC_S_MODEM_HARDWARE, }, + [MMC_F_HARDWARE_SUPPORTED_CAPABILITIES] = { "modem.generic.supported-capabilities", "supported", MMC_S_MODEM_HARDWARE, }, + [MMC_F_HARDWARE_CURRENT_CAPABILITIES] = { "modem.generic.current-capabilities", "current", MMC_S_MODEM_HARDWARE, }, + [MMC_F_HARDWARE_EQUIPMENT_ID] = { "modem.generic.equipment-identifier", "equipment id", MMC_S_MODEM_HARDWARE, }, + [MMC_F_SYSTEM_DEVICE] = { "modem.generic.device", "device", MMC_S_MODEM_SYSTEM, }, + [MMC_F_SYSTEM_DRIVERS] = { "modem.generic.drivers", "drivers", MMC_S_MODEM_SYSTEM, }, + [MMC_F_SYSTEM_PLUGIN] = { "modem.generic.plugin", "plugin", MMC_S_MODEM_SYSTEM, }, + [MMC_F_SYSTEM_PRIMARY_PORT] = { "modem.generic.primary-port", "primary port", MMC_S_MODEM_SYSTEM, }, + [MMC_F_SYSTEM_PORTS] = { "modem.generic.ports", "ports", MMC_S_MODEM_SYSTEM, }, + [MMC_F_NUMBERS_OWN] = { "modem.generic.own-numbers", "own", MMC_S_MODEM_NUMBERS, }, + [MMC_F_STATUS_LOCK] = { "modem.generic.unlock-required", "lock", MMC_S_MODEM_STATUS, }, + [MMC_F_STATUS_UNLOCK_RETRIES] = { "modem.generic.unlock-retries", "unlock retries", MMC_S_MODEM_STATUS, }, + [MMC_F_STATUS_STATE] = { "modem.generic.state", "state", MMC_S_MODEM_STATUS, }, + [MMC_F_STATUS_FAILED_REASON] = { "modem.generic.state-failed-reason", "failed reason", MMC_S_MODEM_STATUS, }, + [MMC_F_STATUS_POWER_STATE] = { "modem.generic.power-state", "power state", MMC_S_MODEM_STATUS, }, + [MMC_F_STATUS_ACCESS_TECH] = { "modem.generic.access-technologies", "access tech", MMC_S_MODEM_STATUS, }, + [MMC_F_STATUS_SIGNAL_QUALITY_VALUE] = { "modem.generic.signal-quality.value", "signal quality", MMC_S_MODEM_STATUS, }, + [MMC_F_STATUS_SIGNAL_QUALITY_RECENT] = { "modem.generic.signal-quality.recent", NULL, MMC_S_UNKNOWN, }, + [MMC_F_MODES_SUPPORTED] = { "modem.generic.supported-modes", "supported", MMC_S_MODEM_MODES, }, + [MMC_F_MODES_CURRENT] = { "modem.generic.current-modes", "current", MMC_S_MODEM_MODES, }, + [MMC_F_BANDS_SUPPORTED] = { "modem.generic.supported-bands", "supported", MMC_S_MODEM_BANDS, }, + [MMC_F_BANDS_CURRENT] = { "modem.generic.current-bands", "current", MMC_S_MODEM_BANDS, }, + [MMC_F_IP_SUPPORTED] = { "modem.generic.supported-ip-families", "supported", MMC_S_MODEM_IP, }, + [MMC_F_3GPP_IMEI] = { "modem.3gpp.imei", "imei", MMC_S_MODEM_3GPP, }, + [MMC_F_3GPP_ENABLED_LOCKS] = { "modem.3gpp.enabled-locks", "enabled locks", MMC_S_MODEM_3GPP, }, + [MMC_F_3GPP_OPERATOR_ID] = { "modem.3gpp.operator-code", "operator id", MMC_S_MODEM_3GPP, }, + [MMC_F_3GPP_OPERATOR_NAME] = { "modem.3gpp.operator-name", "operator name", MMC_S_MODEM_3GPP, }, + [MMC_F_3GPP_REGISTRATION] = { "modem.3gpp.registration-state", "registration", MMC_S_MODEM_3GPP, }, + [MMC_F_3GPP_EPS_UE_MODE] = { "modem.3gpp.eps-ue-mode-operation", "eps ue mode", MMC_S_MODEM_3GPP, }, + [MMC_F_3GPP_PCO] = { "modem.3gpp.pco", "pco", MMC_S_MODEM_3GPP, }, + [MMC_F_3GPP_SCAN_NETWORKS] = { "modem.3gpp.scan-networks", "networks", MMC_S_MODEM_3GPP_SCAN, }, + [MMC_F_3GPP_USSD_STATUS] = { "modem.3gpp.ussd.status", "status", MMC_S_MODEM_3GPP_USSD, }, + [MMC_F_3GPP_USSD_NETWORK_REQUEST] = { "modem.3gpp.ussd.network-request", "network request", MMC_S_MODEM_3GPP_USSD, }, + [MMC_F_3GPP_USSD_NETWORK_NOTIFICATION] = { "modem.3gpp.ussd.network-notification", "network notification", MMC_S_MODEM_3GPP_USSD, }, + [MMC_F_CDMA_MEID] = { "modem.cdma.meid", "meid", MMC_S_MODEM_CDMA, }, + [MMC_F_CDMA_ESN] = { "modem.cdma.esn", "esn", MMC_S_MODEM_CDMA, }, + [MMC_F_CDMA_SID] = { "modem.cdma.sid", "sid", MMC_S_MODEM_CDMA, }, + [MMC_F_CDMA_NID] = { "modem.cdma.nid", "nid", MMC_S_MODEM_CDMA, }, + [MMC_F_CDMA_REGISTRATION_CDMA1X] = { "modem.cdma.cdma1x-registration-state", "registration cdma1x", MMC_S_MODEM_CDMA, }, + [MMC_F_CDMA_REGISTRATION_EVDO] = { "modem.cdma.evdo-registration-state", "registration evdo", MMC_S_MODEM_CDMA, }, + [MMC_F_CDMA_ACTIVATION] = { "modem.cdma.activation-state", "activation", MMC_S_MODEM_CDMA, }, + [MMC_F_SIM_PATH] = { "modem.generic.sim", "dbus path", MMC_S_MODEM_SIM, }, + [MMC_F_BEARER_PATHS] = { "modem.generic.bearers", "dbus path", MMC_S_MODEM_BEARER, }, + [MMC_F_TIME_CURRENT] = { "modem.time.current", "current", MMC_S_MODEM_TIME, }, + [MMC_F_TIMEZONE_CURRENT] = { "modem.timezone.current", "current", MMC_S_MODEM_TIMEZONE, }, + [MMC_F_TIMEZONE_DST_OFFSET] = { "modem.time.dst-offset", "dst offset", MMC_S_MODEM_TIMEZONE, }, + [MMC_F_TIMEZONE_LEAP_SECONDS] = { "modem.time.leap-seconds", "leap seconds", MMC_S_MODEM_TIMEZONE, }, + [MMC_F_MESSAGING_SUPPORTED_STORAGES] = { "modem.messaging.supported-storages", "supported storages", MMC_S_MODEM_MESSAGING, }, + [MMC_F_MESSAGING_DEFAULT_STORAGES] = { "modem.messaging.default-storages", "default storages", MMC_S_MODEM_MESSAGING, }, + [MMC_F_SIGNAL_REFRESH_RATE] = { "modem.signal.refresh.rate", "refresh rate", MMC_S_MODEM_SIGNAL, }, + [MMC_F_SIGNAL_CDMA1X_RSSI] = { "modem.signal.cdma1x.rssi", "rssi", MMC_S_MODEM_SIGNAL_CDMA1X, }, + [MMC_F_SIGNAL_CDMA1X_ECIO] = { "modem.signal.cdma1x.ecio", "ecio", MMC_S_MODEM_SIGNAL_CDMA1X, }, + [MMC_F_SIGNAL_EVDO_RSSI] = { "modem.signal.evdo.rssi", "rssi", MMC_S_MODEM_SIGNAL_EVDO, }, + [MMC_F_SIGNAL_EVDO_ECIO] = { "modem.signal.evdo.ecio", "ecio", MMC_S_MODEM_SIGNAL_EVDO, }, + [MMC_F_SIGNAL_EVDO_SINR] = { "modem.signal.evdo.sinr", "sinr", MMC_S_MODEM_SIGNAL_EVDO, }, + [MMC_F_SIGNAL_EVDO_IO] = { "modem.signal.evdo.io", "io", MMC_S_MODEM_SIGNAL_EVDO, }, + [MMC_F_SIGNAL_GSM_RSSI] = { "modem.signal.gsm.rssi", "rssi", MMC_S_MODEM_SIGNAL_GSM, }, + [MMC_F_SIGNAL_UMTS_RSSI] = { "modem.signal.umts.rssi", "rssi", MMC_S_MODEM_SIGNAL_UMTS, }, + [MMC_F_SIGNAL_UMTS_RSCP] = { "modem.signal.umts.rscp", "rscp", MMC_S_MODEM_SIGNAL_UMTS, }, + [MMC_F_SIGNAL_UMTS_ECIO] = { "modem.signal.umts.ecio", "ecio", MMC_S_MODEM_SIGNAL_UMTS, }, + [MMC_F_SIGNAL_LTE_RSSI] = { "modem.signal.lte.rssi", "rssi", MMC_S_MODEM_SIGNAL_LTE, }, + [MMC_F_SIGNAL_LTE_RSRQ] = { "modem.signal.lte.rsrq", "rsrq", MMC_S_MODEM_SIGNAL_LTE, }, + [MMC_F_SIGNAL_LTE_RSRP] = { "modem.signal.lte.rsrp", "rsrp", MMC_S_MODEM_SIGNAL_LTE, }, + [MMC_F_SIGNAL_LTE_SNR] = { "modem.signal.lte.snr", "s/n", MMC_S_MODEM_SIGNAL_LTE, }, + [MMC_F_OMA_FEATURES] = { "modem.oma.features", "features", MMC_S_MODEM_OMA, }, + [MMC_F_OMA_CURRENT_TYPE] = { "modem.oma.current.type", "type", MMC_S_MODEM_OMA_CURRENT, }, + [MMC_F_OMA_CURRENT_STATE] = { "modem.oma.current.state", "state", MMC_S_MODEM_OMA_CURRENT, }, + [MMC_F_OMA_PENDING_SESSIONS] = { "modem.oma.pending-sessions", "sessions", MMC_S_MODEM_OMA_PENDING, }, + [MMC_F_LOCATION_CAPABILITIES] = { "modem.location.capabilities", "capabilities", MMC_S_MODEM_LOCATION, }, + [MMC_F_LOCATION_ENABLED] = { "modem.location.enabled", "enabled", MMC_S_MODEM_LOCATION, }, + [MMC_F_LOCATION_SIGNALS] = { "modem.location.signals", "signals", MMC_S_MODEM_LOCATION, }, + [MMC_F_LOCATION_GPS_REFRESH_RATE] = { "modem.location.gps.refresh-rate", "refresh rate", MMC_S_MODEM_LOCATION_GPS, }, + [MMC_F_LOCATION_GPS_SUPL_SERVER] = { "modem.location.gps.supl-server", "a-gps supl server", MMC_S_MODEM_LOCATION_GPS, }, + [MMC_F_LOCATION_GPS_ASSISTANCE] = { "modem.location.gps.assistance", "supported assistance", MMC_S_MODEM_LOCATION_GPS, }, + [MMC_F_LOCATION_GPS_ASSISTANCE_SERVERS] = { "modem.location.gps.assistance-servers", "assistance servers", MMC_S_MODEM_LOCATION_GPS, }, + [MMC_F_LOCATION_3GPP_MCC] = { "modem.location.3gpp.mcc", "operator code", MMC_S_MODEM_LOCATION_3GPP, }, + [MMC_F_LOCATION_3GPP_MNC] = { "modem.location.3gpp.mnc", "operator name", MMC_S_MODEM_LOCATION_3GPP, }, + [MMC_F_LOCATION_3GPP_LAC] = { "modem.location.3gpp.lac", "location area code", MMC_S_MODEM_LOCATION_3GPP, }, + [MMC_F_LOCATION_3GPP_TAC] = { "modem.location.3gpp.tac", "tracking area code", MMC_S_MODEM_LOCATION_3GPP, }, + [MMC_F_LOCATION_3GPP_CID] = { "modem.location.3gpp.cid", "cell id", MMC_S_MODEM_LOCATION_3GPP, }, + [MMC_F_LOCATION_GPS_NMEA] = { "modem.location.gps.nmea", "nmea", MMC_S_MODEM_LOCATION_GPS, }, + [MMC_F_LOCATION_GPS_UTC] = { "modem.location.gps.utc", "utc", MMC_S_MODEM_LOCATION_GPS, }, + [MMC_F_LOCATION_GPS_LONG] = { "modem.location.gps.longitude", "longitude", MMC_S_MODEM_LOCATION_GPS, }, + [MMC_F_LOCATION_GPS_LAT] = { "modem.location.gps.latitude", "latitude", MMC_S_MODEM_LOCATION_GPS, }, + [MMC_F_LOCATION_GPS_ALT] = { "modem.location.gps.altitude", "altitude", MMC_S_MODEM_LOCATION_GPS, }, + [MMC_F_LOCATION_CDMABS_LONG] = { "modem.location.cdma-bs.longitude", "longitude", MMC_S_MODEM_LOCATION_CDMABS, }, + [MMC_F_LOCATION_CDMABS_LAT] = { "modem.location.cdma-bs.latitude", "latitude", MMC_S_MODEM_LOCATION_CDMABS, }, + [MMC_F_FIRMWARE_LIST] = { "modem.firmware-list", "list", MMC_S_MODEM_FIRMWARE, }, + [MMC_F_BEARER_GENERAL_DBUS_PATH] = { "bearer.dbus-path", "dbus path", MMC_S_BEARER_GENERAL, }, + [MMC_F_BEARER_STATUS_CONNECTED] = { "bearer.status.connected", "connected", MMC_S_BEARER_STATUS, }, + [MMC_F_BEARER_STATUS_SUSPENDED] = { "bearer.status.suspended", "suspended", MMC_S_BEARER_STATUS, }, + [MMC_F_BEARER_STATUS_INTERFACE] = { "bearer.status.interface", "interface", MMC_S_BEARER_STATUS, }, + [MMC_F_BEARER_STATUS_IP_TIMEOUT] = { "bearer.status.ip-timeout", "ip timeout", MMC_S_BEARER_STATUS, }, + [MMC_F_BEARER_PROPERTIES_APN] = { "bearer.properties.apn", "apn", MMC_S_BEARER_PROPERTIES, }, + [MMC_F_BEARER_PROPERTIES_ROAMING] = { "bearer.properties.roaming", "roaming", MMC_S_BEARER_PROPERTIES, }, + [MMC_F_BEARER_PROPERTIES_IP_TYPE] = { "bearer.properties.ip-type", "ip type", MMC_S_BEARER_PROPERTIES, }, + [MMC_F_BEARER_PROPERTIES_USER] = { "bearer.properties.user", "user", MMC_S_BEARER_PROPERTIES, }, + [MMC_F_BEARER_PROPERTIES_PASSWORD] = { "bearer.properties.password", "password", MMC_S_BEARER_PROPERTIES, }, + [MMC_F_BEARER_PROPERTIES_NUMBER] = { "bearer.properties.number", "number", MMC_S_BEARER_PROPERTIES, }, + [MMC_F_BEARER_PROPERTIES_RM_PROTOCOL] = { "bearer.properties.rm-protocol", "rm protocol", MMC_S_BEARER_PROPERTIES, }, + [MMC_F_BEARER_IPV4_CONFIG_METHOD] = { "bearer.ipv4-config.method", "method", MMC_S_BEARER_IPV4_CONFIG, }, + [MMC_F_BEARER_IPV4_CONFIG_ADDRESS] = { "bearer.ipv4-config.address", "address", MMC_S_BEARER_IPV4_CONFIG, }, + [MMC_F_BEARER_IPV4_CONFIG_PREFIX] = { "bearer.ipv4-config.prefix", "prefix", MMC_S_BEARER_IPV4_CONFIG, }, + [MMC_F_BEARER_IPV4_CONFIG_GATEWAY] = { "bearer.ipv4-config.gateway", "gateway", MMC_S_BEARER_IPV4_CONFIG, }, + [MMC_F_BEARER_IPV4_CONFIG_DNS] = { "bearer.ipv4-config.dns", "dns", MMC_S_BEARER_IPV4_CONFIG, }, + [MMC_F_BEARER_IPV4_CONFIG_MTU] = { "bearer.ipv4-config.mtu", "mtu", MMC_S_BEARER_IPV4_CONFIG, }, + [MMC_F_BEARER_IPV6_CONFIG_METHOD] = { "bearer.ipv6-config.method", "method", MMC_S_BEARER_IPV6_CONFIG, }, + [MMC_F_BEARER_IPV6_CONFIG_ADDRESS] = { "bearer.ipv6-config.address", "address", MMC_S_BEARER_IPV6_CONFIG, }, + [MMC_F_BEARER_IPV6_CONFIG_PREFIX] = { "bearer.ipv6-config.prefix", "prefix", MMC_S_BEARER_IPV6_CONFIG, }, + [MMC_F_BEARER_IPV6_CONFIG_GATEWAY] = { "bearer.ipv6-config.gateway", "gateway", MMC_S_BEARER_IPV6_CONFIG, }, + [MMC_F_BEARER_IPV6_CONFIG_DNS] = { "bearer.ipv6-config.dns", "dns", MMC_S_BEARER_IPV6_CONFIG, }, + [MMC_F_BEARER_IPV6_CONFIG_MTU] = { "bearer.ipv6-config.mtu", "mtu", MMC_S_BEARER_IPV6_CONFIG, }, + [MMC_F_BEARER_STATS_DURATION] = { "bearer.stats.duration", "duration", MMC_S_BEARER_STATS, }, + [MMC_F_BEARER_STATS_BYTES_RX] = { "bearer.stats.bytes-rx", "bytes rx", MMC_S_BEARER_STATS, }, + [MMC_F_BEARER_STATS_BYTES_TX] = { "bearer.stats.bytes-tx", "bytes tx", MMC_S_BEARER_STATS, }, + [MMC_F_CALL_GENERAL_DBUS_PATH] = { "call.dbus-path", "dbus path", MMC_S_CALL_GENERAL, }, + [MMC_F_CALL_PROPERTIES_NUMBER] = { "call.properties.number", "number", MMC_S_CALL_PROPERTIES, }, + [MMC_F_CALL_PROPERTIES_DIRECTION] = { "call.properties.direction", "direction", MMC_S_CALL_PROPERTIES, }, + [MMC_F_CALL_PROPERTIES_STATE] = { "call.properties.state", "state", MMC_S_CALL_PROPERTIES, }, + [MMC_F_CALL_PROPERTIES_STATE_REASON] = { "call.properties.state-reason", "state reason", MMC_S_CALL_PROPERTIES, }, + [MMC_F_CALL_PROPERTIES_AUDIO_PORT] = { "call.properties.audio-port", "audio port", MMC_S_CALL_PROPERTIES, }, + [MMC_F_CALL_AUDIO_FORMAT_ENCODING] = { "call.audio-format.encoding", "encoding", MMC_S_CALL_AUDIO_FORMAT, }, + [MMC_F_CALL_AUDIO_FORMAT_RESOLUTION] = { "call.audio-format.resolution", "resolution", MMC_S_CALL_AUDIO_FORMAT, }, + [MMC_F_CALL_AUDIO_FORMAT_RATE] = { "call.audio-format.rate", "rate", MMC_S_CALL_AUDIO_FORMAT, }, + [MMC_F_SMS_GENERAL_DBUS_PATH] = { "sms.dbus-path", "dbus path", MMC_S_SMS_GENERAL, }, + [MMC_F_SMS_CONTENT_NUMBER] = { "sms.content.number", "number", MMC_S_SMS_CONTENT, }, + [MMC_F_SMS_CONTENT_TEXT] = { "sms.content.text", "text", MMC_S_SMS_CONTENT, }, + [MMC_F_SMS_CONTENT_DATA] = { "sms.content.data", "data", MMC_S_SMS_CONTENT, }, + [MMC_F_SMS_PROPERTIES_PDU_TYPE] = { "sms.properties.pdu-type", "pdu type", MMC_S_SMS_PROPERTIES, }, + [MMC_F_SMS_PROPERTIES_STATE] = { "sms.properties.state", "state", MMC_S_SMS_PROPERTIES, }, + [MMC_F_SMS_PROPERTIES_VALIDITY] = { "sms.properties.validity", "validity", MMC_S_SMS_PROPERTIES, }, + [MMC_F_SMS_PROPERTIES_STORAGE] = { "sms.properties.storage", "storage", MMC_S_SMS_PROPERTIES, }, + [MMC_F_SMS_PROPERTIES_SMSC] = { "sms.properties.smsc", "smsc", MMC_S_SMS_PROPERTIES, }, + [MMC_F_SMS_PROPERTIES_CLASS] = { "sms.properties.class", "class", MMC_S_SMS_PROPERTIES, }, + [MMC_F_SMS_PROPERTIES_TELESERVICE_ID] = { "sms.properties.teleservice-id", "teleservice id", MMC_S_SMS_PROPERTIES, }, + [MMC_F_SMS_PROPERTIES_SERVICE_CATEGORY] = { "sms.properties.service-category", "service category", MMC_S_SMS_PROPERTIES, }, + [MMC_F_SMS_PROPERTIES_DELIVERY_REPORT] = { "sms.properties.delivery-report", "delivery report", MMC_S_SMS_PROPERTIES, }, + [MMC_F_SMS_PROPERTIES_MSG_REFERENCE] = { "sms.properties.message-reference", "message reference", MMC_S_SMS_PROPERTIES, }, + [MMC_F_SMS_PROPERTIES_TIMESTAMP] = { "sms.properties.timestamp", "timestamp", MMC_S_SMS_PROPERTIES, }, + [MMC_F_SMS_PROPERTIES_DELIVERY_STATE] = { "sms.properties.delivery-state", "delivery state", MMC_S_SMS_PROPERTIES, }, + [MMC_F_SMS_PROPERTIES_DISCH_TIMESTAMP] = { "sms.properties.discharge-timestamp", "discharge timestamp", MMC_S_SMS_PROPERTIES, }, + [MMC_F_SIM_GENERAL_DBUS_PATH] = { "sim.dbus-path", "dbus path", MMC_S_SIM_GENERAL, }, + [MMC_F_SIM_PROPERTIES_IMSI] = { "sim.properties.imsi", "imsi", MMC_S_SIM_PROPERTIES, }, + [MMC_F_SIM_PROPERTIES_ICCID] = { "sim.properties.iccid", "iccid", MMC_S_SIM_PROPERTIES, }, + [MMC_F_SIM_PROPERTIES_OPERATOR_ID] = { "sim.properties.operator-code", "operator id", MMC_S_SIM_PROPERTIES, }, + [MMC_F_SIM_PROPERTIES_OPERATOR_NAME] = { "sim.properties.operator-name", "operator name", MMC_S_SIM_PROPERTIES, }, + [MMC_F_MODEM_LIST_DBUS_PATH] = { "modem-list", "modems", MMC_S_UNKNOWN, }, + [MMC_F_SMS_LIST_DBUS_PATH] = { "modem.messaging.sms", "sms messages", MMC_S_UNKNOWN, }, + [MMC_F_CALL_LIST_DBUS_PATH] = { "modem.voice.call", "calls", MMC_S_UNKNOWN, }, +}; + +/******************************************************************************/ +/* Output type selection */ + +static MmcOutputType selected_type = MMC_OUTPUT_TYPE_NONE; + +void +mmcli_output_set (MmcOutputType type) +{ + selected_type = type; +} + +MmcOutputType +mmcli_output_get (void) +{ + return selected_type; +} + +/******************************************************************************/ +/* Generic output management */ + +typedef enum { + VALUE_TYPE_SINGLE, + VALUE_TYPE_MULTIPLE, + VALUE_TYPE_LISTITEM, +} ValueType; + +typedef struct { + MmcF field; + ValueType type; +} OutputItem; + +typedef struct { + OutputItem base; + gchar *value; +} OutputItemSingle; + +typedef struct { + OutputItem base; + gchar **values; + gboolean multiline; +} OutputItemMultiple; + +typedef struct { + OutputItem base; + gchar *prefix; + gchar *value; + gchar *extra; +} OutputItemListitem; + +static GList *output_items; + +static void +output_item_free (OutputItem *item) +{ + switch (item->type) { + case VALUE_TYPE_SINGLE: + g_free (((OutputItemSingle *)item)->value); + g_slice_free (OutputItemSingle, (OutputItemSingle *)item); + break; + case VALUE_TYPE_MULTIPLE: + g_strfreev (((OutputItemMultiple *)item)->values); + g_slice_free (OutputItemMultiple, (OutputItemMultiple *)item); + break; + case VALUE_TYPE_LISTITEM: + g_free (((OutputItemListitem *)item)->prefix); + g_free (((OutputItemListitem *)item)->value); + g_free (((OutputItemListitem *)item)->extra); + break; + } +} + +static gboolean +filter_out_value (const gchar *value) +{ + return (!g_strcmp0 (value, "unknown") || !g_strcmp0 (value, "none")); +} + +static void +output_item_new_take_single (MmcF field, + gchar *value) +{ + OutputItemSingle *item; + + item = g_slice_new0 (OutputItemSingle); + item->base.field = field; + item->base.type = VALUE_TYPE_SINGLE; + + if (filter_out_value (value)) + g_free (value); + else + item->value = value; + + output_items = g_list_prepend (output_items, item); +} + +static void +output_item_new_take_multiple (MmcF field, + gchar **values, + gboolean multiline) +{ + OutputItemMultiple *item; + + item = g_slice_new0 (OutputItemMultiple); + item->base.field = field; + item->base.type = VALUE_TYPE_MULTIPLE; + item->multiline = multiline; + + if (values && (g_strv_length (values) == 1) && filter_out_value (values[0])) + g_strfreev (values); + else + item->values = values; + + output_items = g_list_prepend (output_items, item); +} + +static void +output_item_new_take_listitem (MmcF field, + gchar *prefix, + gchar *value, + gchar *extra) +{ + OutputItemListitem *item; + + item = g_slice_new0 (OutputItemListitem); + item->base.field = field; + item->base.type = VALUE_TYPE_LISTITEM; + item->prefix = prefix; + item->value = value; + item->extra = extra; + + output_items = g_list_prepend (output_items, item); +} + +void +mmcli_output_string_list (MmcF field, + const gchar *str) +{ + gchar **split; + + split = str ? g_strsplit (str, ",", -1) : NULL; + if (split) { + guint i; + for (i = 0; split[i]; i++) + g_strstrip (split[i]); + } + + output_item_new_take_multiple (field, split, FALSE); +} + +void +mmcli_output_string_list_take (MmcF field, + gchar *str) +{ + mmcli_output_string_list (field, str); + g_free (str); +} + +void +mmcli_output_string_multiline (MmcF field, + const gchar *str) +{ + gchar **split; + + split = str ? g_strsplit (str, "\n", -1) : NULL; + if (split) { + guint i; + for (i = 0; split[i]; i++) + g_strstrip (split[i]); + } + + output_item_new_take_multiple (field, split, TRUE); +} + +void +mmcli_output_string_multiline_take (MmcF field, + gchar *str) +{ + mmcli_output_string_multiline (field, str); + g_free (str); +} + +void +mmcli_output_string_array (MmcF field, + const gchar **strv, + gboolean multiline) +{ + output_item_new_take_multiple (field, g_strdupv ((gchar **)strv), multiline); +} + +void +mmcli_output_string_array_take (MmcF field, + gchar **strv, + gboolean multiline) +{ + output_item_new_take_multiple (field, strv, multiline); +} + +void +mmcli_output_string (MmcF field, + const gchar *str) +{ + output_item_new_take_single (field, g_strdup (str)); +} + +void +mmcli_output_string_take (MmcF field, + gchar *str) +{ + output_item_new_take_single (field, str); +} + +void +mmcli_output_string_take_typed (MmcF field, + gchar *value, + const gchar *type) +{ + if (value && selected_type == MMC_OUTPUT_TYPE_HUMAN) { + gchar *aux; + + aux = g_strdup_printf ("%s %s", value, type); + g_free (value); + output_item_new_take_single (field, aux); + return; + } + + output_item_new_take_single (field, value); +} + +void +mmcli_output_listitem (MmcF field, + const gchar *prefix, + const gchar *value, + const gchar *extra) +{ + output_item_new_take_listitem (field, g_strdup (prefix), g_strdup (value), g_strdup (extra)); +} + +/******************************************************************************/ +/* (Custom) Signal quality output */ + +void +mmcli_output_signal_quality (guint value, + gboolean recent) +{ + /* Merge value and recent flag in a single item in human output */ + if (selected_type == MMC_OUTPUT_TYPE_HUMAN) { + output_item_new_take_single (MMC_F_STATUS_SIGNAL_QUALITY_VALUE, + g_strdup_printf ("%u%% (%s)", value, recent ? "recent" : "cached")); + return; + } + + output_item_new_take_single (MMC_F_STATUS_SIGNAL_QUALITY_VALUE, + g_strdup_printf ("%u", value)); + output_item_new_take_single (MMC_F_STATUS_SIGNAL_QUALITY_RECENT, + g_strdup_printf ("%s", recent ? "yes" : "no")); +} + +/******************************************************************************/ +/* (Custom) State output */ + +void +mmcli_output_state (MMModemState state, + MMModemStateFailedReason reason) +{ +#define KNRM "\x1B[0m" +#define KRED "\x1B[31m" +#define KGRN "\x1B[32m" +#define KYEL "\x1B[33m" + + if (selected_type == MMC_OUTPUT_TYPE_HUMAN) { + if (state == MM_MODEM_STATE_FAILED) + output_item_new_take_single (MMC_F_STATUS_STATE, g_strdup_printf (KRED "%s" KNRM, mm_modem_state_get_string (state))); + else if (state == MM_MODEM_STATE_CONNECTED) + output_item_new_take_single (MMC_F_STATUS_STATE, g_strdup_printf (KGRN "%s" KNRM, mm_modem_state_get_string (state))); + else if (state == MM_MODEM_STATE_CONNECTING) + output_item_new_take_single (MMC_F_STATUS_STATE, g_strdup_printf (KYEL "%s" KNRM, mm_modem_state_get_string (state))); + else + output_item_new_take_single (MMC_F_STATUS_STATE, g_strdup (mm_modem_state_get_string (state))) ; + + if (state == MM_MODEM_STATE_FAILED) + output_item_new_take_single (MMC_F_STATUS_FAILED_REASON, + g_strdup_printf (KRED "%s" KNRM, mm_modem_state_failed_reason_get_string (reason))); + return; + } + + output_item_new_take_single (MMC_F_STATUS_STATE, g_strdup (mm_modem_state_get_string (state))); + output_item_new_take_single (MMC_F_STATUS_FAILED_REASON, + (state == MM_MODEM_STATE_FAILED) ? + g_strdup (mm_modem_state_failed_reason_get_string (reason)) : + NULL); +} + +/******************************************************************************/ +/* (Custom) Network scan output */ + +static gchar * +build_network_info (MMModem3gppNetwork *network) +{ + const gchar *operator_code; + const gchar *operator_name; + gchar *access_technologies; + const gchar *availability; + gchar *out; + + operator_code = mm_modem_3gpp_network_get_operator_code (network); + operator_name = mm_modem_3gpp_network_get_operator_long (network); + if (!operator_name) + operator_name = mm_modem_3gpp_network_get_operator_short (network); + access_technologies = mm_modem_access_technology_build_string_from_mask (mm_modem_3gpp_network_get_access_technology (network)); + availability = mm_modem_3gpp_network_availability_get_string (mm_modem_3gpp_network_get_availability (network)); + + if (selected_type == MMC_OUTPUT_TYPE_HUMAN) + out = g_strdup_printf ("%s - %s (%s, %s)", + operator_code ? operator_code : "code n/a", + operator_name ? operator_name : "name n/a", + access_technologies, + availability); + else + out = g_strdup_printf ("operator-code: %s, operator-name: %s, access-technologies: %s, availability: %s", + operator_code ? operator_code : "--", + operator_name ? operator_name : "--", + access_technologies, + availability); + g_free (access_technologies); + + return out; +} + +void +mmcli_output_scan_networks (GList *network_list) +{ + gchar **networks = NULL; + + if (network_list) { + GPtrArray *aux; + GList *l; + + aux = g_ptr_array_new (); + for (l = network_list; l; l = g_list_next (l)) + g_ptr_array_add (aux, build_network_info ((MMModem3gppNetwork *)(l->data))); + g_ptr_array_add (aux, NULL); + networks = (gchar **) g_ptr_array_free (aux, FALSE); + } + + /* When printing human result, we want to show some result even if no networks + * are found, so we force a explicit string result. */ + if (selected_type == MMC_OUTPUT_TYPE_HUMAN && !networks) + output_item_new_take_single (MMC_F_3GPP_SCAN_NETWORKS, g_strdup ("n/a")); + else + output_item_new_take_multiple (MMC_F_3GPP_SCAN_NETWORKS, networks, TRUE); +} + +/******************************************************************************/ +/* (Custom) Firmware list output */ + +static void +build_firmware_info_human (GPtrArray *array, + MMFirmwareProperties *props, + gboolean selected) +{ + g_ptr_array_add (array, g_strdup (mm_firmware_properties_get_unique_id (props))); + g_ptr_array_add (array, g_strdup_printf ("\tcurrent: %s", selected ? "yes" : "no")); + + if (mm_firmware_properties_get_image_type (props) == MM_FIRMWARE_IMAGE_TYPE_GOBI) { + const gchar *aux; + + if ((aux = mm_firmware_properties_get_gobi_pri_version (props)) != NULL) + g_ptr_array_add (array, g_strdup_printf ("\tgobi pri version: %s", aux)); + if ((aux = mm_firmware_properties_get_gobi_pri_info (props)) != NULL) + g_ptr_array_add (array, g_strdup_printf ("\tgobi pri info: %s", aux)); + if ((aux = mm_firmware_properties_get_gobi_boot_version (props)) != NULL) + g_ptr_array_add (array, g_strdup_printf ("\tgobi boot version: %s", aux)); + if ((aux = mm_firmware_properties_get_gobi_pri_unique_id (props)) != NULL) + g_ptr_array_add (array, g_strdup_printf ("\tgobi pri unique id: %s", aux)); + if ((aux = mm_firmware_properties_get_gobi_modem_unique_id (props)) != NULL) + g_ptr_array_add (array, g_strdup_printf ("\tgobi modem unique id: %s", aux)); + } +} + +static void +build_firmware_info_keyvalue (GPtrArray *array, + MMFirmwareProperties *props, + gboolean selected) +{ + GString *str; + + str = g_string_new (""); + g_string_append_printf (str, "unique-id: %s", mm_firmware_properties_get_unique_id (props)); + g_string_append_printf (str, ", current: %s", selected ? "yes" : "no"); + + if (mm_firmware_properties_get_image_type (props) == MM_FIRMWARE_IMAGE_TYPE_GOBI) { + const gchar *aux; + + if ((aux = mm_firmware_properties_get_gobi_pri_version (props)) != NULL) + g_string_append_printf (str, ", gobi-pri-version: %s", aux); + if ((aux = mm_firmware_properties_get_gobi_pri_info (props)) != NULL) + g_string_append_printf (str, ", gobi-pri-info: %s", aux); + if ((aux = mm_firmware_properties_get_gobi_boot_version (props)) != NULL) + g_string_append_printf (str, ", gobi-boot-version: %s", aux); + if ((aux = mm_firmware_properties_get_gobi_pri_unique_id (props)) != NULL) + g_string_append_printf (str, ", gobi-pri-unique id: %s", aux); + if ((aux = mm_firmware_properties_get_gobi_modem_unique_id (props)) != NULL) + g_string_append_printf (str, ", gobi-modem-unique id: %s", aux); + } + + g_ptr_array_add (array, g_string_free (str, FALSE)); +} + +void +mmcli_output_firmware_list (GList *firmware_list, + MMFirmwareProperties *selected) +{ + gchar **firmwares = NULL; + + if (firmware_list) { + GPtrArray *aux; + GList *l; + + aux = g_ptr_array_new (); + for (l = firmware_list; l; l = g_list_next (l)) { + MMFirmwareProperties *props = (MMFirmwareProperties *)(l->data); + gboolean current_selected; + + current_selected = (selected && + g_str_equal (mm_firmware_properties_get_unique_id (props), + mm_firmware_properties_get_unique_id (selected))); + + if (selected_type == MMC_OUTPUT_TYPE_HUMAN) + build_firmware_info_human (aux, props, current_selected); + else + build_firmware_info_keyvalue (aux, props, current_selected); + } + g_ptr_array_add (aux, NULL); + firmwares = (gchar **) g_ptr_array_free (aux, FALSE); + } + + /* When printing human result, we want to show some result even if no firmwares + * are found, so we force a explicit string result. */ + if (selected_type == MMC_OUTPUT_TYPE_HUMAN && !firmwares) + output_item_new_take_single (MMC_F_FIRMWARE_LIST, g_strdup ("n/a")); + else + output_item_new_take_multiple (MMC_F_FIRMWARE_LIST, firmwares, TRUE); +} + +/******************************************************************************/ +/* (Custom) PCO list output */ + +void +mmcli_output_pco_list (GList *pco_list) +{ + GPtrArray *aux; + GList *l; + + if (!pco_list) { + output_item_new_take_single (MMC_F_3GPP_PCO, NULL); + return; + } + + aux = g_ptr_array_new (); + for (l = pco_list; l; l = g_list_next (l)) { + MMPco *pco; + gchar *pco_data_hex; + const guint8 *pco_data; + gsize pco_data_size; + + pco = MM_PCO (l->data); + pco_data = mm_pco_get_data (pco, &pco_data_size); + pco_data_hex = (pco_data ? mm_utils_bin2hexstr (pco_data, pco_data_size) : NULL); + + if (selected_type == MMC_OUTPUT_TYPE_HUMAN) + g_ptr_array_add (aux, g_strdup_printf ("%u: (%s) '%s'\n", + mm_pco_get_session_id (pco), + mm_pco_is_complete (pco) ? "complete" : "partial", + pco_data_hex ? pco_data_hex : "")); + else + g_ptr_array_add (aux, g_strdup_printf ("session-id: %u, complete: %s, data: %s\n", + mm_pco_get_session_id (pco), + mm_pco_is_complete (pco) ? "yes" : "no", + pco_data_hex ? pco_data_hex : "")); + g_free (pco_data_hex); + } + g_ptr_array_add (aux, NULL); + + output_item_new_take_multiple (MMC_F_3GPP_PCO, (gchar **) g_ptr_array_free (aux, FALSE), TRUE); +} + +/******************************************************************************/ +/* Human-friendly output */ + +#define HUMAN_MAX_VALUE_LENGTH 60 + +static gint +list_sort_human (const OutputItem *item_a, + const OutputItem *item_b) +{ + if (field_infos[item_a->field].section < field_infos[item_b->field].section) + return -1; + if (field_infos[item_a->field].section > field_infos[item_b->field].section) + return 1; + return item_a->field - item_b->field; +} + +static void +dump_output_human (void) +{ + GList *l; + MmcS current_section = MMC_S_UNKNOWN; + guint longest_section_name = 0; + guint longest_field_name = 0; + + output_items = g_list_sort (output_items, (GCompareFunc) list_sort_human); + + /* First pass to process */ + for (l = output_items; l; l = g_list_next (l)) { + OutputItem *item_l; + guint aux; + gboolean ignore = FALSE; + + item_l = (OutputItem *)(l->data); + + /* Post-process values */ + if (item_l->type == VALUE_TYPE_SINGLE) { + OutputItemSingle *single = (OutputItemSingle *)item_l; + + if (!single->value) + ignore = TRUE; + } else if (item_l->type == VALUE_TYPE_MULTIPLE) { + OutputItemMultiple *multiple = (OutputItemMultiple *)item_l; + + if (!multiple->values) + ignore = TRUE; + } + + /* Compute max lengths */ + if (!ignore) { + aux = strlen (section_infos[field_infos[item_l->field].section].name); + if (aux > longest_section_name) + longest_section_name = aux; + aux = strlen (field_infos[item_l->field].name); + if (aux > longest_field_name) + longest_field_name = aux; + } + } + + /* Second pass to print */ + for (l = output_items; l; l = g_list_next (l)) { + OutputItem *item_l; + OutputItemSingle *single = NULL; + OutputItemMultiple *multiple = NULL; + + item_l = (OutputItem *)(l->data); + if (item_l->type == VALUE_TYPE_SINGLE) + single = (OutputItemSingle *)item_l; + else if (item_l->type == VALUE_TYPE_MULTIPLE) + multiple = (OutputItemMultiple *)item_l; + else + g_assert_not_reached (); + + /* Ignore items without a value set */ + if ((single && (!single->value || !single->value[0])) || + (multiple && !multiple->values)) + continue; + + /* Section change? */ + if (field_infos[item_l->field].section != current_section) { + current_section = field_infos[item_l->field].section; + g_print (" %.*s\n", + longest_section_name + longest_field_name + 4, + "------------------------------------------------------------"); + g_print (" %-*.*s | ", + longest_section_name, + longest_section_name, + section_infos[field_infos[item_l->field].section].name); + } else + g_print (" %*.*s | ", + longest_section_name, + longest_section_name, + ""); + + g_print ("%*.*s: ", + longest_field_name, longest_field_name, field_infos[item_l->field].name); + + if (single) { + gchar **split_lines; + guint i; + + split_lines = g_strsplit (single->value, "\n", -1); + for (i = 0; split_lines[i]; i++) { + if (i != 0) { + g_print (" %*.*s | %*.*s ", + longest_section_name, longest_section_name, "", + longest_field_name, longest_field_name, ""); + } + g_print ("%s\n", split_lines[i]); + } + g_strfreev (split_lines); + } else if (multiple) { + guint line_length = 0; + guint n, i; + + n = multiple->values ? g_strv_length (multiple->values) : 0; + for (i = 0; i < n; i++) { + const gchar *value; + guint value_length; + + value = multiple->values[i]; + value_length = strlen (value) + ((i < (n - 1)) ? 2 : 0); + if ((multiple->multiline && i != 0) || ((line_length + value_length) > HUMAN_MAX_VALUE_LENGTH)) { + line_length = 0; + g_print ("\n" + " %*.*s | %*.*s ", + longest_section_name, longest_section_name, "", + longest_field_name, longest_field_name, ""); + } else + line_length += value_length; + g_print ("%s%s", value, (!multiple->multiline && i < (n - 1)) ? ", " : ""); + } + g_print ("\n"); + } + } +} + +static void +dump_output_list_human (MmcF field) +{ + GList *l; + guint n; + + g_assert (field != MMC_F_UNKNOWN); + + /* First pass to process */ + for (n = 0, l = output_items; l; l = g_list_next (l), n++) { + OutputItem *item_l; + OutputItemListitem *listitem; + + item_l = (OutputItem *)(l->data); + g_assert (item_l->type == VALUE_TYPE_LISTITEM); + listitem = (OutputItemListitem *)item_l; + g_assert (listitem->value); + + /* All items must be of same type */ + g_assert_cmpint (item_l->field, ==, field); + } + + /* Second pass to print */ + if (n == 0) { + g_print ("No %s were found\n", field_infos[field].name); + return; + } + for (l = output_items; l; l = g_list_next (l)) { + OutputItemListitem *listitem; + + listitem = (OutputItemListitem *)(l->data); + g_print ("%s%s %s\n", listitem->prefix, listitem->value, listitem->extra); + } +} + +/******************************************************************************/ +/* Key-value output */ + +#define KEY_ARRAY_LENGTH_SUFFIX ".length" +#define KEY_ARRAY_VALUE_SUFFIX ".value" + +static gint +list_sort_keyvalue (const OutputItem *item_a, + const OutputItem *item_b) +{ + return item_a->field - item_b->field; +} + +static void +dump_output_keyvalue (void) +{ + GList *l; + guint longest_field_key = 0; + + output_items = g_list_sort (output_items, (GCompareFunc) list_sort_keyvalue); + + /* First pass to process */ + for (l = output_items; l; l = g_list_next (l)) { + OutputItem *item_l; + OutputItemMultiple *multiple = NULL; + guint key_length; + + item_l = (OutputItem *)(l->data); + if (item_l->type == VALUE_TYPE_MULTIPLE) + multiple = (OutputItemMultiple *)item_l; + + key_length = strlen (field_infos[item_l->field].key); + + /* when printing array contents, each item is given with an index, + * e.g.: something.value[1] + * The max length of the field will need to consider the array length + * in order to accommodate the length of the index. + */ + if (multiple) { + guint n; + + n = multiple->values ? g_strv_length (multiple->values) : 0; + if (n > 0) { + key_length += ((strlen (KEY_ARRAY_VALUE_SUFFIX)) + 3); + if (n > 10) + key_length++; + } + } + + if (key_length > longest_field_key) + longest_field_key = key_length; + } + + /* Second pass to print */ + for (l = output_items; l; l = g_list_next (l)) { + OutputItem *item_l; + OutputItemSingle *single = NULL; + OutputItemMultiple *multiple = NULL; + + item_l = (OutputItem *)(l->data); + if (item_l->type == VALUE_TYPE_SINGLE) + single = (OutputItemSingle *)item_l; + else if (item_l->type == VALUE_TYPE_MULTIPLE) + multiple = (OutputItemMultiple *)item_l; + else + g_assert_not_reached (); + + if (single) { + gchar *escaped = NULL; + + if (single->value) + escaped = g_strescape (single->value, NULL); + g_print ("%-*.*s : %s\n", + longest_field_key, longest_field_key, field_infos[item_l->field].key, + escaped ? escaped : "--"); + g_free (escaped); + } else if (multiple) { + guint n; + + n = multiple->values ? g_strv_length (multiple->values) : 0; + if (n > 0) { + guint i; + gchar *new_key; + + new_key = g_strdup_printf ("%s" KEY_ARRAY_LENGTH_SUFFIX, field_infos[item_l->field].key); + g_print ("%-*.*s : %u\n", longest_field_key, longest_field_key, new_key, n); + g_free (new_key); + + for (i = 0; i < n; i++) { + gchar *escaped = NULL; + + /* Printed indices start at 1 */ + new_key = g_strdup_printf ("%s" KEY_ARRAY_VALUE_SUFFIX "[%u]", field_infos[item_l->field].key, i + 1); + escaped = g_strescape (multiple->values[i], NULL); + g_print ("%-*.*s : %s\n", longest_field_key, longest_field_key, new_key, escaped); + g_free (escaped); + g_free (new_key); + } + } else + g_print ("%-*.*s : --\n", + longest_field_key, longest_field_key, field_infos[item_l->field].key); + } + } +} + +static void +dump_output_list_keyvalue (MmcF field) +{ + GList *l; + guint key_length; + guint n; + gchar *new_key; + + g_assert (field != MMC_F_UNKNOWN); + key_length = strlen (field_infos[field].key); + + /* First pass to process */ + for (n = 0, l = output_items; l; l = g_list_next (l), n++) { + OutputItem *item_l; + OutputItemListitem *listitem; + + item_l = (OutputItem *)(l->data); + g_assert (item_l->type == VALUE_TYPE_LISTITEM); + listitem = (OutputItemListitem *)item_l; + g_assert (listitem->value); + + /* All items must be of same type */ + g_assert_cmpint (item_l->field, ==, field); + } + + if (n > 0) { + key_length += ((strlen (KEY_ARRAY_VALUE_SUFFIX)) + 3); + if (n > 10) + key_length++; + } + + new_key = g_strdup_printf ("%s" KEY_ARRAY_LENGTH_SUFFIX, field_infos[field].key); + g_print ("%-*.*s : %u\n", key_length, key_length, new_key, n); + g_free (new_key); + + /* Second pass to print */ + for (n = 0, l = output_items; l; l = g_list_next (l), n++) { + OutputItemListitem *listitem; + + listitem = (OutputItemListitem *)(l->data); + new_key = g_strdup_printf ("%s" KEY_ARRAY_VALUE_SUFFIX "[%u]", field_infos[field].key, n + 1); + g_print ("%-*.*s : %s\n", + key_length, key_length, new_key, + listitem->value); + g_free (new_key); + } +} + +/******************************************************************************/ +/* Dump output */ + +void +mmcli_output_dump (void) +{ + switch (selected_type) { + case MMC_OUTPUT_TYPE_NONE: + break; + case MMC_OUTPUT_TYPE_HUMAN: + dump_output_human (); + break; + case MMC_OUTPUT_TYPE_KEYVALUE: + dump_output_keyvalue (); + break; + } + + g_list_free_full (output_items, (GDestroyNotify) output_item_free); + output_items = NULL; + + fflush (stdout); +} + +void +mmcli_output_list_dump (MmcF field) +{ + switch (selected_type) { + case MMC_OUTPUT_TYPE_NONE: + break; + case MMC_OUTPUT_TYPE_HUMAN: + dump_output_list_human (field); + break; + case MMC_OUTPUT_TYPE_KEYVALUE: + dump_output_list_keyvalue (field); + break; + } + + g_list_free_full (output_items, (GDestroyNotify) output_item_free); + output_items = NULL; + + fflush (stdout); +} diff --git a/cli/mmcli-output.h b/cli/mmcli-output.h new file mode 100644 index 000000000..374af66f0 --- /dev/null +++ b/cli/mmcli-output.h @@ -0,0 +1,324 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * mmcli -- Control modem status & access information from the command line + * + * 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) 2018 Aleksander Morgado <aleksander@aleksander.es> + */ + +#ifndef MMCLI_OUTPUT_H +#define MMCLI_OUTPUT_H + +#define _LIBMM_INSIDE_MMCLI +#include <libmm-glib.h> + +/******************************************************************************/ +/* List of sections (grouped fields) displayed in the human-friendly output */ + +typedef enum { + MMC_S_UNKNOWN = -1, + /* Modem object related sections */ + MMC_S_MODEM_GENERAL = 0, + MMC_S_MODEM_HARDWARE, + MMC_S_MODEM_SYSTEM, + MMC_S_MODEM_NUMBERS, + MMC_S_MODEM_STATUS, + MMC_S_MODEM_MODES, + MMC_S_MODEM_BANDS, + MMC_S_MODEM_IP, + MMC_S_MODEM_3GPP, + MMC_S_MODEM_3GPP_SCAN, + MMC_S_MODEM_3GPP_USSD, + MMC_S_MODEM_CDMA, + MMC_S_MODEM_SIM, + MMC_S_MODEM_BEARER, + MMC_S_MODEM_TIME, + MMC_S_MODEM_TIMEZONE, + MMC_S_MODEM_MESSAGING, + MMC_S_MODEM_SIGNAL, + MMC_S_MODEM_SIGNAL_CDMA1X, + MMC_S_MODEM_SIGNAL_EVDO, + MMC_S_MODEM_SIGNAL_GSM, + MMC_S_MODEM_SIGNAL_UMTS, + MMC_S_MODEM_SIGNAL_LTE, + MMC_S_MODEM_OMA, + MMC_S_MODEM_OMA_CURRENT, + MMC_S_MODEM_OMA_PENDING, + MMC_S_MODEM_LOCATION, + MMC_S_MODEM_LOCATION_3GPP, + MMC_S_MODEM_LOCATION_GPS, + MMC_S_MODEM_LOCATION_CDMABS, + MMC_S_MODEM_FIRMWARE, + MMC_S_BEARER_GENERAL, + MMC_S_BEARER_STATUS, + MMC_S_BEARER_PROPERTIES, + MMC_S_BEARER_IPV4_CONFIG, + MMC_S_BEARER_IPV6_CONFIG, + MMC_S_BEARER_STATS, + MMC_S_CALL_GENERAL, + MMC_S_CALL_PROPERTIES, + MMC_S_CALL_AUDIO_FORMAT, + MMC_S_SMS_GENERAL, + MMC_S_SMS_CONTENT, + MMC_S_SMS_PROPERTIES, + MMC_S_SIM_GENERAL, + MMC_S_SIM_PROPERTIES, +} MmcS; + +/******************************************************************************/ +/* List of fields */ + +typedef enum { + MMC_F_UNKNOWN = -1, + /* General section */ + MMC_F_GENERAL_DBUS_PATH = 0, + MMC_F_GENERAL_DEVICE_ID, + /* Hardware section */ + MMC_F_HARDWARE_MANUFACTURER, + MMC_F_HARDWARE_MODEL, + MMC_F_HARDWARE_REVISION, + MMC_F_HARDWARE_HW_REVISION, + MMC_F_HARDWARE_SUPPORTED_CAPABILITIES, + MMC_F_HARDWARE_CURRENT_CAPABILITIES, + MMC_F_HARDWARE_EQUIPMENT_ID, + /* System section */ + MMC_F_SYSTEM_DEVICE, + MMC_F_SYSTEM_DRIVERS, + MMC_F_SYSTEM_PLUGIN, + MMC_F_SYSTEM_PRIMARY_PORT, + MMC_F_SYSTEM_PORTS, + /* Numbers section */ + MMC_F_NUMBERS_OWN, + /* Status section */ + MMC_F_STATUS_LOCK, + MMC_F_STATUS_UNLOCK_RETRIES, + MMC_F_STATUS_STATE, + MMC_F_STATUS_FAILED_REASON, + MMC_F_STATUS_POWER_STATE, + MMC_F_STATUS_ACCESS_TECH, + MMC_F_STATUS_SIGNAL_QUALITY_VALUE, + MMC_F_STATUS_SIGNAL_QUALITY_RECENT, + /* Modes section */ + MMC_F_MODES_SUPPORTED, + MMC_F_MODES_CURRENT, + /* Bands section */ + MMC_F_BANDS_SUPPORTED, + MMC_F_BANDS_CURRENT, + /* IP section */ + MMC_F_IP_SUPPORTED, + /* 3GPP section */ + MMC_F_3GPP_IMEI, + MMC_F_3GPP_ENABLED_LOCKS, + MMC_F_3GPP_OPERATOR_ID, + MMC_F_3GPP_OPERATOR_NAME, + MMC_F_3GPP_REGISTRATION, + MMC_F_3GPP_EPS_UE_MODE, + MMC_F_3GPP_PCO, + /* 3GPP scan section */ + MMC_F_3GPP_SCAN_NETWORKS, + /* USSD section */ + MMC_F_3GPP_USSD_STATUS, + MMC_F_3GPP_USSD_NETWORK_REQUEST, + MMC_F_3GPP_USSD_NETWORK_NOTIFICATION, + /* CDMA section */ + MMC_F_CDMA_MEID, + MMC_F_CDMA_ESN, + MMC_F_CDMA_SID, + MMC_F_CDMA_NID, + MMC_F_CDMA_REGISTRATION_CDMA1X, + MMC_F_CDMA_REGISTRATION_EVDO, + MMC_F_CDMA_ACTIVATION, + /* SIM section */ + MMC_F_SIM_PATH, + /* Bearer section */ + MMC_F_BEARER_PATHS, + /* Time section */ + MMC_F_TIME_CURRENT, + MMC_F_TIMEZONE_CURRENT, + MMC_F_TIMEZONE_DST_OFFSET, + MMC_F_TIMEZONE_LEAP_SECONDS, + /* Messaging section */ + MMC_F_MESSAGING_SUPPORTED_STORAGES, + MMC_F_MESSAGING_DEFAULT_STORAGES, + /* Signal section */ + MMC_F_SIGNAL_REFRESH_RATE, + MMC_F_SIGNAL_CDMA1X_RSSI, + MMC_F_SIGNAL_CDMA1X_ECIO, + MMC_F_SIGNAL_EVDO_RSSI, + MMC_F_SIGNAL_EVDO_ECIO, + MMC_F_SIGNAL_EVDO_SINR, + MMC_F_SIGNAL_EVDO_IO, + MMC_F_SIGNAL_GSM_RSSI, + MMC_F_SIGNAL_UMTS_RSSI, + MMC_F_SIGNAL_UMTS_RSCP, + MMC_F_SIGNAL_UMTS_ECIO, + MMC_F_SIGNAL_LTE_RSSI, + MMC_F_SIGNAL_LTE_RSRQ, + MMC_F_SIGNAL_LTE_RSRP, + MMC_F_SIGNAL_LTE_SNR, + /* OMA section */ + MMC_F_OMA_FEATURES, + MMC_F_OMA_CURRENT_TYPE, + MMC_F_OMA_CURRENT_STATE, + MMC_F_OMA_PENDING_SESSIONS, + /* Location status section */ + MMC_F_LOCATION_CAPABILITIES, + MMC_F_LOCATION_ENABLED, + MMC_F_LOCATION_SIGNALS, + MMC_F_LOCATION_GPS_REFRESH_RATE, + MMC_F_LOCATION_GPS_SUPL_SERVER, + MMC_F_LOCATION_GPS_ASSISTANCE, + MMC_F_LOCATION_GPS_ASSISTANCE_SERVERS, + MMC_F_LOCATION_3GPP_MCC, + MMC_F_LOCATION_3GPP_MNC, + MMC_F_LOCATION_3GPP_LAC, + MMC_F_LOCATION_3GPP_TAC, + MMC_F_LOCATION_3GPP_CID, + MMC_F_LOCATION_GPS_NMEA, + MMC_F_LOCATION_GPS_UTC, + MMC_F_LOCATION_GPS_LONG, + MMC_F_LOCATION_GPS_LAT, + MMC_F_LOCATION_GPS_ALT, + MMC_F_LOCATION_CDMABS_LONG, + MMC_F_LOCATION_CDMABS_LAT, + /* Firmware list */ + MMC_F_FIRMWARE_LIST, + /* Bearer general section */ + MMC_F_BEARER_GENERAL_DBUS_PATH, + /* Bearer status section */ + MMC_F_BEARER_STATUS_CONNECTED, + MMC_F_BEARER_STATUS_SUSPENDED, + MMC_F_BEARER_STATUS_INTERFACE, + MMC_F_BEARER_STATUS_IP_TIMEOUT, + /* Bearer properties section */ + MMC_F_BEARER_PROPERTIES_APN, + MMC_F_BEARER_PROPERTIES_ROAMING, + MMC_F_BEARER_PROPERTIES_IP_TYPE, + MMC_F_BEARER_PROPERTIES_USER, + MMC_F_BEARER_PROPERTIES_PASSWORD, + MMC_F_BEARER_PROPERTIES_NUMBER, + MMC_F_BEARER_PROPERTIES_RM_PROTOCOL, + MMC_F_BEARER_IPV4_CONFIG_METHOD, + MMC_F_BEARER_IPV4_CONFIG_ADDRESS, + MMC_F_BEARER_IPV4_CONFIG_PREFIX, + MMC_F_BEARER_IPV4_CONFIG_GATEWAY, + MMC_F_BEARER_IPV4_CONFIG_DNS, + MMC_F_BEARER_IPV4_CONFIG_MTU, + MMC_F_BEARER_IPV6_CONFIG_METHOD, + MMC_F_BEARER_IPV6_CONFIG_ADDRESS, + MMC_F_BEARER_IPV6_CONFIG_PREFIX, + MMC_F_BEARER_IPV6_CONFIG_GATEWAY, + MMC_F_BEARER_IPV6_CONFIG_DNS, + MMC_F_BEARER_IPV6_CONFIG_MTU, + MMC_F_BEARER_STATS_DURATION, + MMC_F_BEARER_STATS_BYTES_RX, + MMC_F_BEARER_STATS_BYTES_TX, + MMC_F_CALL_GENERAL_DBUS_PATH, + MMC_F_CALL_PROPERTIES_NUMBER, + MMC_F_CALL_PROPERTIES_DIRECTION, + MMC_F_CALL_PROPERTIES_STATE, + MMC_F_CALL_PROPERTIES_STATE_REASON, + MMC_F_CALL_PROPERTIES_AUDIO_PORT, + MMC_F_CALL_AUDIO_FORMAT_ENCODING, + MMC_F_CALL_AUDIO_FORMAT_RESOLUTION, + MMC_F_CALL_AUDIO_FORMAT_RATE, + MMC_F_SMS_GENERAL_DBUS_PATH, + MMC_F_SMS_CONTENT_NUMBER, + MMC_F_SMS_CONTENT_TEXT, + MMC_F_SMS_CONTENT_DATA, + MMC_F_SMS_PROPERTIES_PDU_TYPE, + MMC_F_SMS_PROPERTIES_STATE, + MMC_F_SMS_PROPERTIES_VALIDITY, + MMC_F_SMS_PROPERTIES_STORAGE, + MMC_F_SMS_PROPERTIES_SMSC, + MMC_F_SMS_PROPERTIES_CLASS, + MMC_F_SMS_PROPERTIES_TELESERVICE_ID, + MMC_F_SMS_PROPERTIES_SERVICE_CATEGORY, + MMC_F_SMS_PROPERTIES_DELIVERY_REPORT, + MMC_F_SMS_PROPERTIES_MSG_REFERENCE, + MMC_F_SMS_PROPERTIES_TIMESTAMP, + MMC_F_SMS_PROPERTIES_DELIVERY_STATE, + MMC_F_SMS_PROPERTIES_DISCH_TIMESTAMP, + MMC_F_SIM_GENERAL_DBUS_PATH, + MMC_F_SIM_PROPERTIES_IMSI, + MMC_F_SIM_PROPERTIES_ICCID, + MMC_F_SIM_PROPERTIES_OPERATOR_ID, + MMC_F_SIM_PROPERTIES_OPERATOR_NAME, + /* Lists */ + MMC_F_MODEM_LIST_DBUS_PATH, + MMC_F_SMS_LIST_DBUS_PATH, + MMC_F_CALL_LIST_DBUS_PATH, +} MmcF; + +/******************************************************************************/ +/* Output type selection */ + +typedef enum { + MMC_OUTPUT_TYPE_NONE, + MMC_OUTPUT_TYPE_HUMAN, + MMC_OUTPUT_TYPE_KEYVALUE, +} MmcOutputType; + +void mmcli_output_set (MmcOutputType type); +MmcOutputType mmcli_output_get (void); + +/******************************************************************************/ +/* Generic output management */ + +void mmcli_output_string (MmcF field, + const gchar *str); +void mmcli_output_string_take (MmcF field, + gchar *str); +void mmcli_output_string_list (MmcF field, + const gchar *str); +void mmcli_output_string_list_take (MmcF field, + gchar *str); +void mmcli_output_string_multiline (MmcF field, + const gchar *str); +void mmcli_output_string_multiline_take (MmcF field, + gchar *str); +void mmcli_output_string_array (MmcF field, + const gchar **strv, + gboolean multiline); +void mmcli_output_string_array_take (MmcF field, + gchar **strv, + gboolean multiline); +void mmcli_output_string_take_typed (MmcF field, + gchar *value, + const gchar *type); +void mmcli_output_listitem (MmcF field, + const gchar *prefix, + const gchar *value, + const gchar *extra); + +/******************************************************************************/ +/* Custom output management */ + +void mmcli_output_signal_quality (guint value, + gboolean recent); +void mmcli_output_state (MMModemState state, + MMModemStateFailedReason reason); +void mmcli_output_scan_networks (GList *network_list); +void mmcli_output_firmware_list (GList *firmware_list, + MMFirmwareProperties *selected); +void mmcli_output_pco_list (GList *pco_list); + +/******************************************************************************/ +/* Dump output */ + +void mmcli_output_dump (void); +void mmcli_output_list_dump (MmcF field); + +#endif /* MMCLI_OUTPUT_H */ diff --git a/cli/mmcli-sim.c b/cli/mmcli-sim.c index c8713743a..d31f07cba 100644 --- a/cli/mmcli-sim.c +++ b/cli/mmcli-sim.c @@ -15,7 +15,7 @@ * 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) 2011 Aleksander Morgado <aleksander@gnu.org> + * Copyright (C) 2011-2018 Aleksander Morgado <aleksander@aleksander.es> */ #include "config.h" @@ -33,6 +33,7 @@ #include "mmcli.h" #include "mmcli-common.h" +#include "mmcli-output.h" /* Context */ typedef struct { @@ -157,22 +158,12 @@ mmcli_sim_shutdown (void) static void print_sim_info (MMSim *sim) { - /* Not the best thing to do, as we may be doing _get() calls twice, but - * easiest to maintain */ -#undef VALIDATE -#define VALIDATE(str) (str ? str : "unknown") - - g_print ("SIM '%s'\n", - mm_sim_get_path (sim)); - g_print (" -------------------------\n" - " Properties | imsi : '%s'\n" - " | id : '%s'\n" - " | operator id : '%s'\n" - " | operator name : '%s'\n", - VALIDATE (mm_sim_get_imsi (sim)), - VALIDATE (mm_sim_get_identifier (sim)), - VALIDATE (mm_sim_get_operator_identifier (sim)), - VALIDATE (mm_sim_get_operator_name (sim))); + mmcli_output_string (MMC_F_SIM_GENERAL_DBUS_PATH, mm_sim_get_path (sim)); + mmcli_output_string (MMC_F_SIM_PROPERTIES_IMSI, mm_sim_get_imsi (sim)); + mmcli_output_string (MMC_F_SIM_PROPERTIES_ICCID, mm_sim_get_identifier (sim)); + mmcli_output_string (MMC_F_SIM_PROPERTIES_OPERATOR_ID, mm_sim_get_operator_identifier (sim)); + mmcli_output_string (MMC_F_SIM_PROPERTIES_OPERATOR_NAME, mm_sim_get_operator_name (sim)); + mmcli_output_dump (); } static void diff --git a/cli/mmcli-sms.c b/cli/mmcli-sms.c index 1fd88178b..575e35440 100644 --- a/cli/mmcli-sms.c +++ b/cli/mmcli-sms.c @@ -33,6 +33,7 @@ #include "mmcli.h" #include "mmcli-common.h" +#include "mmcli-output.h" /* Context */ typedef struct { @@ -147,89 +148,49 @@ mmcli_sms_shutdown (void) static void print_sms_info (MMSms *sms) { - MMSmsPduType pdu_type; - const guint8 *data; - gsize data_size; - - /* Not the best thing to do, as we may be doing _get() calls twice, but - * easiest to maintain */ -#undef VALIDATE -#define VALIDATE(str) (str ? str : "unknown") - - pdu_type = mm_sms_get_pdu_type (sms); - - g_print ("SMS '%s'\n", - mm_sms_get_path (sms)); - g_print (" -----------------------------------\n" - " Content | number: '%s'\n", - VALIDATE (mm_sms_get_number (sms))); - - if (mm_sms_get_text (sms)) - g_print (" | text: '%s'\n", - VALIDATE (mm_sms_get_text (sms))); - - data = mm_sms_get_data (sms, &data_size); - if (data) { - gchar *data_hex; - - data_hex = mm_utils_bin2hexstr (data, data_size); - g_print (" | data: '%s'\n", - VALIDATE (data_hex)); - g_free (data_hex); - } - - g_print (" -----------------------------------\n" - " Properties | PDU type: '%s'\n" - " | state: '%s'\n", - mm_sms_pdu_type_get_string (pdu_type), - mm_sms_state_get_string (mm_sms_get_state (sms))); - + MMSmsPduType pdu_type; + gchar *data = NULL; + const guint8 *databin; + gsize databin_size; + gchar *validity = NULL; + gchar *class = NULL; + const gchar *delivery_report = NULL; + gchar *message_reference = NULL; + const gchar *delivery_state = NULL; + + databin = mm_sms_get_data (sms, &databin_size); + if (databin) + data = mm_utils_bin2hexstr (databin, databin_size); if (mm_sms_get_validity_type (sms) == MM_SMS_VALIDITY_TYPE_RELATIVE) - g_print (" | validity (relative): '%u'\n", - mm_sms_get_validity_relative (sms)); - - g_print (" | storage: '%s'\n", - mm_sms_storage_get_string (mm_sms_get_storage (sms))); - - /* Print properties which are set, regardless of the pdu type */ - - if (mm_sms_get_smsc (sms)) - g_print (" | smsc: '%s'\n", - mm_sms_get_smsc (sms)); - + validity = g_strdup_printf ("%u", mm_sms_get_validity_relative (sms)); if (mm_sms_get_class (sms) >= 0) - g_print (" | class: '%d'\n", - mm_sms_get_class (sms)); - - if (mm_sms_get_teleservice_id (sms) != MM_SMS_CDMA_TELESERVICE_ID_UNKNOWN) - g_print (" | teleservice id: '%s'\n", - mm_sms_cdma_teleservice_id_get_string (mm_sms_get_teleservice_id (sms))); - - if (mm_sms_get_service_category (sms) != MM_SMS_CDMA_SERVICE_CATEGORY_UNKNOWN) - g_print (" | service category: '%s'\n", - mm_sms_cdma_service_category_get_string (mm_sms_get_service_category (sms))); - - /* Delivery report request just in 3GPP submit PDUs */ + class = g_strdup_printf ("%d", mm_sms_get_class (sms)); + pdu_type = mm_sms_get_pdu_type (sms); if (pdu_type == MM_SMS_PDU_TYPE_SUBMIT) - g_print (" | delivery report: '%s'\n", - mm_sms_get_delivery_report_request (sms) ? "requested" : "not requested"); - + delivery_report = mm_sms_get_delivery_report_request (sms) ? "requested" : "not requested"; if (mm_sms_get_message_reference (sms) != 0) - g_print (" | message reference: '%u'\n", - mm_sms_get_message_reference (sms)); - - if (mm_sms_get_timestamp (sms)) - g_print (" | timestamp: '%s'\n", - mm_sms_get_timestamp (sms)); - + message_reference = g_strdup_printf ("%u", mm_sms_get_message_reference (sms)); if (mm_sms_get_delivery_state (sms) != MM_SMS_DELIVERY_STATE_UNKNOWN) - g_print (" | delivery state: '%s' (0x%X)\n", - VALIDATE (mm_sms_delivery_state_get_string_extended (mm_sms_get_delivery_state (sms))), - mm_sms_get_delivery_state (sms)); - - if (mm_sms_get_discharge_timestamp (sms)) - g_print (" | discharge timestamp: '%s'\n", - mm_sms_get_discharge_timestamp (sms)); + delivery_state = mm_sms_delivery_state_get_string_extended (mm_sms_get_delivery_state (sms)); + + mmcli_output_string (MMC_F_SMS_GENERAL_DBUS_PATH, mm_sms_get_path (sms)); + mmcli_output_string (MMC_F_SMS_CONTENT_NUMBER, mm_sms_get_number (sms)); + mmcli_output_string (MMC_F_SMS_CONTENT_TEXT, mm_sms_get_text (sms)); + mmcli_output_string_take (MMC_F_SMS_CONTENT_DATA, data); + mmcli_output_string (MMC_F_SMS_PROPERTIES_PDU_TYPE, mm_sms_pdu_type_get_string (pdu_type)); + mmcli_output_string (MMC_F_SMS_PROPERTIES_STATE, mm_sms_state_get_string (mm_sms_get_state (sms))); + mmcli_output_string_take (MMC_F_SMS_PROPERTIES_VALIDITY, validity); + mmcli_output_string (MMC_F_SMS_PROPERTIES_STORAGE, mm_sms_storage_get_string (mm_sms_get_storage (sms))); + mmcli_output_string (MMC_F_SMS_PROPERTIES_SMSC, mm_sms_get_smsc (sms)); + mmcli_output_string_take (MMC_F_SMS_PROPERTIES_CLASS, class); + mmcli_output_string (MMC_F_SMS_PROPERTIES_TELESERVICE_ID, mm_sms_cdma_teleservice_id_get_string (mm_sms_get_teleservice_id (sms))); + mmcli_output_string (MMC_F_SMS_PROPERTIES_SERVICE_CATEGORY, mm_sms_cdma_service_category_get_string (mm_sms_get_service_category (sms))); + mmcli_output_string (MMC_F_SMS_PROPERTIES_DELIVERY_REPORT, delivery_report); + mmcli_output_string (MMC_F_SMS_PROPERTIES_MSG_REFERENCE, message_reference); + mmcli_output_string (MMC_F_SMS_PROPERTIES_TIMESTAMP, mm_sms_get_timestamp (sms)); + mmcli_output_string (MMC_F_SMS_PROPERTIES_DELIVERY_STATE, delivery_state); + mmcli_output_string (MMC_F_SMS_PROPERTIES_DISCH_TIMESTAMP, mm_sms_get_discharge_timestamp (sms)); + mmcli_output_dump (); } static void diff --git a/cli/mmcli.c b/cli/mmcli.c index 7349b2151..80b9e656b 100644 --- a/cli/mmcli.c +++ b/cli/mmcli.c @@ -34,6 +34,7 @@ #include "mmcli.h" #include "mmcli-common.h" +#include "mmcli-output.h" #define PROGRAM_NAME "mmcli" #define PROGRAM_VERSION PACKAGE_VERSION @@ -43,12 +44,17 @@ static GMainLoop *loop; static GCancellable *cancellable; /* Context */ +static gboolean output_keyvalue_flag; static gboolean verbose_flag; static gboolean version_flag; static gboolean async_flag; static gint timeout = 30; /* by default, use 30s for all operations */ static GOptionEntry main_entries[] = { + { "output-keyvalue", 'K', 0, G_OPTION_ARG_NONE, &output_keyvalue_flag, + "Run action with machine-friendly key-value output", + NULL + }, { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose_flag, "Run action with verbose logs", NULL @@ -230,6 +236,16 @@ main (gint argc, gchar **argv) if (verbose_flag) g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MASK, log_handler, NULL); + /* Setup output */ + if (output_keyvalue_flag) { + if (verbose_flag) { + g_printerr ("error: cannot set verbose output in keyvalue output type\n"); + exit (EXIT_FAILURE); + } + mmcli_output_set (MMC_OUTPUT_TYPE_KEYVALUE); + } else + mmcli_output_set (MMC_OUTPUT_TYPE_HUMAN); + /* Setup signals */ signal (SIGINT, signals_handler); signal (SIGHUP, signals_handler); |