From 5358d6fea0b27ae4c71de6ce0b4d71060906216e Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Sun, 6 Jul 2014 16:50:30 +0200 Subject: sim: rename 'MMSim' to 'MMBaseSim' Just so that we don't have same header names in src/ and /libmm-glib. --- plugins/huawei/mm-broadband-modem-huawei.c | 2 +- plugins/huawei/mm-sim-huawei.c | 34 +- plugins/huawei/mm-sim-huawei.h | 18 +- plugins/iridium/mm-broadband-modem-iridium.c | 2 +- plugins/iridium/mm-sim-iridium.c | 28 +- plugins/iridium/mm-sim-iridium.h | 18 +- plugins/mbm/mm-broadband-modem-mbm.c | 2 +- plugins/mbm/mm-sim-mbm.c | 30 +- plugins/mbm/mm-sim-mbm.h | 18 +- plugins/nokia/mm-broadband-modem-nokia.c | 2 +- plugins/nokia/mm-sim-nokia.c | 24 +- plugins/nokia/mm-sim-nokia.h | 18 +- plugins/novatel/mm-broadband-modem-novatel-lte.c | 2 +- plugins/novatel/mm-sim-novatel-lte.c | 22 +- plugins/novatel/mm-sim-novatel-lte.h | 18 +- plugins/pantech/mm-broadband-modem-pantech.c | 2 +- plugins/pantech/mm-sim-pantech.c | 30 +- plugins/pantech/mm-sim-pantech.h | 18 +- plugins/sierra/mm-common-sierra.c | 2 +- plugins/sierra/mm-common-sierra.h | 13 +- plugins/sierra/mm-sim-sierra.c | 22 +- plugins/sierra/mm-sim-sierra.h | 18 +- src/Makefile.am | 4 +- src/mm-base-sim.c | 1809 +++++++++++++++++++++ src/mm-base-sim.h | 168 ++ src/mm-broadband-modem-mbim.c | 2 +- src/mm-broadband-modem-qmi.c | 2 +- src/mm-broadband-modem.c | 20 +- src/mm-iface-modem-3gpp.c | 6 +- src/mm-iface-modem-simple.c | 16 +- src/mm-iface-modem.c | 22 +- src/mm-iface-modem.h | 8 +- src/mm-sim-mbim.c | 80 +- src/mm-sim-mbim.h | 18 +- src/mm-sim-qmi.c | 72 +- src/mm-sim-qmi.h | 18 +- src/mm-sim.c | 1811 ---------------------- src/mm-sim.h | 168 -- 38 files changed, 2283 insertions(+), 2284 deletions(-) create mode 100644 src/mm-base-sim.c create mode 100644 src/mm-base-sim.h delete mode 100644 src/mm-sim.c delete mode 100644 src/mm-sim.h diff --git a/plugins/huawei/mm-broadband-modem-huawei.c b/plugins/huawei/mm-broadband-modem-huawei.c index 3a7bb33f3..9cbbfb854 100644 --- a/plugins/huawei/mm-broadband-modem-huawei.c +++ b/plugins/huawei/mm-broadband-modem-huawei.c @@ -3158,7 +3158,7 @@ huawei_modem_power_down (MMIfaceModem *self, /*****************************************************************************/ /* Create SIM (Modem interface) */ -static MMSim * +static MMBaseSim * huawei_modem_create_sim_finish (MMIfaceModem *self, GAsyncResult *res, GError **error) diff --git a/plugins/huawei/mm-sim-huawei.c b/plugins/huawei/mm-sim-huawei.c index 62fc41ee5..4bb8f0826 100644 --- a/plugins/huawei/mm-sim-huawei.c +++ b/plugins/huawei/mm-sim-huawei.c @@ -31,13 +31,13 @@ #include "mm-sim-huawei.h" -G_DEFINE_TYPE (MMSimHuawei, mm_sim_huawei, MM_TYPE_SIM); +G_DEFINE_TYPE (MMSimHuawei, mm_sim_huawei, MM_TYPE_BASE_SIM) /*****************************************************************************/ /* SIM identifier loading */ static gchar * -load_sim_identifier_finish (MMSim *self, +load_sim_identifier_finish (MMBaseSim *self, GAsyncResult *res, GError **error) { @@ -59,7 +59,7 @@ parent_load_sim_identifier_ready (MMSimHuawei *self, GError *error = NULL; gchar *simid; - simid = MM_SIM_CLASS (mm_sim_huawei_parent_class)->load_sim_identifier_finish (MM_SIM (self), res, &error); + simid = MM_BASE_SIM_CLASS (mm_sim_huawei_parent_class)->load_sim_identifier_finish (MM_BASE_SIM (self), res, &error); if (simid) g_simple_async_result_set_op_res_gpointer (simple, simid, g_free); else @@ -74,7 +74,7 @@ iccid_read_ready (MMBaseModem *modem, GAsyncResult *res, GSimpleAsyncResult *simple) { - MMSim *self; + MMBaseSim *self; const gchar *response; const gchar *p; char *parsed; @@ -97,22 +97,22 @@ iccid_read_ready (MMBaseModem *modem, error: /* Chain up to parent method; older devices don't support ^ICCID */ - self = MM_SIM (g_async_result_get_source_object (G_ASYNC_RESULT (simple))); - MM_SIM_CLASS (mm_sim_huawei_parent_class)->load_sim_identifier (self, - (GAsyncReadyCallback) parent_load_sim_identifier_ready, - simple); + self = MM_BASE_SIM (g_async_result_get_source_object (G_ASYNC_RESULT (simple))); + MM_BASE_SIM_CLASS (mm_sim_huawei_parent_class)->load_sim_identifier (self, + (GAsyncReadyCallback) parent_load_sim_identifier_ready, + simple); g_object_unref (self); } static void -load_sim_identifier (MMSim *self, +load_sim_identifier (MMBaseSim *self, GAsyncReadyCallback callback, gpointer user_data) { MMBaseModem *modem = NULL; g_object_get (self, - MM_SIM_MODEM, &modem, + MM_BASE_SIM_MODEM, &modem, NULL); mm_dbg ("loading (Huawei) SIM identifier..."); @@ -131,7 +131,7 @@ load_sim_identifier (MMSim *self, /*****************************************************************************/ -MMSim * +MMBaseSim * mm_sim_huawei_new_finish (GAsyncResult *res, GError **error) { @@ -146,9 +146,9 @@ mm_sim_huawei_new_finish (GAsyncResult *res, return NULL; /* Only export valid SIMs */ - mm_sim_export (MM_SIM (sim)); + mm_base_sim_export (MM_BASE_SIM (sim)); - return MM_SIM (sim); + return MM_BASE_SIM (sim); } void @@ -162,7 +162,7 @@ mm_sim_huawei_new (MMBaseModem *modem, cancellable, callback, user_data, - MM_SIM_MODEM, modem, + MM_BASE_SIM_MODEM, modem, NULL); } @@ -174,8 +174,8 @@ mm_sim_huawei_init (MMSimHuawei *self) static void mm_sim_huawei_class_init (MMSimHuaweiClass *klass) { - MMSimClass *sim_class = MM_SIM_CLASS (klass); + MMBaseSimClass *base_sim_class = MM_BASE_SIM_CLASS (klass); - sim_class->load_sim_identifier = load_sim_identifier; - sim_class->load_sim_identifier_finish = load_sim_identifier_finish; + base_sim_class->load_sim_identifier = load_sim_identifier; + base_sim_class->load_sim_identifier_finish = load_sim_identifier_finish; } diff --git a/plugins/huawei/mm-sim-huawei.h b/plugins/huawei/mm-sim-huawei.h index dfd0d2904..eeeefbaf6 100644 --- a/plugins/huawei/mm-sim-huawei.h +++ b/plugins/huawei/mm-sim-huawei.h @@ -21,7 +21,7 @@ #include #include -#include "mm-sim.h" +#include "mm-base-sim.h" #define MM_TYPE_SIM_HUAWEI (mm_sim_huawei_get_type ()) #define MM_SIM_HUAWEI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_SIM_HUAWEI, MMSimHuawei)) @@ -34,20 +34,20 @@ typedef struct _MMSimHuawei MMSimHuawei; typedef struct _MMSimHuaweiClass MMSimHuaweiClass; struct _MMSimHuawei { - MMSim parent; + MMBaseSim parent; }; struct _MMSimHuaweiClass { - MMSimClass parent; + MMBaseSimClass parent; }; GType mm_sim_huawei_get_type (void); -void mm_sim_huawei_new (MMBaseModem *modem, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -MMSim *mm_sim_huawei_new_finish (GAsyncResult *res, - GError **error); +void mm_sim_huawei_new (MMBaseModem *modem, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +MMBaseSim *mm_sim_huawei_new_finish (GAsyncResult *res, + GError **error); #endif /* MM_SIM_HUAWEI_H */ diff --git a/plugins/iridium/mm-broadband-modem-iridium.c b/plugins/iridium/mm-broadband-modem-iridium.c index 8000c5dd6..c64e8d2df 100644 --- a/plugins/iridium/mm-broadband-modem-iridium.c +++ b/plugins/iridium/mm-broadband-modem-iridium.c @@ -257,7 +257,7 @@ load_supported_modes (MMIfaceModem *self, /*****************************************************************************/ /* Create SIM (Modem inteface) */ -static MMSim * +static MMBaseSim * create_sim_finish (MMIfaceModem *self, GAsyncResult *res, GError **error) diff --git a/plugins/iridium/mm-sim-iridium.c b/plugins/iridium/mm-sim-iridium.c index 9d77d7858..1240e6af1 100644 --- a/plugins/iridium/mm-sim-iridium.c +++ b/plugins/iridium/mm-sim-iridium.c @@ -27,11 +27,11 @@ #include "mm-sim-iridium.h" -G_DEFINE_TYPE (MMSimIridium, mm_sim_iridium, MM_TYPE_SIM); +G_DEFINE_TYPE (MMSimIridium, mm_sim_iridium, MM_TYPE_BASE_SIM) /*****************************************************************************/ -MMSim * +MMBaseSim * mm_sim_iridium_new_finish (GAsyncResult *res, GError **error) { @@ -46,9 +46,9 @@ mm_sim_iridium_new_finish (GAsyncResult *res, return NULL; /* Only export valid SIMs */ - mm_sim_export (MM_SIM (sim)); + mm_base_sim_export (MM_BASE_SIM (sim)); - return MM_SIM (sim); + return MM_BASE_SIM (sim); } void @@ -62,7 +62,7 @@ mm_sim_iridium_new (MMBaseModem *modem, cancellable, callback, user_data, - MM_SIM_MODEM, modem, + MM_BASE_SIM_MODEM, modem, NULL); } @@ -74,15 +74,15 @@ mm_sim_iridium_init (MMSimIridium *self) static void mm_sim_iridium_class_init (MMSimIridiumClass *klass) { - MMSimClass *sim_class = MM_SIM_CLASS (klass); + MMBaseSimClass *base_sim_class = MM_BASE_SIM_CLASS (klass); /* Skip querying the SIM card info, not supported by Iridium modems */ - sim_class->load_sim_identifier = NULL; - sim_class->load_sim_identifier_finish = NULL; - sim_class->load_imsi = NULL; - sim_class->load_imsi_finish = NULL; - sim_class->load_operator_identifier = NULL; - sim_class->load_operator_identifier_finish = NULL; - sim_class->load_operator_name = NULL; - sim_class->load_operator_name_finish = NULL; + base_sim_class->load_sim_identifier = NULL; + base_sim_class->load_sim_identifier_finish = NULL; + base_sim_class->load_imsi = NULL; + base_sim_class->load_imsi_finish = NULL; + base_sim_class->load_operator_identifier = NULL; + base_sim_class->load_operator_identifier_finish = NULL; + base_sim_class->load_operator_name = NULL; + base_sim_class->load_operator_name_finish = NULL; } diff --git a/plugins/iridium/mm-sim-iridium.h b/plugins/iridium/mm-sim-iridium.h index 0150cb1ee..2f3e29165 100644 --- a/plugins/iridium/mm-sim-iridium.h +++ b/plugins/iridium/mm-sim-iridium.h @@ -20,7 +20,7 @@ #include #include -#include "mm-sim.h" +#include "mm-base-sim.h" #define MM_TYPE_SIM_IRIDIUM (mm_sim_iridium_get_type ()) #define MM_SIM_IRIDIUM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_SIM_IRIDIUM, MMSimIridium)) @@ -33,20 +33,20 @@ typedef struct _MMSimIridium MMSimIridium; typedef struct _MMSimIridiumClass MMSimIridiumClass; struct _MMSimIridium { - MMSim parent; + MMBaseSim parent; }; struct _MMSimIridiumClass { - MMSimClass parent; + MMBaseSimClass parent; }; GType mm_sim_iridium_get_type (void); -void mm_sim_iridium_new (MMBaseModem *modem, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -MMSim *mm_sim_iridium_new_finish (GAsyncResult *res, - GError **error); +void mm_sim_iridium_new (MMBaseModem *modem, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +MMBaseSim *mm_sim_iridium_new_finish (GAsyncResult *res, + GError **error); #endif /* MM_SIM_IRIDIUM_H */ diff --git a/plugins/mbm/mm-broadband-modem-mbm.c b/plugins/mbm/mm-broadband-modem-mbm.c index 7c2d1de2a..0eaa65a7e 100644 --- a/plugins/mbm/mm-broadband-modem-mbm.c +++ b/plugins/mbm/mm-broadband-modem-mbm.c @@ -136,7 +136,7 @@ modem_create_bearer (MMIfaceModem *self, /*****************************************************************************/ /* Create SIM (Modem interface) */ -static MMSim * +static MMBaseSim * create_sim_finish (MMIfaceModem *self, GAsyncResult *res, GError **error) diff --git a/plugins/mbm/mm-sim-mbm.c b/plugins/mbm/mm-sim-mbm.c index 437669bfc..a1e1a76ee 100644 --- a/plugins/mbm/mm-sim-mbm.c +++ b/plugins/mbm/mm-sim-mbm.c @@ -28,7 +28,7 @@ #include "mm-base-modem-at.h" #include "mm-sim-mbm.h" -G_DEFINE_TYPE (MMSimMbm, mm_sim_mbm, MM_TYPE_SIM); +G_DEFINE_TYPE (MMSimMbm, mm_sim_mbm, MM_TYPE_BASE_SIM) /*****************************************************************************/ /* SEND PIN/PUK (Generic implementation) */ @@ -52,7 +52,7 @@ send_pin_puk_context_complete_and_free (SendPinPukContext *ctx) } static gboolean -common_send_pin_puk_finish (MMSim *self, +common_send_pin_puk_finish (MMBaseSim *self, GAsyncResult *res, GError **error) { @@ -133,7 +133,7 @@ send_pin_puk_ready (MMBaseModem *modem, } static void -common_send_pin_puk (MMSim *self, +common_send_pin_puk (MMBaseSim *self, const gchar *pin, const gchar *puk, GAsyncReadyCallback callback, @@ -149,7 +149,7 @@ common_send_pin_puk (MMSim *self, user_data, common_send_pin_puk); g_object_get (ctx->self, - MM_SIM_MODEM, &ctx->modem, + MM_BASE_SIM_MODEM, &ctx->modem, NULL); command = (puk ? @@ -165,7 +165,7 @@ common_send_pin_puk (MMSim *self, } static void -send_puk (MMSim *self, +send_puk (MMBaseSim *self, const gchar *puk, const gchar *new_pin, GAsyncReadyCallback callback, @@ -175,7 +175,7 @@ send_puk (MMSim *self, } static void -send_pin (MMSim *self, +send_pin (MMBaseSim *self, const gchar *pin, GAsyncReadyCallback callback, gpointer user_data) @@ -185,7 +185,7 @@ send_pin (MMSim *self, /*****************************************************************************/ -MMSim * +MMBaseSim * mm_sim_mbm_new_finish (GAsyncResult *res, GError **error) { @@ -200,9 +200,9 @@ mm_sim_mbm_new_finish (GAsyncResult *res, return NULL; /* Only export valid SIMs */ - mm_sim_export (MM_SIM (sim)); + mm_base_sim_export (MM_BASE_SIM (sim)); - return MM_SIM (sim); + return MM_BASE_SIM (sim); } void @@ -216,7 +216,7 @@ mm_sim_mbm_new (MMBaseModem *modem, cancellable, callback, user_data, - MM_SIM_MODEM, modem, + MM_BASE_SIM_MODEM, modem, NULL); } @@ -228,10 +228,10 @@ mm_sim_mbm_init (MMSimMbm *self) static void mm_sim_mbm_class_init (MMSimMbmClass *klass) { - MMSimClass *sim_class = MM_SIM_CLASS (klass); + MMBaseSimClass *base_sim_class = MM_BASE_SIM_CLASS (klass); - sim_class->send_pin = send_pin; - sim_class->send_pin_finish = common_send_pin_puk_finish; - sim_class->send_puk = send_puk; - sim_class->send_puk_finish = common_send_pin_puk_finish; + base_sim_class->send_pin = send_pin; + base_sim_class->send_pin_finish = common_send_pin_puk_finish; + base_sim_class->send_puk = send_puk; + base_sim_class->send_puk_finish = common_send_pin_puk_finish; } diff --git a/plugins/mbm/mm-sim-mbm.h b/plugins/mbm/mm-sim-mbm.h index 18e920fd5..1d843242e 100644 --- a/plugins/mbm/mm-sim-mbm.h +++ b/plugins/mbm/mm-sim-mbm.h @@ -19,7 +19,7 @@ #include #include -#include "mm-sim.h" +#include "mm-base-sim.h" #define MM_TYPE_SIM_MBM (mm_sim_mbm_get_type ()) #define MM_SIM_MBM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_SIM_MBM, MMSimMbm)) @@ -32,20 +32,20 @@ typedef struct _MMSimMbm MMSimMbm; typedef struct _MMSimMbmClass MMSimMbmClass; struct _MMSimMbm { - MMSim parent; + MMBaseSim parent; }; struct _MMSimMbmClass { - MMSimClass parent; + MMBaseSimClass parent; }; GType mm_sim_mbm_get_type (void); -void mm_sim_mbm_new (MMBaseModem *modem, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -MMSim *mm_sim_mbm_new_finish (GAsyncResult *res, - GError **error); +void mm_sim_mbm_new (MMBaseModem *modem, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +MMBaseSim *mm_sim_mbm_new_finish (GAsyncResult *res, + GError **error); #endif /* MM_SIM_MBM_H */ diff --git a/plugins/nokia/mm-broadband-modem-nokia.c b/plugins/nokia/mm-broadband-modem-nokia.c index 26f6d0704..21e76dd8e 100644 --- a/plugins/nokia/mm-broadband-modem-nokia.c +++ b/plugins/nokia/mm-broadband-modem-nokia.c @@ -47,7 +47,7 @@ G_DEFINE_TYPE_EXTENDED (MMBroadbandModemNokia, mm_broadband_modem_nokia, MM_TYPE /*****************************************************************************/ /* Create SIM (Modem interface) */ -static MMSim * +static MMBaseSim * create_sim_finish (MMIfaceModem *self, GAsyncResult *res, GError **error) diff --git a/plugins/nokia/mm-sim-nokia.c b/plugins/nokia/mm-sim-nokia.c index 6497b0412..043d63499 100644 --- a/plugins/nokia/mm-sim-nokia.c +++ b/plugins/nokia/mm-sim-nokia.c @@ -26,11 +26,11 @@ #include "mm-sim-nokia.h" -G_DEFINE_TYPE (MMSimNokia, mm_sim_nokia, MM_TYPE_SIM); +G_DEFINE_TYPE (MMSimNokia, mm_sim_nokia, MM_TYPE_BASE_SIM) /*****************************************************************************/ -MMSim * +MMBaseSim * mm_sim_nokia_new_finish (GAsyncResult *res, GError **error) { @@ -45,9 +45,9 @@ mm_sim_nokia_new_finish (GAsyncResult *res, return NULL; /* Only export valid SIMs */ - mm_sim_export (MM_SIM (sim)); + mm_base_sim_export (MM_BASE_SIM (sim)); - return MM_SIM (sim); + return MM_BASE_SIM (sim); } void @@ -61,7 +61,7 @@ mm_sim_nokia_new (MMBaseModem *modem, cancellable, callback, user_data, - MM_SIM_MODEM, modem, + MM_BASE_SIM_MODEM, modem, NULL); } @@ -73,13 +73,13 @@ mm_sim_nokia_init (MMSimNokia *self) static void mm_sim_nokia_class_init (MMSimNokiaClass *klass) { - MMSimClass *sim_class = MM_SIM_CLASS (klass); + MMBaseSimClass *base_sim_class = MM_BASE_SIM_CLASS (klass); /* Skip querying most SIM card info, +CRSM not supported by Nokia modems */ - sim_class->load_sim_identifier = NULL; - sim_class->load_sim_identifier_finish = NULL; - sim_class->load_operator_identifier = NULL; - sim_class->load_operator_identifier_finish = NULL; - sim_class->load_operator_name = NULL; - sim_class->load_operator_name_finish = NULL; + base_sim_class->load_sim_identifier = NULL; + base_sim_class->load_sim_identifier_finish = NULL; + base_sim_class->load_operator_identifier = NULL; + base_sim_class->load_operator_identifier_finish = NULL; + base_sim_class->load_operator_name = NULL; + base_sim_class->load_operator_name_finish = NULL; } diff --git a/plugins/nokia/mm-sim-nokia.h b/plugins/nokia/mm-sim-nokia.h index 222309796..05d6e2b13 100644 --- a/plugins/nokia/mm-sim-nokia.h +++ b/plugins/nokia/mm-sim-nokia.h @@ -19,7 +19,7 @@ #include #include -#include "mm-sim.h" +#include "mm-base-sim.h" #define MM_TYPE_SIM_NOKIA (mm_sim_nokia_get_type ()) #define MM_SIM_NOKIA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_SIM_NOKIA, MMSimNokia)) @@ -32,20 +32,20 @@ typedef struct _MMSimNokia MMSimNokia; typedef struct _MMSimNokiaClass MMSimNokiaClass; struct _MMSimNokia { - MMSim parent; + MMBaseSim parent; }; struct _MMSimNokiaClass { - MMSimClass parent; + MMBaseSimClass parent; }; GType mm_sim_nokia_get_type (void); -void mm_sim_nokia_new (MMBaseModem *modem, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -MMSim *mm_sim_nokia_new_finish (GAsyncResult *res, - GError **error); +void mm_sim_nokia_new (MMBaseModem *modem, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +MMBaseSim *mm_sim_nokia_new_finish (GAsyncResult *res, + GError **error); #endif /* MM_SIM_NOKIA_H */ diff --git a/plugins/novatel/mm-broadband-modem-novatel-lte.c b/plugins/novatel/mm-broadband-modem-novatel-lte.c index f4f2d9dca..499aafe7a 100644 --- a/plugins/novatel/mm-broadband-modem-novatel-lte.c +++ b/plugins/novatel/mm-broadband-modem-novatel-lte.c @@ -128,7 +128,7 @@ modem_create_bearer (MMIfaceModem *self, /*****************************************************************************/ /* Create SIM (Modem interface) */ -static MMSim * +static MMBaseSim * modem_create_sim_finish (MMIfaceModem *self, GAsyncResult *res, GError **error) diff --git a/plugins/novatel/mm-sim-novatel-lte.c b/plugins/novatel/mm-sim-novatel-lte.c index 489dd02e1..41d30411e 100644 --- a/plugins/novatel/mm-sim-novatel-lte.c +++ b/plugins/novatel/mm-sim-novatel-lte.c @@ -29,13 +29,13 @@ #include "mm-sim-novatel-lte.h" -G_DEFINE_TYPE (MMSimNovatelLte, mm_sim_novatel_lte, MM_TYPE_SIM); +G_DEFINE_TYPE (MMSimNovatelLte, mm_sim_novatel_lte, MM_TYPE_BASE_SIM) /*****************************************************************************/ /* IMSI loading */ static gchar * -load_imsi_finish (MMSim *self, +load_imsi_finish (MMBaseSim *self, GAsyncResult *res, GError **error) { @@ -176,14 +176,14 @@ imsi_read_ready (MMBaseModem *modem, } static void -load_imsi (MMSim *self, +load_imsi (MMBaseSim *self, GAsyncReadyCallback callback, gpointer user_data) { MMBaseModem *modem = NULL; g_object_get (self, - MM_SIM_MODEM, &modem, + MM_BASE_SIM_MODEM, &modem, NULL); mm_dbg ("loading (Novatel LTE) IMSI..."); @@ -202,7 +202,7 @@ load_imsi (MMSim *self, /*****************************************************************************/ -MMSim * +MMBaseSim * mm_sim_novatel_lte_new_finish (GAsyncResult *res, GError **error) { @@ -217,9 +217,9 @@ mm_sim_novatel_lte_new_finish (GAsyncResult *res, return NULL; /* Only export valid SIMs */ - mm_sim_export (MM_SIM (sim)); + mm_base_sim_export (MM_BASE_SIM (sim)); - return MM_SIM (sim); + return MM_BASE_SIM (sim); } void @@ -233,7 +233,7 @@ mm_sim_novatel_lte_new (MMBaseModem *modem, cancellable, callback, user_data, - MM_SIM_MODEM, modem, + MM_BASE_SIM_MODEM, modem, NULL); } @@ -245,8 +245,8 @@ mm_sim_novatel_lte_init (MMSimNovatelLte *self) static void mm_sim_novatel_lte_class_init (MMSimNovatelLteClass *klass) { - MMSimClass *sim_class = MM_SIM_CLASS (klass); + MMBaseSimClass *base_sim_class = MM_BASE_SIM_CLASS (klass); - sim_class->load_imsi = load_imsi; - sim_class->load_imsi_finish = load_imsi_finish; + base_sim_class->load_imsi = load_imsi; + base_sim_class->load_imsi_finish = load_imsi_finish; } diff --git a/plugins/novatel/mm-sim-novatel-lte.h b/plugins/novatel/mm-sim-novatel-lte.h index 8beaea19e..df8f38e6c 100644 --- a/plugins/novatel/mm-sim-novatel-lte.h +++ b/plugins/novatel/mm-sim-novatel-lte.h @@ -19,7 +19,7 @@ #include #include -#include "mm-sim.h" +#include "mm-base-sim.h" #define MM_TYPE_SIM_NOVATEL_LTE (mm_sim_novatel_lte_get_type ()) #define MM_SIM_NOVATEL_LTE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_SIM_NOVATEL_LTE, MMSimNovatelLte)) @@ -32,20 +32,20 @@ typedef struct _MMSimNovatelLte MMSimNovatelLte; typedef struct _MMSimNovatelLteClass MMSimNovatelLteClass; struct _MMSimNovatelLte { - MMSim parent; + MMBaseSim parent; }; struct _MMSimNovatelLteClass { - MMSimClass parent; + MMBaseSimClass parent; }; GType mm_sim_novatel_lte_get_type (void); -void mm_sim_novatel_lte_new (MMBaseModem *modem, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -MMSim *mm_sim_novatel_lte_new_finish (GAsyncResult *res, - GError **error); +void mm_sim_novatel_lte_new (MMBaseModem *modem, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +MMBaseSim *mm_sim_novatel_lte_new_finish (GAsyncResult *res, + GError **error); #endif /* MM_SIM_NOVATEL_LTE_H */ diff --git a/plugins/pantech/mm-broadband-modem-pantech.c b/plugins/pantech/mm-broadband-modem-pantech.c index 12b3d550d..65464569a 100644 --- a/plugins/pantech/mm-broadband-modem-pantech.c +++ b/plugins/pantech/mm-broadband-modem-pantech.c @@ -86,7 +86,7 @@ load_supported_storages (MMIfaceModemMessaging *self, /*****************************************************************************/ /* Create SIM (Modem interface) */ -static MMSim * +static MMBaseSim * create_sim_finish (MMIfaceModem *self, GAsyncResult *res, GError **error) diff --git a/plugins/pantech/mm-sim-pantech.c b/plugins/pantech/mm-sim-pantech.c index 74aa21727..0cf61e976 100644 --- a/plugins/pantech/mm-sim-pantech.c +++ b/plugins/pantech/mm-sim-pantech.c @@ -26,11 +26,11 @@ #include "mm-sim-pantech.h" -G_DEFINE_TYPE (MMSimPantech, mm_sim_pantech, MM_TYPE_SIM); +G_DEFINE_TYPE (MMSimPantech, mm_sim_pantech, MM_TYPE_BASE_SIM) /*****************************************************************************/ -MMSim * +MMBaseSim * mm_sim_pantech_new_finish (GAsyncResult *res, GError **error) { @@ -45,23 +45,23 @@ mm_sim_pantech_new_finish (GAsyncResult *res, return NULL; /* Only export valid SIMs */ - mm_sim_export (MM_SIM (sim)); + mm_base_sim_export (MM_BASE_SIM (sim)); - return MM_SIM (sim); + return MM_BASE_SIM (sim); } void mm_sim_pantech_new (MMBaseModem *modem, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { g_async_initable_new_async (MM_TYPE_SIM_PANTECH, G_PRIORITY_DEFAULT, cancellable, callback, user_data, - MM_SIM_MODEM, modem, + MM_BASE_SIM_MODEM, modem, NULL); } @@ -73,14 +73,14 @@ mm_sim_pantech_init (MMSimPantech *self) static void mm_sim_pantech_class_init (MMSimPantechClass *klass) { - MMSimClass *sim_class = MM_SIM_CLASS (klass); + MMBaseSimClass *base_sim_class = MM_BASE_SIM_CLASS (klass); /* Skip querying most SIM card info, +CRSM just shoots the Pantech modems * (at least the UMW190) in the head */ - sim_class->load_sim_identifier = NULL; - sim_class->load_sim_identifier_finish = NULL; - sim_class->load_operator_identifier = NULL; - sim_class->load_operator_identifier_finish = NULL; - sim_class->load_operator_name = NULL; - sim_class->load_operator_name_finish = NULL; + base_sim_class->load_sim_identifier = NULL; + base_sim_class->load_sim_identifier_finish = NULL; + base_sim_class->load_operator_identifier = NULL; + base_sim_class->load_operator_identifier_finish = NULL; + base_sim_class->load_operator_name = NULL; + base_sim_class->load_operator_name_finish = NULL; } diff --git a/plugins/pantech/mm-sim-pantech.h b/plugins/pantech/mm-sim-pantech.h index 0c4a19c50..8d227645e 100644 --- a/plugins/pantech/mm-sim-pantech.h +++ b/plugins/pantech/mm-sim-pantech.h @@ -19,7 +19,7 @@ #include #include -#include "mm-sim.h" +#include "mm-base-sim.h" #define MM_TYPE_SIM_PANTECH (mm_sim_pantech_get_type ()) #define MM_SIM_PANTECH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_SIM_PANTECH, MMSimPantech)) @@ -32,20 +32,20 @@ typedef struct _MMSimPantech MMSimPantech; typedef struct _MMSimPantechClass MMSimPantechClass; struct _MMSimPantech { - MMSim parent; + MMBaseSim parent; }; struct _MMSimPantechClass { - MMSimClass parent; + MMBaseSimClass parent; }; GType mm_sim_pantech_get_type (void); -void mm_sim_pantech_new (MMBaseModem *modem, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -MMSim *mm_sim_pantech_new_finish (GAsyncResult *res, - GError **error); +void mm_sim_pantech_new (MMBaseModem *modem, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +MMBaseSim *mm_sim_pantech_new_finish (GAsyncResult *res, + GError **error); #endif /* MM_SIM_PANTECH_H */ diff --git a/plugins/sierra/mm-common-sierra.c b/plugins/sierra/mm-common-sierra.c index 67ca1643e..82a5d7ba7 100644 --- a/plugins/sierra/mm-common-sierra.c +++ b/plugins/sierra/mm-common-sierra.c @@ -242,7 +242,7 @@ mm_common_sierra_load_power_state (MMIfaceModem *self, /*****************************************************************************/ /* Create SIM (Modem interface) */ -MMSim * +MMBaseSim * mm_common_sierra_create_sim_finish (MMIfaceModem *self, GAsyncResult *res, GError **error) diff --git a/plugins/sierra/mm-common-sierra.h b/plugins/sierra/mm-common-sierra.h index a82f87a09..ec206d2a7 100644 --- a/plugins/sierra/mm-common-sierra.h +++ b/plugins/sierra/mm-common-sierra.h @@ -20,6 +20,7 @@ #include "mm-broadband-modem.h" #include "mm-iface-modem.h" +#include "mm-base-sim.h" void mm_common_sierra_load_power_state (MMIfaceModem *self, GAsyncReadyCallback callback, @@ -35,12 +36,12 @@ gboolean mm_common_sierra_modem_power_up_finish (MMIfaceModem *self, GAsyncResult *res, GError **error); -void mm_common_sierra_create_sim (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data); -MMSim *mm_common_sierra_create_sim_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error); +void mm_common_sierra_create_sim (MMIfaceModem *self, + GAsyncReadyCallback callback, + gpointer user_data); +MMBaseSim *mm_common_sierra_create_sim_finish (MMIfaceModem *self, + GAsyncResult *res, + GError **error); void mm_common_sierra_setup_ports (MMBroadbandModem *self); diff --git a/plugins/sierra/mm-sim-sierra.c b/plugins/sierra/mm-sim-sierra.c index a0f0f459f..2c2c5ff69 100644 --- a/plugins/sierra/mm-sim-sierra.c +++ b/plugins/sierra/mm-sim-sierra.c @@ -31,13 +31,13 @@ #include "mm-sim-sierra.h" -G_DEFINE_TYPE (MMSimSierra, mm_sim_sierra, MM_TYPE_SIM); +G_DEFINE_TYPE (MMSimSierra, mm_sim_sierra, MM_TYPE_BASE_SIM) /*****************************************************************************/ /* SIM identifier loading */ static gchar * -load_sim_identifier_finish (MMSim *self, +load_sim_identifier_finish (MMBaseSim *self, GAsyncResult *res, GError **error) { @@ -93,14 +93,14 @@ iccid_read_ready (MMBaseModem *modem, } static void -load_sim_identifier (MMSim *self, +load_sim_identifier (MMBaseSim *self, GAsyncReadyCallback callback, gpointer user_data) { MMBaseModem *modem = NULL; g_object_get (self, - MM_SIM_MODEM, &modem, + MM_BASE_SIM_MODEM, &modem, NULL); mm_dbg ("loading (Sierra) SIM identifier..."); @@ -119,7 +119,7 @@ load_sim_identifier (MMSim *self, /*****************************************************************************/ -MMSim * +MMBaseSim * mm_sim_sierra_new_finish (GAsyncResult *res, GError **error) { @@ -134,9 +134,9 @@ mm_sim_sierra_new_finish (GAsyncResult *res, return NULL; /* Only export valid SIMs */ - mm_sim_export (MM_SIM (sim)); + mm_base_sim_export (MM_BASE_SIM (sim)); - return MM_SIM (sim); + return MM_BASE_SIM (sim); } void @@ -150,7 +150,7 @@ mm_sim_sierra_new (MMBaseModem *modem, cancellable, callback, user_data, - MM_SIM_MODEM, modem, + MM_BASE_SIM_MODEM, modem, NULL); } @@ -162,8 +162,8 @@ mm_sim_sierra_init (MMSimSierra *self) static void mm_sim_sierra_class_init (MMSimSierraClass *klass) { - MMSimClass *sim_class = MM_SIM_CLASS (klass); + MMBaseSimClass *base_sim_class = MM_BASE_SIM_CLASS (klass); - sim_class->load_sim_identifier = load_sim_identifier; - sim_class->load_sim_identifier_finish = load_sim_identifier_finish; + base_sim_class->load_sim_identifier = load_sim_identifier; + base_sim_class->load_sim_identifier_finish = load_sim_identifier_finish; } diff --git a/plugins/sierra/mm-sim-sierra.h b/plugins/sierra/mm-sim-sierra.h index 3595bd941..470d4e957 100644 --- a/plugins/sierra/mm-sim-sierra.h +++ b/plugins/sierra/mm-sim-sierra.h @@ -21,7 +21,7 @@ #include #include -#include "mm-sim.h" +#include "mm-base-sim.h" #define MM_TYPE_SIM_SIERRA (mm_sim_sierra_get_type ()) #define MM_SIM_SIERRA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_SIM_SIERRA, MMSimSierra)) @@ -34,20 +34,20 @@ typedef struct _MMSimSierra MMSimSierra; typedef struct _MMSimSierraClass MMSimSierraClass; struct _MMSimSierra { - MMSim parent; + MMBaseSim parent; }; struct _MMSimSierraClass { - MMSimClass parent; + MMBaseSimClass parent; }; GType mm_sim_sierra_get_type (void); -void mm_sim_sierra_new (MMBaseModem *modem, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -MMSim *mm_sim_sierra_new_finish (GAsyncResult *res, - GError **error); +void mm_sim_sierra_new (MMBaseModem *modem, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +MMBaseSim *mm_sim_sierra_new_finish (GAsyncResult *res, + GError **error); #endif /* MM_SIM_SIERRA_H */ diff --git a/src/Makefile.am b/src/Makefile.am index 7e7693f58..6912b00e7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -175,8 +175,8 @@ ModemManager_SOURCES = \ mm-device.h \ mm-plugin-manager.c \ mm-plugin-manager.h \ - mm-sim.h \ - mm-sim.c \ + mm-base-sim.h \ + mm-base-sim.c \ mm-base-bearer.h \ mm-base-bearer.c \ mm-broadband-bearer.h \ diff --git a/src/mm-base-sim.c b/src/mm-base-sim.c new file mode 100644 index 000000000..104e7f8d8 --- /dev/null +++ b/src/mm-base-sim.c @@ -0,0 +1,1809 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include +#define _LIBMM_INSIDE_MM +#include + +#include "mm-iface-modem.h" +#include "mm-base-sim.h" +#include "mm-base-modem-at.h" +#include "mm-base-modem.h" +#include "mm-log.h" +#include "mm-modem-helpers.h" + +static void async_initable_iface_init (GAsyncInitableIface *iface); + +G_DEFINE_TYPE_EXTENDED (MMBaseSim, mm_base_sim, MM_GDBUS_TYPE_SIM_SKELETON, 0, + G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, + async_initable_iface_init)) + +enum { + PROP_0, + PROP_PATH, + PROP_CONNECTION, + PROP_MODEM, + PROP_LAST +}; + +enum { + SIGNAL_PIN_LOCK_ENABLED, + SIGNAL_LAST +}; + +static GParamSpec *properties[PROP_LAST]; + +struct _MMBaseSimPrivate { + /* The connection to the system bus */ + GDBusConnection *connection; + /* The modem which owns this SIM */ + MMBaseModem *modem; + /* The path where the SIM object is exported */ + gchar *path; +}; + +static guint signals[SIGNAL_LAST] = { 0 }; + +/*****************************************************************************/ + +void +mm_base_sim_export (MMBaseSim *self) +{ + static guint id = 0; + gchar *path; + + path = g_strdup_printf (MM_DBUS_SIM_PREFIX "/%d", id++); + g_object_set (self, + MM_BASE_SIM_PATH, path, + NULL); + g_free (path); +} + +/*****************************************************************************/ +/* CHANGE PIN (Generic implementation) */ + +static gboolean +change_pin_finish (MMBaseSim *self, + GAsyncResult *res, + GError **error) +{ + return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); +} + +static void +change_pin_ready (MMBaseModem *modem, + GAsyncResult *res, + GSimpleAsyncResult *simple) +{ + GError *error = NULL; + + mm_base_modem_at_command_finish (modem, res, &error); + if (error) + g_simple_async_result_take_error (simple, error); + else + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +static void +change_pin (MMBaseSim *self, + const gchar *old_pin, + const gchar *new_pin, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *result; + gchar *command; + + result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + change_pin); + + command = g_strdup_printf ("+CPWD=\"SC\",\"%s\",\"%s\"", + old_pin, + new_pin); + mm_base_modem_at_command (MM_BASE_MODEM (self->priv->modem), + command, + 3, + FALSE, + (GAsyncReadyCallback)change_pin_ready, + result); + g_free (command); +} + +/*****************************************************************************/ +/* CHANGE PIN (DBus call handling) */ + +typedef struct { + MMBaseSim *self; + GDBusMethodInvocation *invocation; + gchar *old_pin; + gchar *new_pin; + GError *save_error; +} HandleChangePinContext; + +static void +handle_change_pin_context_free (HandleChangePinContext *ctx) +{ + g_assert (ctx->save_error == NULL); + + g_object_unref (ctx->invocation); + g_object_unref (ctx->self); + g_free (ctx->old_pin); + g_free (ctx->new_pin); + g_free (ctx); +} + +static void +after_change_update_lock_info_ready (MMIfaceModem *self, + GAsyncResult *res, + HandleChangePinContext *ctx) +{ + /* We just want to ensure that we tried to update the unlock + * retries, no big issue if it failed */ + mm_iface_modem_update_lock_info_finish (self, res, NULL); + + if (ctx->save_error) { + g_dbus_method_invocation_take_error (ctx->invocation, ctx->save_error); + ctx->save_error = NULL; + } else { + mm_gdbus_sim_complete_change_pin (MM_GDBUS_SIM (ctx->self), ctx->invocation); + } + + handle_change_pin_context_free (ctx); +} + +static void +handle_change_pin_ready (MMBaseSim *self, + GAsyncResult *res, + HandleChangePinContext *ctx) +{ + MMModemLock known_lock = MM_MODEM_LOCK_UNKNOWN; + + if (!MM_BASE_SIM_GET_CLASS (self)->change_pin_finish (self, res, &ctx->save_error)) { + if (g_error_matches (ctx->save_error, + MM_MOBILE_EQUIPMENT_ERROR, + MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK)) + known_lock = MM_MODEM_LOCK_SIM_PUK; + } + + mm_iface_modem_update_lock_info ( + MM_IFACE_MODEM (self->priv->modem), + known_lock, + (GAsyncReadyCallback)after_change_update_lock_info_ready, + ctx); +} + +static void +handle_change_pin_auth_ready (MMBaseModem *modem, + GAsyncResult *res, + HandleChangePinContext *ctx) +{ + GError *error = NULL; + + if (!mm_base_modem_authorize_finish (modem, res, &error)) { + g_dbus_method_invocation_take_error (ctx->invocation, error); + handle_change_pin_context_free (ctx); + return; + } + + /* If changing PIN is not implemented, report an error */ + if (!MM_BASE_SIM_GET_CLASS (ctx->self)->change_pin || + !MM_BASE_SIM_GET_CLASS (ctx->self)->change_pin_finish) { + g_dbus_method_invocation_return_error (ctx->invocation, + MM_CORE_ERROR, + MM_CORE_ERROR_UNSUPPORTED, + "Cannot change PIN: " + "operation not supported"); + handle_change_pin_context_free (ctx); + return; + } + + MM_BASE_SIM_GET_CLASS (ctx->self)->change_pin (ctx->self, + ctx->old_pin, + ctx->new_pin, + (GAsyncReadyCallback)handle_change_pin_ready, + ctx); +} + +static gboolean +handle_change_pin (MMBaseSim *self, + GDBusMethodInvocation *invocation, + const gchar *old_pin, + const gchar *new_pin, + gboolean changed) +{ + HandleChangePinContext *ctx; + + ctx = g_new0 (HandleChangePinContext, 1); + ctx->self = g_object_ref (self); + ctx->invocation = g_object_ref (invocation); + ctx->old_pin = g_strdup (old_pin); + ctx->new_pin = g_strdup (new_pin); + + mm_base_modem_authorize (self->priv->modem, + invocation, + MM_AUTHORIZATION_DEVICE_CONTROL, + (GAsyncReadyCallback)handle_change_pin_auth_ready, + ctx); + return TRUE; +} + +/*****************************************************************************/ +/* ENABLE PIN (Generic implementation) */ + +static gboolean +enable_pin_finish (MMBaseSim *self, + GAsyncResult *res, + GError **error) +{ + return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); +} + +static void +enable_pin_ready (MMBaseModem *modem, + GAsyncResult *res, + GSimpleAsyncResult *simple) +{ + GError *error = NULL; + + mm_base_modem_at_command_finish (modem, res, &error); + if (error) + g_simple_async_result_take_error (simple, error); + else + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +static void +enable_pin (MMBaseSim *self, + const gchar *pin, + gboolean enabled, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *result; + gchar *command; + + result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + enable_pin); + + command = g_strdup_printf ("+CLCK=\"SC\",%d,\"%s\"", + enabled ? 1 : 0, + pin); + mm_base_modem_at_command (MM_BASE_MODEM (self->priv->modem), + command, + 3, + FALSE, + (GAsyncReadyCallback)enable_pin_ready, + result); + g_free (command); +} + +/*****************************************************************************/ +/* ENABLE PIN (DBus call handling) */ + +typedef struct { + MMBaseSim *self; + GDBusMethodInvocation *invocation; + gchar *pin; + gboolean enabled; + GError *save_error; +} HandleEnablePinContext; + +static void +handle_enable_pin_context_free (HandleEnablePinContext *ctx) +{ + g_assert (ctx->save_error == NULL); + + g_object_unref (ctx->invocation); + g_object_unref (ctx->self); + g_free (ctx->pin); + g_free (ctx); +} + +static void +after_enable_update_lock_info_ready (MMIfaceModem *modem, + GAsyncResult *res, + HandleEnablePinContext *ctx) +{ + /* We just want to ensure that we tried to update the unlock + * retries, no big issue if it failed */ + mm_iface_modem_update_lock_info_finish (modem, res, NULL); + + if (ctx->save_error) { + g_dbus_method_invocation_take_error (ctx->invocation, ctx->save_error); + ctx->save_error = NULL; + } else { + /* Signal about the new lock state */ + g_signal_emit (ctx->self, signals[SIGNAL_PIN_LOCK_ENABLED], 0, ctx->enabled); + mm_gdbus_sim_complete_enable_pin (MM_GDBUS_SIM (ctx->self), ctx->invocation); + } + + handle_enable_pin_context_free (ctx); +} + +static void +handle_enable_pin_ready (MMBaseSim *self, + GAsyncResult *res, + HandleEnablePinContext *ctx) +{ + MMModemLock known_lock = MM_MODEM_LOCK_UNKNOWN; + + if (!MM_BASE_SIM_GET_CLASS (self)->enable_pin_finish (self, res, &ctx->save_error)) { + if (g_error_matches (ctx->save_error, + MM_MOBILE_EQUIPMENT_ERROR, + MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK)) + known_lock = MM_MODEM_LOCK_SIM_PUK; + } + + mm_iface_modem_update_lock_info ( + MM_IFACE_MODEM (self->priv->modem), + known_lock, + (GAsyncReadyCallback)after_enable_update_lock_info_ready, + ctx); +} + +static void +handle_enable_pin_auth_ready (MMBaseModem *modem, + GAsyncResult *res, + HandleEnablePinContext *ctx) +{ + GError *error = NULL; + + if (!mm_base_modem_authorize_finish (modem, res, &error)) { + g_dbus_method_invocation_take_error (ctx->invocation, error); + handle_enable_pin_context_free (ctx); + return; + } + + /* If changing PIN is not implemented, report an error */ + if (!MM_BASE_SIM_GET_CLASS (ctx->self)->enable_pin || + !MM_BASE_SIM_GET_CLASS (ctx->self)->enable_pin_finish) { + g_dbus_method_invocation_return_error (ctx->invocation, + MM_CORE_ERROR, + MM_CORE_ERROR_UNSUPPORTED, + "Cannot enable/disable PIN: " + "operation not supported"); + handle_enable_pin_context_free (ctx); + return; + } + + MM_BASE_SIM_GET_CLASS (ctx->self)->enable_pin (ctx->self, + ctx->pin, + ctx->enabled, + (GAsyncReadyCallback)handle_enable_pin_ready, + ctx); +} + +static gboolean +handle_enable_pin (MMBaseSim *self, + GDBusMethodInvocation *invocation, + const gchar *pin, + gboolean enabled) +{ + HandleEnablePinContext *ctx; + + ctx = g_new0 (HandleEnablePinContext, 1); + ctx->self = g_object_ref (self); + ctx->invocation = g_object_ref (invocation); + ctx->pin = g_strdup (pin); + ctx->enabled = enabled; + + mm_base_modem_authorize (self->priv->modem, + invocation, + MM_AUTHORIZATION_DEVICE_CONTROL, + (GAsyncReadyCallback)handle_enable_pin_auth_ready, + ctx); + return TRUE; +} + +/*****************************************************************************/ +/* SEND PIN/PUK (Generic implementation) */ + +static gboolean +common_send_pin_puk_finish (MMBaseSim *self, + GAsyncResult *res, + GError **error) +{ + return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); +} + +static void +send_pin_puk_ready (MMBaseModem *modem, + GAsyncResult *res, + GSimpleAsyncResult *simple) +{ + GError *error = NULL; + + mm_base_modem_at_command_finish (modem, res, &error); + if (error) + g_simple_async_result_take_error (simple, error); + else + g_simple_async_result_set_op_res_gboolean (simple, TRUE); + g_simple_async_result_complete (simple); + g_object_unref (simple); +} + +static void +common_send_pin_puk (MMBaseSim *self, + const gchar *pin, + const gchar *puk, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *result; + gchar *command; + + result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + common_send_pin_puk); + + command = (puk ? + g_strdup_printf ("+CPIN=\"%s\",\"%s\"", puk, pin) : + g_strdup_printf ("+CPIN=\"%s\"", pin)); + + mm_base_modem_at_command (MM_BASE_MODEM (self->priv->modem), + command, + 3, + FALSE, + (GAsyncReadyCallback)send_pin_puk_ready, + result); + g_free (command); +} + +static void +send_puk (MMBaseSim *self, + const gchar *puk, + const gchar *new_pin, + GAsyncReadyCallback callback, + gpointer user_data) +{ + common_send_pin_puk (self, new_pin, puk, callback, user_data); +} + +static void +send_pin (MMBaseSim *self, + const gchar *pin, + GAsyncReadyCallback callback, + gpointer user_data) +{ + common_send_pin_puk (self, pin, NULL, callback, user_data); +} + +/*****************************************************************************/ +/* SEND PIN/PUK (common logic) */ + +typedef struct { + MMBaseSim *self; + GSimpleAsyncResult *result; + GError *save_error; + gulong wait_for_unlock_id; +} SendPinPukContext; + +static void +send_pin_puk_context_complete_and_free (SendPinPukContext *ctx) +{ + if (ctx->wait_for_unlock_id) + g_signal_handler_disconnect (ctx->self->priv->modem, + ctx->wait_for_unlock_id); + if (ctx->save_error) + g_error_free (ctx->save_error); + g_simple_async_result_complete (ctx->result); + g_object_unref (ctx->result); + g_object_unref (ctx->self); + g_free (ctx); +} + +static GError * +error_for_unlock_check (MMModemLock lock) +{ + static const MMMobileEquipmentError errors_for_locks [] = { + MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN, /* MM_MODEM_LOCK_UNKNOWN */ + MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN, /* MM_MODEM_LOCK_NONE */ + MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN, /* MM_MODEM_LOCK_SIM_PIN */ + MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN2, /* MM_MODEM_LOCK_SIM_PIN2 */ + MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK, /* MM_MODEM_LOCK_SIM_PUK */ + MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK2, /* MM_MODEM_LOCK_SIM_PUK2 */ + MM_MOBILE_EQUIPMENT_ERROR_SERVICE_PIN, /* MM_MODEM_LOCK_PH_SP_PIN */ + MM_MOBILE_EQUIPMENT_ERROR_SERVICE_PUK, /* MM_MODEM_LOCK_PH_SP_PUK */ + MM_MOBILE_EQUIPMENT_ERROR_NETWORK_PIN, /* MM_MODEM_LOCK_PH_NET_PIN */ + MM_MOBILE_EQUIPMENT_ERROR_NETWORK_PUK, /* MM_MODEM_LOCK_PH_NET_PUK */ + MM_MOBILE_EQUIPMENT_ERROR_PH_SIM_PIN, /* MM_MODEM_LOCK_PH_SIM_PIN */ + MM_MOBILE_EQUIPMENT_ERROR_CORP_PIN, /* MM_MODEM_LOCK_PH_CORP_PIN */ + MM_MOBILE_EQUIPMENT_ERROR_CORP_PUK, /* MM_MODEM_LOCK_PH_CORP_PUK */ + MM_MOBILE_EQUIPMENT_ERROR_PH_FSIM_PIN, /* MM_MODEM_LOCK_PH_FSIM_PIN */ + MM_MOBILE_EQUIPMENT_ERROR_PH_FSIM_PUK, /* MM_MODEM_LOCK_PH_FSIM_PUK */ + MM_MOBILE_EQUIPMENT_ERROR_NETWORK_SUBSET_PIN, /* MM_MODEM_LOCK_PH_NETSUB_PIN */ + MM_MOBILE_EQUIPMENT_ERROR_NETWORK_SUBSET_PUK, /* MM_MODEM_LOCK_PH_NETSUB_PUK */ + }; + + g_assert (lock >= MM_MODEM_LOCK_UNKNOWN); + g_assert (lock <= MM_MODEM_LOCK_PH_NETSUB_PUK); + + return g_error_new (MM_MOBILE_EQUIPMENT_ERROR, + errors_for_locks[lock], + "Device is locked: '%s'", + mm_modem_lock_get_string (lock)); +} + +gboolean +mm_base_sim_send_pin_finish (MMBaseSim *self, + GAsyncResult *res, + GError **error) +{ + return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); +} + +gboolean +mm_base_sim_send_puk_finish (MMBaseSim *self, + GAsyncResult *res, + GError **error) +{ + return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); +} + +static void +update_lock_info_ready (MMIfaceModem *modem, + GAsyncResult *res, + SendPinPukContext *ctx) +{ + GError *error = NULL; + MMModemLock lock; + + lock = mm_iface_modem_update_lock_info_finish (modem, res, &error); + /* Even if we may be SIM-PIN2/PUK2 locked, we don't consider this an error + * in the PIN/PUK sending */ + if (lock != MM_MODEM_LOCK_NONE && + lock != MM_MODEM_LOCK_SIM_PIN2 && + lock != MM_MODEM_LOCK_SIM_PUK2) { + /* Device is locked. Now: + * - If we got an error in the original send-pin action, report it. + * - If we got an error in the pin-check action, report it. + * - Otherwise, build our own error from the lock code. + */ + if (ctx->save_error) { + g_simple_async_result_take_error (ctx->result, ctx->save_error); + ctx->save_error = NULL; + g_clear_error (&error); + } else if (error) + g_simple_async_result_take_error (ctx->result, error); + else + g_simple_async_result_take_error (ctx->result, + error_for_unlock_check (lock)); + send_pin_puk_context_complete_and_free (ctx); + return; + } + + g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); + send_pin_puk_context_complete_and_free (ctx); +} + +static void +send_pin_ready (MMBaseSim *self, + GAsyncResult *res, + SendPinPukContext *ctx) +{ + MMModemLock known_lock = MM_MODEM_LOCK_UNKNOWN; + + if (!MM_BASE_SIM_GET_CLASS (self)->send_pin_finish (self, res, &ctx->save_error)) { + if (g_error_matches (ctx->save_error, + MM_MOBILE_EQUIPMENT_ERROR, + MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK)) + known_lock = MM_MODEM_LOCK_SIM_PUK; + } + + /* Once pin/puk has been sent, recheck lock */ + mm_iface_modem_update_lock_info ( + MM_IFACE_MODEM (self->priv->modem), + known_lock, + (GAsyncReadyCallback)update_lock_info_ready, + ctx); +} + +static void +send_puk_ready (MMBaseSim *self, + GAsyncResult *res, + SendPinPukContext *ctx) +{ + MM_BASE_SIM_GET_CLASS (self)->send_puk_finish (self, res, &ctx->save_error); + + /* Once pin/puk has been sent, recheck lock */ + mm_iface_modem_update_lock_info (MM_IFACE_MODEM (self->priv->modem), + MM_MODEM_LOCK_UNKNOWN, /* ask */ + (GAsyncReadyCallback)update_lock_info_ready, + ctx); +} + +void +mm_base_sim_send_pin (MMBaseSim *self, + const gchar *pin, + GAsyncReadyCallback callback, + gpointer user_data) +{ + SendPinPukContext *ctx; + + /* If sending PIN is not implemented, report an error */ + if (!MM_BASE_SIM_GET_CLASS (self)->send_pin || + !MM_BASE_SIM_GET_CLASS (self)->send_pin_finish) { + g_simple_async_report_error_in_idle (G_OBJECT (self), + callback, + user_data, + MM_CORE_ERROR, + MM_CORE_ERROR_UNSUPPORTED, + "Cannot send PIN: " + "operation not supported"); + return; + } + + ctx = g_new0 (SendPinPukContext, 1); + ctx->self = g_object_ref (self); + ctx->result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + mm_base_sim_send_pin); + + MM_BASE_SIM_GET_CLASS (self)->send_pin (self, + pin, + (GAsyncReadyCallback)send_pin_ready, + ctx); +} + +void +mm_base_sim_send_puk (MMBaseSim *self, + const gchar *puk, + const gchar *new_pin, + GAsyncReadyCallback callback, + gpointer user_data) +{ + SendPinPukContext *ctx; + + /* If sending PIN is not implemented, report an error */ + if (!MM_BASE_SIM_GET_CLASS (self)->send_puk || + !MM_BASE_SIM_GET_CLASS (self)->send_puk_finish) { + g_simple_async_report_error_in_idle (G_OBJECT (self), + callback, + user_data, + MM_CORE_ERROR, + MM_CORE_ERROR_UNSUPPORTED, + "Cannot send PUK: " + "operation not supported"); + return; + } + + ctx = g_new0 (SendPinPukContext, 1); + ctx->self = g_object_ref (self); + ctx->result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + mm_base_sim_send_puk); + + MM_BASE_SIM_GET_CLASS (self)->send_puk (self, + puk, + new_pin, + (GAsyncReadyCallback)send_puk_ready, + ctx); +} + +/*****************************************************************************/ +/* SEND PIN (DBus call handling) */ + +typedef struct { + MMBaseSim *self; + GDBusMethodInvocation *invocation; + gchar *pin; +} HandleSendPinContext; + +static void +handle_send_pin_context_free (HandleSendPinContext *ctx) +{ + g_object_unref (ctx->invocation); + g_object_unref (ctx->self); + g_free (ctx->pin); + g_free (ctx); +} + +static void +handle_send_pin_ready (MMBaseSim *self, + GAsyncResult *res, + HandleSendPinContext *ctx) +{ + GError *error = NULL; + + if (!mm_base_sim_send_pin_finish (self, res, &error)) + g_dbus_method_invocation_take_error (ctx->invocation, error); + else + mm_gdbus_sim_complete_send_pin (MM_GDBUS_SIM (self), ctx->invocation); + + handle_send_pin_context_free (ctx); +} + +static void +handle_send_pin_auth_ready (MMBaseModem *modem, + GAsyncResult *res, + HandleSendPinContext *ctx) +{ + GError *error = NULL; + + if (!mm_base_modem_authorize_finish (modem, res, &error)) { + g_dbus_method_invocation_take_error (ctx->invocation, error); + handle_send_pin_context_free (ctx); + return; + } + + mm_base_sim_send_pin (ctx->self, + ctx->pin, + (GAsyncReadyCallback)handle_send_pin_ready, + ctx); +} + +static gboolean +handle_send_pin (MMBaseSim *self, + GDBusMethodInvocation *invocation, + const gchar *pin) +{ + HandleSendPinContext *ctx; + + ctx = g_new0 (HandleSendPinContext, 1); + ctx->self = g_object_ref (self); + ctx->invocation = g_object_ref (invocation); + ctx->pin = g_strdup (pin); + + mm_base_modem_authorize (self->priv->modem, + invocation, + MM_AUTHORIZATION_DEVICE_CONTROL, + (GAsyncReadyCallback)handle_send_pin_auth_ready, + ctx); + return TRUE; +} + +/*****************************************************************************/ +/* SEND PUK (DBus call handling) */ + +typedef struct { + MMBaseSim *self; + GDBusMethodInvocation *invocation; + gchar *puk; + gchar *new_pin; +} HandleSendPukContext; + +static void +handle_send_puk_context_free (HandleSendPukContext *ctx) +{ + g_object_unref (ctx->invocation); + g_object_unref (ctx->self); + g_free (ctx->puk); + g_free (ctx->new_pin); + g_free (ctx); +} + +static void +handle_send_puk_ready (MMBaseSim *self, + GAsyncResult *res, + HandleSendPukContext *ctx) +{ + GError *error = NULL; + + if (!mm_base_sim_send_puk_finish (self, res, &error)) + g_dbus_method_invocation_take_error (ctx->invocation, error); + else + mm_gdbus_sim_complete_send_puk (MM_GDBUS_SIM (self), ctx->invocation); + + handle_send_puk_context_free (ctx); +} + +static void +handle_send_puk_auth_ready (MMBaseModem *modem, + GAsyncResult *res, + HandleSendPukContext *ctx) +{ + GError *error = NULL; + + if (!mm_base_modem_authorize_finish (modem, res, &error)) { + g_dbus_method_invocation_take_error (ctx->invocation, error); + handle_send_puk_context_free (ctx); + return; + } + + mm_base_sim_send_puk (ctx->self, + ctx->puk, + ctx->new_pin, + (GAsyncReadyCallback)handle_send_puk_ready, + ctx); +} + +static gboolean +handle_send_puk (MMBaseSim *self, + GDBusMethodInvocation *invocation, + const gchar *puk, + const gchar *new_pin) +{ + HandleSendPukContext *ctx; + + ctx = g_new0 (HandleSendPukContext, 1); + ctx->self = g_object_ref (self); + ctx->invocation = g_object_ref (invocation); + ctx->puk = g_strdup (puk); + ctx->new_pin = g_strdup (new_pin); + + mm_base_modem_authorize (self->priv->modem, + invocation, + MM_AUTHORIZATION_DEVICE_CONTROL, + (GAsyncReadyCallback)handle_send_puk_auth_ready, + ctx); + return TRUE; +} + +/*****************************************************************************/ + +static void +sim_dbus_export (MMBaseSim *self) +{ + GError *error = NULL; + + /* Handle method invocations */ + g_signal_connect (self, + "handle-change-pin", + G_CALLBACK (handle_change_pin), + NULL); + g_signal_connect (self, + "handle-enable-pin", + G_CALLBACK (handle_enable_pin), + NULL); + g_signal_connect (self, + "handle-send-pin", + G_CALLBACK (handle_send_pin), + NULL); + g_signal_connect (self, + "handle-send-puk", + G_CALLBACK (handle_send_puk), + NULL); + + if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self), + self->priv->connection, + self->priv->path, + &error)) { + mm_warn ("couldn't export SIM at '%s': '%s'", + self->priv->path, + error->message); + g_error_free (error); + } +} + +static void +sim_dbus_unexport (MMBaseSim *self) +{ + /* Only unexport if currently exported */ + if (g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (self))) + g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (self)); +} + +/*****************************************************************************/ + +const gchar * +mm_base_sim_get_path (MMBaseSim *self) +{ + return self->priv->path; +} + +/*****************************************************************************/ + +#undef STR_REPLY_READY_FN +#define STR_REPLY_READY_FN(NAME) \ + static void \ + NAME##_command_ready (MMBaseModem *modem, \ + GAsyncResult *res, \ + GSimpleAsyncResult *operation_result) \ + { \ + GError *error = NULL; \ + const gchar *response; \ + \ + response = mm_base_modem_at_command_finish (modem, res, &error); \ + if (error) \ + g_simple_async_result_take_error (operation_result, error); \ + else \ + g_simple_async_result_set_op_res_gpointer (operation_result, \ + (gpointer)response, \ + NULL); \ + \ + g_simple_async_result_complete (operation_result); \ + g_object_unref (operation_result); \ + } + +/*****************************************************************************/ +/* SIM IDENTIFIER */ + +static gchar * +parse_iccid (const gchar *response, + GError **error) +{ + gchar buf[21]; + const gchar *str; + gint sw1; + gint sw2; + gboolean success = FALSE; + + memset (buf, 0, sizeof (buf)); + str = mm_strip_tag (response, "+CRSM:"); + if (sscanf (str, "%d,%d,\"%20c\"", &sw1, &sw2, (char *) &buf) == 3) + success = TRUE; + else { + /* May not include quotes... */ + if (sscanf (str, "%d,%d,%20c", &sw1, &sw2, (char *) &buf) == 3) + success = TRUE; + } + + if (!success) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Could not parse the CRSM response"); + return NULL; + } + + if ((sw1 == 0x90 && sw2 == 0x00) || + (sw1 == 0x91) || + (sw1 == 0x92) || + (sw1 == 0x9f)) { + return mm_3gpp_parse_iccid (buf, error); + } else { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "SIM failed to handle CRSM request (sw1 %d sw2 %d)", + sw1, sw2); + return NULL; + } +} + +static gchar * +load_sim_identifier_finish (MMBaseSim *self, + GAsyncResult *res, + GError **error) +{ + const gchar *result; + gchar *sim_identifier; + + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) + return NULL; + result = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)); + + sim_identifier = parse_iccid (result, error); + if (!sim_identifier) + return NULL; + + mm_dbg ("loaded SIM identifier: %s", sim_identifier); + return sim_identifier; +} + +STR_REPLY_READY_FN (load_sim_identifier) + +static void +load_sim_identifier (MMBaseSim *self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + mm_dbg ("loading SIM identifier..."); + + /* READ BINARY of EFiccid (ICC Identification) ETSI TS 102.221 section 13.2 */ + mm_base_modem_at_command ( + MM_BASE_MODEM (self->priv->modem), + "+CRSM=176,12258,0,0,10", + 20, + FALSE, + (GAsyncReadyCallback)load_sim_identifier_command_ready, + g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + load_sim_identifier)); +} + +/*****************************************************************************/ +/* IMSI */ + +static gchar * +parse_imsi (const gchar *response, + GError **error) +{ + const gchar *s; + gint len; + + g_assert (response != NULL); + + for (s = mm_strip_tag (response, "+CIMI"), len = 0; + *s; + ++s, ++len) { + /* IMSI is a number with 15 or less decimal digits. */ + if (!isdigit (*s) || len > 15) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Invalid +CIMI response '%s'", response ? response : ""); + return NULL; + } + } + + return g_strdup (response); +} + +static gchar * +load_imsi_finish (MMBaseSim *self, + GAsyncResult *res, + GError **error) +{ + const gchar *result; + gchar *imsi; + + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) + return NULL; + result = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)); + + imsi = parse_imsi (result, error); + if (!imsi) + return NULL; + + mm_dbg ("loaded IMSI: %s", imsi); + return imsi; +} + +STR_REPLY_READY_FN (load_imsi) + +static void +load_imsi (MMBaseSim *self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + mm_dbg ("loading IMSI..."); + + mm_base_modem_at_command ( + MM_BASE_MODEM (self->priv->modem), + "+CIMI", + 3, + FALSE, + (GAsyncReadyCallback)load_imsi_command_ready, + g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + load_imsi)); +} + +/*****************************************************************************/ +/* Operator ID */ + +static guint +parse_mnc_length (const gchar *response, + GError **error) +{ + gint sw1; + gint sw2; + gboolean success = FALSE; + gchar hex[51]; + + memset (hex, 0, sizeof (hex)); + if (sscanf (response, "+CRSM:%d,%d,\"%50c\"", &sw1, &sw2, (char *) &hex) == 3) + success = TRUE; + else { + /* May not include quotes... */ + if (sscanf (response, "+CRSM:%d,%d,%50c", &sw1, &sw2, (char *) &hex) == 3) + success = TRUE; + } + + if (!success) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Could not parse the CRSM response"); + return 0; + } + + if ((sw1 == 0x90 && sw2 == 0x00) || + (sw1 == 0x91) || + (sw1 == 0x92) || + (sw1 == 0x9f)) { + gsize buflen = 0; + guint32 mnc_len; + gchar *bin; + + /* Make sure the buffer is only hex characters */ + while (buflen < sizeof (hex) && hex[buflen]) { + if (!isxdigit (hex[buflen])) { + hex[buflen] = 0x0; + break; + } + buflen++; + } + + /* Convert hex string to binary */ + bin = mm_utils_hexstr2bin (hex, &buflen); + if (!bin || buflen < 4) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "SIM returned malformed response '%s'", + hex); + g_free (bin); + return 0; + } + + /* MNC length is byte 4 of this SIM file */ + mnc_len = bin[3] & 0xFF; + if (mnc_len == 2 || mnc_len == 3) { + g_free (bin); + return mnc_len; + } + + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "SIM returned invalid MNC length %d (should be either 2 or 3)", + mnc_len); + g_free (bin); + return 0; + } + + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "SIM failed to handle CRSM request (sw1 %d sw2 %d)", + sw1, sw2); + return 0; +} + +static gchar * +load_operator_identifier_finish (MMBaseSim *self, + GAsyncResult *res, + GError **error) +{ + GError *inner_error = NULL; + const gchar *imsi; + const gchar *result; + guint mnc_length; + + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) + return NULL; + result = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)); + + imsi = mm_gdbus_sim_get_imsi (MM_GDBUS_SIM (self)); + if (!imsi) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Cannot load Operator ID without IMSI"); + return NULL; + } + + mnc_length = parse_mnc_length (result, &inner_error); + if (inner_error) { + g_propagate_error (error, inner_error); + return NULL; + } + + /* Build Operator ID */ + return g_strndup (imsi, 3 + mnc_length); +} + +STR_REPLY_READY_FN (load_operator_identifier) + +static void +load_operator_identifier (MMBaseSim *self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + mm_dbg ("loading Operator ID..."); + + /* READ BINARY of EFad (Administrative Data) ETSI 51.011 section 10.3.18 */ + mm_base_modem_at_command ( + MM_BASE_MODEM (self->priv->modem), + "+CRSM=176,28589,0,0,4", + 10, + FALSE, + (GAsyncReadyCallback)load_operator_identifier_command_ready, + g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + load_operator_identifier)); +} + +/*****************************************************************************/ +/* Operator Name (Service Provider Name) */ + +static gchar * +parse_spn (const gchar *response, + GError **error) +{ + gint sw1; + gint sw2; + gboolean success = FALSE; + gchar hex[51]; + + memset (hex, 0, sizeof (hex)); + if (sscanf (response, "+CRSM:%d,%d,\"%50c\"", &sw1, &sw2, (char *) &hex) == 3) + success = TRUE; + else { + /* May not include quotes... */ + if (sscanf (response, "+CRSM:%d,%d,%50c", &sw1, &sw2, (char *) &hex) == 3) + success = TRUE; + } + + if (!success) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Could not parse the CRSM response"); + return NULL; + } + + if ((sw1 == 0x90 && sw2 == 0x00) || + (sw1 == 0x91) || + (sw1 == 0x92) || + (sw1 == 0x9f)) { + gsize buflen = 0; + gchar *bin; + gchar *utf8; + + /* Make sure the buffer is only hex characters */ + while (buflen < sizeof (hex) && hex[buflen]) { + if (!isxdigit (hex[buflen])) { + hex[buflen] = 0x0; + break; + } + buflen++; + } + + /* Convert hex string to binary */ + bin = mm_utils_hexstr2bin (hex, &buflen); + if (!bin) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "SIM returned malformed response '%s'", + hex); + return NULL; + } + + /* Remove the FF filler at the end */ + while (buflen > 1 && bin[buflen - 1] == (char)0xff) + buflen--; + + /* First byte is metadata; remainder is GSM-7 unpacked into octets; convert to UTF8 */ + utf8 = (gchar *)mm_charset_gsm_unpacked_to_utf8 ((guint8 *)bin + 1, buflen - 1); + g_free (bin); + return utf8; + } + + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "SIM failed to handle CRSM request (sw1 %d sw2 %d)", + sw1, sw2); + return NULL; +} + +static gchar * +load_operator_name_finish (MMBaseSim *self, + GAsyncResult *res, + GError **error) +{ + const gchar *result; + + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) + return NULL; + result = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)); + + return parse_spn (result, error); +} + +STR_REPLY_READY_FN (load_operator_name) + +static void +load_operator_name (MMBaseSim *self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + mm_dbg ("loading Operator Name..."); + + /* READ BINARY of EFspn (Service Provider Name) ETSI 51.011 section 10.3.11 */ + mm_base_modem_at_command ( + MM_BASE_MODEM (self->priv->modem), + "+CRSM=176,28486,0,0,17", + 10, + FALSE, + (GAsyncReadyCallback)load_operator_name_command_ready, + g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + load_operator_name)); +} + +/*****************************************************************************/ + +typedef struct _InitAsyncContext InitAsyncContext; +static void interface_initialization_step (InitAsyncContext *ctx); + +typedef enum { + INITIALIZATION_STEP_FIRST, + INITIALIZATION_STEP_SIM_IDENTIFIER, + INITIALIZATION_STEP_IMSI, + INITIALIZATION_STEP_OPERATOR_ID, + INITIALIZATION_STEP_OPERATOR_NAME, + INITIALIZATION_STEP_LAST +} InitializationStep; + +struct _InitAsyncContext { + GSimpleAsyncResult *result; + GCancellable *cancellable; + MMBaseSim *self; + InitializationStep step; + guint sim_identifier_tries; +}; + +static void +init_async_context_free (InitAsyncContext *ctx) +{ + g_object_unref (ctx->self); + g_object_unref (ctx->result); + if (ctx->cancellable) + g_object_unref (ctx->cancellable); + g_free (ctx); +} + +MMBaseSim * +mm_base_sim_new_finish (GAsyncResult *res, + GError **error) +{ + GObject *source; + GObject *sim; + + source = g_async_result_get_source_object (res); + sim = g_async_initable_new_finish (G_ASYNC_INITABLE (source), res, error); + g_object_unref (source); + + if (!sim) + return NULL; + + /* Only export valid SIMs */ + mm_base_sim_export (MM_BASE_SIM (sim)); + + return MM_BASE_SIM (sim); +} + +static gboolean +initable_init_finish (GAsyncInitable *initable, + GAsyncResult *result, + GError **error) +{ + return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error); +} + +static void +load_sim_identifier_ready (MMBaseSim *self, + GAsyncResult *res, + InitAsyncContext *ctx) +{ + GError *error = NULL; + gchar *simid; + + simid = MM_BASE_SIM_GET_CLASS (ctx->self)->load_sim_identifier_finish (self, res, &error); + if (!simid) { + /* TODO: make the retries gobi-specific? */ + + /* Try one more time... Gobi 1K cards may reply to the first + * request with '+CRSM: 106,134,""' which is bogus because + * subsequent requests work fine. + */ + if (++ctx->sim_identifier_tries < 2) { + g_clear_error (&error); + interface_initialization_step (ctx); + return; + } + + mm_warn ("couldn't load SIM identifier: '%s'", + error ? error->message : "unknown error"); + g_clear_error (&error); + } + + mm_gdbus_sim_set_sim_identifier (MM_GDBUS_SIM (self), simid); + g_free (simid); + + /* Go on to next step */ + ctx->step++; + interface_initialization_step (ctx); +} + +#undef STR_REPLY_READY_FN +#define STR_REPLY_READY_FN(NAME,DISPLAY) \ + static void \ + load_##NAME##_ready (MMBaseSim *self, \ + GAsyncResult *res, \ + InitAsyncContext *ctx) \ + { \ + GError *error = NULL; \ + gchar *val; \ + \ + val = MM_BASE_SIM_GET_CLASS (ctx->self)->load_##NAME##_finish (self, res, &error); \ + mm_gdbus_sim_set_##NAME (MM_GDBUS_SIM (self), val); \ + g_free (val); \ + \ + if (error) { \ + mm_warn ("couldn't load %s: '%s'", DISPLAY, error->message); \ + g_error_free (error); \ + } \ + \ + /* Go on to next step */ \ + ctx->step++; \ + interface_initialization_step (ctx); \ + } + +STR_REPLY_READY_FN (imsi, "IMSI") +STR_REPLY_READY_FN (operator_identifier, "Operator identifier") +STR_REPLY_READY_FN (operator_name, "Operator name") + +static void +interface_initialization_step (InitAsyncContext *ctx) +{ + if (g_cancellable_is_cancelled (ctx->cancellable)) { + g_simple_async_result_set_error (ctx->result, + MM_CORE_ERROR, + MM_CORE_ERROR_CANCELLED, + "Interface initialization cancelled"); + g_simple_async_result_complete_in_idle (ctx->result); + init_async_context_free (ctx); + return; + } + + switch (ctx->step) { + case INITIALIZATION_STEP_FIRST: + /* Fall down to next step */ + ctx->step++; + + case INITIALIZATION_STEP_SIM_IDENTIFIER: + /* SIM ID is meant to be loaded only once during the whole + * lifetime of the modem. Therefore, if we already have them loaded, + * don't try to load them again. */ + if (mm_gdbus_sim_get_sim_identifier (MM_GDBUS_SIM (ctx->self)) == NULL && + MM_BASE_SIM_GET_CLASS (ctx->self)->load_sim_identifier && + MM_BASE_SIM_GET_CLASS (ctx->self)->load_sim_identifier_finish) { + MM_BASE_SIM_GET_CLASS (ctx->self)->load_sim_identifier ( + ctx->self, + (GAsyncReadyCallback)load_sim_identifier_ready, + ctx); + return; + } + /* Fall down to next step */ + ctx->step++; + + case INITIALIZATION_STEP_IMSI: + /* IMSI is meant to be loaded only once during the whole + * lifetime of the modem. Therefore, if we already have them loaded, + * don't try to load them again. */ + if (mm_gdbus_sim_get_imsi (MM_GDBUS_SIM (ctx->self)) == NULL && + MM_BASE_SIM_GET_CLASS (ctx->self)->load_imsi && + MM_BASE_SIM_GET_CLASS (ctx->self)->load_imsi_finish) { + MM_BASE_SIM_GET_CLASS (ctx->self)->load_imsi ( + ctx->self, + (GAsyncReadyCallback)load_imsi_ready, + ctx); + return; + } + /* Fall down to next step */ + ctx->step++; + + case INITIALIZATION_STEP_OPERATOR_ID: + /* Operator ID is meant to be loaded only once during the whole + * lifetime of the modem. Therefore, if we already have them loaded, + * don't try to load them again. */ + if (mm_gdbus_sim_get_operator_identifier (MM_GDBUS_SIM (ctx->self)) == NULL && + MM_BASE_SIM_GET_CLASS (ctx->self)->load_operator_identifier && + MM_BASE_SIM_GET_CLASS (ctx->self)->load_operator_identifier_finish) { + MM_BASE_SIM_GET_CLASS (ctx->self)->load_operator_identifier ( + ctx->self, + (GAsyncReadyCallback)load_operator_identifier_ready, + ctx); + return; + } + /* Fall down to next step */ + ctx->step++; + + case INITIALIZATION_STEP_OPERATOR_NAME: + /* Operator Name is meant to be loaded only once during the whole + * lifetime of the modem. Therefore, if we already have them loaded, + * don't try to load them again. */ + if (mm_gdbus_sim_get_operator_name (MM_GDBUS_SIM (ctx->self)) == NULL && + MM_BASE_SIM_GET_CLASS (ctx->self)->load_operator_name && + MM_BASE_SIM_GET_CLASS (ctx->self)->load_operator_name_finish) { + MM_BASE_SIM_GET_CLASS (ctx->self)->load_operator_name ( + ctx->self, + (GAsyncReadyCallback)load_operator_name_ready, + ctx); + return; + } + /* Fall down to next step */ + ctx->step++; + + case INITIALIZATION_STEP_LAST: + /* We are done without errors! */ + g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); + g_simple_async_result_complete_in_idle (ctx->result); + init_async_context_free (ctx); + return; + } + + + g_assert_not_reached (); +} + +static void +common_init_async (GAsyncInitable *initable, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) + +{ + InitAsyncContext *ctx; + + ctx = g_new (InitAsyncContext, 1); + ctx->self = g_object_ref (initable); + ctx->result = g_simple_async_result_new (G_OBJECT (initable), + callback, + user_data, + common_init_async); + ctx->cancellable = (cancellable ? + g_object_ref (cancellable) : + NULL); + ctx->step = INITIALIZATION_STEP_FIRST; + ctx->sim_identifier_tries = 0; + + interface_initialization_step (ctx); +} + +static void +initable_init_async (GAsyncInitable *initable, + int io_priority, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + mm_gdbus_sim_set_sim_identifier (MM_GDBUS_SIM (initable), NULL); + mm_gdbus_sim_set_imsi (MM_GDBUS_SIM (initable), NULL); + mm_gdbus_sim_set_operator_identifier (MM_GDBUS_SIM (initable), NULL); + mm_gdbus_sim_set_operator_name (MM_GDBUS_SIM (initable), NULL); + + common_init_async (initable, cancellable, callback, user_data); +} + +void +mm_base_sim_new (MMBaseModem *modem, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_async_initable_new_async (MM_TYPE_BASE_SIM, + G_PRIORITY_DEFAULT, + cancellable, + callback, + user_data, + MM_BASE_SIM_MODEM, modem, + NULL); +} + +gboolean +mm_base_sim_initialize_finish (MMBaseSim *self, + GAsyncResult *result, + GError **error) +{ + return initable_init_finish (G_ASYNC_INITABLE (self), result, error); +} + +void +mm_base_sim_initialize (MMBaseSim *self, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + common_init_async (G_ASYNC_INITABLE (self), + cancellable, + callback, + user_data); +} + +static void +set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MMBaseSim *self = MM_BASE_SIM (object); + + switch (prop_id) { + case PROP_PATH: + g_free (self->priv->path); + self->priv->path = g_value_dup_string (value); + + /* Export when we get a DBus connection AND we have a path */ + if (self->priv->path && + self->priv->connection) + sim_dbus_export (self); + break; + case PROP_CONNECTION: + g_clear_object (&self->priv->connection); + self->priv->connection = g_value_dup_object (value); + + /* Export when we get a DBus connection AND we have a path */ + if (!self->priv->connection) + sim_dbus_unexport (self); + else if (self->priv->path) + sim_dbus_export (self); + break; + case PROP_MODEM: + g_clear_object (&self->priv->modem); + self->priv->modem = g_value_dup_object (value); + if (self->priv->modem) { + /* Bind the modem's connection (which is set when it is exported, + * and unset when unexported) to the SIM's connection */ + g_object_bind_property (self->priv->modem, MM_BASE_MODEM_CONNECTION, + self, MM_BASE_SIM_CONNECTION, + G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MMBaseSim *self = MM_BASE_SIM (object); + + switch (prop_id) { + case PROP_PATH: + g_value_set_string (value, self->priv->path); + break; + case PROP_CONNECTION: + g_value_set_object (value, self->priv->connection); + break; + case PROP_MODEM: + g_value_set_object (value, self->priv->modem); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +mm_base_sim_init (MMBaseSim *self) +{ + /* Initialize private data */ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MM_TYPE_BASE_SIM, MMBaseSimPrivate); +} + +static void +finalize (GObject *object) +{ + MMBaseSim *self = MM_BASE_SIM (object); + + g_free (self->priv->path); + + G_OBJECT_CLASS (mm_base_sim_parent_class)->finalize (object); +} + +static void +dispose (GObject *object) +{ + MMBaseSim *self = MM_BASE_SIM (object); + + if (self->priv->connection) { + /* If we arrived here with a valid connection, make sure we unexport + * the object */ + sim_dbus_unexport (self); + g_clear_object (&self->priv->connection); + } + + g_clear_object (&self->priv->modem); + + G_OBJECT_CLASS (mm_base_sim_parent_class)->dispose (object); +} + +static void +async_initable_iface_init (GAsyncInitableIface *iface) +{ + iface->init_async = initable_init_async; + iface->init_finish = initable_init_finish; +} + +static void +mm_base_sim_class_init (MMBaseSimClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (MMBaseSimPrivate)); + + /* Virtual methods */ + object_class->get_property = get_property; + object_class->set_property = set_property; + object_class->finalize = finalize; + object_class->dispose = dispose; + + klass->load_sim_identifier = load_sim_identifier; + klass->load_sim_identifier_finish = load_sim_identifier_finish; + klass->load_imsi = load_imsi; + klass->load_imsi_finish = load_imsi_finish; + klass->load_operator_identifier = load_operator_identifier; + klass->load_operator_identifier_finish = load_operator_identifier_finish; + klass->load_operator_name = load_operator_name; + klass->load_operator_name_finish = load_operator_name_finish; + klass->send_pin = send_pin; + klass->send_pin_finish = common_send_pin_puk_finish; + klass->send_puk = send_puk; + klass->send_puk_finish = common_send_pin_puk_finish; + klass->enable_pin = enable_pin; + klass->enable_pin_finish = enable_pin_finish; + klass->change_pin = change_pin; + klass->change_pin_finish = change_pin_finish; + + properties[PROP_CONNECTION] = + g_param_spec_object (MM_BASE_SIM_CONNECTION, + "Connection", + "GDBus connection to the system bus.", + G_TYPE_DBUS_CONNECTION, + G_PARAM_READWRITE); + g_object_class_install_property (object_class, PROP_CONNECTION, properties[PROP_CONNECTION]); + + properties[PROP_PATH] = + g_param_spec_string (MM_BASE_SIM_PATH, + "Path", + "DBus path of the SIM", + NULL, + G_PARAM_READWRITE); + g_object_class_install_property (object_class, PROP_PATH, properties[PROP_PATH]); + + properties[PROP_MODEM] = + g_param_spec_object (MM_BASE_SIM_MODEM, + "Modem", + "The Modem which owns this SIM", + MM_TYPE_BASE_MODEM, + G_PARAM_READWRITE); + g_object_class_install_property (object_class, PROP_MODEM, properties[PROP_MODEM]); + + /* Signals */ + signals[SIGNAL_PIN_LOCK_ENABLED] = + g_signal_new (MM_BASE_SIM_PIN_LOCK_ENABLED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (MMBaseSimClass, pin_lock_enabled), + NULL, NULL, + g_cclosure_marshal_generic, + G_TYPE_NONE, 1, G_TYPE_BOOLEAN); +} diff --git a/src/mm-base-sim.h b/src/mm-base-sim.h new file mode 100644 index 000000000..19039942b --- /dev/null +++ b/src/mm-base-sim.h @@ -0,0 +1,168 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details: + * + * Author: Aleksander Morgado + * + * Copyright (C) 2011 Google, Inc. + */ + +#ifndef MM_BASE_SIM_H +#define MM_BASE_SIM_H + +#include +#include + +#include +#include "mm-base-modem.h" + +#define MM_TYPE_BASE_SIM (mm_base_sim_get_type ()) +#define MM_BASE_SIM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_BASE_SIM, MMBaseSim)) +#define MM_BASE_SIM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_BASE_SIM, MMBaseSimClass)) +#define MM_IS_BASE_SIM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_BASE_SIM)) +#define MM_IS_BASE_SIM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_BASE_SIM)) +#define MM_BASE_SIM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_BASE_SIM, MMBaseSimClass)) + +typedef struct _MMBaseSim MMBaseSim; +typedef struct _MMBaseSimClass MMBaseSimClass; +typedef struct _MMBaseSimPrivate MMBaseSimPrivate; + +/* Properties */ +#define MM_BASE_SIM_PATH "sim-path" +#define MM_BASE_SIM_CONNECTION "sim-connection" +#define MM_BASE_SIM_MODEM "sim-modem" + +/* Signals */ +#define MM_BASE_SIM_PIN_LOCK_ENABLED "sim-pin-lock-enabled" + +struct _MMBaseSim { + MmGdbusSimSkeleton parent; + MMBaseSimPrivate *priv; +}; + +struct _MMBaseSimClass { + MmGdbusSimSkeletonClass parent; + + /* Load SIM identifier (async) */ + void (* load_sim_identifier) (MMBaseSim *self, + GAsyncReadyCallback callback, + gpointer user_data); + gchar * (* load_sim_identifier_finish) (MMBaseSim *self, + GAsyncResult *res, + GError **error); + + /* Load IMSI (async) */ + void (* load_imsi) (MMBaseSim *self, + GAsyncReadyCallback callback, + gpointer user_data); + gchar * (* load_imsi_finish) (MMBaseSim *self, + GAsyncResult *res, + GError **error); + + /* Load operator identifier (async) */ + void (* load_operator_identifier) (MMBaseSim *self, + GAsyncReadyCallback callback, + gpointer user_data); + gchar * (* load_operator_identifier_finish) (MMBaseSim *self, + GAsyncResult *res, + GError **error); + + /* Load operator name (async) */ + void (* load_operator_name) (MMBaseSim *self, + GAsyncReadyCallback callback, + gpointer user_data); + gchar * (* load_operator_name_finish) (MMBaseSim *self, + GAsyncResult *res, + GError **error); + + /* Change PIN (async) */ + void (* change_pin) (MMBaseSim *self, + const gchar *old_pin, + const gchar *new_pin, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* change_pin_finish) (MMBaseSim *self, + GAsyncResult *res, + GError **error); + + /* Enable PIN (async) */ + void (* enable_pin) (MMBaseSim *self, + const gchar *pin, + gboolean enabled, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* enable_pin_finish) (MMBaseSim *self, + GAsyncResult *res, + GError **error); + + /* Send PIN (async) */ + void (* send_pin) (MMBaseSim *self, + const gchar *pin, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* send_pin_finish) (MMBaseSim *self, + GAsyncResult *res, + GError **error); + + /* Send PUK (async) */ + void (* send_puk) (MMBaseSim *self, + const gchar *puk, + const gchar *new_pin, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* send_puk_finish) (MMBaseSim *self, + GAsyncResult *res, + GError **error); + + /* Signals */ + void (* pin_lock_enabled) (MMBaseSim *self, + gboolean enabled); +}; + +GType mm_base_sim_get_type (void); + +void mm_base_sim_new (MMBaseModem *modem, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +MMBaseSim *mm_base_sim_new_finish (GAsyncResult *res, + GError **error); + +void mm_base_sim_initialize (MMBaseSim *self, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean mm_base_sim_initialize_finish (MMBaseSim *self, + GAsyncResult *result, + GError **error); + +void mm_base_sim_send_pin (MMBaseSim *self, + const gchar *pin, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean mm_base_sim_send_pin_finish (MMBaseSim *self, + GAsyncResult *res, + GError **error); + +void mm_base_sim_send_puk (MMBaseSim *self, + const gchar *puk, + const gchar *new_pin, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean mm_base_sim_send_puk_finish (MMBaseSim *self, + GAsyncResult *res, + GError **error); + +void mm_base_sim_export (MMBaseSim *self); + +const gchar *mm_base_sim_get_path (MMBaseSim *sim); + +#endif /* MM_BASE_SIM_H */ diff --git a/src/mm-broadband-modem-mbim.c b/src/mm-broadband-modem-mbim.c index 1a5c34b70..9fa78b994 100644 --- a/src/mm-broadband-modem-mbim.c +++ b/src/mm-broadband-modem-mbim.c @@ -1161,7 +1161,7 @@ modem_create_bearer (MMIfaceModem *self, /*****************************************************************************/ /* Create SIM (Modem interface) */ -static MMSim * +static MMBaseSim * create_sim_finish (MMIfaceModem *self, GAsyncResult *res, GError **error) diff --git a/src/mm-broadband-modem-qmi.c b/src/mm-broadband-modem-qmi.c index 872b00534..1092ba297 100644 --- a/src/mm-broadband-modem-qmi.c +++ b/src/mm-broadband-modem-qmi.c @@ -2691,7 +2691,7 @@ load_power_state (MMIfaceModem *self, /*****************************************************************************/ /* Create SIM (Modem interface) */ -static MMSim * +static MMBaseSim * create_sim_finish (MMIfaceModem *self, GAsyncResult *res, GError **error) diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c index 7089737cd..93be6a5da 100644 --- a/src/mm-broadband-modem.c +++ b/src/mm-broadband-modem.c @@ -43,7 +43,7 @@ #include "mm-bearer-list.h" #include "mm-sms-list.h" #include "mm-sms-part-3gpp.h" -#include "mm-sim.h" +#include "mm-base-sim.h" #include "mm-log.h" #include "mm-modem-helpers.h" #include "mm-error-helpers.h" @@ -122,7 +122,7 @@ struct _MMBroadbandModemPrivate { /*<--- Modem interface --->*/ /* Properties */ GObject *modem_dbus_skeleton; - MMSim *modem_sim; + MMBaseSim *modem_sim; MMBearerList *modem_bearer_list; MMModemState modem_state; /* Implementation helpers */ @@ -294,12 +294,12 @@ modem_create_bearer (MMIfaceModem *self, /*****************************************************************************/ /* Create SIM (Modem interface) */ -static MMSim * +static MMBaseSim * modem_create_sim_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) + GAsyncResult *res, + GError **error) { - return mm_sim_new_finish (res, error); + return mm_base_sim_new_finish (res, error); } static void @@ -308,10 +308,10 @@ modem_create_sim (MMIfaceModem *self, gpointer user_data) { /* New generic SIM */ - mm_sim_new (MM_BASE_MODEM (self), - NULL, /* cancellable */ - callback, - user_data); + mm_base_sim_new (MM_BASE_MODEM (self), + NULL, /* cancellable */ + callback, + user_data); } /*****************************************************************************/ diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c index 22bb9a6a3..919954c5a 100644 --- a/src/mm-iface-modem-3gpp.c +++ b/src/mm-iface-modem-3gpp.c @@ -1866,7 +1866,7 @@ initialization_context_complete_and_free_if_cancelled (InitializationContext *ct } static void -sim_pin_lock_enabled_cb (MMSim *self, +sim_pin_lock_enabled_cb (MMBaseSim *self, gboolean enabled, MmGdbusModem3gpp *skeleton) { @@ -1896,7 +1896,7 @@ load_enabled_facility_locks_ready (MMIfaceModem3gpp *self, mm_warn ("couldn't load facility locks: '%s'", error->message); g_error_free (error); } else { - MMSim *sim = NULL; + MMBaseSim *sim = NULL; /* We loaded the initial list of facility locks; but we do need to update * the SIM PIN lock status when that changes. We'll connect to the signal @@ -1906,7 +1906,7 @@ load_enabled_facility_locks_ready (MMIfaceModem3gpp *self, MM_IFACE_MODEM_SIM, &sim, NULL); g_signal_connect (sim, - MM_SIM_PIN_LOCK_ENABLED, + MM_BASE_SIM_PIN_LOCK_ENABLED, G_CALLBACK (sim_pin_lock_enabled_cb), ctx->skeleton); g_object_unref (sim); diff --git a/src/mm-iface-modem-simple.c b/src/mm-iface-modem-simple.c index be3f6ff8a..ec1825e57 100644 --- a/src/mm-iface-modem-simple.c +++ b/src/mm-iface-modem-simple.c @@ -20,7 +20,7 @@ #include #include "mm-bearer-list.h" -#include "mm-sim.h" +#include "mm-base-sim.h" #include "mm-error-helpers.h" #include "mm-iface-modem.h" #include "mm-iface-modem-3gpp.h" @@ -336,13 +336,13 @@ wait_for_initialized_ready (MMIfaceModem *self, } static void -send_pin_ready (MMSim *sim, +send_pin_ready (MMBaseSim *sim, GAsyncResult *res, ConnectionContext *ctx) { GError *error = NULL; - if (!mm_sim_send_pin_finish (sim, res, &error)) { + if (!mm_base_sim_send_pin_finish (sim, res, &error)) { g_dbus_method_invocation_take_error (ctx->invocation, error); connection_context_free (ctx); return; @@ -360,7 +360,7 @@ update_lock_info_ready (MMIfaceModem *self, { GError *error = NULL; MMModemLock lock; - MMSim *sim; + MMBaseSim *sim; lock = mm_iface_modem_update_lock_info_finish (self, res, &error); if (error) { @@ -407,10 +407,10 @@ update_lock_info_ready (MMIfaceModem *self, return; } - mm_sim_send_pin (sim, - mm_simple_connect_properties_get_pin (ctx->properties), - (GAsyncReadyCallback)send_pin_ready, - ctx); + mm_base_sim_send_pin (sim, + mm_simple_connect_properties_get_pin (ctx->properties), + (GAsyncReadyCallback)send_pin_ready, + ctx); g_object_unref (sim); } diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c index fcdbc766c..45e273a22 100644 --- a/src/mm-iface-modem.c +++ b/src/mm-iface-modem.c @@ -22,7 +22,7 @@ #include "mm-iface-modem.h" #include "mm-base-modem.h" #include "mm-base-modem-at.h" -#include "mm-sim.h" +#include "mm-base-sim.h" #include "mm-bearer-list.h" #include "mm-log.h" #include "mm-context.h" @@ -4037,7 +4037,7 @@ sim_new_ready (GAsyncInitable *initable, GAsyncResult *res, InitializationContext *ctx) { - MMSim *sim; + MMBaseSim *sim; GError *error = NULL; sim = MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->create_sim_finish (ctx->self, res, &error); @@ -4051,7 +4051,7 @@ sim_new_ready (GAsyncInitable *initable, /* We may get error with !sim, when the implementation doesn't want to * handle any (e.g. CDMA) */ if (sim) { - g_object_bind_property (sim, MM_SIM_PATH, + g_object_bind_property (sim, MM_BASE_SIM_PATH, ctx->skeleton, "sim", G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE); @@ -4067,13 +4067,13 @@ sim_new_ready (GAsyncInitable *initable, } static void -sim_reinit_ready (MMSim *sim, +sim_reinit_ready (MMBaseSim *sim, GAsyncResult *res, InitializationContext *ctx) { GError *error = NULL; - if (!mm_sim_initialize_finish (sim, res, &error)) { + if (!mm_base_sim_initialize_finish (sim, res, &error)) { mm_warn ("SIM re-initialization failed: '%s'", error ? error->message : "Unknown error"); g_clear_error (&error); @@ -4544,7 +4544,7 @@ interface_initialization_step (InitializationContext *ctx) if (!mm_iface_modem_is_cdma_only (ctx->self) && MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->create_sim && MM_IFACE_MODEM_GET_INTERFACE (ctx->self)->create_sim_finish) { - MMSim *sim = NULL; + MMBaseSim *sim = NULL; g_object_get (ctx->self, MM_IFACE_MODEM_SIM, &sim, @@ -4560,10 +4560,10 @@ interface_initialization_step (InitializationContext *ctx) /* If already available the sim object, relaunch initialization. * This will try to load any missing property value that couldn't be * retrieved before due to having the SIM locked. */ - mm_sim_initialize (sim, - ctx->cancellable, - (GAsyncReadyCallback)sim_reinit_ready, - ctx); + mm_base_sim_initialize (sim, + ctx->cancellable, + (GAsyncReadyCallback)sim_reinit_ready, + ctx); g_object_unref (sim); return; } @@ -5082,7 +5082,7 @@ iface_modem_init (gpointer g_iface) g_param_spec_object (MM_IFACE_MODEM_SIM, "SIM", "SIM object", - MM_TYPE_SIM, + MM_TYPE_BASE_SIM, G_PARAM_READWRITE)); g_object_interface_install_property diff --git a/src/mm-iface-modem.h b/src/mm-iface-modem.h index 56e38d13a..74ea9f924 100644 --- a/src/mm-iface-modem.h +++ b/src/mm-iface-modem.h @@ -25,7 +25,7 @@ #include "mm-charsets.h" #include "mm-port-serial-at.h" #include "mm-base-bearer.h" -#include "mm-sim.h" +#include "mm-base-sim.h" #define MM_TYPE_IFACE_MODEM (mm_iface_modem_get_type ()) #define MM_IFACE_MODEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_IFACE_MODEM, MMIfaceModem)) @@ -315,9 +315,9 @@ struct _MMIfaceModem { void (*create_sim) (MMIfaceModem *self, GAsyncReadyCallback callback, gpointer user_data); - MMSim * (*create_sim_finish) (MMIfaceModem *self, - GAsyncResult *res, - GError **error); + MMBaseSim * (*create_sim_finish) (MMIfaceModem *self, + GAsyncResult *res, + GError **error); /* Create bearer */ void (*create_bearer) (MMIfaceModem *self, diff --git a/src/mm-sim-mbim.c b/src/mm-sim-mbim.c index 5b395d7b4..8d7f3f850 100644 --- a/src/mm-sim-mbim.c +++ b/src/mm-sim-mbim.c @@ -28,7 +28,7 @@ #include "mm-log.h" #include "mm-sim-mbim.h" -G_DEFINE_TYPE (MMSimMbim, mm_sim_mbim, MM_TYPE_SIM) +G_DEFINE_TYPE (MMSimMbim, mm_sim_mbim, MM_TYPE_BASE_SIM) /*****************************************************************************/ @@ -42,7 +42,7 @@ peek_device (gpointer self, MMPortMbim *port; g_object_get (G_OBJECT (self), - MM_SIM_MODEM, &modem, + MM_BASE_SIM_MODEM, &modem, NULL); g_assert (MM_IS_BASE_MODEM (modem)); @@ -67,7 +67,7 @@ peek_device (gpointer self, /* Load SIM identifier */ static gchar * -load_sim_identifier_finish (MMSim *self, +load_sim_identifier_finish (MMBaseSim *self, GAsyncResult *res, GError **error) { @@ -108,7 +108,7 @@ simid_subscriber_ready_state_ready (MbimDevice *device, } static void -load_sim_identifier (MMSim *self, +load_sim_identifier (MMBaseSim *self, GAsyncReadyCallback callback, gpointer user_data) { @@ -135,7 +135,7 @@ load_sim_identifier (MMSim *self, /* Load IMSI */ static gchar * -load_imsi_finish (MMSim *self, +load_imsi_finish (MMBaseSim *self, GAsyncResult *res, GError **error) { @@ -176,7 +176,7 @@ imsi_subscriber_ready_state_ready (MbimDevice *device, } static void -load_imsi (MMSim *self, +load_imsi (MMBaseSim *self, GAsyncReadyCallback callback, gpointer user_data) { @@ -203,7 +203,7 @@ load_imsi (MMSim *self, /* Load operator identifier */ static gchar * -load_operator_identifier_finish (MMSim *self, +load_operator_identifier_finish (MMBaseSim *self, GAsyncResult *res, GError **error) { @@ -243,7 +243,7 @@ load_operator_identifier_ready (MbimDevice *device, } static void -load_operator_identifier (MMSim *self, +load_operator_identifier (MMBaseSim *self, GAsyncReadyCallback callback, gpointer user_data) { @@ -270,7 +270,7 @@ load_operator_identifier (MMSim *self, /* Load operator name */ static gchar * -load_operator_name_finish (MMSim *self, +load_operator_name_finish (MMBaseSim *self, GAsyncResult *res, GError **error) { @@ -310,7 +310,7 @@ load_operator_name_ready (MbimDevice *device, } static void -load_operator_name (MMSim *self, +load_operator_name (MMBaseSim *self, GAsyncReadyCallback callback, gpointer user_data) { @@ -337,7 +337,7 @@ load_operator_name (MMSim *self, /* Send PIN */ static gboolean -send_pin_finish (MMSim *self, +send_pin_finish (MMBaseSim *self, GAsyncResult *res, GError **error) { @@ -386,7 +386,7 @@ pin_set_enter_ready (MbimDevice *device, } static void -send_pin (MMSim *self, +send_pin (MMBaseSim *self, const gchar *pin, GAsyncReadyCallback callback, gpointer user_data) @@ -428,7 +428,7 @@ send_pin (MMSim *self, /* Send PUK */ static gboolean -send_puk_finish (MMSim *self, +send_puk_finish (MMBaseSim *self, GAsyncResult *res, GError **error) { @@ -478,7 +478,7 @@ puk_set_enter_ready (MbimDevice *device, } static void -send_puk (MMSim *self, +send_puk (MMBaseSim *self, const gchar *puk, const gchar *new_pin, GAsyncReadyCallback callback, @@ -521,7 +521,7 @@ send_puk (MMSim *self, /* Enable PIN */ static gboolean -enable_pin_finish (MMSim *self, +enable_pin_finish (MMBaseSim *self, GAsyncResult *res, GError **error) { @@ -558,7 +558,7 @@ pin_set_enable_ready (MbimDevice *device, } static void -enable_pin (MMSim *self, +enable_pin (MMBaseSim *self, const gchar *pin, gboolean enabled, GAsyncReadyCallback callback, @@ -601,7 +601,7 @@ enable_pin (MMSim *self, /* Change PIN */ static gboolean -change_pin_finish (MMSim *self, +change_pin_finish (MMBaseSim *self, GAsyncResult *res, GError **error) { @@ -638,7 +638,7 @@ pin_set_change_ready (MbimDevice *device, } static void -change_pin (MMSim *self, +change_pin (MMBaseSim *self, const gchar *old_pin, const gchar *new_pin, GAsyncReadyCallback callback, @@ -679,7 +679,7 @@ change_pin (MMSim *self, /*****************************************************************************/ -MMSim * +MMBaseSim * mm_sim_mbim_new_finish (GAsyncResult *res, GError **error) { @@ -694,9 +694,9 @@ mm_sim_mbim_new_finish (GAsyncResult *res, return NULL; /* Only export valid SIMs */ - mm_sim_export (MM_SIM (sim)); + mm_base_sim_export (MM_BASE_SIM (sim)); - return MM_SIM (sim); + return MM_BASE_SIM (sim); } void @@ -710,7 +710,7 @@ mm_sim_mbim_new (MMBaseModem *modem, cancellable, callback, user_data, - MM_SIM_MODEM, modem, + MM_BASE_SIM_MODEM, modem, NULL); } @@ -722,22 +722,22 @@ mm_sim_mbim_init (MMSimMbim *self) static void mm_sim_mbim_class_init (MMSimMbimClass *klass) { - MMSimClass *sim_class = MM_SIM_CLASS (klass); - - sim_class->load_sim_identifier = load_sim_identifier; - sim_class->load_sim_identifier_finish = load_sim_identifier_finish; - sim_class->load_imsi = load_imsi; - sim_class->load_imsi_finish = load_imsi_finish; - sim_class->load_operator_identifier = load_operator_identifier; - sim_class->load_operator_identifier_finish = load_operator_identifier_finish; - sim_class->load_operator_name = load_operator_name; - sim_class->load_operator_name_finish = load_operator_name_finish; - sim_class->send_pin = send_pin; - sim_class->send_pin_finish = send_pin_finish; - sim_class->send_puk = send_puk; - sim_class->send_puk_finish = send_puk_finish; - sim_class->enable_pin = enable_pin; - sim_class->enable_pin_finish = enable_pin_finish; - sim_class->change_pin = change_pin; - sim_class->change_pin_finish = change_pin_finish; + MMBaseSimClass *base_sim_class = MM_BASE_SIM_CLASS (klass); + + base_sim_class->load_sim_identifier = load_sim_identifier; + base_sim_class->load_sim_identifier_finish = load_sim_identifier_finish; + base_sim_class->load_imsi = load_imsi; + base_sim_class->load_imsi_finish = load_imsi_finish; + base_sim_class->load_operator_identifier = load_operator_identifier; + base_sim_class->load_operator_identifier_finish = load_operator_identifier_finish; + base_sim_class->load_operator_name = load_operator_name; + base_sim_class->load_operator_name_finish = load_operator_name_finish; + base_sim_class->send_pin = send_pin; + base_sim_class->send_pin_finish = send_pin_finish; + base_sim_class->send_puk = send_puk; + base_sim_class->send_puk_finish = send_puk_finish; + base_sim_class->enable_pin = enable_pin; + base_sim_class->enable_pin_finish = enable_pin_finish; + base_sim_class->change_pin = change_pin; + base_sim_class->change_pin_finish = change_pin_finish; } diff --git a/src/mm-sim-mbim.h b/src/mm-sim-mbim.h index 7cbf2e4a6..f7bf6ab1f 100644 --- a/src/mm-sim-mbim.h +++ b/src/mm-sim-mbim.h @@ -19,7 +19,7 @@ #include #include -#include "mm-sim.h" +#include "mm-base-sim.h" #define MM_TYPE_SIM_MBIM (mm_sim_mbim_get_type ()) #define MM_SIM_MBIM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_SIM_MBIM, MMSimMbim)) @@ -32,20 +32,20 @@ typedef struct _MMSimMbim MMSimMbim; typedef struct _MMSimMbimClass MMSimMbimClass; struct _MMSimMbim { - MMSim parent; + MMBaseSim parent; }; struct _MMSimMbimClass { - MMSimClass parent; + MMBaseSimClass parent; }; GType mm_sim_mbim_get_type (void); -void mm_sim_mbim_new (MMBaseModem *modem, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -MMSim *mm_sim_mbim_new_finish (GAsyncResult *res, - GError **error); +void mm_sim_mbim_new (MMBaseModem *modem, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +MMBaseSim *mm_sim_mbim_new_finish (GAsyncResult *res, + GError **error); #endif /* MM_SIM_MBIM_H */ diff --git a/src/mm-sim-qmi.c b/src/mm-sim-qmi.c index bed62ba68..4eb1b24fa 100644 --- a/src/mm-sim-qmi.c +++ b/src/mm-sim-qmi.c @@ -27,7 +27,7 @@ #include "mm-log.h" #include "mm-sim-qmi.h" -G_DEFINE_TYPE (MMSimQmi, mm_sim_qmi, MM_TYPE_SIM); +G_DEFINE_TYPE (MMSimQmi, mm_sim_qmi, MM_TYPE_BASE_SIM) /*****************************************************************************/ @@ -43,7 +43,7 @@ ensure_qmi_client (MMSimQmi *self, MMPortQmi *port; g_object_get (self, - MM_SIM_MODEM, &modem, + MM_BASE_SIM_MODEM, &modem, NULL); g_assert (MM_IS_BASE_MODEM (modem)); @@ -82,7 +82,7 @@ ensure_qmi_client (MMSimQmi *self, /* Load SIM ID (ICCID) */ static gchar * -load_sim_identifier_finish (MMSim *self, +load_sim_identifier_finish (MMBaseSim *self, GAsyncResult *res, GError **error) { @@ -128,7 +128,7 @@ dms_uim_get_iccid_ready (QmiClientDms *client, } static void -load_sim_identifier (MMSim *self, +load_sim_identifier (MMBaseSim *self, GAsyncReadyCallback callback, gpointer user_data) { @@ -158,7 +158,7 @@ load_sim_identifier (MMSim *self, /* Load IMSI */ static gchar * -load_imsi_finish (MMSim *self, +load_imsi_finish (MMBaseSim *self, GAsyncResult *res, GError **error) { @@ -204,7 +204,7 @@ dms_uim_get_imsi_ready (QmiClientDms *client, } static void -load_imsi (MMSim *self, +load_imsi (MMBaseSim *self, GAsyncReadyCallback callback, gpointer user_data) { @@ -261,7 +261,7 @@ pin_qmi_error_to_mobile_equipment_error (GError *qmi_error) } static gboolean -send_pin_finish (MMSim *self, +send_pin_finish (MMBaseSim *self, GAsyncResult *res, GError **error) { @@ -296,7 +296,7 @@ dms_uim_verify_pin_ready (QmiClientDms *client, } static void -send_pin (MMSim *self, +send_pin (MMBaseSim *self, const gchar *pin, GAsyncReadyCallback callback, gpointer user_data) @@ -335,7 +335,7 @@ send_pin (MMSim *self, /* Send PUK */ static gboolean -send_puk_finish (MMSim *self, +send_puk_finish (MMBaseSim *self, GAsyncResult *res, GError **error) { @@ -370,7 +370,7 @@ dms_uim_unblock_pin_ready (QmiClientDms *client, } static void -send_puk (MMSim *self, +send_puk (MMBaseSim *self, const gchar *puk, const gchar *new_pin, GAsyncReadyCallback callback, @@ -412,7 +412,7 @@ send_puk (MMSim *self, /* Change PIN */ static gboolean -change_pin_finish (MMSim *self, +change_pin_finish (MMBaseSim *self, GAsyncResult *res, GError **error) { @@ -447,7 +447,7 @@ dms_uim_change_pin_ready (QmiClientDms *client, } static void -change_pin (MMSim *self, +change_pin (MMBaseSim *self, const gchar *old_pin, const gchar *new_pin, GAsyncReadyCallback callback, @@ -489,7 +489,7 @@ change_pin (MMSim *self, /* Enable PIN */ static gboolean -enable_pin_finish (MMSim *self, +enable_pin_finish (MMBaseSim *self, GAsyncResult *res, GError **error) { @@ -524,7 +524,7 @@ dms_uim_set_pin_protection_ready (QmiClientDms *client, } static void -enable_pin (MMSim *self, +enable_pin (MMBaseSim *self, const gchar *pin, gboolean enabled, GAsyncReadyCallback callback, @@ -565,7 +565,7 @@ enable_pin (MMSim *self, /*****************************************************************************/ -MMSim * +MMBaseSim * mm_sim_qmi_new_finish (GAsyncResult *res, GError **error) { @@ -580,9 +580,9 @@ mm_sim_qmi_new_finish (GAsyncResult *res, return NULL; /* Only export valid SIMs */ - mm_sim_export (MM_SIM (sim)); + mm_base_sim_export (MM_BASE_SIM (sim)); - return MM_SIM (sim); + return MM_BASE_SIM (sim); } void @@ -596,7 +596,7 @@ mm_sim_qmi_new (MMBaseModem *modem, cancellable, callback, user_data, - MM_SIM_MODEM, modem, + MM_BASE_SIM_MODEM, modem, NULL); } @@ -608,22 +608,22 @@ mm_sim_qmi_init (MMSimQmi *self) static void mm_sim_qmi_class_init (MMSimQmiClass *klass) { - MMSimClass *sim_class = MM_SIM_CLASS (klass); - - sim_class->load_sim_identifier = load_sim_identifier; - sim_class->load_sim_identifier_finish = load_sim_identifier_finish; - sim_class->load_imsi = load_imsi; - sim_class->load_imsi_finish = load_imsi_finish; - sim_class->load_operator_identifier = NULL; - sim_class->load_operator_identifier_finish = NULL; - sim_class->load_operator_name = NULL; - sim_class->load_operator_name_finish = NULL; - sim_class->send_pin = send_pin; - sim_class->send_pin_finish = send_pin_finish; - sim_class->send_puk = send_puk; - sim_class->send_puk_finish = send_puk_finish; - sim_class->change_pin = change_pin; - sim_class->change_pin_finish = change_pin_finish; - sim_class->enable_pin = enable_pin; - sim_class->enable_pin_finish = enable_pin_finish; + MMBaseSimClass *base_sim_class = MM_BASE_SIM_CLASS (klass); + + base_sim_class->load_sim_identifier = load_sim_identifier; + base_sim_class->load_sim_identifier_finish = load_sim_identifier_finish; + base_sim_class->load_imsi = load_imsi; + base_sim_class->load_imsi_finish = load_imsi_finish; + base_sim_class->load_operator_identifier = NULL; + base_sim_class->load_operator_identifier_finish = NULL; + base_sim_class->load_operator_name = NULL; + base_sim_class->load_operator_name_finish = NULL; + base_sim_class->send_pin = send_pin; + base_sim_class->send_pin_finish = send_pin_finish; + base_sim_class->send_puk = send_puk; + base_sim_class->send_puk_finish = send_puk_finish; + base_sim_class->change_pin = change_pin; + base_sim_class->change_pin_finish = change_pin_finish; + base_sim_class->enable_pin = enable_pin; + base_sim_class->enable_pin_finish = enable_pin_finish; } diff --git a/src/mm-sim-qmi.h b/src/mm-sim-qmi.h index 3fbea08fd..070f98f6a 100644 --- a/src/mm-sim-qmi.h +++ b/src/mm-sim-qmi.h @@ -19,7 +19,7 @@ #include #include -#include "mm-sim.h" +#include "mm-base-sim.h" #define MM_TYPE_SIM_QMI (mm_sim_qmi_get_type ()) #define MM_SIM_QMI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_SIM_QMI, MMSimQmi)) @@ -32,20 +32,20 @@ typedef struct _MMSimQmi MMSimQmi; typedef struct _MMSimQmiClass MMSimQmiClass; struct _MMSimQmi { - MMSim parent; + MMBaseSim parent; }; struct _MMSimQmiClass { - MMSimClass parent; + MMBaseSimClass parent; }; GType mm_sim_qmi_get_type (void); -void mm_sim_qmi_new (MMBaseModem *modem, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -MMSim *mm_sim_qmi_new_finish (GAsyncResult *res, - GError **error); +void mm_sim_qmi_new (MMBaseModem *modem, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +MMBaseSim *mm_sim_qmi_new_finish (GAsyncResult *res, + GError **error); #endif /* MM_SIM_QMI_H */ diff --git a/src/mm-sim.c b/src/mm-sim.c deleted file mode 100644 index f3598de9c..000000000 --- a/src/mm-sim.c +++ /dev/null @@ -1,1811 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * 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. - */ - -#include -#include -#include -#include -#include -#include - -#include -#define _LIBMM_INSIDE_MM -#include - -#include "mm-iface-modem.h" -#include "mm-sim.h" -#include "mm-base-modem-at.h" -#include "mm-base-modem.h" -#include "mm-log.h" -#include "mm-modem-helpers.h" - -static void async_initable_iface_init (GAsyncInitableIface *iface); - -G_DEFINE_TYPE_EXTENDED (MMSim, mm_sim, MM_GDBUS_TYPE_SIM_SKELETON, 0, - G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, - async_initable_iface_init)); - -enum { - PROP_0, - PROP_PATH, - PROP_CONNECTION, - PROP_MODEM, - PROP_LAST -}; - -enum { - SIGNAL_PIN_LOCK_ENABLED, - SIGNAL_LAST -}; - -static GParamSpec *properties[PROP_LAST]; - -struct _MMSimPrivate { - /* The connection to the system bus */ - GDBusConnection *connection; - /* The modem which owns this SIM */ - MMBaseModem *modem; - /* The path where the SIM object is exported */ - gchar *path; -}; - -static guint signals[SIGNAL_LAST] = { 0 }; - -/*****************************************************************************/ - -void -mm_sim_export (MMSim *self) -{ - static guint id = 0; - gchar *path; - - path = g_strdup_printf (MM_DBUS_SIM_PREFIX "/%d", id++); - g_object_set (self, - MM_SIM_PATH, path, - NULL); - g_free (path); -} - -/*****************************************************************************/ -/* CHANGE PIN (Generic implementation) */ - -static gboolean -change_pin_finish (MMSim *self, - GAsyncResult *res, - GError **error) -{ - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); -} - -static void -change_pin_ready (MMBaseModem *modem, - GAsyncResult *res, - GSimpleAsyncResult *simple) -{ - GError *error = NULL; - - mm_base_modem_at_command_finish (modem, res, &error); - if (error) - g_simple_async_result_take_error (simple, error); - else - g_simple_async_result_set_op_res_gboolean (simple, TRUE); - g_simple_async_result_complete (simple); - g_object_unref (simple); -} - -static void -change_pin (MMSim *self, - const gchar *old_pin, - const gchar *new_pin, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *result; - gchar *command; - - result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - change_pin); - - command = g_strdup_printf ("+CPWD=\"SC\",\"%s\",\"%s\"", - old_pin, - new_pin); - mm_base_modem_at_command (MM_BASE_MODEM (self->priv->modem), - command, - 3, - FALSE, - (GAsyncReadyCallback)change_pin_ready, - result); - g_free (command); -} - -/*****************************************************************************/ -/* CHANGE PIN (DBus call handling) */ - -typedef struct { - MMSim *self; - GDBusMethodInvocation *invocation; - gchar *old_pin; - gchar *new_pin; - GError *save_error; -} HandleChangePinContext; - -static void -handle_change_pin_context_free (HandleChangePinContext *ctx) -{ - g_assert (ctx->save_error == NULL); - - g_object_unref (ctx->invocation); - g_object_unref (ctx->self); - g_free (ctx->old_pin); - g_free (ctx->new_pin); - g_free (ctx); -} - -static void -after_change_update_lock_info_ready (MMIfaceModem *self, - GAsyncResult *res, - HandleChangePinContext *ctx) -{ - /* We just want to ensure that we tried to update the unlock - * retries, no big issue if it failed */ - mm_iface_modem_update_lock_info_finish (self, res, NULL); - - if (ctx->save_error) { - g_dbus_method_invocation_take_error (ctx->invocation, ctx->save_error); - ctx->save_error = NULL; - } else { - mm_gdbus_sim_complete_change_pin (MM_GDBUS_SIM (ctx->self), ctx->invocation); - } - - handle_change_pin_context_free (ctx); -} - -static void -handle_change_pin_ready (MMSim *self, - GAsyncResult *res, - HandleChangePinContext *ctx) -{ - MMModemLock known_lock = MM_MODEM_LOCK_UNKNOWN; - - if (!MM_SIM_GET_CLASS (self)->change_pin_finish (self, res, &ctx->save_error)) { - if (g_error_matches (ctx->save_error, - MM_MOBILE_EQUIPMENT_ERROR, - MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK)) - known_lock = MM_MODEM_LOCK_SIM_PUK; - } - - mm_iface_modem_update_lock_info ( - MM_IFACE_MODEM (self->priv->modem), - known_lock, - (GAsyncReadyCallback)after_change_update_lock_info_ready, - ctx); -} - -static void -handle_change_pin_auth_ready (MMBaseModem *modem, - GAsyncResult *res, - HandleChangePinContext *ctx) -{ - GError *error = NULL; - - if (!mm_base_modem_authorize_finish (modem, res, &error)) { - g_dbus_method_invocation_take_error (ctx->invocation, error); - handle_change_pin_context_free (ctx); - return; - } - - /* If changing PIN is not implemented, report an error */ - if (!MM_SIM_GET_CLASS (ctx->self)->change_pin || - !MM_SIM_GET_CLASS (ctx->self)->change_pin_finish) { - g_dbus_method_invocation_return_error (ctx->invocation, - MM_CORE_ERROR, - MM_CORE_ERROR_UNSUPPORTED, - "Cannot change PIN: " - "operation not supported"); - handle_change_pin_context_free (ctx); - return; - } - - MM_SIM_GET_CLASS (ctx->self)->change_pin (ctx->self, - ctx->old_pin, - ctx->new_pin, - (GAsyncReadyCallback)handle_change_pin_ready, - ctx); -} - -static gboolean -handle_change_pin (MMSim *self, - GDBusMethodInvocation *invocation, - const gchar *old_pin, - const gchar *new_pin, - gboolean changed) -{ - HandleChangePinContext *ctx; - - ctx = g_new0 (HandleChangePinContext, 1); - ctx->self = g_object_ref (self); - ctx->invocation = g_object_ref (invocation); - ctx->old_pin = g_strdup (old_pin); - ctx->new_pin = g_strdup (new_pin); - - mm_base_modem_authorize (self->priv->modem, - invocation, - MM_AUTHORIZATION_DEVICE_CONTROL, - (GAsyncReadyCallback)handle_change_pin_auth_ready, - ctx); - return TRUE; -} - -/*****************************************************************************/ -/* ENABLE PIN (Generic implementation) */ - -static gboolean -enable_pin_finish (MMSim *self, - GAsyncResult *res, - GError **error) -{ - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); -} - -static void -enable_pin_ready (MMBaseModem *modem, - GAsyncResult *res, - GSimpleAsyncResult *simple) -{ - GError *error = NULL; - - mm_base_modem_at_command_finish (modem, res, &error); - if (error) - g_simple_async_result_take_error (simple, error); - else - g_simple_async_result_set_op_res_gboolean (simple, TRUE); - g_simple_async_result_complete (simple); - g_object_unref (simple); -} - -static void -enable_pin (MMSim *self, - const gchar *pin, - gboolean enabled, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *result; - gchar *command; - - result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - enable_pin); - - command = g_strdup_printf ("+CLCK=\"SC\",%d,\"%s\"", - enabled ? 1 : 0, - pin); - mm_base_modem_at_command (MM_BASE_MODEM (self->priv->modem), - command, - 3, - FALSE, - (GAsyncReadyCallback)enable_pin_ready, - result); - g_free (command); -} - -/*****************************************************************************/ -/* ENABLE PIN (DBus call handling) */ - -typedef struct { - MMSim *self; - GDBusMethodInvocation *invocation; - gchar *pin; - gboolean enabled; - GError *save_error; -} HandleEnablePinContext; - -static void -handle_enable_pin_context_free (HandleEnablePinContext *ctx) -{ - g_assert (ctx->save_error == NULL); - - g_object_unref (ctx->invocation); - g_object_unref (ctx->self); - g_free (ctx->pin); - g_free (ctx); -} - -static void -after_enable_update_lock_info_ready (MMIfaceModem *modem, - GAsyncResult *res, - HandleEnablePinContext *ctx) -{ - /* We just want to ensure that we tried to update the unlock - * retries, no big issue if it failed */ - mm_iface_modem_update_lock_info_finish (modem, res, NULL); - - if (ctx->save_error) { - g_dbus_method_invocation_take_error (ctx->invocation, ctx->save_error); - ctx->save_error = NULL; - } else { - /* Signal about the new lock state */ - g_signal_emit (ctx->self, signals[SIGNAL_PIN_LOCK_ENABLED], 0, ctx->enabled); - mm_gdbus_sim_complete_enable_pin (MM_GDBUS_SIM (ctx->self), ctx->invocation); - } - - handle_enable_pin_context_free (ctx); -} - -static void -handle_enable_pin_ready (MMSim *self, - GAsyncResult *res, - HandleEnablePinContext *ctx) -{ - MMModemLock known_lock = MM_MODEM_LOCK_UNKNOWN; - - if (!MM_SIM_GET_CLASS (self)->enable_pin_finish (self, res, &ctx->save_error)) { - if (g_error_matches (ctx->save_error, - MM_MOBILE_EQUIPMENT_ERROR, - MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK)) - known_lock = MM_MODEM_LOCK_SIM_PUK; - } - - mm_iface_modem_update_lock_info ( - MM_IFACE_MODEM (self->priv->modem), - known_lock, - (GAsyncReadyCallback)after_enable_update_lock_info_ready, - ctx); -} - -static void -handle_enable_pin_auth_ready (MMBaseModem *modem, - GAsyncResult *res, - HandleEnablePinContext *ctx) -{ - GError *error = NULL; - - if (!mm_base_modem_authorize_finish (modem, res, &error)) { - g_dbus_method_invocation_take_error (ctx->invocation, error); - handle_enable_pin_context_free (ctx); - return; - } - - /* If changing PIN is not implemented, report an error */ - if (!MM_SIM_GET_CLASS (ctx->self)->enable_pin || - !MM_SIM_GET_CLASS (ctx->self)->enable_pin_finish) { - g_dbus_method_invocation_return_error (ctx->invocation, - MM_CORE_ERROR, - MM_CORE_ERROR_UNSUPPORTED, - "Cannot enable/disable PIN: " - "operation not supported"); - handle_enable_pin_context_free (ctx); - return; - } - - MM_SIM_GET_CLASS (ctx->self)->enable_pin (ctx->self, - ctx->pin, - ctx->enabled, - (GAsyncReadyCallback)handle_enable_pin_ready, - ctx); -} - -static gboolean -handle_enable_pin (MMSim *self, - GDBusMethodInvocation *invocation, - const gchar *pin, - gboolean enabled) -{ - HandleEnablePinContext *ctx; - - ctx = g_new0 (HandleEnablePinContext, 1); - ctx->self = g_object_ref (self); - ctx->invocation = g_object_ref (invocation); - ctx->pin = g_strdup (pin); - ctx->enabled = enabled; - - mm_base_modem_authorize (self->priv->modem, - invocation, - MM_AUTHORIZATION_DEVICE_CONTROL, - (GAsyncReadyCallback)handle_enable_pin_auth_ready, - ctx); - return TRUE; -} - -/*****************************************************************************/ -/* SEND PIN/PUK (Generic implementation) */ - -static gboolean -common_send_pin_puk_finish (MMSim *self, - GAsyncResult *res, - GError **error) -{ - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); -} - -static void -send_pin_puk_ready (MMBaseModem *modem, - GAsyncResult *res, - GSimpleAsyncResult *simple) -{ - GError *error = NULL; - - mm_base_modem_at_command_finish (modem, res, &error); - if (error) - g_simple_async_result_take_error (simple, error); - else - g_simple_async_result_set_op_res_gboolean (simple, TRUE); - g_simple_async_result_complete (simple); - g_object_unref (simple); -} - -static void -common_send_pin_puk (MMSim *self, - const gchar *pin, - const gchar *puk, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *result; - gchar *command; - - result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - common_send_pin_puk); - - command = (puk ? - g_strdup_printf ("+CPIN=\"%s\",\"%s\"", puk, pin) : - g_strdup_printf ("+CPIN=\"%s\"", pin)); - - mm_base_modem_at_command (MM_BASE_MODEM (self->priv->modem), - command, - 3, - FALSE, - (GAsyncReadyCallback)send_pin_puk_ready, - result); - g_free (command); -} - -static void -send_puk (MMSim *self, - const gchar *puk, - const gchar *new_pin, - GAsyncReadyCallback callback, - gpointer user_data) -{ - common_send_pin_puk (self, new_pin, puk, callback, user_data); -} - -static void -send_pin (MMSim *self, - const gchar *pin, - GAsyncReadyCallback callback, - gpointer user_data) -{ - common_send_pin_puk (self, pin, NULL, callback, user_data); -} - -/*****************************************************************************/ -/* SEND PIN/PUK (common logic) */ - -typedef struct { - MMSim *self; - GSimpleAsyncResult *result; - GError *save_error; - gulong wait_for_unlock_id; -} SendPinPukContext; - -static void -send_pin_puk_context_complete_and_free (SendPinPukContext *ctx) -{ - if (ctx->wait_for_unlock_id) - g_signal_handler_disconnect (ctx->self->priv->modem, - ctx->wait_for_unlock_id); - if (ctx->save_error) - g_error_free (ctx->save_error); - g_simple_async_result_complete (ctx->result); - g_object_unref (ctx->result); - g_object_unref (ctx->self); - g_free (ctx); -} - -static GError * -error_for_unlock_check (MMModemLock lock) -{ - static const MMMobileEquipmentError errors_for_locks [] = { - MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN, /* MM_MODEM_LOCK_UNKNOWN */ - MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN, /* MM_MODEM_LOCK_NONE */ - MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN, /* MM_MODEM_LOCK_SIM_PIN */ - MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN2, /* MM_MODEM_LOCK_SIM_PIN2 */ - MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK, /* MM_MODEM_LOCK_SIM_PUK */ - MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK2, /* MM_MODEM_LOCK_SIM_PUK2 */ - MM_MOBILE_EQUIPMENT_ERROR_SERVICE_PIN, /* MM_MODEM_LOCK_PH_SP_PIN */ - MM_MOBILE_EQUIPMENT_ERROR_SERVICE_PUK, /* MM_MODEM_LOCK_PH_SP_PUK */ - MM_MOBILE_EQUIPMENT_ERROR_NETWORK_PIN, /* MM_MODEM_LOCK_PH_NET_PIN */ - MM_MOBILE_EQUIPMENT_ERROR_NETWORK_PUK, /* MM_MODEM_LOCK_PH_NET_PUK */ - MM_MOBILE_EQUIPMENT_ERROR_PH_SIM_PIN, /* MM_MODEM_LOCK_PH_SIM_PIN */ - MM_MOBILE_EQUIPMENT_ERROR_CORP_PIN, /* MM_MODEM_LOCK_PH_CORP_PIN */ - MM_MOBILE_EQUIPMENT_ERROR_CORP_PUK, /* MM_MODEM_LOCK_PH_CORP_PUK */ - MM_MOBILE_EQUIPMENT_ERROR_PH_FSIM_PIN, /* MM_MODEM_LOCK_PH_FSIM_PIN */ - MM_MOBILE_EQUIPMENT_ERROR_PH_FSIM_PUK, /* MM_MODEM_LOCK_PH_FSIM_PUK */ - MM_MOBILE_EQUIPMENT_ERROR_NETWORK_SUBSET_PIN, /* MM_MODEM_LOCK_PH_NETSUB_PIN */ - MM_MOBILE_EQUIPMENT_ERROR_NETWORK_SUBSET_PUK, /* MM_MODEM_LOCK_PH_NETSUB_PUK */ - }; - - g_assert (lock >= MM_MODEM_LOCK_UNKNOWN); - g_assert (lock <= MM_MODEM_LOCK_PH_NETSUB_PUK); - - return g_error_new (MM_MOBILE_EQUIPMENT_ERROR, - errors_for_locks[lock], - "Device is locked: '%s'", - mm_modem_lock_get_string (lock)); -} - -gboolean -mm_sim_send_pin_finish (MMSim *self, - GAsyncResult *res, - GError **error) -{ - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); -} - -gboolean -mm_sim_send_puk_finish (MMSim *self, - GAsyncResult *res, - GError **error) -{ - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); -} - -static void -update_lock_info_ready (MMIfaceModem *modem, - GAsyncResult *res, - SendPinPukContext *ctx) -{ - GError *error = NULL; - MMModemLock lock; - - lock = mm_iface_modem_update_lock_info_finish (modem, res, &error); - /* Even if we may be SIM-PIN2/PUK2 locked, we don't consider this an error - * in the PIN/PUK sending */ - if (lock != MM_MODEM_LOCK_NONE && - lock != MM_MODEM_LOCK_SIM_PIN2 && - lock != MM_MODEM_LOCK_SIM_PUK2) { - /* Device is locked. Now: - * - If we got an error in the original send-pin action, report it. - * - If we got an error in the pin-check action, report it. - * - Otherwise, build our own error from the lock code. - */ - if (ctx->save_error) { - g_simple_async_result_take_error (ctx->result, ctx->save_error); - ctx->save_error = NULL; - g_clear_error (&error); - } else if (error) - g_simple_async_result_take_error (ctx->result, error); - else - g_simple_async_result_take_error (ctx->result, - error_for_unlock_check (lock)); - send_pin_puk_context_complete_and_free (ctx); - return; - } - - g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); - send_pin_puk_context_complete_and_free (ctx); -} - -static void -send_pin_ready (MMSim *self, - GAsyncResult *res, - SendPinPukContext *ctx) -{ - MMModemLock known_lock = MM_MODEM_LOCK_UNKNOWN; - - if (!MM_SIM_GET_CLASS (self)->send_pin_finish (self, res, &ctx->save_error)) { - if (g_error_matches (ctx->save_error, - MM_MOBILE_EQUIPMENT_ERROR, - MM_MOBILE_EQUIPMENT_ERROR_SIM_PUK)) - known_lock = MM_MODEM_LOCK_SIM_PUK; - } - - /* Once pin/puk has been sent, recheck lock */ - mm_iface_modem_update_lock_info ( - MM_IFACE_MODEM (self->priv->modem), - known_lock, - (GAsyncReadyCallback)update_lock_info_ready, - ctx); -} - -static void -send_puk_ready (MMSim *self, - GAsyncResult *res, - SendPinPukContext *ctx) -{ - MM_SIM_GET_CLASS (self)->send_puk_finish (self, res, &ctx->save_error); - - /* Once pin/puk has been sent, recheck lock */ - mm_iface_modem_update_lock_info (MM_IFACE_MODEM (self->priv->modem), - MM_MODEM_LOCK_UNKNOWN, /* ask */ - (GAsyncReadyCallback)update_lock_info_ready, - ctx); -} - -void -mm_sim_send_pin (MMSim *self, - const gchar *pin, - GAsyncReadyCallback callback, - gpointer user_data) -{ - SendPinPukContext *ctx; - - /* If sending PIN is not implemented, report an error */ - if (!MM_SIM_GET_CLASS (self)->send_pin || - !MM_SIM_GET_CLASS (self)->send_pin_finish) { - g_simple_async_report_error_in_idle (G_OBJECT (self), - callback, - user_data, - MM_CORE_ERROR, - MM_CORE_ERROR_UNSUPPORTED, - "Cannot send PIN: " - "operation not supported"); - return; - } - - ctx = g_new0 (SendPinPukContext, 1); - ctx->self = g_object_ref (self); - ctx->result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - mm_sim_send_pin); - - MM_SIM_GET_CLASS (self)->send_pin (self, - pin, - (GAsyncReadyCallback)send_pin_ready, - ctx); -} - -void -mm_sim_send_puk (MMSim *self, - const gchar *puk, - const gchar *new_pin, - GAsyncReadyCallback callback, - gpointer user_data) -{ - SendPinPukContext *ctx; - - /* If sending PIN is not implemented, report an error */ - if (!MM_SIM_GET_CLASS (self)->send_puk || - !MM_SIM_GET_CLASS (self)->send_puk_finish) { - g_simple_async_report_error_in_idle (G_OBJECT (self), - callback, - user_data, - MM_CORE_ERROR, - MM_CORE_ERROR_UNSUPPORTED, - "Cannot send PUK: " - "operation not supported"); - return; - } - - ctx = g_new0 (SendPinPukContext, 1); - ctx->self = g_object_ref (self); - ctx->result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - mm_sim_send_puk); - - MM_SIM_GET_CLASS (self)->send_puk (self, - puk, - new_pin, - (GAsyncReadyCallback)send_puk_ready, - ctx); -} - -/*****************************************************************************/ -/* SEND PIN (DBus call handling) */ - -typedef struct { - MMSim *self; - GDBusMethodInvocation *invocation; - gchar *pin; -} HandleSendPinContext; - -static void -handle_send_pin_context_free (HandleSendPinContext *ctx) -{ - g_object_unref (ctx->invocation); - g_object_unref (ctx->self); - g_free (ctx->pin); - g_free (ctx); -} - -static void -handle_send_pin_ready (MMSim *self, - GAsyncResult *res, - HandleSendPinContext *ctx) -{ - GError *error = NULL; - - if (!mm_sim_send_pin_finish (self, res, &error)) - g_dbus_method_invocation_take_error (ctx->invocation, error); - else - mm_gdbus_sim_complete_send_pin (MM_GDBUS_SIM (self), ctx->invocation); - - handle_send_pin_context_free (ctx); -} - -static void -handle_send_pin_auth_ready (MMBaseModem *modem, - GAsyncResult *res, - HandleSendPinContext *ctx) -{ - GError *error = NULL; - - if (!mm_base_modem_authorize_finish (modem, res, &error)) { - g_dbus_method_invocation_take_error (ctx->invocation, error); - handle_send_pin_context_free (ctx); - return; - } - - mm_sim_send_pin (ctx->self, - ctx->pin, - (GAsyncReadyCallback)handle_send_pin_ready, - ctx); -} - -static gboolean -handle_send_pin (MMSim *self, - GDBusMethodInvocation *invocation, - const gchar *pin) -{ - HandleSendPinContext *ctx; - - ctx = g_new0 (HandleSendPinContext, 1); - ctx->self = g_object_ref (self); - ctx->invocation = g_object_ref (invocation); - ctx->pin = g_strdup (pin); - - mm_base_modem_authorize (self->priv->modem, - invocation, - MM_AUTHORIZATION_DEVICE_CONTROL, - (GAsyncReadyCallback)handle_send_pin_auth_ready, - ctx); - return TRUE; -} - -/*****************************************************************************/ -/* SEND PUK (DBus call handling) */ - -typedef struct { - MMSim *self; - GDBusMethodInvocation *invocation; - gchar *puk; - gchar *new_pin; -} HandleSendPukContext; - -static void -handle_send_puk_context_free (HandleSendPukContext *ctx) -{ - g_object_unref (ctx->invocation); - g_object_unref (ctx->self); - g_free (ctx->puk); - g_free (ctx->new_pin); - g_free (ctx); -} - -static void -handle_send_puk_ready (MMSim *self, - GAsyncResult *res, - HandleSendPukContext *ctx) -{ - GError *error = NULL; - - if (!mm_sim_send_puk_finish (self, res, &error)) - g_dbus_method_invocation_take_error (ctx->invocation, error); - else - mm_gdbus_sim_complete_send_puk (MM_GDBUS_SIM (self), ctx->invocation); - - handle_send_puk_context_free (ctx); -} - -static void -handle_send_puk_auth_ready (MMBaseModem *modem, - GAsyncResult *res, - HandleSendPukContext *ctx) -{ - GError *error = NULL; - - if (!mm_base_modem_authorize_finish (modem, res, &error)) { - g_dbus_method_invocation_take_error (ctx->invocation, error); - handle_send_puk_context_free (ctx); - return; - } - - mm_sim_send_puk (ctx->self, - ctx->puk, - ctx->new_pin, - (GAsyncReadyCallback)handle_send_puk_ready, - ctx); -} - -static gboolean -handle_send_puk (MMSim *self, - GDBusMethodInvocation *invocation, - const gchar *puk, - const gchar *new_pin) -{ - HandleSendPukContext *ctx; - - ctx = g_new0 (HandleSendPukContext, 1); - ctx->self = g_object_ref (self); - ctx->invocation = g_object_ref (invocation); - ctx->puk = g_strdup (puk); - ctx->new_pin = g_strdup (new_pin); - - mm_base_modem_authorize (self->priv->modem, - invocation, - MM_AUTHORIZATION_DEVICE_CONTROL, - (GAsyncReadyCallback)handle_send_puk_auth_ready, - ctx); - return TRUE; -} - -/*****************************************************************************/ - -static void -mm_sim_dbus_export (MMSim *self) -{ - GError *error = NULL; - - /* Handle method invocations */ - g_signal_connect (self, - "handle-change-pin", - G_CALLBACK (handle_change_pin), - NULL); - g_signal_connect (self, - "handle-enable-pin", - G_CALLBACK (handle_enable_pin), - NULL); - g_signal_connect (self, - "handle-send-pin", - G_CALLBACK (handle_send_pin), - NULL); - g_signal_connect (self, - "handle-send-puk", - G_CALLBACK (handle_send_puk), - NULL); - - if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self), - self->priv->connection, - self->priv->path, - &error)) { - mm_warn ("couldn't export SIM at '%s': '%s'", - self->priv->path, - error->message); - g_error_free (error); - } -} - -static void -mm_sim_dbus_unexport (MMSim *self) -{ - /* Only unexport if currently exported */ - if (g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (self))) - g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (self)); -} - -/*****************************************************************************/ - -const gchar * -mm_sim_get_path (MMSim *self) -{ - return self->priv->path; -} - -/*****************************************************************************/ - -#undef STR_REPLY_READY_FN -#define STR_REPLY_READY_FN(NAME) \ - static void \ - NAME##_command_ready (MMBaseModem *modem, \ - GAsyncResult *res, \ - GSimpleAsyncResult *operation_result) \ - { \ - GError *error = NULL; \ - const gchar *response; \ - \ - response = mm_base_modem_at_command_finish (modem, res, &error); \ - if (error) \ - g_simple_async_result_take_error (operation_result, error); \ - else \ - g_simple_async_result_set_op_res_gpointer (operation_result, \ - (gpointer)response, \ - NULL); \ - \ - g_simple_async_result_complete (operation_result); \ - g_object_unref (operation_result); \ - } - -/*****************************************************************************/ -/* SIM IDENTIFIER */ - -static gchar * -parse_iccid (const gchar *response, - GError **error) -{ - gchar buf[21]; - const gchar *str; - gint sw1; - gint sw2; - gboolean success = FALSE; - - memset (buf, 0, sizeof (buf)); - str = mm_strip_tag (response, "+CRSM:"); - if (sscanf (str, "%d,%d,\"%20c\"", &sw1, &sw2, (char *) &buf) == 3) - success = TRUE; - else { - /* May not include quotes... */ - if (sscanf (str, "%d,%d,%20c", &sw1, &sw2, (char *) &buf) == 3) - success = TRUE; - } - - if (!success) { - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Could not parse the CRSM response"); - return NULL; - } - - if ((sw1 == 0x90 && sw2 == 0x00) || - (sw1 == 0x91) || - (sw1 == 0x92) || - (sw1 == 0x9f)) { - return mm_3gpp_parse_iccid (buf, error); - } else { - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "SIM failed to handle CRSM request (sw1 %d sw2 %d)", - sw1, sw2); - return NULL; - } -} - -static gchar * -load_sim_identifier_finish (MMSim *self, - GAsyncResult *res, - GError **error) -{ - const gchar *result; - gchar *sim_identifier; - - if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) - return NULL; - result = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)); - - sim_identifier = parse_iccid (result, error); - if (!sim_identifier) - return NULL; - - mm_dbg ("loaded SIM identifier: %s", sim_identifier); - return sim_identifier; -} - -STR_REPLY_READY_FN (load_sim_identifier) - -static void -load_sim_identifier (MMSim *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - mm_dbg ("loading SIM identifier..."); - - /* READ BINARY of EFiccid (ICC Identification) ETSI TS 102.221 section 13.2 */ - mm_base_modem_at_command ( - MM_BASE_MODEM (self->priv->modem), - "+CRSM=176,12258,0,0,10", - 20, - FALSE, - (GAsyncReadyCallback)load_sim_identifier_command_ready, - g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - load_sim_identifier)); -} - -/*****************************************************************************/ -/* IMSI */ - -static gchar * -parse_imsi (const gchar *response, - GError **error) -{ - const gchar *s; - gint len; - - g_assert (response != NULL); - - for (s = mm_strip_tag (response, "+CIMI"), len = 0; - *s; - ++s, ++len) { - /* IMSI is a number with 15 or less decimal digits. */ - if (!isdigit (*s) || len > 15) { - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Invalid +CIMI response '%s'", response ? response : ""); - return NULL; - } - } - - return g_strdup (response); -} - -static gchar * -load_imsi_finish (MMSim *self, - GAsyncResult *res, - GError **error) -{ - const gchar *result; - gchar *imsi; - - if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) - return NULL; - result = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)); - - imsi = parse_imsi (result, error); - if (!imsi) - return NULL; - - mm_dbg ("loaded IMSI: %s", imsi); - return imsi; -} - -STR_REPLY_READY_FN (load_imsi) - -static void -load_imsi (MMSim *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - mm_dbg ("loading IMSI..."); - - mm_base_modem_at_command ( - MM_BASE_MODEM (self->priv->modem), - "+CIMI", - 3, - FALSE, - (GAsyncReadyCallback)load_imsi_command_ready, - g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - load_imsi)); -} - -/*****************************************************************************/ -/* Operator ID */ - -static guint -parse_mnc_length (const gchar *response, - GError **error) -{ - gint sw1; - gint sw2; - gboolean success = FALSE; - gchar hex[51]; - - memset (hex, 0, sizeof (hex)); - if (sscanf (response, "+CRSM:%d,%d,\"%50c\"", &sw1, &sw2, (char *) &hex) == 3) - success = TRUE; - else { - /* May not include quotes... */ - if (sscanf (response, "+CRSM:%d,%d,%50c", &sw1, &sw2, (char *) &hex) == 3) - success = TRUE; - } - - if (!success) { - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Could not parse the CRSM response"); - return 0; - } - - if ((sw1 == 0x90 && sw2 == 0x00) || - (sw1 == 0x91) || - (sw1 == 0x92) || - (sw1 == 0x9f)) { - gsize buflen = 0; - guint32 mnc_len; - gchar *bin; - - /* Make sure the buffer is only hex characters */ - while (buflen < sizeof (hex) && hex[buflen]) { - if (!isxdigit (hex[buflen])) { - hex[buflen] = 0x0; - break; - } - buflen++; - } - - /* Convert hex string to binary */ - bin = mm_utils_hexstr2bin (hex, &buflen); - if (!bin || buflen < 4) { - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "SIM returned malformed response '%s'", - hex); - g_free (bin); - return 0; - } - - /* MNC length is byte 4 of this SIM file */ - mnc_len = bin[3] & 0xFF; - if (mnc_len == 2 || mnc_len == 3) { - g_free (bin); - return mnc_len; - } - - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "SIM returned invalid MNC length %d (should be either 2 or 3)", - mnc_len); - g_free (bin); - return 0; - } - - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "SIM failed to handle CRSM request (sw1 %d sw2 %d)", - sw1, sw2); - return 0; -} - -static gchar * -load_operator_identifier_finish (MMSim *self, - GAsyncResult *res, - GError **error) -{ - GError *inner_error = NULL; - const gchar *imsi; - const gchar *result; - guint mnc_length; - - if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) - return NULL; - result = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)); - - imsi = mm_gdbus_sim_get_imsi (MM_GDBUS_SIM (self)); - if (!imsi) { - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Cannot load Operator ID without IMSI"); - return NULL; - } - - mnc_length = parse_mnc_length (result, &inner_error); - if (inner_error) { - g_propagate_error (error, inner_error); - return NULL; - } - - /* Build Operator ID */ - return g_strndup (imsi, 3 + mnc_length); -} - -STR_REPLY_READY_FN (load_operator_identifier) - -static void -load_operator_identifier (MMSim *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - mm_dbg ("loading Operator ID..."); - - /* READ BINARY of EFad (Administrative Data) ETSI 51.011 section 10.3.18 */ - mm_base_modem_at_command ( - MM_BASE_MODEM (self->priv->modem), - "+CRSM=176,28589,0,0,4", - 10, - FALSE, - (GAsyncReadyCallback)load_operator_identifier_command_ready, - g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - load_operator_identifier)); -} - -/*****************************************************************************/ -/* Operator Name (Service Provider Name) */ - -static gchar * -parse_spn (const gchar *response, - GError **error) -{ - gint sw1; - gint sw2; - gboolean success = FALSE; - gchar hex[51]; - - memset (hex, 0, sizeof (hex)); - if (sscanf (response, "+CRSM:%d,%d,\"%50c\"", &sw1, &sw2, (char *) &hex) == 3) - success = TRUE; - else { - /* May not include quotes... */ - if (sscanf (response, "+CRSM:%d,%d,%50c", &sw1, &sw2, (char *) &hex) == 3) - success = TRUE; - } - - if (!success) { - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Could not parse the CRSM response"); - return NULL; - } - - if ((sw1 == 0x90 && sw2 == 0x00) || - (sw1 == 0x91) || - (sw1 == 0x92) || - (sw1 == 0x9f)) { - gsize buflen = 0; - gchar *bin; - gchar *utf8; - - /* Make sure the buffer is only hex characters */ - while (buflen < sizeof (hex) && hex[buflen]) { - if (!isxdigit (hex[buflen])) { - hex[buflen] = 0x0; - break; - } - buflen++; - } - - /* Convert hex string to binary */ - bin = mm_utils_hexstr2bin (hex, &buflen); - if (!bin) { - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "SIM returned malformed response '%s'", - hex); - return NULL; - } - - /* Remove the FF filler at the end */ - while (buflen > 1 && bin[buflen - 1] == (char)0xff) - buflen--; - - /* First byte is metadata; remainder is GSM-7 unpacked into octets; convert to UTF8 */ - utf8 = (gchar *)mm_charset_gsm_unpacked_to_utf8 ((guint8 *)bin + 1, buflen - 1); - g_free (bin); - return utf8; - } - - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "SIM failed to handle CRSM request (sw1 %d sw2 %d)", - sw1, sw2); - return NULL; -} - -static gchar * -load_operator_name_finish (MMSim *self, - GAsyncResult *res, - GError **error) -{ - const gchar *result; - - if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) - return NULL; - result = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)); - - return parse_spn (result, error); -} - -STR_REPLY_READY_FN (load_operator_name) - -static void -load_operator_name (MMSim *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - mm_dbg ("loading Operator Name..."); - - /* READ BINARY of EFspn (Service Provider Name) ETSI 51.011 section 10.3.11 */ - mm_base_modem_at_command ( - MM_BASE_MODEM (self->priv->modem), - "+CRSM=176,28486,0,0,17", - 10, - FALSE, - (GAsyncReadyCallback)load_operator_name_command_ready, - g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - load_operator_name)); -} - -/*****************************************************************************/ - -typedef struct _InitAsyncContext InitAsyncContext; -static void interface_initialization_step (InitAsyncContext *ctx); - -typedef enum { - INITIALIZATION_STEP_FIRST, - INITIALIZATION_STEP_SIM_IDENTIFIER, - INITIALIZATION_STEP_IMSI, - INITIALIZATION_STEP_OPERATOR_ID, - INITIALIZATION_STEP_OPERATOR_NAME, - INITIALIZATION_STEP_LAST -} InitializationStep; - -struct _InitAsyncContext { - GSimpleAsyncResult *result; - GCancellable *cancellable; - MMSim *self; - InitializationStep step; - guint sim_identifier_tries; -}; - -static void -init_async_context_free (InitAsyncContext *ctx) -{ - g_object_unref (ctx->self); - g_object_unref (ctx->result); - if (ctx->cancellable) - g_object_unref (ctx->cancellable); - g_free (ctx); -} - -MMSim * -mm_sim_new_finish (GAsyncResult *res, - GError **error) -{ - GObject *source; - GObject *sim; - - source = g_async_result_get_source_object (res); - sim = g_async_initable_new_finish (G_ASYNC_INITABLE (source), res, error); - g_object_unref (source); - - if (!sim) - return NULL; - - /* Only export valid SIMs */ - mm_sim_export (MM_SIM (sim)); - - return MM_SIM (sim); -} - -static gboolean -initable_init_finish (GAsyncInitable *initable, - GAsyncResult *result, - GError **error) -{ - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error); -} - -static void -load_sim_identifier_ready (MMSim *self, - GAsyncResult *res, - InitAsyncContext *ctx) -{ - GError *error = NULL; - gchar *simid; - - simid = MM_SIM_GET_CLASS (ctx->self)->load_sim_identifier_finish (self, res, &error); - if (!simid) { - /* TODO: make the retries gobi-specific? */ - - /* Try one more time... Gobi 1K cards may reply to the first - * request with '+CRSM: 106,134,""' which is bogus because - * subsequent requests work fine. - */ - if (++ctx->sim_identifier_tries < 2) { - g_clear_error (&error); - interface_initialization_step (ctx); - return; - } - - mm_warn ("couldn't load SIM identifier: '%s'", - error ? error->message : "unknown error"); - g_clear_error (&error); - } - - mm_gdbus_sim_set_sim_identifier (MM_GDBUS_SIM (self), simid); - g_free (simid); - - /* Go on to next step */ - ctx->step++; - interface_initialization_step (ctx); -} - -#undef STR_REPLY_READY_FN -#define STR_REPLY_READY_FN(NAME,DISPLAY) \ - static void \ - load_##NAME##_ready (MMSim *self, \ - GAsyncResult *res, \ - InitAsyncContext *ctx) \ - { \ - GError *error = NULL; \ - gchar *val; \ - \ - val = MM_SIM_GET_CLASS (ctx->self)->load_##NAME##_finish (self, res, &error); \ - mm_gdbus_sim_set_##NAME (MM_GDBUS_SIM (self), val); \ - g_free (val); \ - \ - if (error) { \ - mm_warn ("couldn't load %s: '%s'", DISPLAY, error->message); \ - g_error_free (error); \ - } \ - \ - /* Go on to next step */ \ - ctx->step++; \ - interface_initialization_step (ctx); \ - } - -STR_REPLY_READY_FN (imsi, "IMSI") -STR_REPLY_READY_FN (operator_identifier, "Operator identifier") -STR_REPLY_READY_FN (operator_name, "Operator name") - -static void -interface_initialization_step (InitAsyncContext *ctx) -{ - if (g_cancellable_is_cancelled (ctx->cancellable)) { - g_simple_async_result_set_error (ctx->result, - MM_CORE_ERROR, - MM_CORE_ERROR_CANCELLED, - "Interface initialization cancelled"); - g_simple_async_result_complete_in_idle (ctx->result); - init_async_context_free (ctx); - return; - } - - switch (ctx->step) { - case INITIALIZATION_STEP_FIRST: - /* Fall down to next step */ - ctx->step++; - - case INITIALIZATION_STEP_SIM_IDENTIFIER: - /* SIM ID is meant to be loaded only once during the whole - * lifetime of the modem. Therefore, if we already have them loaded, - * don't try to load them again. */ - if (mm_gdbus_sim_get_sim_identifier (MM_GDBUS_SIM (ctx->self)) == NULL && - MM_SIM_GET_CLASS (ctx->self)->load_sim_identifier && - MM_SIM_GET_CLASS (ctx->self)->load_sim_identifier_finish) { - MM_SIM_GET_CLASS (ctx->self)->load_sim_identifier ( - ctx->self, - (GAsyncReadyCallback)load_sim_identifier_ready, - ctx); - return; - } - /* Fall down to next step */ - ctx->step++; - - case INITIALIZATION_STEP_IMSI: - /* IMSI is meant to be loaded only once during the whole - * lifetime of the modem. Therefore, if we already have them loaded, - * don't try to load them again. */ - if (mm_gdbus_sim_get_imsi (MM_GDBUS_SIM (ctx->self)) == NULL && - MM_SIM_GET_CLASS (ctx->self)->load_imsi && - MM_SIM_GET_CLASS (ctx->self)->load_imsi_finish) { - MM_SIM_GET_CLASS (ctx->self)->load_imsi ( - ctx->self, - (GAsyncReadyCallback)load_imsi_ready, - ctx); - return; - } - /* Fall down to next step */ - ctx->step++; - - case INITIALIZATION_STEP_OPERATOR_ID: - /* Operator ID is meant to be loaded only once during the whole - * lifetime of the modem. Therefore, if we already have them loaded, - * don't try to load them again. */ - if (mm_gdbus_sim_get_operator_identifier (MM_GDBUS_SIM (ctx->self)) == NULL && - MM_SIM_GET_CLASS (ctx->self)->load_operator_identifier && - MM_SIM_GET_CLASS (ctx->self)->load_operator_identifier_finish) { - MM_SIM_GET_CLASS (ctx->self)->load_operator_identifier ( - ctx->self, - (GAsyncReadyCallback)load_operator_identifier_ready, - ctx); - return; - } - /* Fall down to next step */ - ctx->step++; - - case INITIALIZATION_STEP_OPERATOR_NAME: - /* Operator Name is meant to be loaded only once during the whole - * lifetime of the modem. Therefore, if we already have them loaded, - * don't try to load them again. */ - if (mm_gdbus_sim_get_operator_name (MM_GDBUS_SIM (ctx->self)) == NULL && - MM_SIM_GET_CLASS (ctx->self)->load_operator_name && - MM_SIM_GET_CLASS (ctx->self)->load_operator_name_finish) { - MM_SIM_GET_CLASS (ctx->self)->load_operator_name ( - ctx->self, - (GAsyncReadyCallback)load_operator_name_ready, - ctx); - return; - } - /* Fall down to next step */ - ctx->step++; - - case INITIALIZATION_STEP_LAST: - /* We are done without errors! */ - g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); - g_simple_async_result_complete_in_idle (ctx->result); - init_async_context_free (ctx); - return; - } - - - g_assert_not_reached (); -} - -static void -common_init_async (GAsyncInitable *initable, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) - -{ - InitAsyncContext *ctx; - - ctx = g_new (InitAsyncContext, 1); - ctx->self = g_object_ref (initable); - ctx->result = g_simple_async_result_new (G_OBJECT (initable), - callback, - user_data, - common_init_async); - ctx->cancellable = (cancellable ? - g_object_ref (cancellable) : - NULL); - ctx->step = INITIALIZATION_STEP_FIRST; - ctx->sim_identifier_tries = 0; - - interface_initialization_step (ctx); -} - -static void -initable_init_async (GAsyncInitable *initable, - int io_priority, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - mm_gdbus_sim_set_sim_identifier (MM_GDBUS_SIM (initable), NULL); - mm_gdbus_sim_set_imsi (MM_GDBUS_SIM (initable), NULL); - mm_gdbus_sim_set_operator_identifier (MM_GDBUS_SIM (initable), NULL); - mm_gdbus_sim_set_operator_name (MM_GDBUS_SIM (initable), NULL); - - common_init_async (initable, cancellable, callback, user_data); -} - -void -mm_sim_new (MMBaseModem *modem, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - g_async_initable_new_async (MM_TYPE_SIM, - G_PRIORITY_DEFAULT, - cancellable, - callback, - user_data, - MM_SIM_MODEM, modem, - NULL); -} - -gboolean -mm_sim_initialize_finish (MMSim *self, - GAsyncResult *result, - GError **error) -{ - return initable_init_finish (G_ASYNC_INITABLE (self), result, error); -} - -void -mm_sim_initialize (MMSim *self, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - common_init_async (G_ASYNC_INITABLE (self), - cancellable, - callback, - user_data); -} - -static void -set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - MMSim *self = MM_SIM (object); - - switch (prop_id) { - case PROP_PATH: - g_free (self->priv->path); - self->priv->path = g_value_dup_string (value); - - /* Export when we get a DBus connection AND we have a path */ - if (self->priv->path && - self->priv->connection) - mm_sim_dbus_export (self); - break; - case PROP_CONNECTION: - g_clear_object (&self->priv->connection); - self->priv->connection = g_value_dup_object (value); - - /* Export when we get a DBus connection AND we have a path */ - if (!self->priv->connection) - mm_sim_dbus_unexport (self); - else if (self->priv->path) - mm_sim_dbus_export (self); - break; - case PROP_MODEM: - g_clear_object (&self->priv->modem); - self->priv->modem = g_value_dup_object (value); - if (self->priv->modem) { - /* Bind the modem's connection (which is set when it is exported, - * and unset when unexported) to the SIM's connection */ - g_object_bind_property (self->priv->modem, MM_BASE_MODEM_CONNECTION, - self, MM_SIM_CONNECTION, - G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE); - } - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - MMSim *self = MM_SIM (object); - - switch (prop_id) { - case PROP_PATH: - g_value_set_string (value, self->priv->path); - break; - case PROP_CONNECTION: - g_value_set_object (value, self->priv->connection); - break; - case PROP_MODEM: - g_value_set_object (value, self->priv->modem); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -mm_sim_init (MMSim *self) -{ - /* Initialize private data */ - self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, - MM_TYPE_SIM, - MMSimPrivate); -} - -static void -finalize (GObject *object) -{ - MMSim *self = MM_SIM (object); - - g_free (self->priv->path); - - G_OBJECT_CLASS (mm_sim_parent_class)->finalize (object); -} - -static void -dispose (GObject *object) -{ - MMSim *self = MM_SIM (object); - - if (self->priv->connection) { - /* If we arrived here with a valid connection, make sure we unexport - * the object */ - mm_sim_dbus_unexport (self); - g_clear_object (&self->priv->connection); - } - - g_clear_object (&self->priv->modem); - - G_OBJECT_CLASS (mm_sim_parent_class)->dispose (object); -} - -static void -async_initable_iface_init (GAsyncInitableIface *iface) -{ - iface->init_async = initable_init_async; - iface->init_finish = initable_init_finish; -} - -static void -mm_sim_class_init (MMSimClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (object_class, sizeof (MMSimPrivate)); - - /* Virtual methods */ - object_class->get_property = get_property; - object_class->set_property = set_property; - object_class->finalize = finalize; - object_class->dispose = dispose; - - klass->load_sim_identifier = load_sim_identifier; - klass->load_sim_identifier_finish = load_sim_identifier_finish; - klass->load_imsi = load_imsi; - klass->load_imsi_finish = load_imsi_finish; - klass->load_operator_identifier = load_operator_identifier; - klass->load_operator_identifier_finish = load_operator_identifier_finish; - klass->load_operator_name = load_operator_name; - klass->load_operator_name_finish = load_operator_name_finish; - klass->send_pin = send_pin; - klass->send_pin_finish = common_send_pin_puk_finish; - klass->send_puk = send_puk; - klass->send_puk_finish = common_send_pin_puk_finish; - klass->enable_pin = enable_pin; - klass->enable_pin_finish = enable_pin_finish; - klass->change_pin = change_pin; - klass->change_pin_finish = change_pin_finish; - - properties[PROP_CONNECTION] = - g_param_spec_object (MM_SIM_CONNECTION, - "Connection", - "GDBus connection to the system bus.", - G_TYPE_DBUS_CONNECTION, - G_PARAM_READWRITE); - g_object_class_install_property (object_class, PROP_CONNECTION, properties[PROP_CONNECTION]); - - properties[PROP_PATH] = - g_param_spec_string (MM_SIM_PATH, - "Path", - "DBus path of the SIM", - NULL, - G_PARAM_READWRITE); - g_object_class_install_property (object_class, PROP_PATH, properties[PROP_PATH]); - - properties[PROP_MODEM] = - g_param_spec_object (MM_SIM_MODEM, - "Modem", - "The Modem which owns this SIM", - MM_TYPE_BASE_MODEM, - G_PARAM_READWRITE); - g_object_class_install_property (object_class, PROP_MODEM, properties[PROP_MODEM]); - - /* Signals */ - signals[SIGNAL_PIN_LOCK_ENABLED] = - g_signal_new (MM_SIM_PIN_LOCK_ENABLED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (MMSimClass, pin_lock_enabled), - NULL, NULL, - g_cclosure_marshal_generic, - G_TYPE_NONE, 1, G_TYPE_BOOLEAN); -} diff --git a/src/mm-sim.h b/src/mm-sim.h deleted file mode 100644 index 6ff875ff6..000000000 --- a/src/mm-sim.h +++ /dev/null @@ -1,168 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details: - * - * Author: Aleksander Morgado - * - * Copyright (C) 2011 Google, Inc. - */ - -#ifndef MM_SIM_H -#define MM_SIM_H - -#include -#include - -#include -#include "mm-base-modem.h" - -#define MM_TYPE_SIM (mm_sim_get_type ()) -#define MM_SIM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_SIM, MMSim)) -#define MM_SIM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_SIM, MMSimClass)) -#define MM_IS_SIM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_SIM)) -#define MM_IS_SIM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_SIM)) -#define MM_SIM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_SIM, MMSimClass)) - -typedef struct _MMSim MMSim; -typedef struct _MMSimClass MMSimClass; -typedef struct _MMSimPrivate MMSimPrivate; - -/* Properties */ -#define MM_SIM_PATH "sim-path" -#define MM_SIM_CONNECTION "sim-connection" -#define MM_SIM_MODEM "sim-modem" - -/* Signals */ -#define MM_SIM_PIN_LOCK_ENABLED "pin-lock-enabled" - -struct _MMSim { - MmGdbusSimSkeleton parent; - MMSimPrivate *priv; -}; - -struct _MMSimClass { - MmGdbusSimSkeletonClass parent; - - /* Load SIM identifier (async) */ - void (* load_sim_identifier) (MMSim *self, - GAsyncReadyCallback callback, - gpointer user_data); - gchar * (* load_sim_identifier_finish) (MMSim *self, - GAsyncResult *res, - GError **error); - - /* Load IMSI (async) */ - void (* load_imsi) (MMSim *self, - GAsyncReadyCallback callback, - gpointer user_data); - gchar * (* load_imsi_finish) (MMSim *self, - GAsyncResult *res, - GError **error); - - /* Load operator identifier (async) */ - void (* load_operator_identifier) (MMSim *self, - GAsyncReadyCallback callback, - gpointer user_data); - gchar * (* load_operator_identifier_finish) (MMSim *self, - GAsyncResult *res, - GError **error); - - /* Load operator name (async) */ - void (* load_operator_name) (MMSim *self, - GAsyncReadyCallback callback, - gpointer user_data); - gchar * (* load_operator_name_finish) (MMSim *self, - GAsyncResult *res, - GError **error); - - /* Change PIN (async) */ - void (* change_pin) (MMSim *self, - const gchar *old_pin, - const gchar *new_pin, - GAsyncReadyCallback callback, - gpointer user_data); - gboolean (* change_pin_finish) (MMSim *self, - GAsyncResult *res, - GError **error); - - /* Enable PIN (async) */ - void (* enable_pin) (MMSim *self, - const gchar *pin, - gboolean enabled, - GAsyncReadyCallback callback, - gpointer user_data); - gboolean (* enable_pin_finish) (MMSim *self, - GAsyncResult *res, - GError **error); - - /* Send PIN (async) */ - void (* send_pin) (MMSim *self, - const gchar *pin, - GAsyncReadyCallback callback, - gpointer user_data); - gboolean (* send_pin_finish) (MMSim *self, - GAsyncResult *res, - GError **error); - - /* Send PUK (async) */ - void (* send_puk) (MMSim *self, - const gchar *puk, - const gchar *new_pin, - GAsyncReadyCallback callback, - gpointer user_data); - gboolean (* send_puk_finish) (MMSim *self, - GAsyncResult *res, - GError **error); - - /* Signals */ - void (*pin_lock_enabled) (MMSim *self, - gboolean enabled); -}; - -GType mm_sim_get_type (void); - -void mm_sim_new (MMBaseModem *modem, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -MMSim *mm_sim_new_finish (GAsyncResult *res, - GError **error); - -void mm_sim_initialize (MMSim *self, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean mm_sim_initialize_finish (MMSim *self, - GAsyncResult *result, - GError **error); - -void mm_sim_send_pin (MMSim *self, - const gchar *pin, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean mm_sim_send_pin_finish (MMSim *self, - GAsyncResult *res, - GError **error); - -void mm_sim_send_puk (MMSim *self, - const gchar *puk, - const gchar *new_pin, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean mm_sim_send_puk_finish (MMSim *self, - GAsyncResult *res, - GError **error); - -void mm_sim_export (MMSim *self); - -const gchar *mm_sim_get_path (MMSim *sim); - -#endif /* MM_SIM_H */ -- cgit v1.2.1