diff options
author | Dan Williams <dcbw@redhat.com> | 2010-03-19 11:01:19 -0700 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2010-03-19 11:01:19 -0700 |
commit | 85fc71818e3f3058cf256aaab1ba269a424a27f8 (patch) | |
tree | 8e7612df505f895fc4d6d81e42696af700bf16db | |
parent | 4558df894bb20a121ee1d2942c206b5bfde2c030 (diff) |
core: have modem base class handle card information
-rw-r--r-- | src/mm-generic-cdma.c | 115 | ||||
-rw-r--r-- | src/mm-generic-gsm.c | 103 | ||||
-rw-r--r-- | src/mm-modem-base.c | 209 | ||||
-rw-r--r-- | src/mm-modem-base.h | 17 |
4 files changed, 266 insertions, 178 deletions
diff --git a/src/mm-generic-cdma.c b/src/mm-generic-cdma.c index c247d790..6fce3716 100644 --- a/src/mm-generic-cdma.c +++ b/src/mm-generic-cdma.c @@ -27,6 +27,7 @@ #include "mm-errors.h" #include "mm-callback-info.h" #include "mm-serial-parsers.h" +#include "mm-modem-helpers.h" #define MM_GENERIC_CDMA_PREV_STATE_TAG "prev-state" @@ -372,6 +373,17 @@ registration_cleanup (MMGenericCdma *self, GQuark error_class, guint32 error_num } static void +get_enable_info_done (MMModem *modem, + const char *manufacturer, + const char *model, + const char *version, + GError *error, + gpointer user_data) +{ + /* Modem base class handles the response for us */ +} + +static void enable_all_done (MMModem *modem, GError *error, gpointer user_data) { MMCallbackInfo *info = user_data; @@ -393,6 +405,9 @@ enable_all_done (MMModem *modem, GError *error, gpointer user_data) } update_enabled_state (self, FALSE, MM_MODEM_STATE_REASON_NONE); + + /* Grab device info right away */ + mm_modem_get_info (modem, get_enable_info_done, NULL); } out: @@ -678,104 +693,16 @@ disconnect (MMModem *modem, } static void -card_info_invoke (MMCallbackInfo *info) -{ - MMModemInfoFn callback = (MMModemInfoFn) info->callback; - - callback (info->modem, - (char *) mm_callback_info_get_data (info, "card-info-manufacturer"), - (char *) mm_callback_info_get_data (info, "card-info-model"), - (char *) mm_callback_info_get_data (info, "card-info-version"), - info->error, info->user_data); -} - -static const char * -strip_response (const char *resp, const char *cmd) -{ - const char *p = resp; - - if (p) { - if (!strncmp (p, cmd, strlen (cmd))) - p += strlen (cmd); - while (*p == ' ') - p++; - } - return p; -} - -static void -get_version_done (MMAtSerialPort *port, - GString *response, - GError *error, - gpointer user_data) -{ - MMCallbackInfo *info = (MMCallbackInfo *) user_data; - const char *p; - - if (!error) { - p = strip_response (response->str, "+GMR:"); - mm_callback_info_set_data (info, "card-info-version", g_strdup (p), g_free); - } else if (!info->error) - info->error = g_error_copy (error); - - mm_callback_info_schedule (info); -} - -static void -get_model_done (MMAtSerialPort *port, - GString *response, - GError *error, - gpointer user_data) -{ - MMCallbackInfo *info = (MMCallbackInfo *) user_data; - const char *p; - - if (!error) { - p = strip_response (response->str, "+GMM:"); - mm_callback_info_set_data (info, "card-info-model", g_strdup (p), g_free); - } else if (!info->error) - info->error = g_error_copy (error); -} - -static void -get_manufacturer_done (MMAtSerialPort *port, - GString *response, - GError *error, - gpointer user_data) -{ - MMCallbackInfo *info = (MMCallbackInfo *) user_data; - const char *p; - - if (!error) { - p = strip_response (response->str, "+GMI:"); - mm_callback_info_set_data (info, "card-info-manufacturer", g_strdup (p), g_free); - } else - info->error = g_error_copy (error); -} - -static void get_card_info (MMModem *modem, MMModemInfoFn callback, gpointer user_data) { - MMGenericCdma *self = MM_GENERIC_CDMA (modem); - MMCallbackInfo *info; MMAtSerialPort *port; + GError *error = NULL; - info = mm_callback_info_new_full (MM_MODEM (modem), - card_info_invoke, - G_CALLBACK (callback), - user_data); - - port = mm_generic_cdma_get_best_at_port (self, &info->error); - if (!port) { - mm_callback_info_schedule (info); - return; - } - - mm_at_serial_port_queue_command_cached (port, "+GMI", 3, get_manufacturer_done, info); - mm_at_serial_port_queue_command_cached (port, "+GMM", 3, get_model_done, info); - mm_at_serial_port_queue_command_cached (port, "+GMR", 3, get_version_done, info); + port = mm_generic_cdma_get_best_at_port (MM_GENERIC_CDMA (modem), &error); + mm_modem_base_get_card_info (MM_MODEM_BASE (modem), port, error, callback, user_data); + g_clear_error (&error); } /*****************************************************************************/ @@ -900,7 +827,7 @@ get_string_done (MMAtSerialPort *port, if (error) info->error = g_error_copy (error); else { - p = strip_response (response->str, "+GSN:"); + p = mm_strip_tag (response->str, "+GSN:"); mm_callback_info_set_result (info, g_strdup (p), g_free); } @@ -1314,7 +1241,7 @@ get_analog_digital_done (MMAtSerialPort *port, } /* Strip any leading command tag and spaces */ - reply = strip_response (response->str, "+CAD:"); + reply = mm_strip_tag (response->str, "+CAD:"); errno = 0; int_cad = strtol (reply, NULL, 10); diff --git a/src/mm-generic-gsm.c b/src/mm-generic-gsm.c index 050229ea..e1aec8ee 100644 --- a/src/mm-generic-gsm.c +++ b/src/mm-generic-gsm.c @@ -746,6 +746,17 @@ get_allowed_mode_done (MMModem *modem, } } +static void +get_enable_info_done (MMModem *modem, + const char *manufacturer, + const char *model, + const char *version, + GError *error, + gpointer user_data) +{ + /* Modem base class handles the response for us */ +} + void mm_generic_gsm_enable_complete (MMGenericGsm *self, GError *error, @@ -783,6 +794,9 @@ mm_generic_gsm_enable_complete (MMGenericGsm *self, /* Try to enable XON/XOFF flow control */ mm_at_serial_port_queue_command (priv->primary, "+IFC=1,1", 3, NULL, NULL); + /* Grab device info right away */ + mm_modem_get_info (MM_MODEM (self), get_enable_info_done, NULL); + /* Get allowed mode */ if (MM_GENERIC_GSM_GET_CLASS (self)->get_allowed_mode) MM_GENERIC_GSM_GET_CLASS (self)->get_allowed_mode (self, get_allowed_mode_done, NULL); @@ -1075,95 +1089,16 @@ get_imsi (MMModemGsmCard *modem, } static void -card_info_invoke (MMCallbackInfo *info) -{ - MMModemInfoFn callback = (MMModemInfoFn) info->callback; - - callback (info->modem, - (char *) mm_callback_info_get_data (info, "card-info-manufacturer"), - (char *) mm_callback_info_get_data (info, "card-info-model"), - (char *) mm_callback_info_get_data (info, "card-info-version"), - info->error, info->user_data); -} - -#define GMI_RESP_TAG "+CGMI:" -#define GMM_RESP_TAG "+CGMM:" -#define GMR_RESP_TAG "+CGMR:" - -static const char * -strip_tag (const char *str, const char *tag) -{ - /* Strip the response header, if any */ - if (strncmp (str, tag, strlen (tag)) == 0) - str += strlen (tag); - while (*str && isspace (*str)) - str++; - return str; -} - -static void -get_version_done (MMAtSerialPort *port, - GString *response, - GError *error, - gpointer user_data) -{ - MMCallbackInfo *info = (MMCallbackInfo *) user_data; - const char *resp = strip_tag (response->str, GMR_RESP_TAG); - - if (!error) - mm_callback_info_set_data (info, "card-info-version", g_strdup (resp), g_free); - else if (!info->error) - info->error = g_error_copy (error); - - mm_callback_info_schedule (info); -} - -static void -get_model_done (MMAtSerialPort *port, - GString *response, - GError *error, - gpointer user_data) -{ - MMCallbackInfo *info = (MMCallbackInfo *) user_data; - const char *resp = strip_tag (response->str, GMM_RESP_TAG); - - if (!error) - mm_callback_info_set_data (info, "card-info-model", g_strdup (resp), g_free); - else if (!info->error) - info->error = g_error_copy (error); -} - -static void -get_manufacturer_done (MMAtSerialPort *port, - GString *response, - GError *error, - gpointer user_data) -{ - MMCallbackInfo *info = (MMCallbackInfo *) user_data; - const char *resp = strip_tag (response->str, GMI_RESP_TAG); - - if (!error) - mm_callback_info_set_data (info, "card-info-manufacturer", g_strdup (resp), g_free); - else - info->error = g_error_copy (error); -} - -static void get_card_info (MMModem *modem, MMModemInfoFn callback, gpointer user_data) { - MMGenericGsmPrivate *priv = MM_GENERIC_GSM_GET_PRIVATE (modem); - MMCallbackInfo *info; - - info = mm_callback_info_new_full (MM_MODEM (modem), - card_info_invoke, - G_CALLBACK (callback), - user_data); + MMAtSerialPort *port; + GError *error = NULL; - mm_at_serial_port_queue_command_cached (priv->primary, "+CGMI", 3, get_manufacturer_done, info); - mm_at_serial_port_queue_command_cached (priv->primary, "+CGMM", 3, get_model_done, info); - mm_at_serial_port_queue_command_cached (priv->primary, "+CGMR", 3, get_version_done, info); + port = mm_generic_gsm_get_best_at_port (MM_GENERIC_GSM (modem), &error); + mm_modem_base_get_card_info (MM_MODEM_BASE (modem), port, error, callback, user_data); + g_clear_error (&error); } #define PIN_CLOSE_PORT_TAG "pin-close-port" diff --git a/src/mm-modem-base.c b/src/mm-modem-base.c index 8af9bd14..389f5f04 100644 --- a/src/mm-modem-base.c +++ b/src/mm-modem-base.c @@ -25,6 +25,8 @@ #include "mm-errors.h" #include "mm-options.h" #include "mm-properties-changed-signal.h" +#include "mm-callback-info.h" +#include "mm-modem-helpers.h" static void modem_init (MMModem *modem_class); @@ -44,6 +46,10 @@ typedef struct { gboolean valid; MMModemState state; + char *manf; + char *model; + char *revision; + MMAuthProvider *authp; GHashTable *ports; @@ -213,6 +219,209 @@ mm_modem_base_set_unlock_required (MMModemBase *self, const char *unlock_require g_object_notify (G_OBJECT (self), MM_MODEM_UNLOCK_REQUIRED); } +const char * +mm_modem_base_get_manf (MMModemBase *self) +{ + g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (MM_IS_MODEM_BASE (self), NULL); + + return MM_MODEM_BASE_GET_PRIVATE (self)->manf; +} + +void +mm_modem_base_set_manf (MMModemBase *self, const char *manf) +{ + MMModemBasePrivate *priv; + + g_return_if_fail (self != NULL); + g_return_if_fail (MM_IS_MODEM_BASE (self)); + + priv = MM_MODEM_BASE_GET_PRIVATE (self); + g_free (priv->manf); + priv->manf = g_strdup (manf); +} + +const char * +mm_modem_base_get_model (MMModemBase *self) +{ + g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (MM_IS_MODEM_BASE (self), NULL); + + return MM_MODEM_BASE_GET_PRIVATE (self)->model; +} + +void +mm_modem_base_set_model (MMModemBase *self, const char *model) +{ + MMModemBasePrivate *priv; + + g_return_if_fail (self != NULL); + g_return_if_fail (MM_IS_MODEM_BASE (self)); + + priv = MM_MODEM_BASE_GET_PRIVATE (self); + g_free (priv->model); + priv->model = g_strdup (model); +} + +const char * +mm_modem_base_get_revision (MMModemBase *self) +{ + g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (MM_IS_MODEM_BASE (self), NULL); + + return MM_MODEM_BASE_GET_PRIVATE (self)->revision; +} + +void +mm_modem_base_set_revision (MMModemBase *self, const char *revision) +{ + MMModemBasePrivate *priv; + + g_return_if_fail (self != NULL); + g_return_if_fail (MM_IS_MODEM_BASE (self)); + + priv = MM_MODEM_BASE_GET_PRIVATE (self); + g_free (priv->revision); + priv->revision = g_strdup (revision); +} + +/*************************************************************************/ +static void +card_info_simple_invoke (MMCallbackInfo *info) +{ + MMModemBase *self = MM_MODEM_BASE (info->modem); + MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (self); + MMModemInfoFn callback = (MMModemInfoFn) info->callback; + + callback (info->modem, priv->manf, priv->model, priv->revision, info->error, info->user_data); +} + +static void +card_info_cache_invoke (MMCallbackInfo *info) +{ + MMModemBase *self = MM_MODEM_BASE (info->modem); + MMModemBasePrivate *priv = MM_MODEM_BASE_GET_PRIVATE (self); + MMModemInfoFn callback = (MMModemInfoFn) info->callback; + const char *manf, *cmanf, *model, *cmodel, *rev, *crev; + + manf = mm_callback_info_get_data (info, "card-info-manf"); + cmanf = mm_callback_info_get_data (info, "card-info-c-manf"); + + model = mm_callback_info_get_data (info, "card-info-model"); + cmodel = mm_callback_info_get_data (info, "card-info-c-model"); + + rev = mm_callback_info_get_data (info, "card-info-revision"); + crev = mm_callback_info_get_data (info, "card-info-c-revision"); + + /* Prefer the 'C' responses over the plain responses */ + g_free (priv->manf); + priv->manf = g_strdup (cmanf ? cmanf : manf); + g_free (priv->model); + priv->model = g_strdup (cmodel ? cmodel : model); + g_free (priv->revision); + priv->revision = g_strdup (crev ? crev : rev); + + callback (info->modem, priv->manf, priv->model, priv->revision, info->error, info->user_data); +} + +static void +info_item_done (MMCallbackInfo *info, + GString *response, + GError *error, + const char *tag, + const char *desc) +{ + const char *p; + + if (!error) { + p = mm_strip_tag (response->str, tag); + mm_callback_info_set_data (info, desc, strlen (p) ? g_strdup (p) : NULL, g_free); + } + + mm_callback_info_chain_complete_one (info); +} + +#define GET_INFO_RESP_FN(func_name, tag, desc) \ +static void \ +func_name (MMAtSerialPort *port, \ + GString *response, \ + GError *error, \ + gpointer user_data) \ +{ \ + info_item_done ((MMCallbackInfo *) user_data, response, error, tag , desc ); \ +} + +GET_INFO_RESP_FN(get_revision_done, "+GMR:", "card-info-revision") +GET_INFO_RESP_FN(get_model_done, "+GMM:", "card-info-model") +GET_INFO_RESP_FN(get_manf_done, "+GMI:", "card-info-manf") + +GET_INFO_RESP_FN(get_c_revision_done, "+CGMR:", "card-info-c-revision") +GET_INFO_RESP_FN(get_c_model_done, "+CGMM:", "card-info-c-model") +GET_INFO_RESP_FN(get_c_manf_done, "+CGMI:", "card-info-c-manf") + +void +mm_modem_base_get_card_info (MMModemBase *self, + MMAtSerialPort *port, + GError *port_error, + MMModemInfoFn callback, + gpointer user_data) +{ + MMModemBasePrivate *priv; + MMCallbackInfo *info; + MMModemState state; + gboolean cached = FALSE; + GError *error = port_error; + + g_return_if_fail (self != NULL); + g_return_if_fail (MM_IS_MODEM_BASE (self)); + g_return_if_fail (port != NULL); + g_return_if_fail (MM_IS_AT_SERIAL_PORT (port)); + g_return_if_fail (callback != NULL); + + priv = MM_MODEM_BASE_GET_PRIVATE (self); + + /* Cached info and errors schedule the callback immediately and do + * not hit up the card for it's model information. + */ + if (priv->manf || priv->model || priv->revision) + cached = TRUE; + else { + state = mm_modem_get_state (MM_MODEM (self)); + + if (port_error) + error = g_error_copy (port_error); + else if (state < MM_MODEM_STATE_ENABLING) { + error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, + "The modem is not enabled."); + } + } + + /* If we have cached info or an error, don't hit up the card */ + if (cached || error) { + info = mm_callback_info_new_full (MM_MODEM (self), + card_info_simple_invoke, + G_CALLBACK (callback), + user_data); + info->error = error; + mm_callback_info_schedule (info); + return; + } + + /* Otherwise, ask the card */ + info = mm_callback_info_new_full (MM_MODEM (self), + card_info_cache_invoke, + G_CALLBACK (callback), + user_data); + + mm_callback_info_chain_start (info, 6); + mm_at_serial_port_queue_command_cached (port, "+GMI", 3, get_manf_done, info); + mm_at_serial_port_queue_command_cached (port, "+GMM", 3, get_model_done, info); + mm_at_serial_port_queue_command_cached (port, "+GMR", 3, get_revision_done, info); + mm_at_serial_port_queue_command_cached (port, "+CGMI", 3, get_c_manf_done, info); + mm_at_serial_port_queue_command_cached (port, "+CGMM", 3, get_c_model_done, info); + mm_at_serial_port_queue_command_cached (port, "+CGMR", 3, get_c_revision_done, info); +} + /*****************************************************************************/ static gboolean diff --git a/src/mm-modem-base.h b/src/mm-modem-base.h index db2b5fb6..516af2eb 100644 --- a/src/mm-modem-base.h +++ b/src/mm-modem-base.h @@ -22,6 +22,8 @@ #include <glib-object.h> #include "mm-port.h" +#include "mm-at-serial-port.h" +#include "mm-modem.h" #define MM_TYPE_MODEM_BASE (mm_modem_base_get_type ()) #define MM_MODEM_BASE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_MODEM_BASE, MMModemBase)) @@ -65,5 +67,20 @@ const char *mm_modem_base_get_unlock_required (MMModemBase *self); void mm_modem_base_set_unlock_required (MMModemBase *self, const char *unlock_required); +const char *mm_modem_base_get_manf (MMModemBase *self); +void mm_modem_base_set_manf (MMModemBase *self, const char *manf); + +const char *mm_modem_base_get_model (MMModemBase *self); +void mm_modem_base_set_model (MMModemBase *self, const char *model); + +const char *mm_modem_base_get_revision (MMModemBase *self); +void mm_modem_base_set_revision (MMModemBase *self, const char *revision); + +void mm_modem_base_get_card_info (MMModemBase *self, + MMAtSerialPort *port, + GError *port_error, + MMModemInfoFn callback, + gpointer user_data); + #endif /* MM_MODEM_BASE_H */ |