mbm: implement custom 3GPP dialling sequence
This commit is contained in:
@@ -42,6 +42,411 @@
|
||||
|
||||
G_DEFINE_TYPE (MMBroadbandBearerMbm, mm_broadband_bearer_mbm, MM_TYPE_BROADBAND_BEARER);
|
||||
|
||||
struct _MMBroadbandBearerMbmPrivate {
|
||||
gpointer connect_pending;
|
||||
guint connect_pending_id;
|
||||
gulong connect_cancellable_id;
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
/* 3GPP Dialing (sub-step of the 3GPP Connection sequence) */
|
||||
|
||||
typedef struct {
|
||||
MMBroadbandBearerMbm *self;
|
||||
MMBaseModem *modem;
|
||||
MMAtSerialPort *primary;
|
||||
guint cid;
|
||||
GCancellable *cancellable;
|
||||
GSimpleAsyncResult *result;
|
||||
guint poll_count;
|
||||
} Dial3gppContext;
|
||||
|
||||
static Dial3gppContext *
|
||||
dial_3gpp_context_new (MMBroadbandBearerMbm *self,
|
||||
MMBaseModem *modem,
|
||||
MMAtSerialPort *primary,
|
||||
guint cid,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
Dial3gppContext *ctx;
|
||||
|
||||
ctx = g_new0 (Dial3gppContext, 1);
|
||||
ctx->self = g_object_ref (self);
|
||||
ctx->modem = g_object_ref (modem);
|
||||
ctx->primary = g_object_ref (primary);
|
||||
ctx->cid = cid;
|
||||
ctx->result = g_simple_async_result_new (G_OBJECT (self),
|
||||
callback,
|
||||
user_data,
|
||||
dial_3gpp_context_new);
|
||||
ctx->cancellable = g_object_ref (cancellable);
|
||||
ctx->poll_count = 0;
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static void
|
||||
dial_3gpp_context_complete_and_free (Dial3gppContext *ctx)
|
||||
{
|
||||
g_simple_async_result_complete (ctx->result);
|
||||
g_object_unref (ctx->cancellable);
|
||||
g_object_unref (ctx->result);
|
||||
g_object_unref (ctx->primary);
|
||||
g_object_unref (ctx->modem);
|
||||
g_object_unref (ctx->self);
|
||||
g_free (ctx);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
dial_3gpp_context_set_error_if_cancelled (Dial3gppContext *ctx,
|
||||
GError **error)
|
||||
{
|
||||
if (!g_cancellable_is_cancelled (ctx->cancellable))
|
||||
return FALSE;
|
||||
|
||||
g_set_error (error,
|
||||
MM_CORE_ERROR,
|
||||
MM_CORE_ERROR_CANCELLED,
|
||||
"Dial operation has been cancelled");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
dial_3gpp_context_complete_and_free_if_cancelled (Dial3gppContext *ctx)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
if (!dial_3gpp_context_set_error_if_cancelled (ctx, &error))
|
||||
return FALSE;
|
||||
|
||||
g_simple_async_result_take_error (ctx->result, error);
|
||||
dial_3gpp_context_complete_and_free (ctx);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
dial_3gpp_finish (MMBroadbandBearer *self,
|
||||
GAsyncResult *res,
|
||||
GError **error)
|
||||
{
|
||||
return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
|
||||
}
|
||||
|
||||
void
|
||||
mm_broadband_bearer_mbm_report_connection_status (MMBroadbandBearerMbm *self,
|
||||
MMBroadbandBearerMbmConnectionStatus status)
|
||||
{
|
||||
Dial3gppContext *ctx;
|
||||
|
||||
/* Recover context (if any) and remove both cancellation and timeout (if any)*/
|
||||
ctx = self->priv->connect_pending;
|
||||
self->priv->connect_pending = NULL;
|
||||
|
||||
if (self->priv->connect_pending_id) {
|
||||
g_source_remove (self->priv->connect_pending_id);
|
||||
self->priv->connect_pending_id = 0;
|
||||
}
|
||||
|
||||
if (ctx && self->priv->connect_cancellable_id) {
|
||||
g_cancellable_disconnect (ctx->cancellable,
|
||||
self->priv->connect_cancellable_id);
|
||||
self->priv->connect_cancellable_id = 0;
|
||||
}
|
||||
|
||||
switch (status) {
|
||||
case MM_BROADBAND_BEARER_MBM_CONNECTION_STATUS_UNKNOWN:
|
||||
g_warn_if_reached ();
|
||||
break;
|
||||
|
||||
case MM_BROADBAND_BEARER_MBM_CONNECTION_STATUS_CONNECTED:
|
||||
if (!ctx)
|
||||
break;
|
||||
|
||||
g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
|
||||
dial_3gpp_context_complete_and_free (ctx);
|
||||
return;
|
||||
|
||||
case MM_BROADBAND_BEARER_MBM_CONNECTION_STATUS_DISCONNECTED:
|
||||
if (ctx) {
|
||||
g_simple_async_result_set_error (ctx->result,
|
||||
MM_CORE_ERROR,
|
||||
MM_CORE_ERROR_FAILED,
|
||||
"Call setup failed");
|
||||
dial_3gpp_context_complete_and_free (ctx);
|
||||
} else {
|
||||
/* Just ensure we mark ourselves as being disconnected... */
|
||||
mm_bearer_report_disconnection (MM_BEARER (self));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
connect_cancelled_cb (GCancellable *cancellable,
|
||||
MMBroadbandBearerMbm *self)
|
||||
{
|
||||
GError *error = NULL;
|
||||
Dial3gppContext *ctx;
|
||||
|
||||
/* Recover context and remove timeout */
|
||||
ctx = self->priv->connect_pending;
|
||||
|
||||
g_source_remove (self->priv->connect_pending_id);
|
||||
|
||||
self->priv->connect_pending = NULL;
|
||||
self->priv->connect_pending_id = 0;
|
||||
self->priv->connect_cancellable_id = 0;
|
||||
|
||||
g_assert (dial_3gpp_context_set_error_if_cancelled (ctx, &error));
|
||||
|
||||
g_simple_async_result_take_error (ctx->result, error);
|
||||
dial_3gpp_context_complete_and_free (ctx);
|
||||
}
|
||||
|
||||
static gboolean poll_timeout_cb (MMBroadbandBearerMbm *self);
|
||||
|
||||
static void
|
||||
poll_ready (MMBaseModem *modem,
|
||||
GAsyncResult *res,
|
||||
MMBroadbandBearerMbm *self)
|
||||
{
|
||||
Dial3gppContext *ctx;
|
||||
GError *error = NULL;
|
||||
const gchar *response;
|
||||
guint state;
|
||||
|
||||
/* Try to recover the connection context. If none found, it means the
|
||||
* context was already completed and we have nothing else to do. */
|
||||
ctx = self->priv->connect_pending;
|
||||
|
||||
/* Balance refcount with the extra ref we passed to command_full() */
|
||||
g_object_unref (self);
|
||||
|
||||
if (!ctx) {
|
||||
mm_dbg ("Connection context was finished already by an unsolicited message");
|
||||
|
||||
/* Run _finish() to finalize the async call, even if we don't care
|
||||
* the result */
|
||||
mm_base_modem_at_command_full_finish (modem, res, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
response = mm_base_modem_at_command_full_finish (modem, res, &error);
|
||||
if (response
|
||||
&& sscanf (response, "*ENAP: %d", &state) == 1
|
||||
&& state == 1) {
|
||||
/* Success! Connected... */
|
||||
self->priv->connect_pending = NULL;
|
||||
|
||||
if (ctx && self->priv->connect_cancellable_id) {
|
||||
g_cancellable_disconnect (ctx->cancellable,
|
||||
self->priv->connect_cancellable_id);
|
||||
self->priv->connect_cancellable_id = 0;
|
||||
}
|
||||
|
||||
g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
|
||||
dial_3gpp_context_complete_and_free (ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
self->priv->connect_pending_id = g_timeout_add_seconds (1,
|
||||
(GSourceFunc)poll_timeout_cb,
|
||||
self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
poll_timeout_cb (MMBroadbandBearerMbm *self)
|
||||
{
|
||||
Dial3gppContext *ctx;
|
||||
|
||||
/* Recover context */
|
||||
ctx = self->priv->connect_pending;
|
||||
|
||||
/* Too many retries... */
|
||||
if (ctx->poll_count > 50) {
|
||||
g_cancellable_disconnect (ctx->cancellable,
|
||||
self->priv->connect_cancellable_id);
|
||||
|
||||
self->priv->connect_pending = NULL;
|
||||
self->priv->connect_pending_id = 0;
|
||||
self->priv->connect_cancellable_id = 0;
|
||||
|
||||
g_simple_async_result_set_error (ctx->result,
|
||||
MM_MOBILE_EQUIPMENT_ERROR,
|
||||
MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT,
|
||||
"Connection attempt timed out");
|
||||
dial_3gpp_context_complete_and_free (ctx);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ctx->poll_count++;
|
||||
mm_base_modem_at_command_full (ctx->modem,
|
||||
ctx->primary,
|
||||
"AT*ENAP?",
|
||||
3,
|
||||
FALSE,
|
||||
NULL, /* cancellable */
|
||||
(GAsyncReadyCallback)poll_ready,
|
||||
g_object_ref (ctx->self)); /* we pass the bearer object! */
|
||||
self->priv->connect_pending_id = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
activate_ready (MMBaseModem *modem,
|
||||
GAsyncResult *res,
|
||||
MMBroadbandBearerMbm *self)
|
||||
{
|
||||
Dial3gppContext *ctx;
|
||||
GError *error = NULL;
|
||||
|
||||
/* Try to recover the connection context. If none found, it means the
|
||||
* context was already completed and we have nothing else to do. */
|
||||
ctx = self->priv->connect_pending;
|
||||
|
||||
/* Balance refcount with the extra ref we passed to command_full() */
|
||||
g_object_unref (self);
|
||||
|
||||
if (!ctx) {
|
||||
mm_dbg ("Connection context was finished already by an unsolicited message");
|
||||
|
||||
/* Run _finish() to finalize the async call, even if we don't care
|
||||
* the result */
|
||||
mm_base_modem_at_command_full_finish (modem, res, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* From now on, if we get cancelled, we'll need to run the connection
|
||||
* reset ourselves just in case */
|
||||
|
||||
if (!mm_base_modem_at_command_full_finish (modem, res, &error)) {
|
||||
g_simple_async_result_take_error (ctx->result, error);
|
||||
dial_3gpp_context_complete_and_free (ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
/* We will now setup a timeout to poll for the status */
|
||||
self->priv->connect_pending_id = g_timeout_add_seconds (1,
|
||||
(GSourceFunc)poll_timeout_cb,
|
||||
self);
|
||||
|
||||
self->priv->connect_cancellable_id = g_cancellable_connect (ctx->cancellable,
|
||||
G_CALLBACK (connect_cancelled_cb),
|
||||
self,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
activate (Dial3gppContext *ctx)
|
||||
{
|
||||
gchar *command;
|
||||
|
||||
/* The unsolicited response to ENAP may come before the OK does.
|
||||
* We will keep the connection context in the bearer private data so
|
||||
* that it is accessible from the unsolicited message handler. Note
|
||||
* also that we do NOT pass the ctx to the GAsyncReadyCallback, as it
|
||||
* may not be valid any more when the callback is called (it may be
|
||||
* already completed in the unsolicited handling) */
|
||||
g_assert (ctx->self->priv->connect_pending == NULL);
|
||||
ctx->self->priv->connect_pending = ctx;
|
||||
|
||||
/* Success, activate the PDP context and start the data session */
|
||||
command = g_strdup_printf ("AT*ENAP=1,%d",
|
||||
ctx->cid);
|
||||
mm_base_modem_at_command_full (ctx->modem,
|
||||
ctx->primary,
|
||||
command,
|
||||
3,
|
||||
FALSE,
|
||||
NULL, /* cancellable */
|
||||
(GAsyncReadyCallback)activate_ready,
|
||||
g_object_ref (ctx->self)); /* we pass the bearer object! */
|
||||
g_free (command);
|
||||
}
|
||||
|
||||
static void
|
||||
authenticate_ready (MMBaseModem *modem,
|
||||
GAsyncResult *res,
|
||||
Dial3gppContext *ctx)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
/* If cancelled, complete */
|
||||
if (dial_3gpp_context_complete_and_free_if_cancelled (ctx))
|
||||
return;
|
||||
|
||||
if (!mm_base_modem_at_command_full_finish (modem, res, &error)) {
|
||||
g_simple_async_result_take_error (ctx->result, error);
|
||||
dial_3gpp_context_complete_and_free (ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
activate (ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
authenticate (Dial3gppContext *ctx)
|
||||
{
|
||||
const gchar *user;
|
||||
const gchar *password;
|
||||
|
||||
user = mm_bearer_properties_get_user (mm_bearer_peek_config (MM_BEARER (ctx->self)));
|
||||
password = mm_bearer_properties_get_password (mm_bearer_peek_config (MM_BEARER (ctx->self)));
|
||||
|
||||
/* Both user and password are required; otherwise firmware returns an error */
|
||||
if (user || password) {
|
||||
gchar *command;
|
||||
gchar *encoded_user;
|
||||
gchar *encoded_password;
|
||||
|
||||
encoded_user = mm_broadband_modem_take_and_convert_to_current_charset (MM_BROADBAND_MODEM (ctx->modem),
|
||||
g_strdup (user));
|
||||
encoded_password = mm_broadband_modem_take_and_convert_to_current_charset (MM_BROADBAND_MODEM (ctx->modem),
|
||||
g_strdup (password));
|
||||
|
||||
command = g_strdup_printf ("AT*EIAAUW=%d,1,\"%s\",\"%s\"",
|
||||
ctx->cid,
|
||||
encoded_user,
|
||||
encoded_password);
|
||||
|
||||
mm_base_modem_at_command_full (ctx->modem,
|
||||
ctx->primary,
|
||||
command,
|
||||
3,
|
||||
FALSE,
|
||||
NULL, /* cancellable */
|
||||
(GAsyncReadyCallback)authenticate_ready,
|
||||
ctx);
|
||||
g_free (command);
|
||||
return;
|
||||
}
|
||||
|
||||
activate (ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
dial_3gpp (MMBroadbandBearer *self,
|
||||
MMBaseModem *modem,
|
||||
MMAtSerialPort *primary,
|
||||
MMPort *data, /* unused by us */
|
||||
guint cid,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_assert (primary != NULL);
|
||||
|
||||
authenticate (dial_3gpp_context_new (MM_BROADBAND_BEARER_MBM (self),
|
||||
modem,
|
||||
primary,
|
||||
cid,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
MMBearer *
|
||||
@@ -85,9 +490,21 @@ mm_broadband_bearer_mbm_new (MMBroadbandModemMbm *modem,
|
||||
static void
|
||||
mm_broadband_bearer_mbm_init (MMBroadbandBearerMbm *self)
|
||||
{
|
||||
/* Initialize private data */
|
||||
self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self),
|
||||
MM_TYPE_BROADBAND_BEARER_MBM,
|
||||
MMBroadbandBearerMbmPrivate);
|
||||
}
|
||||
|
||||
static void
|
||||
mm_broadband_bearer_mbm_class_init (MMBroadbandBearerMbmClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
MMBroadbandBearerClass *broadband_bearer_class = MM_BROADBAND_BEARER_CLASS (klass);
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (MMBroadbandBearerMbmPrivate));
|
||||
|
||||
broadband_bearer_class->dial_3gpp = dial_3gpp;
|
||||
broadband_bearer_class->dial_3gpp_finish = dial_3gpp_finish;
|
||||
}
|
||||
|
||||
@@ -40,12 +40,19 @@
|
||||
#define MM_IS_BROADBAND_BEARER_MBM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_BROADBAND_BEARER_MBM))
|
||||
#define MM_BROADBAND_BEARER_MBM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_BROADBAND_BEARER_MBM, MMBroadbandBearerMbmClass))
|
||||
|
||||
typedef enum {
|
||||
MM_BROADBAND_BEARER_MBM_CONNECTION_STATUS_UNKNOWN,
|
||||
MM_BROADBAND_BEARER_MBM_CONNECTION_STATUS_CONNECTED,
|
||||
MM_BROADBAND_BEARER_MBM_CONNECTION_STATUS_DISCONNECTED
|
||||
} MMBroadbandBearerMbmConnectionStatus;
|
||||
|
||||
typedef struct _MMBroadbandBearerMbm MMBroadbandBearerMbm;
|
||||
typedef struct _MMBroadbandBearerMbmClass MMBroadbandBearerMbmClass;
|
||||
typedef struct _MMBroadbandBearerMbmPrivate MMBroadbandBearerMbmPrivate;
|
||||
|
||||
struct _MMBroadbandBearerMbm {
|
||||
MMBroadbandBearer parent;
|
||||
MMBroadbandBearerMbmPrivate *priv;
|
||||
};
|
||||
|
||||
struct _MMBroadbandBearerMbmClass {
|
||||
@@ -63,4 +70,7 @@ void mm_broadband_bearer_mbm_new (MMBroadbandModemMbm *modem,
|
||||
MMBearer *mm_broadband_bearer_mbm_new_finish (GAsyncResult *res,
|
||||
GError **error);
|
||||
|
||||
void mm_broadband_bearer_mbm_report_connection_status (MMBroadbandBearerMbm *self,
|
||||
MMBroadbandBearerMbmConnectionStatus status);
|
||||
|
||||
#endif /* MM_BROADBAND_BEARER_MBM_H */
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#include "ModemManager.h"
|
||||
#include "mm-log.h"
|
||||
#include "mm-bearer-list.h"
|
||||
#include "mm-errors-types.h"
|
||||
#include "mm-modem-helpers.h"
|
||||
#include "mm-broadband-modem-mbm.h"
|
||||
@@ -53,6 +54,10 @@ G_DEFINE_TYPE_EXTENDED (MMBroadbandModemMbm, mm_broadband_modem_mbm, MM_TYPE_BRO
|
||||
#define MBM_NETWORK_MODE_2G 5
|
||||
#define MBM_NETWORK_MODE_3G 6
|
||||
|
||||
#define MBM_E2NAP_DISCONNECTED 0
|
||||
#define MBM_E2NAP_CONNECTED 1
|
||||
#define MBM_E2NAP_CONNECTING 2
|
||||
|
||||
struct _MMBroadbandModemMbmPrivate {
|
||||
guint network_mode;
|
||||
|
||||
@@ -582,12 +587,64 @@ load_unlock_retries (MMIfaceModem *self,
|
||||
/*****************************************************************************/
|
||||
/* Setup/Cleanup unsolicited events (3GPP interface) */
|
||||
|
||||
typedef struct {
|
||||
MMBroadbandBearerMbmConnectionStatus status;
|
||||
} BearerListReportStatusForeachContext;
|
||||
|
||||
static void
|
||||
bearer_list_report_status_foreach (MMBearer *bearer,
|
||||
BearerListReportStatusForeachContext *ctx)
|
||||
{
|
||||
mm_broadband_bearer_mbm_report_connection_status (MM_BROADBAND_BEARER_MBM (bearer),
|
||||
ctx->status);
|
||||
}
|
||||
|
||||
static void
|
||||
e2nap_received (MMAtSerialPort *port,
|
||||
GMatchInfo *info,
|
||||
MMBroadbandModemMbm *self)
|
||||
{
|
||||
/* Just receive them from now */
|
||||
MMBearerList *list = NULL;
|
||||
guint state;
|
||||
BearerListReportStatusForeachContext ctx;
|
||||
|
||||
if (!mm_get_uint_from_match_info (info, 1, &state))
|
||||
return;
|
||||
|
||||
ctx.status = MM_BROADBAND_BEARER_MBM_CONNECTION_STATUS_UNKNOWN;
|
||||
|
||||
switch (state) {
|
||||
case MBM_E2NAP_DISCONNECTED:
|
||||
mm_dbg ("disconnected");
|
||||
ctx.status = MM_BROADBAND_BEARER_MBM_CONNECTION_STATUS_DISCONNECTED;
|
||||
break;
|
||||
case MBM_E2NAP_CONNECTED:
|
||||
mm_dbg ("connected");
|
||||
ctx.status = MM_BROADBAND_BEARER_MBM_CONNECTION_STATUS_CONNECTED;
|
||||
break;
|
||||
case MBM_E2NAP_CONNECTING:
|
||||
mm_dbg ("connecting");
|
||||
break;
|
||||
default:
|
||||
/* Should not happen */
|
||||
mm_dbg ("unhandled E2NAP state %d", state);
|
||||
}
|
||||
|
||||
/* If unknown status, don't try to report anything */
|
||||
if (ctx.status == MM_BROADBAND_BEARER_MBM_CONNECTION_STATUS_UNKNOWN)
|
||||
return;
|
||||
|
||||
/* If empty bearer list, nothing else to do */
|
||||
g_object_get (self,
|
||||
MM_IFACE_MODEM_BEARER_LIST, &list,
|
||||
NULL);
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
mm_bearer_list_foreach (list,
|
||||
(MMBearerListForeachFunc)bearer_list_report_status_foreach,
|
||||
&ctx);
|
||||
g_object_unref (list);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -779,6 +836,12 @@ own_enable_unsolicited_events_ready (MMBaseModem *self,
|
||||
g_object_unref (simple);
|
||||
}
|
||||
|
||||
static const MMBaseModemAtCommand unsolicited_enable_sequence[] = {
|
||||
{ "*ERINFO=1", 5, FALSE, NULL },
|
||||
{ "*E2NAP=1", 5, FALSE, NULL },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
parent_enable_unsolicited_events_ready (MMIfaceModem3gpp *self,
|
||||
GAsyncResult *res,
|
||||
@@ -793,12 +856,15 @@ parent_enable_unsolicited_events_ready (MMIfaceModem3gpp *self,
|
||||
}
|
||||
|
||||
/* Our own enable now */
|
||||
mm_base_modem_at_command (MM_BASE_MODEM (self),
|
||||
"*ERINFO=1",
|
||||
5,
|
||||
FALSE,
|
||||
(GAsyncReadyCallback)own_enable_unsolicited_events_ready,
|
||||
simple);
|
||||
mm_base_modem_at_sequence_full (
|
||||
MM_BASE_MODEM (self),
|
||||
mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)),
|
||||
unsolicited_enable_sequence,
|
||||
NULL, /* response_processor_context */
|
||||
NULL, /* response_processor_context_free */
|
||||
NULL, /* cancellable */
|
||||
(GAsyncReadyCallback)own_enable_unsolicited_events_ready,
|
||||
simple);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -853,7 +919,7 @@ own_disable_unsolicited_events_ready (MMBaseModem *self,
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
mm_base_modem_at_command_full_finish (self, res, &error);
|
||||
mm_base_modem_at_sequence_full_finish (self, res, NULL, &error);
|
||||
if (error) {
|
||||
g_simple_async_result_take_error (simple, error);
|
||||
g_simple_async_result_complete (simple);
|
||||
@@ -868,6 +934,12 @@ own_disable_unsolicited_events_ready (MMBaseModem *self,
|
||||
simple);
|
||||
}
|
||||
|
||||
static const MMBaseModemAtCommand unsolicited_disable_sequence[] = {
|
||||
{ "*ERINFO=0", 5, FALSE, NULL },
|
||||
{ "*E2NAP=0", 5, FALSE, NULL },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
modem_3gpp_disable_unsolicited_events (MMIfaceModem3gpp *self,
|
||||
GAsyncReadyCallback callback,
|
||||
@@ -881,12 +953,15 @@ modem_3gpp_disable_unsolicited_events (MMIfaceModem3gpp *self,
|
||||
modem_3gpp_disable_unsolicited_events);
|
||||
|
||||
/* Our own disable first */
|
||||
mm_base_modem_at_command (MM_BASE_MODEM (self),
|
||||
"*ERINFO=0",
|
||||
5,
|
||||
FALSE,
|
||||
(GAsyncReadyCallback)own_disable_unsolicited_events_ready,
|
||||
result);
|
||||
mm_base_modem_at_sequence_full (
|
||||
MM_BASE_MODEM (self),
|
||||
mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)),
|
||||
unsolicited_disable_sequence,
|
||||
NULL, /* response_processor_context */
|
||||
NULL, /* response_processor_context_free */
|
||||
NULL, /* cancellable */
|
||||
(GAsyncReadyCallback)own_disable_unsolicited_events_ready,
|
||||
result);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
Reference in New Issue
Block a user