iface-modem-3gpp, broadband-modem: update LAC/CI 3gpp-based location
This commit is contained in:
@@ -11,8 +11,8 @@
|
||||
* GNU General Public License for more details:
|
||||
*
|
||||
* Copyright (C) 2008 - 2009 Novell, Inc.
|
||||
* Copyright (C) 2009 - 2011 Red Hat, Inc.
|
||||
* Copyright (C) 2011 Google, Inc.
|
||||
* Copyright (C) 2009 - 2012 Red Hat, Inc.
|
||||
* Copyright (C) 2011 - 2012 Google, Inc.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@@ -1982,14 +1982,15 @@ registration_state_changed (MMAtSerialPort *port,
|
||||
if (cgreg)
|
||||
mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self),
|
||||
state,
|
||||
act);
|
||||
act,
|
||||
lac,
|
||||
cell_id);
|
||||
else
|
||||
mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self),
|
||||
state,
|
||||
act);
|
||||
|
||||
/* TODO: report LAC/CI location */
|
||||
/* update_lac_ci (self, lac, cell_id, cgreg ? 1 : 0); */
|
||||
act,
|
||||
lac,
|
||||
cell_id);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2199,10 +2200,12 @@ run_all_3gpp_registration_checks_ready (MMBroadbandModem *self,
|
||||
mm_dbg ("3GPP registration check failed: '%s'", error->message);
|
||||
mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self),
|
||||
MM_MODEM_3GPP_REGISTRATION_STATE_IDLE,
|
||||
MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
|
||||
MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN,
|
||||
0, 0);
|
||||
mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self),
|
||||
MM_MODEM_3GPP_REGISTRATION_STATE_IDLE,
|
||||
MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
|
||||
MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN,
|
||||
0, 0);
|
||||
g_simple_async_result_take_error (ctx->result, error);
|
||||
register_in_3gpp_network_context_complete_and_free (ctx);
|
||||
return;
|
||||
@@ -2221,10 +2224,12 @@ run_all_3gpp_registration_checks_ready (MMBroadbandModem *self,
|
||||
mm_dbg ("3GPP registration check timed out");
|
||||
mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self),
|
||||
MM_MODEM_3GPP_REGISTRATION_STATE_IDLE,
|
||||
MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
|
||||
MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN,
|
||||
0, 0);
|
||||
mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self),
|
||||
MM_MODEM_3GPP_REGISTRATION_STATE_IDLE,
|
||||
MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
|
||||
MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN,
|
||||
0, 0);
|
||||
g_simple_async_result_take_error (
|
||||
ctx->result,
|
||||
mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT));
|
||||
@@ -2257,10 +2262,12 @@ register_in_3gpp_network_ready (MMBroadbandModem *self,
|
||||
/* Propagate error in COPS, if any */
|
||||
mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self),
|
||||
MM_MODEM_3GPP_REGISTRATION_STATE_IDLE,
|
||||
MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
|
||||
MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN,
|
||||
0, 0);
|
||||
mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self),
|
||||
MM_MODEM_3GPP_REGISTRATION_STATE_IDLE,
|
||||
MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
|
||||
MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN,
|
||||
0, 0);
|
||||
g_simple_async_result_take_error (ctx->result, error);
|
||||
register_in_3gpp_network_context_complete_and_free (ctx);
|
||||
return;
|
||||
@@ -2443,14 +2450,16 @@ registration_status_check_ready (MMBroadbandModem *self,
|
||||
mm_iface_modem_3gpp_update_ps_registration_state (
|
||||
MM_IFACE_MODEM_3GPP (self),
|
||||
state,
|
||||
act);
|
||||
act,
|
||||
lac,
|
||||
cid);
|
||||
else
|
||||
mm_iface_modem_3gpp_update_cs_registration_state (
|
||||
MM_IFACE_MODEM_3GPP (self),
|
||||
state,
|
||||
act);
|
||||
|
||||
/* TODO: report LAC/CI location */
|
||||
act,
|
||||
lac,
|
||||
cid);
|
||||
|
||||
g_simple_async_result_set_op_res_gboolean (operation_result, TRUE);
|
||||
}
|
||||
@@ -2578,12 +2587,14 @@ cleanup_registration_sequence_ready (MMBroadbandModem *self,
|
||||
mm_iface_modem_3gpp_update_cs_registration_state (
|
||||
MM_IFACE_MODEM_3GPP (self),
|
||||
MM_MODEM_3GPP_REGISTRATION_STATE_IDLE,
|
||||
MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
|
||||
MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN,
|
||||
0, 0);
|
||||
else
|
||||
mm_iface_modem_3gpp_update_ps_registration_state (
|
||||
MM_IFACE_MODEM_3GPP (self),
|
||||
MM_MODEM_3GPP_REGISTRATION_STATE_IDLE,
|
||||
MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
|
||||
MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN,
|
||||
0, 0);
|
||||
|
||||
/* We're done */
|
||||
g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
|
||||
@@ -4008,7 +4019,7 @@ modem_location_load_capabilities (MMIfaceModemLocation *self,
|
||||
NULL);
|
||||
else
|
||||
g_simple_async_result_set_op_res_gpointer (result,
|
||||
GUINT_TO_POINTER (MM_MODEM_LOCATION_SOURCE_GSM_LAC_CI),
|
||||
GUINT_TO_POINTER (MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI),
|
||||
NULL);
|
||||
|
||||
g_simple_async_result_complete_in_idle (result);
|
||||
|
@@ -10,13 +10,17 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details:
|
||||
*
|
||||
* Copyright (C) 2011 Google, Inc.
|
||||
* Copyright (C) 2011 - 2012 Google, Inc.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <ModemManager.h>
|
||||
#include <libmm-common.h>
|
||||
|
||||
#include "mm-iface-modem.h"
|
||||
#include "mm-iface-modem-location.h"
|
||||
#include "mm-iface-modem-3gpp.h"
|
||||
#include "mm-bearer-3gpp.h"
|
||||
#include "mm-bearer-list.h"
|
||||
@@ -537,33 +541,91 @@ mm_iface_modem_3gpp_run_all_registration_checks (MMIfaceModem3gpp *self,
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#undef STR_REPLY_READY_FN
|
||||
#define STR_REPLY_READY_FN(NAME, DISPLAY) \
|
||||
static void \
|
||||
load_##NAME##_ready (MMIfaceModem3gpp *self, \
|
||||
GAsyncResult *res) \
|
||||
{ \
|
||||
GError *error = NULL; \
|
||||
MmGdbusModem3gpp *skeleton = NULL; \
|
||||
gchar *str; \
|
||||
\
|
||||
str = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_##NAME##_finish (self, res, &error); \
|
||||
if (error) { \
|
||||
mm_warn ("Couldn't load %s: '%s'", DISPLAY, error->message); \
|
||||
g_error_free (error); \
|
||||
return; \
|
||||
} \
|
||||
\
|
||||
g_object_get (self, \
|
||||
MM_IFACE_MODEM_3GPP_DBUS_SKELETON, &skeleton, \
|
||||
NULL); \
|
||||
mm_gdbus_modem3gpp_set_##NAME (skeleton, str); \
|
||||
g_free (str); \
|
||||
g_object_unref (skeleton); \
|
||||
static void
|
||||
load_operator_name_ready (MMIfaceModem3gpp *self,
|
||||
GAsyncResult *res)
|
||||
{
|
||||
GError *error = NULL;
|
||||
MmGdbusModem3gpp *skeleton = NULL;
|
||||
gchar *str;
|
||||
|
||||
str = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_operator_name_finish (self, res, &error);
|
||||
if (error) {
|
||||
mm_warn ("Couldn't load Operator Name: '%s'", error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
STR_REPLY_READY_FN (operator_code, "Operator Code")
|
||||
STR_REPLY_READY_FN (operator_name, "Operator Name")
|
||||
g_object_get (self,
|
||||
MM_IFACE_MODEM_3GPP_DBUS_SKELETON, &skeleton,
|
||||
NULL);
|
||||
mm_gdbus_modem3gpp_set_operator_name (skeleton, str);
|
||||
g_free (str);
|
||||
g_object_unref (skeleton);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_mcc_mnc (const gchar *mccmnc,
|
||||
guint *mcc_out,
|
||||
guint *mnc_out)
|
||||
{
|
||||
guint mccmnc_len;
|
||||
gchar mcc[4] = { 0, 0, 0, 0 };
|
||||
gchar mnc[4] = { 0, 0, 0, 0 };
|
||||
|
||||
mccmnc_len = strlen (mccmnc);
|
||||
if (mccmnc_len != 5 &&
|
||||
mccmnc_len != 6) {
|
||||
mm_dbg ("Unexpected MCC/MNC string '%s'", mccmnc);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memcpy (mcc, mccmnc, 3);
|
||||
/* Not all modems report 6-digit MNCs */
|
||||
memcpy (mnc, mccmnc + 3, 2);
|
||||
if (mccmnc_len == 6)
|
||||
mnc[2] = mccmnc[5];
|
||||
|
||||
*mcc_out = atoi (mcc);
|
||||
*mnc_out = atoi (mnc);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
load_operator_code_ready (MMIfaceModem3gpp *self,
|
||||
GAsyncResult *res)
|
||||
{
|
||||
GError *error = NULL;
|
||||
MmGdbusModem3gpp *skeleton = NULL;
|
||||
gchar *str;
|
||||
|
||||
str = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_operator_code_finish (self, res, &error);
|
||||
if (error) {
|
||||
mm_warn ("Couldn't load Operator Code: '%s'", error->message);
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
g_object_get (self,
|
||||
MM_IFACE_MODEM_3GPP_DBUS_SKELETON, &skeleton,
|
||||
NULL);
|
||||
mm_gdbus_modem3gpp_set_operator_code (skeleton, str);
|
||||
|
||||
/* If we also implement the location interface, update the 3GPP location */
|
||||
if (MM_IS_IFACE_MODEM_LOCATION (self)) {
|
||||
guint mcc = 0;
|
||||
guint mnc = 0;
|
||||
|
||||
if (parse_mcc_mnc (str, &mcc, &mnc))
|
||||
mm_iface_modem_location_3gpp_update_mcc_mnc (MM_IFACE_MODEM_LOCATION (self),
|
||||
mcc,
|
||||
mnc);
|
||||
}
|
||||
|
||||
g_free (str);
|
||||
g_object_unref (skeleton);
|
||||
}
|
||||
|
||||
static void
|
||||
set_bearer_3gpp_connection_allowed (MMBearer *bearer,
|
||||
@@ -641,14 +703,19 @@ bearer_3gpp_connection_forbidden (MMIfaceModem3gpp *self)
|
||||
static void
|
||||
update_registration_state (MMIfaceModem3gpp *self,
|
||||
MMModem3gppRegistrationState new_state,
|
||||
MMModemAccessTechnology access_tech)
|
||||
MMModemAccessTechnology access_tech,
|
||||
gulong location_area_code,
|
||||
gulong cell_id)
|
||||
{
|
||||
MMModem3gppRegistrationState old_state;
|
||||
MMModem3gppRegistrationState old_state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
|
||||
MmGdbusModem3gpp *skeleton = NULL;
|
||||
|
||||
/* Only set new state if different */
|
||||
g_object_get (self,
|
||||
MM_IFACE_MODEM_3GPP_REGISTRATION_STATE, &old_state,
|
||||
MM_IFACE_MODEM_3GPP_DBUS_SKELETON, &skeleton,
|
||||
NULL);
|
||||
|
||||
if (new_state != old_state) {
|
||||
GEnumClass *enum_class;
|
||||
GEnumValue *new_value;
|
||||
@@ -694,8 +761,6 @@ update_registration_state (MMIfaceModem3gpp *self,
|
||||
(GAsyncReadyCallback)load_operator_name_ready,
|
||||
NULL);
|
||||
|
||||
/* TODO: Update signal quality */
|
||||
|
||||
mm_iface_modem_update_access_tech (MM_IFACE_MODEM (self),
|
||||
access_tech,
|
||||
ALL_3GPP_ACCESS_TECHNOLOGIES_MASK);
|
||||
@@ -704,16 +769,30 @@ update_registration_state (MMIfaceModem3gpp *self,
|
||||
SUBSYSTEM_3GPP,
|
||||
MM_MODEM_STATE_REGISTERED,
|
||||
MM_MODEM_STATE_REASON_NONE);
|
||||
|
||||
/* If we also implement the location interface, update the 3GPP location */
|
||||
if (MM_IS_IFACE_MODEM_LOCATION (self))
|
||||
mm_iface_modem_location_3gpp_update_lac_ci (MM_IFACE_MODEM_LOCATION (self),
|
||||
location_area_code,
|
||||
cell_id);
|
||||
break;
|
||||
|
||||
case MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING:
|
||||
case MM_MODEM_3GPP_REGISTRATION_STATE_IDLE:
|
||||
case MM_MODEM_3GPP_REGISTRATION_STATE_DENIED:
|
||||
case MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN:
|
||||
mm_gdbus_modem3gpp_set_operator_code (skeleton, NULL);
|
||||
mm_gdbus_modem3gpp_set_operator_name (skeleton, NULL);
|
||||
|
||||
if (MM_IS_IFACE_MODEM_LOCATION (self))
|
||||
mm_iface_modem_location_3gpp_clear (MM_IFACE_MODEM_LOCATION (self));
|
||||
|
||||
mm_iface_modem_update_access_tech (MM_IFACE_MODEM (self),
|
||||
0,
|
||||
ALL_3GPP_ACCESS_TECHNOLOGIES_MASK);
|
||||
|
||||
bearer_3gpp_connection_forbidden (self);
|
||||
|
||||
mm_iface_modem_update_subsystem_state (
|
||||
MM_IFACE_MODEM (self),
|
||||
SUBSYSTEM_3GPP,
|
||||
@@ -724,6 +803,8 @@ update_registration_state (MMIfaceModem3gpp *self,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (skeleton);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
@@ -785,7 +866,9 @@ get_consolidated_reg_state (RegistrationStateContext *ctx)
|
||||
void
|
||||
mm_iface_modem_3gpp_update_cs_registration_state (MMIfaceModem3gpp *self,
|
||||
MMModem3gppRegistrationState state,
|
||||
MMModemAccessTechnology access_tech)
|
||||
MMModemAccessTechnology access_tech,
|
||||
gulong location_area_code,
|
||||
gulong cell_id)
|
||||
{
|
||||
RegistrationStateContext *ctx;
|
||||
gboolean supported = FALSE;
|
||||
@@ -799,13 +882,19 @@ mm_iface_modem_3gpp_update_cs_registration_state (MMIfaceModem3gpp *self,
|
||||
|
||||
ctx = get_registration_state_context (self);
|
||||
ctx->cs = state;
|
||||
update_registration_state (self, get_consolidated_reg_state (ctx), access_tech);
|
||||
update_registration_state (self,
|
||||
get_consolidated_reg_state (ctx),
|
||||
access_tech,
|
||||
location_area_code,
|
||||
cell_id);
|
||||
}
|
||||
|
||||
void
|
||||
mm_iface_modem_3gpp_update_ps_registration_state (MMIfaceModem3gpp *self,
|
||||
MMModem3gppRegistrationState state,
|
||||
MMModemAccessTechnology access_tech)
|
||||
MMModemAccessTechnology access_tech,
|
||||
gulong location_area_code,
|
||||
gulong cell_id)
|
||||
{
|
||||
RegistrationStateContext *ctx;
|
||||
gboolean supported = FALSE;
|
||||
@@ -819,7 +908,11 @@ mm_iface_modem_3gpp_update_ps_registration_state (MMIfaceModem3gpp *self,
|
||||
|
||||
ctx = get_registration_state_context (self);
|
||||
ctx->ps = state;
|
||||
update_registration_state (self, get_consolidated_reg_state (ctx), access_tech);
|
||||
update_registration_state (self,
|
||||
get_consolidated_reg_state (ctx),
|
||||
access_tech,
|
||||
location_area_code,
|
||||
cell_id);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@@ -217,10 +217,14 @@ void mm_iface_modem_3gpp_shutdown (MMIfaceModem3gpp *self);
|
||||
* the interface asks to run registration state checks. */
|
||||
void mm_iface_modem_3gpp_update_cs_registration_state (MMIfaceModem3gpp *self,
|
||||
MMModem3gppRegistrationState state,
|
||||
MMModemAccessTechnology access_tech);
|
||||
MMModemAccessTechnology access_tech,
|
||||
gulong location_area_code,
|
||||
gulong cell_id);
|
||||
void mm_iface_modem_3gpp_update_ps_registration_state (MMIfaceModem3gpp *self,
|
||||
MMModem3gppRegistrationState state,
|
||||
MMModemAccessTechnology access_tech);
|
||||
MMModemAccessTechnology access_tech,
|
||||
gulong location_area_code,
|
||||
gulong cell_id);
|
||||
|
||||
/* Run all registration checks */
|
||||
void mm_iface_modem_3gpp_run_all_registration_checks (MMIfaceModem3gpp *self,
|
||||
|
Reference in New Issue
Block a user