aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cli/qmicli-wds.c29
-rw-r--r--src/qmi-client-wds.c30
-rw-r--r--src/qmi-client-wds.h17
-rw-r--r--src/qmi-message-wds.c446
-rw-r--r--src/qmi-message-wds.h10
-rw-r--r--src/qmi-wds.h30
6 files changed, 495 insertions, 67 deletions
diff --git a/cli/qmicli-wds.c b/cli/qmicli-wds.c
index f9f443e..7c13e35 100644
--- a/cli/qmicli-wds.c
+++ b/cli/qmicli-wds.c
@@ -174,14 +174,34 @@ start_network_ready (QmiClientWds *client,
GAsyncResult *res)
{
GError *error = NULL;
+ QmiWdsStartNetworkOutput *output;
- ctx->packet_data_handle = qmi_client_wds_start_network_finish (client, res, &error);
- if (!ctx->packet_data_handle) {
- g_printerr ("error: couldn't start network: %s\n",
+ output = qmi_client_wds_start_network_finish (client, res, &error);
+ if (!output) {
+ g_printerr ("error: operation failed: %s\n",
error->message);
exit (EXIT_FAILURE);
}
+ if (!qmi_wds_start_network_output_get_result (output, &error)) {
+ g_printerr ("error: couldn't start network: %s\n", error->message);
+ if (g_error_matches (error,
+ QMI_PROTOCOL_ERROR,
+ QMI_PROTOCOL_ERROR_CALL_FAILED)) {
+ guint16 cer;
+ guint16 domain;
+
+ if (qmi_wds_start_network_output_get_call_end_reason (output, &cer))
+ g_printerr ("call end reason: %u\n", cer);
+ if (qmi_wds_start_network_output_get_verbose_call_end_reason (output, &cer, &domain))
+ g_printerr ("verbose call end reason: %u, %u\n", domain, cer);
+ }
+
+ exit (EXIT_FAILURE);
+ }
+
+ qmi_wds_start_network_output_get_packet_data_handle (output, &ctx->packet_data_handle);
+
#undef VALIDATE_UNKNOWN
#define VALIDATE_UNKNOWN(str) (str ? str : "unknown")
@@ -195,6 +215,8 @@ start_network_ready (QmiClientWds *client,
G_CALLBACK (network_cancelled),
NULL,
NULL);
+
+ qmi_wds_start_network_output_unref (output);
}
static void
@@ -214,6 +236,7 @@ allocate_client_ready (QmiDevice *device,
if (start_network_flag) {
g_debug ("Asynchronously starting network...");
qmi_client_wds_start_network (ctx->client,
+ NULL, /* allow NULL input for now */
10,
ctx->cancellable,
(GAsyncReadyCallback)start_network_ready,
diff --git a/src/qmi-client-wds.c b/src/qmi-client-wds.c
index 6752526..3f784b5 100644
--- a/src/qmi-client-wds.c
+++ b/src/qmi-client-wds.c
@@ -30,15 +30,15 @@ G_DEFINE_TYPE (QmiClientWds, qmi_client_wds, QMI_TYPE_CLIENT);
/*****************************************************************************/
/* Start network */
-guint32
+QmiWdsStartNetworkOutput *
qmi_client_wds_start_network_finish (QmiClientWds *self,
GAsyncResult *res,
GError **error)
{
if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
- return 0; /* TODO: what would be a good invalid packet data handle? */
+ return NULL;
- return (guint32) GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
+ return qmi_wds_start_network_output_ref (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
}
static void
@@ -48,7 +48,7 @@ start_network_ready (QmiDevice *device,
{
GError *error = NULL;
QmiMessage *reply;
- guint32 result;
+ QmiWdsStartNetworkOutput *output;
reply = qmi_device_command_finish (device, res, &error);
if (!reply) {
@@ -59,19 +59,20 @@ start_network_ready (QmiDevice *device,
}
/* Parse reply */
- result = qmi_message_wds_start_network_reply_parse (reply, &error);
- if (!result)
+ output = qmi_message_wds_start_network_reply_parse (reply, &error);
+ if (!output)
g_simple_async_result_take_error (simple, error);
else
g_simple_async_result_set_op_res_gpointer (simple,
- GUINT_TO_POINTER (result),
- NULL);
+ output,
+ (GDestroyNotify)qmi_wds_start_network_output_unref);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
void
qmi_client_wds_start_network (QmiClientWds *self,
+ QmiWdsStartNetworkInput *input,
guint timeout,
GCancellable *cancellable,
GAsyncReadyCallback callback,
@@ -79,6 +80,7 @@ qmi_client_wds_start_network (QmiClientWds *self,
{
GSimpleAsyncResult *result;
QmiMessage *request;
+ GError *error = NULL;
result = g_simple_async_result_new (G_OBJECT (self),
callback,
@@ -86,7 +88,17 @@ qmi_client_wds_start_network (QmiClientWds *self,
qmi_client_wds_start_network);
request = qmi_message_wds_start_network_new (qmi_client_get_next_transaction_id (QMI_CLIENT (self)),
- qmi_client_get_cid (QMI_CLIENT (self)));
+ qmi_client_get_cid (QMI_CLIENT (self)),
+ input,
+ &error);
+ if (!request) {
+ g_prefix_error (&error, "Couldn't create request message: ");
+ g_simple_async_result_take_error (result, error);
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
+ return;
+ }
+
qmi_device_command (qmi_client_peek_device (QMI_CLIENT (self)),
request,
timeout,
diff --git a/src/qmi-client-wds.h b/src/qmi-client-wds.h
index 7ae0b40..7e81521 100644
--- a/src/qmi-client-wds.h
+++ b/src/qmi-client-wds.h
@@ -53,14 +53,15 @@ GType qmi_client_wds_get_type (void);
/*****************************************************************************/
/* Start network */
-void qmi_client_wds_start_network (QmiClientWds *self,
- guint timeout,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data);
-guint32 qmi_client_wds_start_network_finish (QmiClientWds *self,
- GAsyncResult *res,
- GError **error);
+void qmi_client_wds_start_network (QmiClientWds *self,
+ QmiWdsStartNetworkInput *input,
+ guint timeout,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+QmiWdsStartNetworkOutput *qmi_client_wds_start_network_finish (QmiClientWds *self,
+ GAsyncResult *res,
+ GError **error);
/*****************************************************************************/
/* Stop network */
diff --git a/src/qmi-message-wds.c b/src/qmi-message-wds.c
index a2b4d0b..74efaa4 100644
--- a/src/qmi-message-wds.c
+++ b/src/qmi-message-wds.c
@@ -21,6 +21,8 @@
* Copyright (C) 2012 Aleksander Morgado <aleksander@lanedo.com>
*/
+#include <string.h>
+
#include "qmi-message-wds.h"
#include "qmi-enums.h"
#include "qmi-error-types.h"
@@ -28,15 +30,227 @@
/*****************************************************************************/
/* Start network */
+enum {
+ QMI_WDS_TLV_START_NETWORK_APN = 0x14,
+ QMI_WDS_TLV_START_NETWORK_USERNAME = 0x17,
+ QMI_WDS_TLV_START_NETWORK_PASSWORD = 0x18,
+};
+
+/**
+ * QmiWdsStartNetworkInput:
+ *
+ * An opaque type handling the input arguments that may be passed to the Start
+ * Network operation in the WDS service.
+ */
+struct _QmiWdsStartNetworkInput {
+ volatile gint ref_count;
+ gchar *apn;
+ gchar *username;
+ gchar *password;
+};
+
+/**
+ * qmi_wds_start_network_input_set_apn:
+ * @input: a #QmiWdsStartNetworkInput.
+ * @str: a string with the APN.
+ *
+ * Set the APN to use.
+ */
+void
+qmi_wds_start_network_input_set_apn (QmiWdsStartNetworkInput *input,
+ const gchar *str)
+{
+ g_return_if_fail (input != NULL);
+
+ g_free (input->apn);
+ input->apn = (str ? g_strdup (str) : NULL);
+}
+
+/**
+ * qmi_wds_start_network_input_get_apn:
+ * @input: a #QmiWdsStartNetworkInput.
+ *
+ * Get the configured APN to use.
+ *
+ * Returns: a constant string with the APN, or #NULL if none set.
+ */
+const gchar *
+qmi_wds_start_network_input_get_apn (QmiWdsStartNetworkInput *input)
+{
+ g_return_val_if_fail (input != NULL, NULL);
+
+ return input->apn;
+}
+
+/**
+ * qmi_wds_start_network_input_set_username:
+ * @input: a #QmiWdsStartNetworkInput.
+ * @str: a string with the username.
+ *
+ * Set the username to use when authenticating with the network.
+ */
+void
+qmi_wds_start_network_input_set_username (QmiWdsStartNetworkInput *input,
+ const gchar *str)
+{
+ g_return_if_fail (input != NULL);
+
+ g_free (input->username);
+ input->username = (str ? g_strdup (str) : NULL);
+}
+
+/**
+ * qmi_wds_start_network_input_get_username:
+ * @input: a #QmiWdsStartNetworkInput.
+ *
+ * Get the configured username to use when authenticating with the network.
+ *
+ * Returns: a constant string with the username, or #NULL if none set.
+ */
+const gchar *
+qmi_wds_start_network_input_get_username (QmiWdsStartNetworkInput *input)
+{
+ g_return_val_if_fail (input != NULL, NULL);
+
+ return input->username;
+}
+
+/**
+ * qmi_wds_start_network_input_set_password:
+ * @input: a #QmiWdsStartNetworkInput.
+ * @str: a string with the password.
+ *
+ * Set the password to use when authenticating with the network.
+ */
+void
+qmi_wds_start_network_input_set_password (QmiWdsStartNetworkInput *input,
+ const gchar *str)
+{
+ g_return_if_fail (input != NULL);
+
+ g_free (input->password);
+ input->password = (str ? g_strdup (str) : NULL);
+}
+
+/**
+ * qmi_wds_start_network_input_get_password:
+ * @input: a #QmiWdsStartNetworkInput.
+ *
+ * Get the configured password to use when authenticating with the network.
+ *
+ * Returns: a constant string with the password, or #NULL if none set.
+ */
+const gchar *
+qmi_wds_start_network_input_get_password (QmiWdsStartNetworkInput *input)
+{
+ g_return_val_if_fail (input != NULL, NULL);
+
+ return input->password;
+}
+
+/**
+ * qmi_wds_start_network_input_new:
+ *
+ * Allocates a new #QmiWdsStartNetworkInput.
+ *
+ * Returns: the newly created #QmiWdsStartNetworkInput.
+ */
+QmiWdsStartNetworkInput *
+qmi_wds_start_network_input_new (void)
+{
+ return g_slice_new0 (QmiWdsStartNetworkInput);
+}
+
+/**
+ * qmi_wds_start_network_input_ref:
+ * @input: a #QmiWdsStartNetworkInput.
+ *
+ * Atomically increments the reference count of @input by one.
+ *
+ * Returns: the new reference to @input.
+ */
+QmiWdsStartNetworkInput *
+qmi_wds_start_network_input_ref (QmiWdsStartNetworkInput *input)
+{
+ g_return_val_if_fail (input != NULL, NULL);
+
+ g_atomic_int_inc (&input->ref_count);
+ return input;
+}
+
+/**
+ * qmi_wds_start_network_input_unref:
+ * @input: a #QmiWdsStartNetworkInput.
+ *
+ * Atomically decrements the reference count of @input by one.
+ * If the reference count drops to 0, @input is completely disposed.
+ */
+void
+qmi_wds_start_network_input_unref (QmiWdsStartNetworkInput *input)
+{
+ g_return_if_fail (input != NULL);
+
+ if (g_atomic_int_dec_and_test (&input->ref_count)) {
+ g_free (input->apn);
+ g_free (input->username);
+ g_free (input->password);
+ g_slice_free (QmiWdsStartNetworkInput, input);
+ }
+}
+
QmiMessage *
qmi_message_wds_start_network_new (guint8 transaction_id,
- guint8 client_id)
+ guint8 client_id,
+ QmiWdsStartNetworkInput *input,
+ GError **error)
{
- /* TODO: handle optional TLVs */
- return qmi_message_new (QMI_SERVICE_WDS,
- client_id,
- transaction_id,
- QMI_WDS_MESSAGE_START_NETWORK);
+ QmiMessage *message;
+
+ message = qmi_message_new (QMI_SERVICE_WDS,
+ client_id,
+ transaction_id,
+ QMI_WDS_MESSAGE_START_NETWORK);
+
+ /* If input arguments given, use them */
+ if (input) {
+ /* Add APN if any */
+ if (input->apn &&
+ !qmi_message_tlv_add (message,
+ QMI_WDS_TLV_START_NETWORK_APN,
+ strlen (input->apn) + 1,
+ input->apn,
+ error)) {
+ g_prefix_error (error, "Failed to add APN to message: ");
+ qmi_message_unref (message);
+ return NULL;
+ }
+
+ /* Add username if any */
+ if (input->username &&
+ !qmi_message_tlv_add (message,
+ QMI_WDS_TLV_START_NETWORK_USERNAME,
+ strlen (input->username) + 1,
+ input->username,
+ error)) {
+ g_prefix_error (error, "Failed to add username to message: ");
+ qmi_message_unref (message);
+ return NULL;
+ }
+
+ /* Add password if any */
+ if (input->password &&
+ !qmi_message_tlv_add (message,
+ QMI_WDS_TLV_START_NETWORK_PASSWORD,
+ strlen (input->password) + 1,
+ input->password,
+ error)) {
+ g_prefix_error (error, "Failed to add password to message: ");
+ qmi_message_unref (message);
+ return NULL;
+ }
+ }
+
+ return message;
}
enum {
@@ -45,81 +259,227 @@ enum {
START_NETWORK_OUTPUT_TLV_VERBOSE_CALL_END_REASON = 0x11
};
-struct verbose_call_end_reason {
- guint16 call_end_reason_type;
- guint16 call_end_reason;
-} __attribute__((__packed__));
+/**
+ * QmiWdsStartNetworkOutput:
+ *
+ * An opaque type handling the output of the Start Network operation.
+ */
+struct _QmiWdsStartNetworkOutput {
+ volatile gint ref_count;
+ GError *error;
+
+ gboolean packet_data_handle_set;
+ guint32 packet_data_handle;
+
+ gboolean call_end_reason_set;
+ guint16 call_end_reason;
+
+ gboolean verbose_call_end_reason_set;
+ guint16 verbose_call_end_reason_domain;
+ guint16 verbose_call_end_reason_value;
+};
+
+/**
+ * qmi_wds_start_network_output_get_result:
+ * @output: a #QmiWdsStartNetworkOutput.
+ * @error: a #GError.
+ *
+ * Get the result of the Start Network operation.
+ *
+ * Returns: #TRUE if the operation succeeded, and #FALSE if @error is set.
+ */
+gboolean
+qmi_wds_start_network_output_get_result (QmiWdsStartNetworkOutput *output,
+ GError **error)
+{
+ g_return_val_if_fail (output != NULL, FALSE);
+
+ if (output->error) {
+ if (error)
+ *error = g_error_copy (output->error);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * qmi_wds_start_network_output_get_packet_data_handle:
+ * @output: a #QmiWdsStartNetworkOutput.
+ * @packet_data_handle: location for the output packet data handle.
+ *
+ * Get the packet data handle on a successful Start Network operation.
+ *
+ * Returns: #TRUE if @packet_data_handle is set, #FALSE otherwise.
+ */
+gboolean
+qmi_wds_start_network_output_get_packet_data_handle (QmiWdsStartNetworkOutput *output,
+ guint32 *packet_data_handle)
+{
+ g_return_val_if_fail (output != NULL, FALSE);
+
+ if (output->packet_data_handle_set)
+ *packet_data_handle = output->packet_data_handle;
+ return output->packet_data_handle_set;
+}
+
+/**
+ * qmi_wds_start_network_output_get_call_end_reason:
+ * @output: a #QmiWdsStartNetworkOutput.
+ * @call_end_reason: location for the output call end reason.
+ *
+ * Get the call end reason, if the operation failed with a CALL_FAILED error.
+ * This field is optional.
+ *
+ * Returns: #TRUE if @call_end_reason is set, #FALSE otherwise.
+ */
+gboolean
+qmi_wds_start_network_output_get_call_end_reason (QmiWdsStartNetworkOutput *output,
+ guint16 *call_end_reason)
+{
+ g_return_val_if_fail (output != NULL, FALSE);
+
+ if (output->call_end_reason_set)
+ *call_end_reason = output->call_end_reason;
+ return output->call_end_reason_set;
+}
+
+/**
+ * qmi_wds_start_network_output_get_call_end_reason:
+ * @output: a #QmiWdsStartNetworkOutput.
+ * @verbose_call_end_reason_domain: location for the output call end reason domain.
+ * @verbose_call_end_reason_value: location for the output call end reason value.
+ *
+ * Get the verbose call end reason, if the operation failed with a CALL_FAILED error.
+ * This field is optional.
+ *
+ * Returns: #TRUE if @call_end_reason is set, #FALSE otherwise.
+ */
+gboolean
+qmi_wds_start_network_output_get_verbose_call_end_reason (QmiWdsStartNetworkOutput *output,
+ guint16 *verbose_call_end_reason_domain,
+ guint16 *verbose_call_end_reason_value)
+{
+ g_return_val_if_fail (output != NULL, FALSE);
+
+ if (output->verbose_call_end_reason_set) {
+ *verbose_call_end_reason_domain = output->verbose_call_end_reason_domain;
+ *verbose_call_end_reason_value = output->verbose_call_end_reason_value;
+ }
+ return output->call_end_reason_set;
+}
+
+/**
+ * qmi_wds_start_network_output_ref:
+ * @output: a #QmiWdsStartNetworkOutput.
+ *
+ * Atomically increments the reference count of @output by one.
+ *
+ * Returns: the new reference to @output.
+ */
+QmiWdsStartNetworkOutput *
+qmi_wds_start_network_output_ref (QmiWdsStartNetworkOutput *output)
+{
+ g_return_val_if_fail (output != NULL, NULL);
+
+ g_atomic_int_inc (&output->ref_count);
+ return output;
+}
+
+/**
+ * qmi_wds_start_network_output_unref:
+ * @output: a #QmiWdsStartNetworkOutput.
+ *
+ * Atomically decrements the reference count of @output by one.
+ * If the reference count drops to 0, @output is completely disposed.
+ */
+void
+qmi_wds_start_network_output_unref (QmiWdsStartNetworkOutput *output)
+{
+ g_return_if_fail (output != NULL);
-guint32
+ if (g_atomic_int_dec_and_test (&output->ref_count)) {
+ if (output->error)
+ g_error_free (output->error);
+ g_slice_free (QmiWdsStartNetworkOutput, output);
+ }
+}
+
+QmiWdsStartNetworkOutput *
qmi_message_wds_start_network_reply_parse (QmiMessage *self,
GError **error)
{
+ QmiWdsStartNetworkOutput *output;
GError *inner_error = NULL;
- guint32 packet_data_handle = 0;
g_assert (qmi_message_get_message_id (self) == QMI_WDS_MESSAGE_START_NETWORK);
- /* If we got a QMI error reported and is a CALL_FAILED one, try to gather
- * the call end reason */
if (!qmi_message_get_response_result (self, &inner_error)) {
- /* On CALL_FAILED errors, we can try to get more info on the reason */
- if (g_error_matches (inner_error,
+ /* Only QMI protocol errors are set in the Output result, all the
+ * others (e.g. failures parsing) are directly propagated to error. */
+ if (inner_error->domain != QMI_PROTOCOL_ERROR) {
+ g_propagate_error (error, inner_error);
+ return NULL;
+ }
+
+ /* Otherwise, build output */
+ }
+
+ output = g_slice_new0 (QmiWdsStartNetworkOutput);
+ output->error = inner_error;
+
+ /* On CALL_FAILED errors, we can try to get more info on the reason */
+ if (output->error) {
+ if (g_error_matches (output->error,
QMI_PROTOCOL_ERROR,
QMI_PROTOCOL_ERROR_CALL_FAILED)) {
guint16 cer = 0;
- struct verbose_call_end_reason verbose_cer = { 0, 0 };
+ struct verbose_call_end_reason {
+ guint16 call_end_reason_domain;
+ guint16 call_end_reason_value;
+ } __attribute__((__packed__)) verbose_cer = { 0, 0 };
/* TODO: Prepare an enum with all the possible call end reasons,
* in order to do this nicely */
- /* Try to get the verbose reason first */
if (qmi_message_tlv_get (self,
START_NETWORK_OUTPUT_TLV_VERBOSE_CALL_END_REASON,
sizeof (verbose_cer),
&verbose_cer,
NULL)) {
- g_set_error (error,
- QMI_PROTOCOL_ERROR,
- QMI_PROTOCOL_ERROR_CALL_FAILED,
- "Call end reason: %u, %u",
- verbose_cer.call_end_reason_type,
- verbose_cer.call_end_reason);
- g_error_free (inner_error);
- return 0;
+ output->verbose_call_end_reason_set = TRUE;
+ output->verbose_call_end_reason_domain = verbose_cer.call_end_reason_domain;
+ output->verbose_call_end_reason_value = verbose_cer.call_end_reason_value;
}
- /* If no verbose reason, try to use the legacy one */
if (qmi_message_tlv_get (self,
START_NETWORK_OUTPUT_TLV_CALL_END_REASON,
sizeof (cer),
&cer,
NULL)) {
- g_set_error (error,
- QMI_PROTOCOL_ERROR,
- QMI_PROTOCOL_ERROR_CALL_FAILED,
- "Call end reason: %u",
- cer);
- g_error_free (inner_error);
- return 0;
+ output->call_end_reason_set = TRUE;
+ output->call_end_reason = cer;
}
-
- /* otherwise, fall down and propagate the error */
}
- g_propagate_error (error, inner_error);
- return 0;
+ return output;
}
+ /* success */
+
if (!qmi_message_tlv_get (self,
START_NETWORK_OUTPUT_TLV_PACKET_DATA_HANDLE,
- sizeof (packet_data_handle),
- &packet_data_handle,
+ sizeof (output->packet_data_handle),
+ &output->packet_data_handle,
error)) {
g_prefix_error (error, "Couldn't get the packet data handle TLV: ");
- return 0;
- }
+ qmi_wds_start_network_output_unref (output);
+ return NULL;
+ } else
+ output->packet_data_handle_set = TRUE;
- return packet_data_handle;
+ return output;
}
/*****************************************************************************/
diff --git a/src/qmi-message-wds.h b/src/qmi-message-wds.h
index 4318741..b8b80f8 100644
--- a/src/qmi-message-wds.h
+++ b/src/qmi-message-wds.h
@@ -35,10 +35,12 @@ G_BEGIN_DECLS
/*****************************************************************************/
/* Start network */
-QmiMessage *qmi_message_wds_start_network_new (guint8 transaction_id,
- guint8 client_id);
-guint32 qmi_message_wds_start_network_reply_parse (QmiMessage *self,
- GError **error);
+QmiMessage *qmi_message_wds_start_network_new (guint8 transaction_id,
+ guint8 client_id,
+ QmiWdsStartNetworkInput *input,
+ GError **error);
+QmiWdsStartNetworkOutput *qmi_message_wds_start_network_reply_parse (QmiMessage *self,
+ GError **error);
/*****************************************************************************/
/* Stop network */
diff --git a/src/qmi-wds.h b/src/qmi-wds.h
index 0ea8eac..5c3dcf1 100644
--- a/src/qmi-wds.h
+++ b/src/qmi-wds.h
@@ -37,6 +37,36 @@ typedef enum {
QMI_WDS_MESSAGE_PACKET_STATUS = 0x0022, /* unused currently */
} QmiWdsMessage;
+/*****************************************************************************/
+/* Start network */
+
+typedef struct _QmiWdsStartNetworkInput QmiWdsStartNetworkInput;
+QmiWdsStartNetworkInput *qmi_wds_start_network_input_new (void);
+QmiWdsStartNetworkInput *qmi_wds_start_network_input_ref (QmiWdsStartNetworkInput *input);
+void qmi_wds_start_network_input_unref (QmiWdsStartNetworkInput *input);
+void qmi_wds_start_network_input_set_apn (QmiWdsStartNetworkInput *input,
+ const gchar *str);
+const gchar *qmi_wds_start_network_input_get_apn (QmiWdsStartNetworkInput *input);
+void qmi_wds_start_network_input_set_username (QmiWdsStartNetworkInput *input,
+ const gchar *str);
+const gchar *qmi_wds_start_network_input_get_username (QmiWdsStartNetworkInput *input);
+void qmi_wds_start_network_input_set_password (QmiWdsStartNetworkInput *input,
+ const gchar *str);
+const gchar *qmi_wds_start_network_input_get_password (QmiWdsStartNetworkInput *input);
+
+typedef struct _QmiWdsStartNetworkOutput QmiWdsStartNetworkOutput;
+QmiWdsStartNetworkOutput *qmi_wds_start_network_output_ref (QmiWdsStartNetworkOutput *output);
+void qmi_wds_start_network_output_unref (QmiWdsStartNetworkOutput *output);
+gboolean qmi_wds_start_network_output_get_result (QmiWdsStartNetworkOutput *output,
+ GError **error);
+gboolean qmi_wds_start_network_output_get_packet_data_handle (QmiWdsStartNetworkOutput *output,
+ guint32 *packet_data_handle);
+/* TODO: provide proper enums for the call end reasons */
+gboolean qmi_wds_start_network_output_get_call_end_reason (QmiWdsStartNetworkOutput *output,
+ guint16 *call_end_reason);
+gboolean qmi_wds_start_network_output_get_verbose_call_end_reason (QmiWdsStartNetworkOutput *output,
+ guint16 *verbose_call_end_reason_domain,
+ guint16 *verbose_call_end_reason_value);
G_END_DECLS