aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoic Poulain <loic.poulain@linaro.org>2020-11-06 05:18:18 -0500
committerLoic Poulain <loic.poulain@linaro.org>2020-11-06 05:18:35 -0500
commit5406be1836e16c0339f95f7dea038e69b9065bdf (patch)
tree7bb69af11bda0d16c9631b209171c3a6642d8edd
parentc8682b22567a1757cb68d861659a32ffc6d0ed63 (diff)
Rework exit path + coding style + some memleaks
Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
-rw-r--r--mhi-qmi-connect.c395
1 files changed, 242 insertions, 153 deletions
diff --git a/mhi-qmi-connect.c b/mhi-qmi-connect.c
index 4e4c5d1..b532cc8 100644
--- a/mhi-qmi-connect.c
+++ b/mhi-qmi-connect.c
@@ -42,7 +42,16 @@ static gboolean rmnet_setup_done;
static gchar *ip_route_dump;
static gboolean ping;
-static int exit_code;
+static int exit_reason;
+
+static void op_shutdown(int reason);
+
+enum {
+ SHUTDOWN_UNKNOWN,
+ SHUTDOWN_ERROR,
+ SHUTDOWN_KILLED,
+ SHUTDOWN_DISCONNECTED
+};
/* 16 - cleanup/exit operations */
@@ -53,6 +62,8 @@ static void release_client_ready(QmiDevice *dev, GAsyncResult *res)
static void release_qmi_clients(void)
{
+ connection_status = QMI_WDS_CONNECTION_STATUS_UNKNOWN;
+
if (QMI_IS_CLIENT(client_wda))
qmi_device_release_client(device, (QmiClient *)client_wda, 0, 5, cancellable,
(GAsyncReadyCallback) release_client_ready, NULL);
@@ -82,7 +93,7 @@ static void stop_rmnet(void)
if (!g_spawn_command_line_sync(cmdline, NULL, NULL, NULL, &error)) {
g_printerr("%s: %s\n", cmdline, error->message);
g_error_free(error);
- release_qmi_clients(); return;
+ return;
}
/* Set WWAN interface down */
@@ -90,7 +101,7 @@ static void stop_rmnet(void)
if (!g_spawn_command_line_sync(cmdline, NULL, NULL, NULL, &error)) {
g_printerr("%s: %s\n", cmdline, error->message);
g_error_free(error);
- release_qmi_clients(); return;
+ return;
}
/* del RMNET interface */
@@ -98,7 +109,7 @@ static void stop_rmnet(void)
if (!g_spawn_command_line_sync(cmdline, NULL, NULL, NULL, &error)) {
g_printerr("%s: %s\n", cmdline, error->message);
g_error_free(error);
- release_qmi_clients(); return;
+ return;
}
if (!default_route)
@@ -108,7 +119,7 @@ static void stop_rmnet(void)
if (!g_spawn_command_line_sync(cmdline, NULL, NULL, NULL, &error)) {
g_printerr("%s: %s\n", cmdline, error->message);
g_error_free(error);
- release_qmi_clients(); return;
+ return;
}
/* TODO: restore routing (default route) */
@@ -123,14 +134,16 @@ static void stop_network_ready(QmiClientWds *client, GAsyncResult *res)
if (!output) {
g_printerr("error: operation failed: %s\n", error->message);
g_error_free(error);
- release_qmi_clients(); return;
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
- if (!qmi_message_wds_stop_network_output_get_result (output, &error)) {
+ if (!qmi_message_wds_stop_network_output_get_result(output, &error)) {
g_printerr("error: couldn't stop network: %s\n", error->message);
g_error_free(error);
qmi_message_wds_stop_network_output_unref(output);
- release_qmi_clients(); return;
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
qmi_message_wds_stop_network_output_unref(output);
@@ -144,10 +157,13 @@ static void stop_network(void)
{
QmiMessageWdsStopNetworkInput *input;
- input = qmi_message_wds_stop_network_input_new ();
+ if (connection_status != QMI_WDS_CONNECTION_STATUS_CONNECTED)
+ return;
+
+ input = qmi_message_wds_stop_network_input_new();
qmi_message_wds_stop_network_input_set_packet_data_handle(input, packet_data_handle, NULL);
qmi_client_wds_stop_network(client_wds, input, 10, cancellable,
- (GAsyncReadyCallback)stop_network_ready, NULL);
+ (GAsyncReadyCallback)stop_network_ready, NULL);
qmi_message_wds_stop_network_input_unref(input);
}
@@ -161,14 +177,18 @@ static void get_packet_service_status_ready(QmiClientWds *client, GAsyncResult *
if (!output) {
g_printerr("error: operation failed: %s\n", error->message);
g_error_free(error);
- release_qmi_clients(); release_qmi_clients(); return;
+ connection_status = QMI_WDS_CONNECTION_STATUS_UNKNOWN;
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
if (!qmi_message_wds_get_packet_service_status_output_get_result(output, &error)) {
g_printerr("error: couldn't get packet service status: %s\n", error->message);
g_error_free(error);
qmi_message_wds_get_packet_service_status_output_unref(output);
- release_qmi_clients(); release_qmi_clients(); return;
+ connection_status = QMI_WDS_CONNECTION_STATUS_UNKNOWN;
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
qmi_message_wds_get_packet_service_status_output_get_connection_status(output, &connection_status, NULL);
@@ -177,8 +197,7 @@ static void get_packet_service_status_ready(QmiClientWds *client, GAsyncResult *
if (connection_status != QMI_WDS_CONNECTION_STATUS_CONNECTED) {
g_print("[%s] Connection status: '%s'\n", qmi_device_get_path_display(device),
qmi_wds_connection_status_get_string(connection_status));
- stop_rmnet();
- stop_network();
+ op_shutdown(SHUTDOWN_DISCONNECTED);
return;
}
@@ -215,7 +234,8 @@ static void setup_rmnet(void)
if (!g_spawn_command_line_sync(cmdline, NULL, NULL, NULL, &error)) {
g_printerr("%s: %s\n", cmdline, error->message);
g_error_free(error);
- release_qmi_clients(); return;
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
/* Add link */
@@ -224,7 +244,8 @@ static void setup_rmnet(void)
if (!g_spawn_command_line_sync(cmdline, NULL, NULL, NULL, &error)) {
g_printerr("%s: %s\n", cmdline, error->message);
g_error_free(error);
- release_qmi_clients(); return;
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
g_print("[%s] <rmnet_data%u> interface created\n", qmi_device_get_path_display(device), mux_id);
@@ -237,7 +258,8 @@ static void setup_rmnet(void)
if (!g_spawn_command_line_sync(cmdline, NULL, NULL, NULL, &error)) {
g_printerr("%s: %s\n", cmdline, error->message);
g_error_free(error);
- release_qmi_clients(); return;
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
g_print("[%s] <rmnet_data%u> interface IP is %s\n",
qmi_device_get_path_display(device), mux_id, ip4_addr);
@@ -249,7 +271,8 @@ static void setup_rmnet(void)
if (!g_spawn_command_line_sync(cmdline, NULL, NULL, NULL, &error)) {
g_printerr("%s: %s\n", cmdline, error->message);
g_error_free(error);
- release_qmi_clients(); return;
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
/* Set WWAN interface up */
@@ -257,7 +280,8 @@ static void setup_rmnet(void)
if (!g_spawn_command_line_sync(cmdline, NULL, NULL, NULL, &error)) {
g_printerr("%s: %s\n", cmdline, error->message);
g_error_free(error);
- release_qmi_clients(); return;
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
/* Set RMNET interface up */
@@ -265,7 +289,8 @@ static void setup_rmnet(void)
if (!g_spawn_command_line_sync(cmdline, NULL, NULL, NULL, &error)) {
g_printerr("%s: %s\n", cmdline, error->message);
g_error_free(error);
- release_qmi_clients(); return;
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
rmnet_setup_done = TRUE;
@@ -278,7 +303,8 @@ static void setup_rmnet(void)
if (!g_spawn_command_line_sync(cmdline, &ip_route_dump, NULL, NULL, &error)) {
g_printerr("%s: %s\n", cmdline, error->message);
g_error_free(error);
- release_qmi_clients(); return;
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
/* Set RMNET as default route */
@@ -286,7 +312,8 @@ static void setup_rmnet(void)
if (!g_spawn_command_line_sync(cmdline, NULL, NULL, NULL, &error)) {
g_printerr("%s: %s\n", cmdline, error->message);
g_error_free(error);
- release_qmi_clients(); return;
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
/* TODO: DNS */
@@ -301,21 +328,23 @@ static void get_current_settings_ready(QmiClientWds *client, GAsyncResult *res)
guint32 addr = 0;
struct in_addr in_addr_val;
- output = qmi_client_wds_get_current_settings_finish (client, res, &error);
+ output = qmi_client_wds_get_current_settings_finish(client, res, &error);
if (!output) {
g_printerr("error: operation failed: %s\n", error->message);
g_error_free (error);
- release_qmi_clients(); return;
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
- if (!qmi_message_wds_get_current_settings_output_get_result (output, &error)) {
+ if (!qmi_message_wds_get_current_settings_output_get_result(output, &error)) {
g_printerr("error: couldn't get current settings: %s\n", error->message);
- g_error_free (error);
- qmi_message_wds_get_current_settings_output_unref (output);
- release_qmi_clients(); return;
+ g_error_free(error);
+ qmi_message_wds_get_current_settings_output_unref(output);
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
- if (qmi_message_wds_get_current_settings_output_get_ip_family (output, &ip_family, NULL))
+ if (qmi_message_wds_get_current_settings_output_get_ip_family(output, &ip_family, NULL))
g_print("[%s] IP Family: %s\n", qmi_device_get_path_display(device),
((ip_family == QMI_WDS_IP_FAMILY_IPV4) ? "IPv4" :
((ip_family == QMI_WDS_IP_FAMILY_IPV6) ? "IPv6" :
@@ -324,21 +353,22 @@ static void get_current_settings_ready(QmiClientWds *client, GAsyncResult *res)
/* TODO */
if (ip_family == QMI_WDS_IP_FAMILY_IPV6) {
g_printerr("IPv6 not supported\n");
- release_qmi_clients(); return;
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
if (qmi_message_wds_get_current_settings_output_get_ipv4_address(output, &addr, NULL)) {
- in_addr_val.s_addr = GUINT32_TO_BE (addr);
- memset (ip4_addr, 0, sizeof (ip4_addr));
- inet_ntop (AF_INET, &in_addr_val, ip4_addr, sizeof (ip4_addr));
+ in_addr_val.s_addr = GUINT32_TO_BE(addr);
+ memset (ip4_addr, 0, sizeof(ip4_addr));
+ inet_ntop (AF_INET, &in_addr_val, ip4_addr, sizeof(ip4_addr));
g_print("[%s] IPv4 address: %s\n", qmi_device_get_path_display(device), ip4_addr);
}
if (qmi_message_wds_get_current_settings_output_get_primary_ipv4_dns_address(output, &addr, NULL)) {
- in_addr_val.s_addr = GUINT32_TO_BE (addr);
- memset (ip4_dns, 0, sizeof (ip4_dns));
- inet_ntop (AF_INET, &in_addr_val, ip4_dns, sizeof (ip4_dns));
- g_print ("[%s] IPv4 primary DNS: %s\n", qmi_device_get_path_display(device), ip4_dns);
+ in_addr_val.s_addr = GUINT32_TO_BE(addr);
+ memset(ip4_dns, 0, sizeof(ip4_dns));
+ inet_ntop(AF_INET, &in_addr_val, ip4_dns, sizeof(ip4_dns));
+ g_print("[%s] IPv4 primary DNS: %s\n", qmi_device_get_path_display(device), ip4_dns);
}
qmi_message_wds_get_current_settings_output_unref(output);
@@ -359,7 +389,8 @@ static void start_network_ready(QmiClientWds *client, GAsyncResult *res)
if (!output) {
g_printerr("error: operation failed: %s\n", error->message);
g_error_free(error);
- release_qmi_clients(); return;
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
if (!qmi_message_wds_start_network_output_get_result(output, &error)) {
@@ -372,7 +403,8 @@ static void start_network_ready(QmiClientWds *client, GAsyncResult *res)
g_printerr("error: couldn't start network: %s\n", error->message);
g_error_free(error);
- release_qmi_clients(); return;
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
qmi_message_wds_start_network_output_get_packet_data_handle(output, &packet_data_handle, NULL);
@@ -382,12 +414,12 @@ static void start_network_ready(QmiClientWds *client, GAsyncResult *res)
input = qmi_message_wds_get_current_settings_input_new();
qmi_message_wds_get_current_settings_input_set_requested_settings(input,
- (QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_DNS_ADDRESS |
- QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_GRANTED_QOS |
- QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_IP_ADDRESS |
- QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_GATEWAY_INFO |
- QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_MTU |
- QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_DOMAIN_NAME_LIST |
+ (QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_DNS_ADDRESS |
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_GRANTED_QOS |
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_IP_ADDRESS |
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_GATEWAY_INFO |
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_MTU |
+ QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_DOMAIN_NAME_LIST |
QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_IP_FAMILY),
NULL);
@@ -425,18 +457,20 @@ static void bind_mux_data_port_ready(QmiClientWds *client, GAsyncResult *res)
QmiMessageWdsBindMuxDataPortOutput *output;
GError *error = NULL;
- output = qmi_client_wds_bind_mux_data_port_finish (client, res, &error);
+ output = qmi_client_wds_bind_mux_data_port_finish(client, res, &error);
if (!output) {
- g_printerr ("error: operation failed: %s\n", error->message);
- g_error_free (error);
- release_qmi_clients(); return;
+ g_printerr("error: operation failed: %s\n", error->message);
+ g_error_free(error);
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
- if (!qmi_message_wds_bind_mux_data_port_output_get_result (output, &error)) {
- g_printerr ("error: couldn't bind mux data port: %s\n", error->message);
- g_error_free (error);
+ if (!qmi_message_wds_bind_mux_data_port_output_get_result(output, &error)) {
+ g_printerr("error: couldn't bind mux data port: %s\n", error->message);
+ g_error_free(error);
qmi_message_wds_bind_mux_data_port_output_unref(output);
- release_qmi_clients(); return;
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
qmi_message_wds_bind_mux_data_port_output_unref(output);
@@ -456,7 +490,9 @@ static void allocate_wds_client_ready(QmiDevice *dev, GAsyncResult *res)
if (!client_wds) {
g_printerr("error: couldn't create client for the '%s' service: %s\n",
"WDS", error->message);
- release_qmi_clients(); return;
+ g_error_free(error);
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
input = qmi_message_wds_bind_mux_data_port_input_new();
@@ -473,7 +509,7 @@ static void allocate_wds_client_ready(QmiDevice *dev, GAsyncResult *res)
}
/* 8 - Data format set, start WDS operations */
-static void set_data_format_ready (QmiClientWda *client, GAsyncResult *res)
+static void set_data_format_ready(QmiClientWda *client, GAsyncResult *res)
{
QmiMessageWdaSetDataFormatOutput *output;
GError *error = NULL;
@@ -482,16 +518,20 @@ static void set_data_format_ready (QmiClientWda *client, GAsyncResult *res)
if (!output) {
g_printerr("error: operation failed: %s\n", error->message);
g_error_free(error);
+ op_shutdown(SHUTDOWN_ERROR);
return;
}
- if (!qmi_message_wda_set_data_format_output_get_result (output, &error)) {
- g_printerr ("error: couldn't set data format: %s\n", error->message);
- g_error_free (error);
+ if (!qmi_message_wda_set_data_format_output_get_result(output, &error)) {
+ g_printerr("error: couldn't set data format: %s\n", error->message);
+ g_error_free(error);
qmi_message_wda_set_data_format_output_unref(output);
+ op_shutdown(SHUTDOWN_ERROR);
return;
}
+ qmi_message_wda_set_data_format_output_unref(output);
+
qmi_device_allocate_client(device, service_wds, QMI_CID_NONE, 10, cancellable,
(GAsyncReadyCallback)allocate_wds_client_ready, NULL);
}
@@ -504,9 +544,11 @@ static void allocate_wda_client_ready(QmiDevice *dev, GAsyncResult *res)
client_wda = (QmiClientWda *)qmi_device_allocate_client_finish(dev, res, &error);
if (!client_wda) {
- g_printerr ("error: couldn't create client for the '%s' service: %s\n",
+ g_printerr("error: couldn't create client for the '%s' service: %s\n",
"WDA", error->message);
- release_qmi_clients(); return;
+ g_error_free(error);
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
input = qmi_message_wda_set_data_format_input_new();
@@ -527,50 +569,51 @@ static void allocate_wda_client_ready(QmiDevice *dev, GAsyncResult *res)
qmi_client_wda_set_data_format(client_wda, input, 10, cancellable,
(GAsyncReadyCallback)set_data_format_ready, NULL);
+
+ qmi_message_wda_set_data_format_input_unref(input);
}
/* 6.3 - SIM PIN verified, start WDA operations */
static void verify_pin_ready(QmiClientUim *client, GAsyncResult *res)
{
- QmiMessageUimVerifyPinOutput *output;
- GError *error = NULL;
-
- output = qmi_client_uim_verify_pin_finish(client, res, &error);
- if (!output) {
- g_printerr ("error: operation failed: %s\n", error->message);
- g_error_free(error);
- release_qmi_clients(); return;
- }
-
- if (!qmi_message_uim_verify_pin_output_get_result (output, &error)) {
- guint8 verify_retries_left;
- guint8 unblock_retries_left;
-
- g_printerr("error: couldn't verify PIN: %s\n", error->message);
- g_error_free (error);
-
- if (qmi_message_uim_verify_pin_output_get_retries_remaining (
- output,
- &verify_retries_left,
- &unblock_retries_left,
- NULL)) {
- g_printerr("[%s] Retries left:\n"
- "\tVerify: %u\n"
- "\tUnblock: %u\n",
- qmi_device_get_path_display(device),
- verify_retries_left,
- unblock_retries_left);
- }
-
- qmi_message_uim_verify_pin_output_unref(output);
- release_qmi_clients(); return;
- }
-
- g_print("[%s] PIN verified successfully\n", qmi_device_get_path_display(device));
-
- qmi_message_uim_verify_pin_output_unref(output);
+ QmiMessageUimVerifyPinOutput *output;
+ GError *error = NULL;
+
+ output = qmi_client_uim_verify_pin_finish(client, res, &error);
+ if (!output) {
+ g_printerr("error: operation failed: %s\n", error->message);
+ g_error_free(error);
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
+ }
+
+ if (!qmi_message_uim_verify_pin_output_get_result(output, &error)) {
+ guint8 verify_retries_left;
+ guint8 unblock_retries_left;
+
+ g_printerr("error: couldn't verify PIN: %s\n", error->message);
+ g_error_free(error);
+
+ if (qmi_message_uim_verify_pin_output_get_retries_remaining(
+ output, &verify_retries_left, &unblock_retries_left, NULL)) {
+ g_printerr("[%s] Retries left:\n"
+ "\tVerify: %u\n"
+ "\tUnblock: %u\n",
+ qmi_device_get_path_display(device),
+ verify_retries_left,
+ unblock_retries_left);
+ }
+
+ qmi_message_uim_verify_pin_output_unref(output);
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
+ }
+
+ g_print("[%s] PIN verified successfully\n", qmi_device_get_path_display(device));
+
+ qmi_message_uim_verify_pin_output_unref(output);
- qmi_device_allocate_client(device, service_wda, QMI_CID_NONE, 10, cancellable,
+ qmi_device_allocate_client(device, service_wda, QMI_CID_NONE, 10, cancellable,
(GAsyncReadyCallback)allocate_wda_client_ready, NULL);
}
@@ -585,8 +628,9 @@ static void power_on_sim_ready(QmiClientUim *client, GAsyncResult *res)
output = qmi_client_uim_power_on_sim_finish(client_uim, res, &error);
if (!output) {
g_printerr("error: operation failed: %s\n", error->message);
- g_error_free (error);
- release_qmi_clients(); return;
+ g_error_free(error);
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
if (!qmi_message_uim_power_on_sim_output_get_result(output, &error) &&
@@ -594,7 +638,8 @@ static void power_on_sim_ready(QmiClientUim *client, GAsyncResult *res)
g_printerr("error: could not power on SIM: %s\n", error->message);
g_error_free(error);
qmi_message_uim_power_on_sim_output_unref(output);
- release_qmi_clients(); return;
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
qmi_message_uim_power_on_sim_output_unref(output);
@@ -603,10 +648,10 @@ static void power_on_sim_ready(QmiClientUim *client, GAsyncResult *res)
input = qmi_message_uim_verify_pin_input_new();
- dummy_aid = g_array_new (FALSE, FALSE, sizeof (guint8));
+ dummy_aid = g_array_new(FALSE, FALSE, sizeof(guint8));
qmi_message_uim_verify_pin_input_set_info(input, 1, sim1_pin_str, &error);
- qmi_message_uim_verify_pin_input_set_session (input, QMI_UIM_SESSION_TYPE_CARD_SLOT_1,
+ qmi_message_uim_verify_pin_input_set_session(input, QMI_UIM_SESSION_TYPE_CARD_SLOT_1,
dummy_aid, /* ignored */ &error);
qmi_client_uim_verify_pin(client, input, 10, cancellable,
@@ -625,9 +670,11 @@ static void allocate_uim_client_ready(QmiDevice *dev, GAsyncResult *res)
client_uim = (QmiClientUim *)qmi_device_allocate_client_finish(dev, res, &error);
if (!client_uim) {
- g_printerr ("error: couldn't create client for the '%s' service: %s\n",
+ g_printerr("error: couldn't create client for the '%s' service: %s\n",
"UIM", error->message);
- release_qmi_clients(); return;
+ g_error_free(error);
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
g_print("[%s] Powering SIM1...\n", qmi_device_get_path_display(device));
@@ -637,9 +684,9 @@ static void allocate_uim_client_ready(QmiDevice *dev, GAsyncResult *res)
qmi_message_uim_power_on_sim_input_set_slot(input, slot, &error);
qmi_client_uim_power_on_sim(client_uim, input, 10, cancellable,
- (GAsyncReadyCallback)power_on_sim_ready, NULL);
+ (GAsyncReadyCallback)power_on_sim_ready, NULL);
- qmi_message_uim_power_on_sim_input_unref(input);
+ qmi_message_uim_power_on_sim_input_unref(input);
}
/* 6 - Operating mode retrieved, start WDA operations */
@@ -651,24 +698,28 @@ static void get_operating_mode_ready(QmiClientDms *client, GAsyncResult *res)
output = qmi_client_dms_get_operating_mode_finish(client, res, &error);
if (!output) {
- g_printerr ("error: operation failed: %s\n", error->message);
- g_error_free (error);
- release_qmi_clients(); return;
+ g_printerr("error: operation failed: %s\n", error->message);
+ g_error_free(error);
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
if (!qmi_message_dms_get_operating_mode_output_get_result(output, &error)) {
- g_printerr ("error: couldn't get power state: %s\n", error->message);
- g_error_free (error);
+ g_printerr("error: couldn't get power state: %s\n", error->message);
+ g_error_free(error);
qmi_message_dms_get_operating_mode_output_unref(output);
- release_qmi_clients(); return;
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
qmi_message_dms_get_operating_mode_output_get_mode(output, &mode, NULL);
+ qmi_message_dms_get_operating_mode_output_unref(output);
if (mode != QMI_DMS_OPERATING_MODE_ONLINE) {
/* TODO put it online */
g_print("[%s] Modem is offline\n", qmi_device_get_path_display(device));
- release_qmi_clients(); return;
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
g_print("[%s] Modem is online\n", qmi_device_get_path_display(device));
@@ -689,9 +740,11 @@ static void allocate_dms_client_ready(QmiDevice *dev, GAsyncResult *res)
client_dms = (QmiClientDms *)qmi_device_allocate_client_finish(dev, res, &error);
if (!client_dms) {
- g_printerr ("error: couldn't create client for the '%s' service: %s\n",
+ g_printerr("error: couldn't create client for the '%s' service: %s\n",
"DMS", error->message);
- exit(EXIT_FAILURE);
+ g_error_free(error);
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
qmi_client_dms_get_operating_mode(client_dms, NULL, 10, cancellable,
@@ -705,7 +758,9 @@ static void device_open_ready(QmiDevice *dev, GAsyncResult *res)
if (!qmi_device_open_finish(dev, res, &error)) {
g_printerr("error: couldn't open the QmiDevice: %s\n", error->message);
- exit(EXIT_FAILURE);
+ g_error_free(error);
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
qmi_device_allocate_client(dev, service_dms, QMI_CID_NONE, 10, cancellable,
@@ -721,7 +776,9 @@ static void device_new_ready(GObject *unused, GAsyncResult *res)
device = qmi_device_new_finish(res, &error);
if (!device) {
g_printerr("error: couldn't create QmiDevice: %s\n", error->message);
- exit(EXIT_FAILURE);
+ g_error_free(error);
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
qmi_device_open(device, open_flags, 15, cancellable,
@@ -733,9 +790,11 @@ static void wait_for_services_ready(QrtrNode *node, GAsyncResult *res, gpointer
{
GError *error = NULL;
- if (!qrtr_node_wait_for_services_finish (node, res, &error)) {
+ if (!qrtr_node_wait_for_services_finish(node, res, &error)) {
g_printerr ("error: failed to wait for QRTR services: %s\n", error->message);
- exit(EXIT_FAILURE);
+ g_error_free(error);
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
qmi_device_new_from_node(node, cancellable, (GAsyncReadyCallback)device_new_ready, NULL);
@@ -751,25 +810,27 @@ static void qrtr_node_ready(GObject *unused, GAsyncResult *res)
node = qrtr_node_for_id_finish(res, &error);
if (!node) {
g_printerr("error: couldn't open QRTR node: %s\n", error->message);
- exit(EXIT_FAILURE);
+ g_error_free(error);
+ op_shutdown(SHUTDOWN_ERROR);
+ return;
}
services = g_array_sized_new(FALSE, FALSE, sizeof(QmiService), 10);
g_array_append_val(services, service_wda);
g_array_append_val(services, service_wds);
g_array_append_val(services, service_dms);
-
+
qrtr_node_wait_for_services(node, services, 5, NULL,
(GAsyncReadyCallback) wait_for_services_ready, NULL);
g_array_unref(services);
}
-/* X - Signals */
-static gboolean signals_handler(void)
+
+static void op_shutdown(int reason)
{
- /* TODO perform some nice cleanup here */
stop_rmnet();
+ stop_network();
release_qmi_clients();
if (loop && g_main_loop_is_running(loop)) {
@@ -777,6 +838,14 @@ static gboolean signals_handler(void)
g_idle_add((GSourceFunc)g_main_loop_quit, loop);
}
+ exit_reason = reason;
+}
+
+/* X - Signals */
+static gboolean signals_handler(void)
+{
+ op_shutdown(SHUTDOWN_KILLED);
+
return G_SOURCE_REMOVE;
}
@@ -794,63 +863,43 @@ static GOptionEntry main_entries[] = {
"QMAP/RMNET mux-id of the connection (default is 1)", NULL
},
{ "set-ip", 0, 0, G_OPTION_ARG_NONE, &set_ip,
- "Setup rmnet IP address and DNS from Bearer context info", NULL
- },
+ "Setup rmnet IP address and DNS from Bearer context info", NULL
+ },
{ "default-route", 0, 0, G_OPTION_ARG_NONE, &default_route,
"Set rmnet interface as the defaut network route", NULL
},
{ NULL }
};
-int main(int argc, char **argv)
+int mainloop(void)
{
- GOptionContext *context;
- GError *error = NULL;
GFile *qmi_file;
- context = g_option_context_new("");
-
- g_option_context_add_main_entries(context, main_entries, NULL);
- if (!g_option_context_parse(context, &argc, &argv, &error)) {
- g_printerr ("error: %s\n", error->message);
- exit(EXIT_FAILURE);
- }
- g_option_context_free(context);
-
- if (!apn_str) {
- g_printerr("error: no APN name\n");
- exit(EXIT_FAILURE);
- }
-
- if (default_route && !set_ip) {
- g_printerr("error: Cannot set --default-route without --set-ip option\n");
- exit(EXIT_FAILURE);
- }
-
if (qmi_dev) { /* Use MHI QMI character device */
gchar *id;
qmi_file = g_file_new_for_commandline_arg(qmi_dev);
id = g_file_get_path(qmi_file);
qmi_device_new(qmi_file, cancellable, (GAsyncReadyCallback)device_new_ready, NULL);
- g_free(id);
+ g_free(id);
} else { /* QMI services over IPCR/qrtr */
/* TODO: auto detect qrtr node via lookup */
/* For now qrtr modem services are always exposed via node 3 */
qrtr_node_for_id(3, 10, cancellable, (GAsyncReadyCallback)qrtr_node_ready, NULL);
}
+ exit_reason = SHUTDOWN_UNKNOWN;
+
/* Connect signals */
g_unix_signal_add(SIGINT, (GSourceFunc) signals_handler, NULL);
g_unix_signal_add(SIGHUP, (GSourceFunc) signals_handler, NULL);
g_unix_signal_add(SIGTERM, (GSourceFunc) signals_handler, NULL);
- exit_code = 0;
loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(loop);
if (cancellable)
- g_object_unref(cancellable);
+ g_object_unref(cancellable);
if (client_wda)
g_object_unref(client_wda);
if (client_wds)
@@ -864,5 +913,45 @@ int main(int argc, char **argv)
g_main_loop_unref(loop);
- return exit_code;
+ return exit_reason;
+}
+
+int main(int argc, char **argv)
+{
+ GOptionContext *context;
+ GError *error = NULL;
+ unsigned int ret;
+
+ context = g_option_context_new("");
+
+ g_option_context_add_main_entries(context, main_entries, NULL);
+ if (!g_option_context_parse(context, &argc, &argv, &error)) {
+ g_printerr("error: %s\n", error->message);
+ exit(EXIT_FAILURE);
+ }
+ g_option_context_free(context);
+
+ if (!apn_str) {
+ g_printerr("error: no APN name\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (default_route && !set_ip) {
+ g_printerr("error: Cannot set --default-route without --set-ip option\n");
+ exit(EXIT_FAILURE);
+ }
+
+ while (1) {
+ /* TODO try to reconnect on disconnect event */
+ ret = mainloop();
+ switch(ret) {
+ case SHUTDOWN_ERROR:
+ exit(EXIT_SUCCESS);
+ case SHUTDOWN_DISCONNECTED:
+ case SHUTDOWN_KILLED:
+ exit(EXIT_FAILURE);
+ default:
+ exit(EXIT_FAILURE);
+ }
+ }
}