[PATCH] bearer-qmi: print verbose PDN throttle info on call failure
Dan Williams
dcbw at redhat.com
Mon Jan 11 11:17:48 PST 2016
When a call fails due to throttling, request additional information
and log how long the APN is throttled for.
---
src/mm-bearer-qmi.c | 150 +++++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 120 insertions(+), 30 deletions(-)
diff --git a/src/mm-bearer-qmi.c b/src/mm-bearer-qmi.c
index 30fa2f9..a31452f 100644
--- a/src/mm-bearer-qmi.c
+++ b/src/mm-bearer-qmi.c
@@ -221,12 +221,12 @@ typedef enum {
CONNECT_STEP_WDS_CLIENT_IPV4,
CONNECT_STEP_IP_FAMILY_IPV4,
CONNECT_STEP_START_NETWORK_IPV4,
- CONNECT_STEP_GET_CURRENT_SETTINGS_IPV4,
+ CONNECT_STEP_NETWORK_RESULT_IPV4,
CONNECT_STEP_IPV6,
CONNECT_STEP_WDS_CLIENT_IPV6,
CONNECT_STEP_IP_FAMILY_IPV6,
CONNECT_STEP_START_NETWORK_IPV6,
- CONNECT_STEP_GET_CURRENT_SETTINGS_IPV6,
+ CONNECT_STEP_NETWORK_RESULT_IPV6,
CONNECT_STEP_LAST
} ConnectStep;
@@ -244,6 +244,10 @@ typedef struct {
gboolean no_ip_family_preference;
gboolean default_ip_family_set;
+ QmiWdsCallEndReason call_end_reason;
+ QmiWdsVerboseCallEndReasonType verbose_call_end_reason_type;
+ gint16 verbose_call_end_reason_reason;
+
gboolean ipv4;
gboolean running_ipv4;
QmiClientWds *client_ipv4;
@@ -328,28 +332,15 @@ start_network_ready (QmiClientWds *client,
if (g_error_matches (error,
QMI_PROTOCOL_ERROR,
QMI_PROTOCOL_ERROR_CALL_FAILED)) {
- QmiWdsCallEndReason cer;
- QmiWdsVerboseCallEndReasonType verbose_cer_type;
- gint16 verbose_cer_reason;
-
- if (qmi_message_wds_start_network_output_get_call_end_reason (
+ qmi_message_wds_start_network_output_get_call_end_reason (
output,
- &cer,
- NULL))
- mm_info ("call end reason (%u): '%s'",
- cer,
- qmi_wds_call_end_reason_get_string (cer));
-
- if (qmi_message_wds_start_network_output_get_verbose_call_end_reason (
+ &ctx->call_end_reason,
+ NULL);
+ qmi_message_wds_start_network_output_get_verbose_call_end_reason (
output,
- &verbose_cer_type,
- &verbose_cer_reason,
- NULL))
- mm_info ("verbose call end reason (%u,%d): [%s] %s",
- verbose_cer_type,
- verbose_cer_reason,
- qmi_wds_verbose_call_end_reason_type_get_string (verbose_cer_type),
- qmi_wds_verbose_call_end_reason_get_string (verbose_cer_type, verbose_cer_reason));
+ &ctx->verbose_call_end_reason_type,
+ &ctx->verbose_call_end_reason_reason,
+ NULL);
}
}
}
@@ -713,6 +704,99 @@ get_current_settings (ConnectContext *ctx, QmiClientWds *client)
}
static void
+get_throttle_info_ready (QmiClientWds *client,
+ GAsyncResult *res,
+ ConnectContext *ctx)
+{
+ GError *error = NULL;
+ QmiMessageWdsGetPdnThrottleInfoOutput *output;
+
+ g_assert (ctx->running_ipv4 || ctx->running_ipv6);
+
+ output = qmi_client_wds_get_pdn_throttle_info_finish (client, res, &error);
+ if (!output ||
+ !qmi_message_wds_get_pdn_throttle_info_output_get_result (output, &error)) {
+ /* Never treat this as a hard connection error; not all devices support
+ * "WDS Get PDN Throttle Info" */
+ mm_info ("error: couldn't get PDN throttle info: %s", error->message);
+ g_error_free (error);
+ } else {
+ GArray *array;
+ guint i;
+
+ if (qmi_message_wds_get_pdn_throttle_info_output_get_info (output, &array, &error)) {
+ mm_info ("PDN Throttle Info:");
+ for (i = 0; array && (i < array->len); i++) {
+ const QmiMessageWdsGetPdnThrottleInfoOutputInfoElement *item = &g_array_index (array, QmiMessageWdsGetPdnThrottleInfoOutputInfoElement, i);
+
+ mm_info (" APN: %s (IPv4: %ums, IPv6: %ums)",
+ item->apn,
+ item->ipv4_throttled ? item->ipv4_throttle_time_left_ms : 0,
+ item->ipv6_throttled ? item->ipv6_throttle_time_left_ms : 0);
+ }
+ } else {
+ mm_info ("error: failed to read PDN throttle info: %s", error ? error->message : "unknown");
+ g_clear_error (&error);
+ }
+ }
+
+ if (output)
+ qmi_message_wds_get_pdn_throttle_info_output_unref (output);
+
+ /* Keep on */
+ ctx->step++;
+ connect_context_step (ctx);
+}
+
+static void
+get_start_network_failure_info (ConnectContext *ctx, QmiClientWds *client)
+{
+ g_assert (ctx->running_ipv4 || ctx->running_ipv6);
+
+ if (ctx->call_end_reason != 0) {
+ mm_info ("%s call end reason (%u): '%s'",
+ ctx->running_ipv4 ? "IPv4" : "IPv6",
+ ctx->call_end_reason,
+ qmi_wds_call_end_reason_get_string (ctx->call_end_reason));
+ }
+
+ if (ctx->verbose_call_end_reason_type != 0) {
+ mm_info ("%s verbose call end reason (%u,%d): [%s] %s",
+ ctx->running_ipv4 ? "IPv4" : "IPv6",
+ ctx->verbose_call_end_reason_type,
+ ctx->verbose_call_end_reason_reason,
+ qmi_wds_verbose_call_end_reason_type_get_string (ctx->verbose_call_end_reason_type),
+ qmi_wds_verbose_call_end_reason_get_string (
+ ctx->verbose_call_end_reason_type,
+ ctx->verbose_call_end_reason_reason));
+ }
+
+ if (ctx->verbose_call_end_reason_type == QMI_WDS_VERBOSE_CALL_END_REASON_TYPE_INTERNAL &&
+ (ctx->verbose_call_end_reason_reason == QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_PDN_IPV4_CALL_THROTTLED ||
+ ctx->verbose_call_end_reason_reason == QMI_WDS_VERBOSE_CALL_END_REASON_INTERNAL_PDN_IPV6_CALL_THROTTLED)) {
+ QmiMessageWdsGetPdnThrottleInfoInput *input;
+
+ input = qmi_message_wds_get_pdn_throttle_info_input_new ();
+ qmi_message_wds_get_pdn_throttle_info_input_set_network_type (
+ input,
+ ctx->apn ? QMI_WDS_DATA_SYSTEM_NETWORK_TYPE_3GPP : QMI_WDS_DATA_SYSTEM_NETWORK_TYPE_3GPP2,
+ NULL);
+ qmi_client_wds_get_pdn_throttle_info (client,
+ input,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)get_throttle_info_ready,
+ ctx);
+ qmi_message_wds_get_pdn_throttle_info_input_unref (input);
+ return;
+ }
+
+ /* Keep on */
+ ctx->step++;
+ connect_context_step (ctx);
+}
+
+static void
set_ip_family_ready (QmiClientWds *client,
GAsyncResult *res,
ConnectContext *ctx)
@@ -902,15 +986,18 @@ connect_context_step (ConnectContext *ctx)
return;
}
- case CONNECT_STEP_GET_CURRENT_SETTINGS_IPV4: {
+ case CONNECT_STEP_NETWORK_RESULT_IPV4: {
/* Retrieve and print IP configuration */
if (ctx->packet_data_handle_ipv4) {
mm_dbg ("Getting IPv4 configuration...");
get_current_settings (ctx, ctx->client_ipv4);
- return;
+ } else if (ctx->call_end_reason) {
+ mm_dbg ("Getting IPv4 failure information...");
+ get_start_network_failure_info (ctx, ctx->client_ipv4);
+ } else {
+ /* Fall through */
+ ctx->step++;
}
- /* Fall through */
- ctx->step++;
}
case CONNECT_STEP_IPV6:
@@ -991,15 +1078,18 @@ connect_context_step (ConnectContext *ctx)
return;
}
- case CONNECT_STEP_GET_CURRENT_SETTINGS_IPV6: {
+ case CONNECT_STEP_NETWORK_RESULT_IPV6: {
/* Retrieve and print IP configuration */
if (ctx->packet_data_handle_ipv6) {
mm_dbg ("Getting IPv6 configuration...");
get_current_settings (ctx, ctx->client_ipv6);
- return;
+ } else if (ctx->call_end_reason) {
+ mm_dbg ("Getting IPv6 failure information...");
+ get_start_network_failure_info (ctx, ctx->client_ipv6);
+ } else {
+ /* Fall through */
+ ctx->step++;
}
- /* Fall through */
- ctx->step++;
}
case CONNECT_STEP_LAST:
--
2.4.3
More information about the ModemManager-devel
mailing list