Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • marin/ModemManager
  • mobile-broadband/ModemManager
  • lkundrak/ModemManager
  • t-8ch/ModemManager
  • rah/ModemManager
  • benchan/ModemManager
  • claudep/ModemManager
  • ebassi/ModemManager
  • dcbw/ModemManager
  • alfonsosanchezbeato/ModemManager
  • xingnifeng/ModemManager
  • paulbartell/ModemManager
  • MiloCasagrande/ModemManager
  • afett/ModemManager
  • svenschwermer/ModemManager
  • cancanxinxin/ModemManager
  • mjablonsky/ModemManager
  • vicamo/ModemManager
  • kraj/ModemManager
  • lisablanco777/ModemManager
  • Laymer/ModemManager
  • mahatma/ModemManager
  • ejcaruso/ModemManager
  • scootergrisen/ModemManager
  • fran.dieguez/ModemManager
  • bgalvani/ModemManager
  • dnlplm/ModemManager
  • c.lobrano/ModemManager
  • lingzangwuhen/ModemManager
  • aleksm/ModemManager
  • alexanderyashin/ModemManager
  • welaq/ModemManager
  • wi24rd/ModemManager
  • sadiq/ModemManager
  • Linaro/ModemManager
  • HED-mstarr/ModemManager
  • kdrobinski/ModemManager
  • emintufan/ModemManager
  • yurchor/ModemManager
  • rafaelff/ModemManager
  • remuswu1019/ModemManager
  • Fanice.luo/ModemManager
  • roman.stratiienko/ModemManager
  • mno294163/ModemManager
  • mozzwald/ModemManager
  • andika/ModemManager
  • fiziyr/ModemManager
  • teijo.kinnunen/ModemManager
  • dakhouya/ModemManager
  • gci/ModemManager
  • alexcani109/ModemManager
  • ArenM/ModemManager
  • bpeterlytx/ModemManager
  • Hagstrom/ModemManager
  • aplazas/ModemManager
  • justinsg/ModemManager
  • carlyin/ModemManager
  • dle0/ModemManager
  • jessy.diamondman/ModemManager
  • steven831926/ModemManager
  • nytowl/ModemManager
  • prescott66/ModemManager
  • ajonsson/ModemManager
  • mkm/ModemManager
  • pholla/ModemManager
  • wicadmin/ModemManager
  • deng.yi/ModemManager
  • madhavadas/ModemManager
  • fmartinsons/ModemManager
  • Nananas/ModemManager
  • loicpoulain/ModemManager
  • rafal.mszal/ModemManager
  • dylanvanassche/ModemManager
  • myrkr/ModemManager
  • mobilekiller742/ModemManager
  • maorui/ModemManager
  • timo.jyrinki/ModemManager
  • luksen/ModemManager
  • stoehraj/ModemManager
  • vpalatin/ModemManager
  • yaron/ModemManager
  • yegorslists/ModemManager
  • NorwayFun/ModemManager
  • takc923/ModemManager
  • zrshuo.zhang/ModemManager
  • zhuzhaoyu_fibocom/ModemManager
  • bentiss/ModemManager
  • Som_SP/ModemManager
  • KingSun/ModemManager
  • eliasr/ModemManager
  • craftyguy/ModemManager
  • 3378897661/ModemManager
  • ShivakuS/ModemManager
  • bmork/ModemManager
  • ivan.mikhanchuk/ModemManager
  • SimonGuan/ModemManager
  • ziyou/ModemManager
  • juliandehm/ModemManager
  • Jarrah/ModemManager
  • a-wai/ModemManager
  • ZhangMingjie/ModemManager
  • felipeborges/ModemManager
  • dirksu/ModemManager
  • conklinjames175/ModemManager
  • agupta/ModemManager
  • Jarvis-Jiang-G/ModemManager
  • qyliss/ModemManager
  • UnitacSW/ModemManager
  • joelselvaraj/ModemManager
  • mips171/ModemManager
  • LeSpocky/ModemManager
  • Benoit_Monin/ModemManager
  • inigomartinez/ModemManager
  • humb3rtoguti3rr3z/ModemManager
  • tpikonen/ModemManager
  • awaittrot/ModemManager
  • prakash_p/ModemManager
  • florencewchan/ModemManager
  • shawnguo/ModemManager
  • seabass/ModemManager
  • laeyraud/ModemManager
  • maciejsszmigiero/ModemManager
  • dansebcar/ModemManager
  • Shiva/ModemManager
  • stranche/ModemManager
  • anugrah/ModemManager
  • matthewvia/ModemManager
  • umohr/ModemManager
  • matlinuxer2/ModemManager
  • feckert/ModemManager
  • jakko/ModemManager
  • elguap0x0/ModemManager
  • Project0/ModemManager
  • Pac-Man/ModemManager
  • raphj/ModemManager
  • DadiBit/modem-manager
  • pholla1/ModemManager
  • jinjian.song/ModemManager
  • nathangoulding/ModemManager
  • sc0w/ModemManager
  • guisil/ModemManager
  • arbruijn/ModemManager
  • alor/ModemManager
  • andrewlassalle/ModemManager
  • sdeziel/ModemManager
  • troth/ModemManager
  • Stephan/ModemManager
  • nfollens/ModemManager
  • kzapalowicz/ModemManager
  • alad/ModemManager
  • quic_akasagga/ModemManager
  • rmao/ModemManager
  • chrta/ModemManager
  • nicholas123/ModemManager
  • aa13q/ModemManager
  • chandupokuru/ModemManager
  • dskorykh/ModemManager
  • skv/ModemManager
  • shawn.xiao/ModemManager
  • pineapplefurly/ModemManager
  • tsabsch/ModemManager
  • hthiery/ModemManager
  • devrtz/ModemManager
  • haata/ModemManager
  • okaestne/ModemManager
  • nmarupaka/ModemManager
  • simdeveloper/ModemManager
  • ShaneParslow/ModemManager
  • dukexinaw/ModemManager
  • james.fu/ModemManager
  • dchard/ModemManager
  • lvoegl/ModemManager
  • zaripov-kamil/ModemManager
  • kbuksha/ModemManager
  • dos/ModemManager
  • airsoup/ModemManager
  • mafolk/ModemManager
  • tomwimmenhove/ModemManager
  • Lauszus/ModemManager
  • ujjwalpande/ModemManager
  • jordimas/ModemManager
  • diekleinekuh/ModemManager
  • agx/ModemManager
  • PeterK/ModemManager
  • QuectelDuke/ModemManager
  • Lupuliang/ModemManager
  • sinaro/ModemManager
  • Jerry.Meng/ModemManager
  • dahopem/ModemManager
  • robimarko/ModemManager
  • ausil/ModemManager
  • Ming-Pei/ModemManager
  • mkrle/ModemManager
  • PaulosV/ModemManager
  • fabio.porcedda/ModemManager
  • kop316/ModemManager
  • rgenoud/ModemManager
  • janro/ModemManager
  • RICCIARDI-Adrien/ModemManager
  • Garfield/ModemManager
  • nt8r/ModemManager
  • floris.sm/ModemManager
  • quic_krelangi/ModemManager
  • bolan/ModemManager
  • svalery/ModemManager
  • kevlhop/ModemManager
  • evetsso/ModemManager
  • i-tek/ModemManager
  • vanillan/ModemManager
  • jean/ModemManager
  • tuxor1337/ModemManager
  • lupuliang5/ModemManager
  • fuzzy7k/ModemManager
  • piotrdrag/ModemManager
  • asusmith/ModemManager
  • Mank.Wang/ModemManager
  • mank/ModemManager
  • sleirsgoevy/ModemManager
  • quic_asusmith/ModemManager
  • cs99/ModemManager
  • barracuda156/ModemManager
  • anaghg/ModemManager
  • stigma/ModemManager
  • biemster/ModemManager
  • zolfa/ModemManager
  • Mank-Netprisma/ModemManager
  • andrew-sayers/ModemManager
  • jmkim/ModemManager
  • maldiran/ModemManager
229 results
Show changes
Commits on Source (2)
......@@ -152,6 +152,10 @@
A <link linkend="MMModem3gppSubscriptionState">MMModem3gppSubscriptionState</link>
value representing the subscription status of the account and whether there
is any data remaining, given as an unsigned integer (signature <literal>"u"</literal>).
Deprecated: 1.10.0. The value of this property can only be obtained with operator
specific logic (e.g. processing specific PCO info), and therefore it doesn't make sense
to expose it in the ModemManager interface.
-->
<property name="SubscriptionState" type="u" access="read" />
......
......@@ -253,14 +253,20 @@ mm_modem_3gpp_get_registration_state (MMModem3gpp *self)
* Get the current subscription status of the account. This value is only
* available after the modem attempts to register with the network.
*
* The value of this property can only be obtained with operator specific logic (e.g.
* processing specific PCO info), and therefore it doesn't make sense to expose it in
* the ModemManager interface.
*
* Returns: A #MMModem3gppSubscriptionState value, specifying the current subscription state.
*
* Deprecated: 1.10.0. The value of this property can only be obtained with operator
* specific logic (e.g. processing specific PCO info), and therefore it doesn't make sense
* to expose it in the ModemManager interface.
*/
MMModem3gppSubscriptionState
mm_modem_3gpp_get_subscription_state (MMModem3gpp *self)
{
g_return_val_if_fail (MM_IS_MODEM_3GPP (self), MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN);
return mm_gdbus_modem3gpp_get_subscription_state (MM_GDBUS_MODEM3GPP (self));
return MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN;
}
/*****************************************************************************/
......
......@@ -76,7 +76,6 @@ const gchar *mm_modem_3gpp_get_operator_name (MMModem3gpp *self);
gchar *mm_modem_3gpp_dup_operator_name (MMModem3gpp *self);
MMModem3gppRegistrationState mm_modem_3gpp_get_registration_state (MMModem3gpp *self);
MMModem3gppSubscriptionState mm_modem_3gpp_get_subscription_state (MMModem3gpp *self);
MMModem3gppFacility mm_modem_3gpp_get_enabled_facility_locks (MMModem3gpp *self);
......@@ -136,6 +135,10 @@ gboolean mm_modem_3gpp_set_eps_ue_mode_operation_sync (MMModem3gpp
GCancellable *cancellable,
GError **error);
/* Deprecated APIs */
G_DEPRECATED
MMModem3gppSubscriptionState mm_modem_3gpp_get_subscription_state (MMModem3gpp *self);
G_END_DECLS
#endif /* _MM_MODEM_3GPP_H_ */
......@@ -67,6 +67,8 @@ struct _MMBroadbandModemAltairLtePrivate {
GRegex *statcm_regex;
/* Regex for PCO notifications */
GRegex *pcoinfo_regex;
GList *pco_list;
};
static MMIfaceModem3gpp *iface_modem_3gpp_parent;
......@@ -413,6 +415,29 @@ modem_3gpp_run_registration_checks_finish (MMIfaceModem3gpp *self,
return g_task_propagate_boolean (G_TASK (res), error);
}
static void
simulate_unprovisioned_subscription_pco_update (MMBroadbandModemAltairLte *self)
{
MMPco *pco;
/* Simulate a %PCOINFO notification issued to the IMS PDN that indicates an
* unprovisioned Verizon SIM. See mm_altair_parse_vendor_pco_info() for the
* detailed format of a %PCOINFO response.
*
* 1,FF00,13018405 is constructed as follows:
*
* 1: CID for IMS PDN
* FF 00: Container ID for the Verizon-specific PCO content
* 13 01 84: Binary coded decimal representation of Verizon MCC/MNC 311/084
* 05: Value indicating an unprovisioned SIM
*/
pco = mm_altair_parse_vendor_pco_info ("%PCOINFO: 1,FF00,13018405", NULL);
g_assert (pco != NULL);
self->priv->pco_list = mm_pco_list_add (self->priv->pco_list, pco);
mm_iface_modem_3gpp_update_pco_list (MM_IFACE_MODEM_3GPP (self), self->priv->pco_list);
g_object_unref (pco);
}
static void
run_registration_checks_subscription_state_ready (MMIfaceModem3gpp *self,
GAsyncResult *res,
......@@ -449,7 +474,7 @@ run_registration_checks_subscription_state_ready (MMIfaceModem3gpp *self,
if (g_strcmp0 ("EPS_AND_NON_EPS_SERVICES_NOT_ALLOWED", ceer_response) == 0) {
mm_dbg ("Registration failed due to unprovisioned SIM.");
mm_iface_modem_3gpp_update_subscription_state (self, MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNPROVISIONED);
simulate_unprovisioned_subscription_pco_update (MM_BROADBAND_MODEM_ALTAIR_LTE (self));
} else {
mm_dbg ("Failed to find a better reason for registration failure.");
}
......@@ -1098,162 +1123,31 @@ modem_3gpp_load_operator_name (MMIfaceModem3gpp *self,
user_data);
}
/*****************************************************************************/
/* Subscription State loading (3GPP interface) */
typedef struct {
gchar *pco_info;
} LoadSubscriptionStateContext;
static void
load_subscription_state_context_free (LoadSubscriptionStateContext *ctx)
{
g_free (ctx->pco_info);
g_slice_free (LoadSubscriptionStateContext, ctx);
}
static MMModem3gppSubscriptionState
altair_vzw_pco_value_to_mm_modem_3gpp_subscription_state (guint pco_value)
{
switch (pco_value) {
case 0:
return MM_MODEM_3GPP_SUBSCRIPTION_STATE_PROVISIONED;
case 3:
return MM_MODEM_3GPP_SUBSCRIPTION_STATE_OUT_OF_DATA;
case 5:
return MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNPROVISIONED;
default:
return MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN;
}
}
static MMModem3gppSubscriptionState
modem_3gpp_load_subscription_state_finish (MMIfaceModem3gpp *self,
GAsyncResult *res,
GError **error)
{
GError *inner_error = NULL;
gssize value;
value = g_task_propagate_int (G_TASK (res), &inner_error);
if (inner_error) {
g_propagate_error (error, inner_error);
return MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN;
}
return (MMModem3gppSubscriptionState)value;
}
static void
altair_get_subscription_state (MMIfaceModem3gpp *self,
GTask *task)
{
LoadSubscriptionStateContext *ctx;
guint pco_value = -1;
GError *error = NULL;
MMModem3gppSubscriptionState subscription_state;
ctx = g_task_get_task_data (task);
mm_dbg ("Parsing vendor PCO info: %s", ctx->pco_info);
pco_value = mm_altair_parse_vendor_pco_info (ctx->pco_info, &error);
if (error) {
g_task_return_error (task, error);
g_object_unref (task);
return;
}
mm_dbg ("PCO value = %d", pco_value);
subscription_state = altair_vzw_pco_value_to_mm_modem_3gpp_subscription_state (pco_value);
g_task_return_int (task, subscription_state);
g_object_unref (task);
}
static void
altair_load_vendor_pco_info_ready (MMIfaceModem3gpp *self,
GAsyncResult *res,
GTask *task)
{
LoadSubscriptionStateContext *ctx;
const gchar *response;
GError *error = NULL;
response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
if (error) {
mm_dbg ("Failed to load vendor PCO info.");
g_task_return_error (task, error);
g_object_unref (task);
return;
}
g_assert (response);
ctx = g_task_get_task_data (task);
ctx->pco_info = g_strdup (response);
altair_get_subscription_state (self, task);
}
static void
modem_3gpp_load_subscription_state (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
LoadSubscriptionStateContext *ctx;
GTask *task;
ctx = g_slice_new0 (LoadSubscriptionStateContext);
task = g_task_new (self, NULL, callback, user_data);
g_task_set_task_data (task, ctx, (GDestroyNotify)load_subscription_state_context_free);
mm_dbg ("Loading vendor PCO info...");
mm_base_modem_at_command (MM_BASE_MODEM (self),
"%PCOINFO?",
6,
FALSE,
(GAsyncReadyCallback)altair_load_vendor_pco_info_ready,
task);
}
/*****************************************************************************/
/* PCOINFO unsolicited event handler */
static void
altair_get_subscription_state_ready (MMBroadbandModemAltairLte *self,
GAsyncResult *res,
gpointer *user_data)
altair_pco_info_changed (MMPortSerialAt *port,
GMatchInfo *match_info,
MMBroadbandModemAltairLte *self)
{
const gchar *pco_info;
MMPco *pco;
GError *error = NULL;
MMModem3gppSubscriptionState subscription_state;
subscription_state = (MMModem3gppSubscriptionState)g_task_propagate_int (G_TASK (res), &error);
pco_info = g_match_info_fetch (match_info, 0);
mm_dbg ("Parsing vendor PCO info: %s", pco_info);
pco = mm_altair_parse_vendor_pco_info (pco_info, &error);
if (error) {
mm_warn ("Couldn't load Subscription State: '%s'", error->message);
mm_warn ("Error parsing vendor PCO info: %s", error->message);
g_error_free (error);
return;
}
if (subscription_state != MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN)
mm_iface_modem_3gpp_update_subscription_state (MM_IFACE_MODEM_3GPP (self), subscription_state);
}
static void
altair_pco_info_changed (MMPortSerialAt *port,
GMatchInfo *match_info,
MMBroadbandModemAltairLte *self)
{
LoadSubscriptionStateContext *ctx;
const gchar *response;
GTask *task;
ctx = g_slice_new0 (LoadSubscriptionStateContext);
response = g_match_info_fetch (match_info, 0);
ctx->pco_info = g_strdup (response);
task = g_task_new (self,
NULL,
(GAsyncReadyCallback)altair_get_subscription_state_ready,
NULL);
g_task_set_task_data (task, ctx, (GDestroyNotify)load_subscription_state_context_free);
altair_get_subscription_state (MM_IFACE_MODEM_3GPP (self), task);
self->priv->pco_list = mm_pco_list_add (self->priv->pco_list, pco);
mm_iface_modem_3gpp_update_pco_list (MM_IFACE_MODEM_3GPP (self), self->priv->pco_list);
g_object_unref (pco);
}
/*****************************************************************************/
......@@ -1413,8 +1307,6 @@ iface_modem_3gpp_init (MMIfaceModem3gpp *iface)
iface->load_operator_code_finish = modem_3gpp_load_operator_code_finish;
iface->load_operator_name = modem_3gpp_load_operator_name;
iface->load_operator_name_finish = modem_3gpp_load_operator_name_finish;
iface->load_subscription_state = modem_3gpp_load_subscription_state;
iface->load_subscription_state_finish = modem_3gpp_load_subscription_state_finish;
}
static void
......
......@@ -141,62 +141,17 @@ mm_altair_parse_cid (const gchar *response, GError **error)
/*****************************************************************************/
/* %PCOINFO response parser */
typedef enum {
MM_VZW_PCO_PROVISIONED = 0,
MM_VZW_PCO_LIMIT_REACHED = 1,
MM_VZW_PCO_OUT_OF_DATA = 3,
MM_VZW_PCO_UNPROVISIONED = 5
} MMVzwPco;
static guint
altair_extract_vzw_pco_value (const gchar *pco_payload, GError **error)
{
GRegex *regex;
GMatchInfo *match_info;
guint pco_value = -1;
/* Extract PCO value from PCO payload.
* The PCO value in the VZW network is after the VZW PLMN (MCC+MNC 311-480).
*/
regex = g_regex_new ("130184(\\d+)", G_REGEX_RAW, 0, NULL);
g_assert (regex);
if (!g_regex_match_full (regex,
pco_payload,
strlen (pco_payload),
0,
0,
&match_info,
error)) {
g_match_info_free (match_info);
g_regex_unref (regex);
return -1;
}
if (!g_match_info_matches (match_info) ||
!mm_get_uint_from_match_info (match_info, 1, &pco_value))
g_set_error (error,
MM_CORE_ERROR,
MM_CORE_ERROR_FAILED,
"Failed to parse PCO value from PCO payload: '%s'",
pco_payload);
g_match_info_free (match_info);
g_regex_unref (regex);
return pco_value;
}
guint
MMPco *
mm_altair_parse_vendor_pco_info (const gchar *pco_info, GError **error)
{
GRegex *regex;
GMatchInfo *match_info;
guint pco_value = -1;
MMPco *pco = NULL;
gint num_matches;
if (!pco_info[0])
/* No APNs configured, all done */
return -1;
return NULL;
/* Expected %PCOINFO response:
*
......@@ -210,7 +165,7 @@ mm_altair_parse_vendor_pco_info (const gchar *pco_info, GError **error)
if (!g_regex_match_full (regex, pco_info, strlen (pco_info), 0, 0, &match_info, error)) {
g_match_info_free (match_info);
g_regex_unref (regex);
return -1;
return NULL;
}
num_matches = g_match_info_get_match_count (match_info);
......@@ -222,13 +177,19 @@ mm_altair_parse_vendor_pco_info (const gchar *pco_info, GError **error)
num_matches);
g_match_info_free (match_info);
g_regex_unref (regex);
return -1;
return NULL;
}
while (g_match_info_matches (match_info)) {
guint pco_cid;
gchar *pco_id;
gchar *pco_payload;
gsize pco_payload_len;
gchar *pco_payload_bytes = NULL;
gsize pco_payload_bytes_len;
guint8 pco_prefix[6];
GByteArray *pco_raw;
gsize pco_raw_len;
if (!mm_get_uint_from_match_info (match_info, 1, &pco_cid)) {
g_set_error (error,
......@@ -239,6 +200,12 @@ mm_altair_parse_vendor_pco_info (const gchar *pco_info, GError **error)
break;
}
/* We are only interested in IMS and Internet PDN PCO. */
if (pco_cid != MM_ALTAIR_IMS_PDN_CID && pco_cid != MM_ALTAIR_INTERNET_PDN_CID) {
g_match_info_next (match_info, error);
continue;
}
pco_id = mm_get_string_unquoted_from_match_info (match_info, 3);
if (!pco_id) {
g_set_error (error,
......@@ -265,20 +232,64 @@ mm_altair_parse_vendor_pco_info (const gchar *pco_info, GError **error)
break;
}
pco_value = altair_extract_vzw_pco_value (pco_payload, error);
pco_payload_len = strlen (pco_payload);
if (pco_payload_len % 2 == 0)
pco_payload_bytes = mm_utils_hexstr2bin (pco_payload, &pco_payload_bytes_len);
g_free (pco_payload);
/* We are only interested in IMS and Internet PDN PCO. */
if (pco_cid == MM_ALTAIR_IMS_PDN_CID || pco_cid == MM_ALTAIR_INTERNET_PDN_CID) {
if (!pco_payload_bytes) {
g_set_error (error,
MM_CORE_ERROR,
MM_CORE_ERROR_FAILED,
"Invalid PCO payload from PCO info: '%s'",
pco_info);
break;
}
pco_value = -1;
g_match_info_next (match_info, error);
/* Protocol Configuration Options (PCO) is an information element with an
* identifier (IEI) 0x27 and contains between 3 and 253 octets. See 3GPP TS
* 24.008 for more details on PCO.
*
* NOTE: The standard uses one-based indexing, but to better correlate to the
* code, zero-based indexing is used in the description hereinafter.
*
* Octet | Value
* --------+--------------------------------------------
* 0 | PCO IEI (= 0x27)
* 1 | Length of PCO contents (= total length - 2)
* 2 | bit 7 : ext
* | bit 6 to 3 : spare (= 0b0000)
* | bit 2 to 0 : Configuration protocol
* 3 to 4 | Element 1 ID
* 5 | Length of element 1 contents
* 6 to m | Element 1 contents
* ... |
*/
pco_raw_len = sizeof (pco_prefix) + pco_payload_bytes_len;
pco_prefix[0] = 0x27;
pco_prefix[1] = pco_raw_len - 2;
pco_prefix[2] = 0x80;
/* Verizon uses element ID 0xFF00 for carrier-specific PCO content. */
pco_prefix[3] = 0xFF;
pco_prefix[4] = 0x00;
pco_prefix[5] = pco_payload_bytes_len;
pco_raw = g_byte_array_sized_new (pco_raw_len);
g_byte_array_append (pco_raw, pco_prefix, sizeof (pco_prefix));
g_byte_array_append (pco_raw, (guint8 *)pco_payload_bytes, pco_payload_bytes_len);
g_free (pco_payload_bytes);
pco = mm_pco_new ();
mm_pco_set_session_id (pco, pco_cid);
mm_pco_set_complete (pco, TRUE);
mm_pco_set_data (pco, pco_raw->data, pco_raw->len);
g_byte_array_unref (pco_raw);
break;
}
g_match_info_free (match_info);
g_regex_unref (regex);
return pco_value;
return pco;
}
......@@ -19,6 +19,9 @@
#include <glib.h>
#define _LIBMM_INSIDE_MM
#include <libmm-glib.h>
/* Bands response parser */
GArray *mm_altair_parse_bands_response (const gchar *response);
......@@ -30,6 +33,6 @@ gchar *mm_altair_parse_ceer_response (const gchar *response,
guint mm_altair_parse_cid (const gchar *response, GError **error);
/* %PCOINFO response parser */
guint mm_altair_parse_vendor_pco_info (const gchar *pco_info, GError **error);
MMPco *mm_altair_parse_vendor_pco_info (const gchar *pco_info, GError **error);
#endif /* MM_MODEM_HELPERS_ALTAIR_H */
......@@ -16,6 +16,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <glib.h>
#include <glib-object.h>
#include <locale.h>
......@@ -59,7 +60,7 @@ typedef struct {
} CeerTest;
static const CeerTest ceer_tests[] = {
{ "", "" }, /* Special case, sometimes the response is empty, treat it as a valid response. */
{ "", "" }, /* Special case, sometimes the response is empty, treat it as a good response. */
{ "+CEER:", "" },
{ "+CEER: EPS_AND_NON_EPS_SERVICES_NOT_ALLOWED", "EPS_AND_NON_EPS_SERVICES_NOT_ALLOWED" },
{ "+CEER: NO_SUITABLE_CELLS_IN_TRACKING_AREA", "NO_SUITABLE_CELLS_IN_TRACKING_AREA" },
......@@ -97,45 +98,81 @@ test_parse_cid (void)
g_assert (mm_altair_parse_cid ("%CGINFO:blah", NULL) == -1);
}
static void
test_parse_vendor_pco_info (void)
{
guint pco_value;
/*****************************************************************************/
/* Test %PCOINFO responses */
typedef struct {
const gchar *pco_info;
guint32 session_id;
gsize pco_data_size;
guint8 pco_data[50];
} TestValidPcoInfo;
static const TestValidPcoInfo good_pco_infos[] = {
/* Valid PCO values */
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO: 1,1,FF00,13018400", NULL);
g_assert (pco_value == 0);
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO: 1,1,FF00,13018403", NULL);
g_assert (pco_value == 3);
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO: 1,1,FF00,13018405", NULL);
g_assert (pco_value == 5);
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO: 1,3,FF00,13018400", NULL);
g_assert (pco_value == 0);
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO: 1,3,FF00,13018403", NULL);
g_assert (pco_value == 3);
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO: 1,3,FF00,13018405", NULL);
g_assert (pco_value == 5);
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO:1,FF00,13018400", NULL);
g_assert (pco_value == 0);
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO:1,FF00,13018403", NULL);
g_assert (pco_value == 3);
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO:1,FF00,13018405", NULL);
g_assert (pco_value == 5);
/* Different container */
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO: 1,3,F000,13018401", NULL);
g_assert (pco_value == -1);
/* Invalid CID */
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO: 1,2,FF00,13018401", NULL);
g_assert (pco_value == -1);
{ "%PCOINFO: 1,1,FF00,13018400", 1, 10,
{ 0x27, 0x08, 0x80, 0xFF, 0x00, 0x04, 0x13, 0x01, 0x84, 0x00 } },
{ "%PCOINFO: 1,1,FF00,13018403", 1, 10,
{ 0x27, 0x08, 0x80, 0xFF, 0x00, 0x04, 0x13, 0x01, 0x84, 0x03 } },
{ "%PCOINFO: 1,1,FF00,13018405", 1, 10,
{ 0x27, 0x08, 0x80, 0xFF, 0x00, 0x04, 0x13, 0x01, 0x84, 0x05 } },
{ "%PCOINFO: 1,3,FF00,13018400", 3, 10,
{ 0x27, 0x08, 0x80, 0xFF, 0x00, 0x04, 0x13, 0x01, 0x84, 0x00 } },
{ "%PCOINFO: 1,3,FF00,13018403", 3, 10,
{ 0x27, 0x08, 0x80, 0xFF, 0x00, 0x04, 0x13, 0x01, 0x84, 0x03 } },
{ "%PCOINFO: 1,3,FF00,13018405", 3, 10,
{ 0x27, 0x08, 0x80, 0xFF, 0x00, 0x04, 0x13, 0x01, 0x84, 0x05 } },
{ "%PCOINFO:1,FF00,13018400", 1, 10,
{ 0x27, 0x08, 0x80, 0xFF, 0x00, 0x04, 0x13, 0x01, 0x84, 0x00 } },
{ "%PCOINFO:1,FF00,13018403", 1, 10,
{ 0x27, 0x08, 0x80, 0xFF, 0x00, 0x04, 0x13, 0x01, 0x84, 0x03 } },
{ "%PCOINFO:1,FF00,13018405", 1, 10,
{ 0x27, 0x08, 0x80, 0xFF, 0x00, 0x04, 0x13, 0x01, 0x84, 0x05 } },
/* Different payload */
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO: 1,3,FF00,13018501", NULL);
g_assert (pco_value == -1);
/* Bad PCO info */
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO: blah,blah,FF00,13018401", NULL);
g_assert (pco_value == -1);
{ "%PCOINFO: 1,3,FF00,130185", 3, 9,
{ 0x27, 0x07, 0x80, 0xFF, 0x00, 0x03, 0x13, 0x01, 0x85 } },
/* Multiline PCO info */
pco_value = mm_altair_parse_vendor_pco_info ("%PCOINFO: 1,2,FF00,13018400\r\n%PCOINFO: 1,3,FF00,13018403", NULL);
g_assert (pco_value == 3);
{ "%PCOINFO: 1,2,FF00,13018400\r\n%PCOINFO: 1,3,FF00,13018403", 3, 10,
{ 0x27, 0x08, 0x80, 0xFF, 0x00, 0x04, 0x13, 0x01, 0x84, 0x03 } },
};
static const gchar *bad_pco_infos[] = {
/* Different container */
"%PCOINFO: 1,3,F000,13018401",
/* Ingood CID */
"%PCOINFO: 1,2,FF00,13018401",
/* Bad PCO info */
"%PCOINFO: blah,blah,FF00,13018401",
/* Bad PCO payload */
"%PCOINFO: 1,1,FF00,130184011",
};
static void
test_parse_vendor_pco_info (void)
{
MMPco *pco;
guint i;
for (i = 0; i < G_N_ELEMENTS (good_pco_infos); ++i) {
const guint8 *pco_data;
gsize pco_data_size;
pco = mm_altair_parse_vendor_pco_info (good_pco_infos[i].pco_info, NULL);
g_assert (pco != NULL);
g_assert_cmpuint (mm_pco_get_session_id (pco), ==, good_pco_infos[i].session_id);
g_assert (mm_pco_is_complete (pco));
pco_data = mm_pco_get_data (pco, &pco_data_size);
g_assert (pco_data != NULL);
g_assert_cmpuint (pco_data_size, ==, good_pco_infos[i].pco_data_size);
g_assert_cmpmem (pco_data, pco_data_size,
good_pco_infos[i].pco_data, good_pco_infos[i].pco_data_size);
g_object_unref (pco);
}
for (i = 0; i < G_N_ELEMENTS (bad_pco_infos); ++i) {
pco = mm_altair_parse_vendor_pco_info (bad_pco_infos[i], NULL);
g_assert (pco == NULL);
}
}
int main (int argc, char **argv)
......
......@@ -3954,37 +3954,6 @@ modem_3gpp_load_operator_name (MMIfaceModem3gpp *self,
mm_base_modem_at_command (MM_BASE_MODEM (self), "+COPS?", 3, FALSE, callback, user_data);
}
/*****************************************************************************/
/* Subscription State Loading (3GPP interface) */
static MMModem3gppSubscriptionState
modem_3gpp_load_subscription_state_finish (MMIfaceModem3gpp *self,
GAsyncResult *res,
GError **error)
{
GError *inner_error = NULL;
gssize value;
value = g_task_propagate_int (G_TASK (res), &inner_error);
if (inner_error) {
g_propagate_error (error, inner_error);
return MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN;
}
return (MMModem3gppSubscriptionState)value;
}
static void
modem_3gpp_load_subscription_state (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
GTask *task;
task = g_task_new (self, NULL, callback, user_data);
g_task_return_int (task, MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN);
g_object_unref (task);
}
/*****************************************************************************/
/* UE mode of operation for EPS loading (3GPP interface) */
......@@ -11182,8 +11151,6 @@ iface_modem_3gpp_init (MMIfaceModem3gpp *iface)
iface->load_operator_code_finish = modem_3gpp_load_operator_code_finish;
iface->load_operator_name = modem_3gpp_load_operator_name;
iface->load_operator_name_finish = modem_3gpp_load_operator_name_finish;
iface->load_subscription_state = modem_3gpp_load_subscription_state;
iface->load_subscription_state_finish = modem_3gpp_load_subscription_state_finish;
iface->run_registration_checks = modem_3gpp_run_registration_checks;
iface->run_registration_checks_finish = modem_3gpp_run_registration_checks_finish;
iface->register_in_network = modem_3gpp_register_in_network;
......
......@@ -64,10 +64,6 @@ mm_iface_modem_3gpp_bind_simple_status (MMIfaceModem3gpp *self,
status, MM_SIMPLE_PROPERTY_3GPP_OPERATOR_NAME,
G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
g_object_bind_property (skeleton, "subscription-state",
status, MM_SIMPLE_PROPERTY_3GPP_SUBSCRIPTION_STATE,
G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
g_object_unref (skeleton);
}
......@@ -962,7 +958,6 @@ typedef struct {
MmGdbusModem3gpp *skeleton;
gboolean operator_code_loaded;
gboolean operator_name_loaded;
gboolean subscription_state_loaded;
} ReloadCurrentRegistrationInfoContext;
static void
......@@ -1043,31 +1038,6 @@ load_operator_code_ready (MMIfaceModem3gpp *self,
reload_current_registration_info_context_step (task);
}
static void
load_subscription_state_ready (MMIfaceModem3gpp *self,
GAsyncResult *res,
GTask *task)
{
ReloadCurrentRegistrationInfoContext *ctx;
GError *error = NULL;
MMModem3gppSubscriptionState subscription_state = MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN;
ctx = g_task_get_task_data (task);
subscription_state = MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_subscription_state_finish (self, res, &error);
if (error) {
mm_warn ("Couldn't load Subscription State: '%s'", error->message);
g_error_free (error);
}
if (ctx->skeleton)
mm_gdbus_modem3gpp_set_subscription_state (ctx->skeleton, subscription_state);
ctx->subscription_state_loaded = TRUE;
reload_current_registration_info_context_step (task);
}
static void
reload_current_registration_info_context_step (GTask *task)
{
......@@ -1095,15 +1065,6 @@ reload_current_registration_info_context_step (GTask *task)
return;
}
if (!ctx->subscription_state_loaded) {
/* Launch subscription state update */
MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_subscription_state (
self,
(GAsyncReadyCallback)load_subscription_state_ready,
task);
return;
}
/* If all are loaded, all done */
g_task_return_boolean (task, TRUE);
g_object_unref (task);
......@@ -1147,11 +1108,6 @@ mm_iface_modem_3gpp_reload_current_registration_info (MMIfaceModem3gpp *self,
if (ctx->operator_name_loaded)
mm_gdbus_modem3gpp_set_operator_name (ctx->skeleton, NULL);
ctx->subscription_state_loaded = !(MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_subscription_state &&
MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->load_subscription_state_finish);
if (ctx->subscription_state_loaded)
mm_gdbus_modem3gpp_set_subscription_state (ctx->skeleton, MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN);
reload_current_registration_info_context_step (task);
}
......@@ -1172,19 +1128,6 @@ mm_iface_modem_3gpp_clear_current_operator (MMIfaceModem3gpp *self)
mm_iface_modem_location_3gpp_update_mcc_mnc (MM_IFACE_MODEM_LOCATION (self), 0, 0);
}
static void
clear_subscription_state (MMIfaceModem3gpp *self)
{
MmGdbusModem3gpp *skeleton = NULL;
g_object_get (self,
MM_IFACE_MODEM_3GPP_DBUS_SKELETON, &skeleton,
NULL);
if (!skeleton)
return;
mm_gdbus_modem3gpp_set_subscription_state (skeleton, MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN);
}
/*****************************************************************************/
void
......@@ -1286,13 +1229,6 @@ update_non_registered_state (MMIfaceModem3gpp *self,
/* Not registered neither in home nor roaming network */
mm_iface_modem_3gpp_clear_current_operator (self);
/* The subscription state can be computed in two ways: a) via PCO which is
* sent by the carrier during registration or b) by looking at the
* registration reject error code. If b), we want to make sure we
* preserve the subscription state */
if (reg_state_is_registered (old_state))
clear_subscription_state (self);
/* The property in the interface is bound to the property
* in the skeleton, so just updating here is enough */
g_object_set (self,
......@@ -1429,22 +1365,6 @@ mm_iface_modem_3gpp_update_eps_registration_state (MMIfaceModem3gpp *self,
update_registration_state (self, get_consolidated_reg_state (ctx), TRUE);
}
void
mm_iface_modem_3gpp_update_subscription_state (MMIfaceModem3gpp *self,
MMModem3gppSubscriptionState state)
{
MmGdbusModem3gpp *skeleton = NULL;
g_object_get (self,
MM_IFACE_MODEM_3GPP_DBUS_SKELETON, &skeleton,
NULL);
if (skeleton) {
mm_dbg ("Setting subscription state to: %s", mm_modem_3gpp_subscription_state_get_string (state));
mm_gdbus_modem3gpp_set_subscription_state (skeleton, state);
g_object_unref (skeleton);
}
}
/*****************************************************************************/
typedef struct {
......
......@@ -184,14 +184,6 @@ struct _MMIfaceModem3gpp {
GAsyncResult *res,
GError **error);
/* Loading of the subscription state property */
void (*load_subscription_state) (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
gpointer user_data);
MMModem3gppSubscriptionState (*load_subscription_state_finish) (MMIfaceModem3gpp *self,
GAsyncResult *res,
GError **error);
/* Scan current networks, expect a GList of MMModem3gppNetworkInfo */
void (* scan_networks) (MMIfaceModem3gpp *self,
GAsyncReadyCallback callback,
......