iface-modem-3gpp: removed the 'setup indicators' step

The previous logic would first request to check if indicators were supported,
and only then allow to setup/enable/cleanup/disable unsolicited events. This
behaviour is very specific to the generic 3GPP case, and therefore it shouldn't
be handled in the even more generic 3GPP interface. The logic is still kept,
but handled within the MMBroadbandModem object.
This commit is contained in:
Aleksander Morgado
2012-07-31 12:59:23 +02:00
parent 4d5892204d
commit 4aaafc54c7
3 changed files with 195 additions and 274 deletions

View File

@@ -113,6 +113,7 @@ struct _MMBroadbandModemPrivate {
MMModemState modem_state;
/* Implementation helpers */
MMModemCharset modem_current_charset;
gboolean modem_cind_support_checked;
gboolean modem_cind_supported;
guint modem_cind_indicator_signal_quality;
guint modem_cind_min_signal_quality;
@@ -1489,102 +1490,6 @@ modem_load_signal_quality (MMIfaceModem *self,
signal_quality_context_complete_and_free (ctx);
}
/*****************************************************************************/
/* Setting up indicators (3GPP interface) */
static gboolean
modem_3gpp_setup_indicators_finish (MMIfaceModem3gpp *self,
GAsyncResult *res,
GError **error)
{
return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}
static void
cind_format_check_ready (MMBroadbandModem *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
GHashTable *indicators = NULL;
GError *error = NULL;
const gchar *result;
MM3gppCindResponse *r;
result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
if (error ||
!(indicators = mm_3gpp_parse_cind_test_response (result, &error))) {
/* quit with error */
g_simple_async_result_take_error (simple, error);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return;
}
/* Mark CIND as being supported and find the proper indexes for the
* indicators. */
self->priv->modem_cind_supported = TRUE;
/* Check if we support signal quality indications */
r = g_hash_table_lookup (indicators, "signal");
if (r) {
self->priv->modem_cind_indicator_signal_quality = mm_3gpp_cind_response_get_index (r);
self->priv->modem_cind_min_signal_quality = mm_3gpp_cind_response_get_min (r);
self->priv->modem_cind_max_signal_quality = mm_3gpp_cind_response_get_max (r);
mm_dbg ("Modem supports signal quality indications via CIND at index '%u'"
"(min: %u, max: %u)",
self->priv->modem_cind_indicator_signal_quality,
self->priv->modem_cind_min_signal_quality,
self->priv->modem_cind_max_signal_quality);
} else
self->priv->modem_cind_indicator_signal_quality = CIND_INDICATOR_INVALID;
/* Check if we support roaming indications */
r = g_hash_table_lookup (indicators, "roam");
if (r) {
self->priv->modem_cind_indicator_roaming = mm_3gpp_cind_response_get_index (r);
mm_dbg ("Modem supports roaming indications via CIND at index '%u'",
self->priv->modem_cind_indicator_roaming);
} else
self->priv->modem_cind_indicator_roaming = CIND_INDICATOR_INVALID;
/* Check if we support service indications */
r = g_hash_table_lookup (indicators, "service");
if (r) {
self->priv->modem_cind_indicator_service = mm_3gpp_cind_response_get_index (r);
mm_dbg ("Modem supports service indications via CIND at index '%u'",
self->priv->modem_cind_indicator_service);
} else
self->priv->modem_cind_indicator_service = CIND_INDICATOR_INVALID;
g_hash_table_destroy (indicators);
g_simple_async_result_set_op_res_gboolean (simple, TRUE);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
static void
modem_3gpp_setup_indicators (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *result;
result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
modem_3gpp_setup_indicators);
/* Load supported indicators */
mm_base_modem_at_command (MM_BASE_MODEM (self),
"+CIND=?",
3,
TRUE,
(GAsyncReadyCallback)cind_format_check_ready,
result);
}
/*****************************************************************************/
/* Setup/Cleanup unsolicited events (3GPP interface) */
@@ -1635,21 +1540,13 @@ ciev_received (MMAtSerialPort *port,
}
static void
set_unsolicited_events_handlers (MMIfaceModem3gpp *self,
gboolean enable,
GAsyncReadyCallback callback,
gpointer user_data)
set_unsolicited_events_handlers (MMBroadbandModem *self,
gboolean enable)
{
GSimpleAsyncResult *result;
MMAtSerialPort *ports[2];
GRegex *ciev_regex;
guint i;
result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
set_unsolicited_events_handlers);
ciev_regex = mm_3gpp_ciev_regex_get ();
ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));
@@ -1672,25 +1569,132 @@ set_unsolicited_events_handlers (MMIfaceModem3gpp *self,
}
g_regex_unref (ciev_regex);
}
static void
cind_format_check_ready (MMBroadbandModem *self,
GAsyncResult *res,
GSimpleAsyncResult *simple)
{
GHashTable *indicators = NULL;
GError *error = NULL;
const gchar *result;
MM3gppCindResponse *r;
result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
if (error ||
!(indicators = mm_3gpp_parse_cind_test_response (result, &error))) {
/* unsupported indications */
mm_dbg ("Marking indications as unsupported: '%s'", error->message);
g_free (error);
g_simple_async_result_set_op_res_gboolean (simple, TRUE);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return;
}
/* Mark CIND as being supported and find the proper indexes for the
* indicators. */
self->priv->modem_cind_supported = TRUE;
/* Check if we support signal quality indications */
r = g_hash_table_lookup (indicators, "signal");
if (r) {
self->priv->modem_cind_indicator_signal_quality = mm_3gpp_cind_response_get_index (r);
self->priv->modem_cind_min_signal_quality = mm_3gpp_cind_response_get_min (r);
self->priv->modem_cind_max_signal_quality = mm_3gpp_cind_response_get_max (r);
mm_dbg ("Modem supports signal quality indications via CIND at index '%u'"
"(min: %u, max: %u)",
self->priv->modem_cind_indicator_signal_quality,
self->priv->modem_cind_min_signal_quality,
self->priv->modem_cind_max_signal_quality);
} else
self->priv->modem_cind_indicator_signal_quality = CIND_INDICATOR_INVALID;
/* Check if we support roaming indications */
r = g_hash_table_lookup (indicators, "roam");
if (r) {
self->priv->modem_cind_indicator_roaming = mm_3gpp_cind_response_get_index (r);
mm_dbg ("Modem supports roaming indications via CIND at index '%u'",
self->priv->modem_cind_indicator_roaming);
} else
self->priv->modem_cind_indicator_roaming = CIND_INDICATOR_INVALID;
/* Check if we support service indications */
r = g_hash_table_lookup (indicators, "service");
if (r) {
self->priv->modem_cind_indicator_service = mm_3gpp_cind_response_get_index (r);
mm_dbg ("Modem supports service indications via CIND at index '%u'",
self->priv->modem_cind_indicator_service);
} else
self->priv->modem_cind_indicator_service = CIND_INDICATOR_INVALID;
g_hash_table_destroy (indicators);
/* Now, keep on setting up the ports */
set_unsolicited_events_handlers (self, TRUE);
g_simple_async_result_set_op_res_gboolean (simple, TRUE);
g_simple_async_result_complete (simple);
g_object_unref (simple);
}
static void
modem_3gpp_setup_unsolicited_events (MMIfaceModem3gpp *_self,
GAsyncReadyCallback callback,
gpointer user_data)
{
MMBroadbandModem *self = MM_BROADBAND_MODEM (_self);
GSimpleAsyncResult *result;
result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
modem_3gpp_setup_unsolicited_events);
/* Load supported indicators */
if (!self->priv->modem_cind_support_checked) {
mm_dbg ("Checking indicator support...");
self->priv->modem_cind_support_checked = TRUE;
mm_base_modem_at_command (MM_BASE_MODEM (self),
"+CIND=?",
3,
TRUE,
(GAsyncReadyCallback)cind_format_check_ready,
result);
return;
}
/* If supported, go on */
if (self->priv->modem_cind_supported)
set_unsolicited_events_handlers (self, TRUE);
g_simple_async_result_set_op_res_gboolean (result, TRUE);
g_simple_async_result_complete_in_idle (result);
g_object_unref (result);
}
static void
modem_3gpp_setup_unsolicited_events (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
set_unsolicited_events_handlers (self, TRUE, callback, user_data);
}
static void
modem_3gpp_cleanup_unsolicited_events (MMIfaceModem3gpp *self,
modem_3gpp_cleanup_unsolicited_events (MMIfaceModem3gpp *_self,
GAsyncReadyCallback callback,
gpointer user_data)
{
set_unsolicited_events_handlers (self, FALSE, callback, user_data);
MMBroadbandModem *self = MM_BROADBAND_MODEM (_self);
GSimpleAsyncResult *result;
result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
modem_3gpp_cleanup_unsolicited_events);
/* If supported, go on */
if (self->priv->modem_cind_support_checked && self->priv->modem_cind_supported)
set_unsolicited_events_handlers (self, FALSE);
g_simple_async_result_set_op_res_gboolean (result, TRUE);
g_simple_async_result_complete_in_idle (result);
g_object_unref (result);
}
/*****************************************************************************/
@@ -1780,38 +1784,64 @@ run_unsolicited_events_setup (UnsolicitedEventsContext *ctx)
}
static void
modem_3gpp_enable_unsolicited_events (MMIfaceModem3gpp *self,
modem_3gpp_enable_unsolicited_events (MMIfaceModem3gpp *_self,
GAsyncReadyCallback callback,
gpointer user_data)
{
UnsolicitedEventsContext *ctx;
MMBroadbandModem *self = MM_BROADBAND_MODEM (_self);
GSimpleAsyncResult *result;
ctx = g_new0 (UnsolicitedEventsContext, 1);
ctx->self = g_object_ref (self);
ctx->enable = TRUE;
ctx->command = g_strdup ("+CMER=3,0,0,1");
ctx->result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
modem_3gpp_enable_unsolicited_events);
run_unsolicited_events_setup (ctx);
result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
modem_3gpp_enable_unsolicited_events);
/* If supported, go on */
if (self->priv->modem_cind_support_checked && self->priv->modem_cind_supported) {
UnsolicitedEventsContext *ctx;
ctx = g_new0 (UnsolicitedEventsContext, 1);
ctx->self = g_object_ref (self);
ctx->enable = TRUE;
ctx->command = g_strdup ("+CMER=3,0,0,1");
ctx->result = result;
run_unsolicited_events_setup (ctx);
return;
}
g_simple_async_result_set_op_res_gboolean (result, TRUE);
g_simple_async_result_complete_in_idle (result);
g_object_unref (result);
}
static void
modem_3gpp_disable_unsolicited_events (MMIfaceModem3gpp *self,
modem_3gpp_disable_unsolicited_events (MMIfaceModem3gpp *_self,
GAsyncReadyCallback callback,
gpointer user_data)
{
UnsolicitedEventsContext *ctx;
MMBroadbandModem *self = MM_BROADBAND_MODEM (_self);
GSimpleAsyncResult *result;
ctx = g_new0 (UnsolicitedEventsContext, 1);
ctx->self = g_object_ref (self);
ctx->command = g_strdup ("+CMER=0");
ctx->result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
modem_3gpp_disable_unsolicited_events);
run_unsolicited_events_setup (ctx);
result = g_simple_async_result_new (G_OBJECT (self),
callback,
user_data,
modem_3gpp_disable_unsolicited_events);
/* If supported, go on */
if (self->priv->modem_cind_support_checked && self->priv->modem_cind_supported) {
UnsolicitedEventsContext *ctx;
ctx = g_new0 (UnsolicitedEventsContext, 1);
ctx->self = g_object_ref (self);
ctx->command = g_strdup ("+CMER=0");
ctx->result = result;
run_unsolicited_events_setup (ctx);
return;
}
g_simple_async_result_set_op_res_gboolean (result, TRUE);
g_simple_async_result_complete_in_idle (result);
g_object_unref (result);
}
/*****************************************************************************/
@@ -7878,8 +7908,6 @@ iface_modem_3gpp_init (MMIfaceModem3gpp *iface)
iface->load_enabled_facility_locks_finish = modem_3gpp_load_enabled_facility_locks_finish;
/* Enabling steps */
iface->setup_indicators = modem_3gpp_setup_indicators;
iface->setup_indicators_finish = modem_3gpp_setup_indicators_finish;
iface->setup_unsolicited_events = modem_3gpp_setup_unsolicited_events;
iface->setup_unsolicited_events_finish = modem_3gpp_setup_cleanup_unsolicited_events_finish;
iface->enable_unsolicited_events = modem_3gpp_enable_unsolicited_events;

View File

@@ -30,13 +30,9 @@
#define SUBSYSTEM_3GPP "3gpp"
#define INDICATORS_CHECKED_TAG "3gpp-indicators-checked-tag"
#define UNSOLICITED_EVENTS_SUPPORTED_TAG "3gpp-unsolicited-events-supported-tag"
#define REGISTRATION_STATE_CONTEXT_TAG "3gpp-registration-state-context-tag"
#define REGISTRATION_CHECK_CONTEXT_TAG "3gpp-registration-check-context-tag"
static GQuark indicators_checked_quark;
static GQuark unsolicited_events_supported_quark;
static GQuark registration_state_context_quark;
static GQuark registration_check_context_quark;
@@ -1113,41 +1109,25 @@ interface_disabling_step (DisablingContext *ctx)
ctx->step++;
case DISABLING_STEP_CLEANUP_UNSOLICITED_EVENTS:
if (G_UNLIKELY (!unsolicited_events_supported_quark))
unsolicited_events_supported_quark = (g_quark_from_static_string (
UNSOLICITED_EVENTS_SUPPORTED_TAG));
/* Only try to disable if supported */
if (GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (ctx->self),
unsolicited_events_supported_quark))) {
if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->cleanup_unsolicited_events &&
MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->cleanup_unsolicited_events_finish) {
MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->cleanup_unsolicited_events (
ctx->self,
(GAsyncReadyCallback)cleanup_unsolicited_events_ready,
ctx);
return;
}
if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->cleanup_unsolicited_events &&
MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->cleanup_unsolicited_events_finish) {
MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->cleanup_unsolicited_events (
ctx->self,
(GAsyncReadyCallback)cleanup_unsolicited_events_ready,
ctx);
return;
}
/* Fall down to next step */
ctx->step++;
case DISABLING_STEP_DISABLE_UNSOLICITED_EVENTS:
if (G_UNLIKELY (!unsolicited_events_supported_quark))
unsolicited_events_supported_quark = (g_quark_from_static_string (
UNSOLICITED_EVENTS_SUPPORTED_TAG));
/* Only try to disable if supported */
if (GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (ctx->self),
unsolicited_events_supported_quark))) {
if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->disable_unsolicited_events &&
MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->disable_unsolicited_events_finish) {
MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->disable_unsolicited_events (
ctx->self,
(GAsyncReadyCallback)disable_unsolicited_events_ready,
ctx);
return;
}
if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->disable_unsolicited_events &&
MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->disable_unsolicited_events_finish) {
MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->disable_unsolicited_events (
ctx->self,
(GAsyncReadyCallback)disable_unsolicited_events_ready,
ctx);
return;
}
/* Fall down to next step */
ctx->step++;
@@ -1179,7 +1159,6 @@ static void interface_enabling_step (EnablingContext *ctx);
typedef enum {
ENABLING_STEP_FIRST,
ENABLING_STEP_SETUP_INDICATORS,
ENABLING_STEP_SETUP_UNSOLICITED_EVENTS,
ENABLING_STEP_ENABLE_UNSOLICITED_EVENTS,
ENABLING_STEP_SETUP_UNSOLICITED_REGISTRATION,
@@ -1275,36 +1254,6 @@ mm_iface_modem_3gpp_enable_finish (MMIfaceModem3gpp *self,
interface_enabling_step (ctx); \
}
static void
setup_indicators_ready (MMIfaceModem3gpp *self,
GAsyncResult *res,
EnablingContext *ctx)
{
GError *error = NULL;
MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->setup_indicators_finish (self, res, &error);
if (error) {
/* This error shouldn't be treated as critical */
mm_dbg ("Indicator control setup failed: '%s'", error->message);
g_error_free (error);
/* If we get an error setting up indicators, don't even bother trying to
* enable unsolicited events. */
ctx->step = ENABLING_STEP_ENABLE_UNSOLICITED_EVENTS + 1;
interface_enabling_step (ctx);
return;
}
/* Indicators setup, so assume we support unsolicited events */
g_object_set_qdata (G_OBJECT (self),
unsolicited_events_supported_quark,
GUINT_TO_POINTER (TRUE));
/* Go on to next step */
ctx->step++;
interface_enabling_step (ctx);
}
static void
enable_unsolicited_events_ready (MMIfaceModem3gpp *self,
GAsyncResult *res,
@@ -1317,11 +1266,6 @@ enable_unsolicited_events_ready (MMIfaceModem3gpp *self,
/* This error shouldn't be treated as critical */
mm_dbg ("Enabling unsolicited events failed: '%s'", error->message);
g_error_free (error);
/* Reset support flag */
g_object_set_qdata (G_OBJECT (self),
unsolicited_events_supported_quark,
GUINT_TO_POINTER (FALSE));
}
/* Go on to next step */
@@ -1342,11 +1286,6 @@ setup_unsolicited_events_ready (MMIfaceModem3gpp *self,
mm_dbg ("Setting up unsolicited events failed: '%s'", error->message);
g_error_free (error);
/* Reset support flag */
g_object_set_qdata (G_OBJECT (self),
unsolicited_events_supported_quark,
GUINT_TO_POINTER (FALSE));
/* If we get an error setting up unsolicited events, don't even bother trying to
* enable them. */
ctx->step = ENABLING_STEP_ENABLE_UNSOLICITED_EVENTS + 1;
@@ -1448,67 +1387,29 @@ interface_enabling_step (EnablingContext *ctx)
switch (ctx->step) {
case ENABLING_STEP_FIRST:
/* Setup quarks if we didn't do it before */
if (G_UNLIKELY (!indicators_checked_quark))
indicators_checked_quark = (g_quark_from_static_string (
INDICATORS_CHECKED_TAG));
if (G_UNLIKELY (!unsolicited_events_supported_quark))
unsolicited_events_supported_quark = (g_quark_from_static_string (
UNSOLICITED_EVENTS_SUPPORTED_TAG));
/* Fall down to next step */
ctx->step++;
case ENABLING_STEP_SETUP_INDICATORS:
if (!GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (ctx->self),
indicators_checked_quark))) {
/* Set the checked flag so that we don't run it again */
g_object_set_qdata (G_OBJECT (ctx->self),
indicators_checked_quark,
GUINT_TO_POINTER (TRUE));
/* Initially, assume we don't support unsolicited events */
g_object_set_qdata (G_OBJECT (ctx->self),
unsolicited_events_supported_quark,
GUINT_TO_POINTER (FALSE));
if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->setup_indicators &&
MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->setup_indicators_finish) {
MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->setup_indicators (
ctx->self,
(GAsyncReadyCallback)setup_indicators_ready,
ctx);
return;
}
}
/* Fall down to next step */
ctx->step++;
case ENABLING_STEP_SETUP_UNSOLICITED_EVENTS:
/* Only try to setup unsolicited events if they are supported */
if (GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (ctx->self),
unsolicited_events_supported_quark))) {
if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->setup_unsolicited_events &&
MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->setup_unsolicited_events_finish) {
MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->setup_unsolicited_events (
ctx->self,
(GAsyncReadyCallback)setup_unsolicited_events_ready,
ctx);
return;
}
if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->setup_unsolicited_events &&
MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->setup_unsolicited_events_finish) {
MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->setup_unsolicited_events (
ctx->self,
(GAsyncReadyCallback)setup_unsolicited_events_ready,
ctx);
return;
}
/* Fall down to next step */
ctx->step++;
case ENABLING_STEP_ENABLE_UNSOLICITED_EVENTS:
/* Only try to enable unsolicited events if they are supported */
if (GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (ctx->self),
unsolicited_events_supported_quark))) {
if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->enable_unsolicited_events &&
MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->enable_unsolicited_events_finish) {
MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->enable_unsolicited_events (
ctx->self,
(GAsyncReadyCallback)enable_unsolicited_events_ready,
ctx);
return;
}
if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->enable_unsolicited_events &&
MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->enable_unsolicited_events_finish) {
MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->enable_unsolicited_events (
ctx->self,
(GAsyncReadyCallback)enable_unsolicited_events_ready,
ctx);
return;
}
/* Fall down to next step */
ctx->step++;

View File

@@ -66,14 +66,6 @@ struct _MMIfaceModem3gpp {
GAsyncResult *res,
GError **error);
/* Asynchronous setup of indicators */
void (*setup_indicators) (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean (*setup_indicators_finish) (MMIfaceModem3gpp *self,
GAsyncResult *res,
GError **error);
/* Asynchronous setting up unsolicited events */
void (*setup_unsolicited_events) (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,