core: have modem base class handle card information
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -371,6 +372,17 @@ registration_cleanup (MMGenericCdma *self, GQuark error_class, guint32 error_num
|
||||
priv->simple_connect_info = NULL;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -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:
|
||||
@@ -677,105 +692,17 @@ disconnect (MMModem *modem,
|
||||
mm_serial_port_flash (MM_SERIAL_PORT (priv->primary), 1000, disconnect_flash_done, info);
|
||||
}
|
||||
|
||||
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);
|
||||
|
@@ -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);
|
||||
@@ -1074,96 +1088,17 @@ get_imsi (MMModemGsmCard *modem,
|
||||
mm_at_serial_port_queue_command_cached (priv->primary, "+CIMI", 3, get_string_done, info);
|
||||
}
|
||||
|
||||
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;
|
||||
MMAtSerialPort *port;
|
||||
GError *error = NULL;
|
||||
|
||||
info = mm_callback_info_new_full (MM_MODEM (modem),
|
||||
card_info_invoke,
|
||||
G_CALLBACK (callback),
|
||||
user_data);
|
||||
|
||||
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"
|
||||
|
@@ -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
|
||||
|
@@ -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 */
|
||||
|
||||
|
Reference in New Issue
Block a user