Merge remote branch 'origin/master' into qcdm

This commit is contained in:
Dan Williams
2010-03-11 13:43:06 -08:00
6 changed files with 248 additions and 41 deletions
+28 -16
View File
@@ -157,21 +157,22 @@ typedef struct {
} CPinResult;
static CPinResult unlock_results[] = {
{ "SIM PIN", "sim-pin", MM_MOBILE_ERROR_SIM_PIN },
{ "SIM PUK", "sim-puk", MM_MOBILE_ERROR_SIM_PUK },
{ "PH-SIM PIN", "ph-sim-pin", MM_MOBILE_ERROR_PH_SIM_PIN },
{ "PH-FSIM PIN", "ph-fsim-pin", MM_MOBILE_ERROR_PH_FSIM_PIN },
{ "PH-FSIM PUK", "ph-fsim-puk", MM_MOBILE_ERROR_PH_FSIM_PUK },
{ "SIM PIN2", "sim-pin2", MM_MOBILE_ERROR_SIM_PIN2 },
{ "SIM PUK2", "sim-puk2", MM_MOBILE_ERROR_SIM_PUK2 },
{ "PH-NET PIN", "ph-net-pin", MM_MOBILE_ERROR_NETWORK_PIN },
{ "PH-NET PUK", "ph-net-puk", MM_MOBILE_ERROR_NETWORK_PUK },
/* Longer entries first so we catch the correct one with strcmp() */
{ "PH-NETSUB PIN", "ph-netsub-pin", MM_MOBILE_ERROR_NETWORK_SUBSET_PIN },
{ "PH-NETSUB PUK", "ph-netsub-puk", MM_MOBILE_ERROR_NETWORK_SUBSET_PUK },
{ "PH-SP PIN", "ph-sp-pin", MM_MOBILE_ERROR_SERVICE_PIN },
{ "PH-SP PUK", "ph-sp-puk", MM_MOBILE_ERROR_SERVICE_PUK },
{ "PH-FSIM PIN", "ph-fsim-pin", MM_MOBILE_ERROR_PH_FSIM_PIN },
{ "PH-FSIM PUK", "ph-fsim-puk", MM_MOBILE_ERROR_PH_FSIM_PUK },
{ "PH-CORP PIN", "ph-corp-pin", MM_MOBILE_ERROR_CORP_PIN },
{ "PH-CORP PUK", "ph-corp-puk", MM_MOBILE_ERROR_CORP_PUK },
{ "PH-SIM PIN", "ph-sim-pin", MM_MOBILE_ERROR_PH_SIM_PIN },
{ "PH-NET PIN", "ph-net-pin", MM_MOBILE_ERROR_NETWORK_PIN },
{ "PH-NET PUK", "ph-net-puk", MM_MOBILE_ERROR_NETWORK_PUK },
{ "PH-SP PIN", "ph-sp-pin", MM_MOBILE_ERROR_SERVICE_PIN },
{ "PH-SP PUK", "ph-sp-puk", MM_MOBILE_ERROR_SERVICE_PUK },
{ "SIM PIN2", "sim-pin2", MM_MOBILE_ERROR_SIM_PIN2 },
{ "SIM PUK2", "sim-puk2", MM_MOBILE_ERROR_SIM_PUK2 },
{ "SIM PIN", "sim-pin", MM_MOBILE_ERROR_SIM_PIN },
{ "SIM PUK", "sim-puk", MM_MOBILE_ERROR_SIM_PUK },
{ NULL, NULL, MM_MOBILE_ERROR_PHONE_FAILURE },
};
@@ -665,11 +666,18 @@ mm_generic_gsm_enable_complete (MMGenericGsm *self,
g_return_if_fail (MM_IS_GENERIC_GSM (self));
g_return_if_fail (info != NULL);
priv = MM_GENERIC_GSM_GET_PRIVATE (self);
if (error) {
mm_modem_set_state (MM_MODEM (self),
MM_MODEM_STATE_DISABLED,
MM_MODEM_STATE_REASON_NONE);
if (priv->primary && mm_serial_port_is_open (priv->primary))
mm_serial_port_close (priv->primary);
if (priv->secondary && mm_serial_port_is_open (priv->secondary))
mm_serial_port_close (priv->secondary);
info->error = g_error_copy (error);
mm_callback_info_schedule (info);
return;
@@ -678,8 +686,6 @@ mm_generic_gsm_enable_complete (MMGenericGsm *self,
mm_generic_gsm_update_enabled_state (self, FALSE, MM_MODEM_STATE_REASON_NONE);
}
priv = MM_GENERIC_GSM_GET_PRIVATE (self);
/* Open the second port here if the modem has one. We'll use it for
* signal strength and registration updates when the device is connected,
* but also many devices will send unsolicited registration or other
@@ -1965,13 +1971,19 @@ disconnect_flash_done (MMSerialPort *port,
char *command;
info->error = mm_modem_check_removed (info->modem, error);
if (info->error) {
/* Ignore NO_CARRIER errors and proceed with the PDP context deactivation */
if ( info->error
&& !g_error_matches (info->error,
MM_MODEM_CONNECT_ERROR,
MM_MODEM_CONNECT_ERROR_NO_CARRIER)) {
mm_callback_info_schedule (info);
return;
}
/* Disconnect the PDP context */
priv = MM_GENERIC_GSM_GET_PRIVATE (info->modem);
mm_port_set_connected (priv->data, FALSE);
/* Disconnect the PDP context */
if (priv->cid >= 0)
command = g_strdup_printf ("+CGACT=0,%d", priv->cid);
else {
@@ -1979,7 +1991,7 @@ disconnect_flash_done (MMSerialPort *port,
command = g_strdup_printf ("+CGACT=0");
}
mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), command, 60, disconnect_cgact_done, info);
mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), command, 3, disconnect_cgact_done, info);
g_free (command);
}
+54 -1
View File
@@ -77,6 +77,8 @@ typedef enum {
PROBE_STATE_LAST
} ProbeState;
static void probe_complete (MMPluginBaseSupportsTask *task);
/*****************************************************************************/
G_DEFINE_TYPE (MMPluginBaseSupportsTask, mm_plugin_base_supports_task, G_TYPE_OBJECT)
@@ -91,6 +93,7 @@ typedef struct {
guint open_id;
guint32 open_tries;
guint full_id;
MMAtSerialPort *probe_port;
guint32 probed_caps;
@@ -198,6 +201,11 @@ mm_plugin_base_supports_task_complete (MMPluginBaseSupportsTask *task,
priv = MM_PLUGIN_BASE_SUPPORTS_TASK_GET_PRIVATE (task);
g_return_if_fail (priv->callback != NULL);
if (priv->full_id) {
g_source_remove (priv->full_id);
priv->full_id = 0;
}
subsys = g_udev_device_get_subsystem (priv->port);
name = g_udev_device_get_name (priv->port);
@@ -251,11 +259,15 @@ supports_task_dispose (GObject *object)
if (priv->open_id)
g_source_remove (priv->open_id);
if (priv->full_id)
g_source_remove (priv->full_id);
if (priv->probe_id)
g_source_remove (priv->probe_id);
if (priv->probe_port)
if (priv->probe_port) {
mm_serial_port_close (priv->probe_port);
g_object_unref (priv->probe_port);
}
G_OBJECT_CLASS (mm_plugin_base_supports_task_parent_class)->dispose (object);
}
@@ -349,6 +361,44 @@ parse_cgmm (const char *buf)
return 0;
}
static const char *dq_strings[] = {
"option/faema_", "os_logids.h", NULL
};
static void
port_buffer_full (MMSerialPort *port, GString *buffer, gpointer user_data)
{
MMPluginBaseSupportsTask *task = MM_PLUGIN_BASE_SUPPORTS_TASK (user_data);
MMPluginBaseSupportsTaskPrivate *priv = MM_PLUGIN_BASE_SUPPORTS_TASK_GET_PRIVATE (user_data);
const char **iter;
size_t iter_len;
int i;
/* Check for an immediate disqualification response. There are some
* ports (Option Icera-based chipsets have them, as do Qualcomm Gobi
* devices before their firmware is loaded) that just shouldn't be
* probed if we get a certain response because we know they can't be
* used. Kernel bugs (at least with 2.6.31 and 2.6.32) also trigger port
* flow control kernel oopses if we read too much data for these ports.
*/
for (iter = &dq_strings[0]; iter && *iter; iter++) {
/* Search in the response for the item; the response could have embedded
* nulls so we can't use memcmp() or strstr() on the whole response.
*/
iter_len = strlen (*iter);
for (i = 0; i < buffer->len - iter_len; i++) {
if (!memcmp (&buffer->str[i], *iter, iter_len)) {
/* Immediately close the port and complete probing */
priv->probed_caps = 0;
mm_serial_port_close (priv->probe_port);
probe_complete (task);
return;
}
}
}
}
static gboolean
emit_probe_result (gpointer user_data)
{
@@ -626,6 +676,9 @@ try_open (gpointer user_data)
port = mm_plugin_base_supports_task_get_port (task);
g_assert (port);
task_priv->full_id = g_signal_connect (task_priv->probe_port, "buffer-full",
G_CALLBACK (port_buffer_full), task);
g_debug ("(%s): probe requested by plugin '%s'",
g_udev_device_get_name (port),
mm_plugin_get_name (MM_PLUGIN (task_priv->plugin)));
+21 -6
View File
@@ -629,9 +629,13 @@ data_available (GIOChannel *source,
status = g_io_channel_read_chars (source, buf, SERIAL_BUF_SIZE, &bytes_read, &err);
if (status == G_IO_STATUS_ERROR) {
g_warning ("%s", err->message);
g_error_free (err);
err = NULL;
if (err && err->message)
g_warning ("%s", err->message);
g_clear_error (&err);
/* Serial port is closed; we're done */
if (priv->watch_id == 0)
break;
}
/* If no bytes read, just let g_io_channel wait for more data */
@@ -644,9 +648,9 @@ data_available (GIOChannel *source,
}
/* Make sure the response doesn't grow too long */
if (priv->response->len > SERIAL_BUF_SIZE) {
g_warning ("%s (%s): response buffer filled before repsonse received",
G_STRFUNC, mm_port_get_device (MM_PORT (self)));
if (priv->response->len > SERIAL_BUF_SIZE) {
/* Notify listeners and then trim the buffer */
g_signal_emit_by_name (self, "buffer-full", priv->response);
g_byte_array_remove_range (priv->response, 0, (SERIAL_BUF_SIZE / 2));
}
@@ -789,6 +793,7 @@ mm_serial_port_close (MMSerialPort *self)
if (priv->channel) {
g_source_remove (priv->watch_id);
priv->watch_id = 0;
g_io_channel_shutdown (priv->channel, TRUE, NULL);
g_io_channel_unref (priv->channel);
priv->channel = NULL;
@@ -1238,4 +1243,14 @@ mm_serial_port_class_init (MMSerialPortClass *klass)
"Send delay",
0, G_MAXUINT64, 0,
G_PARAM_READWRITE));
/* Signals */
g_signal_new ("buffer-full",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (MMSerialPortClass, buffer_full),
NULL, NULL,
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1, G_TYPE_POINTER);
}
+4
View File
@@ -50,6 +50,7 @@ struct _MMSerialPort {
struct _MMSerialPortClass {
MMPortClass parent;
<<<<<<< HEAD
/* Called for subclasses to parse unsolicited responses. If any recognized
* unsolicited response is found, it should be removed from the 'response'
* byte array before returning.
@@ -80,6 +81,9 @@ struct _MMSerialPortClass {
* return FALSE and set 'error' as appropriate.
*/
gboolean (*config_fd) (MMSerialPort *self, int fd, GError **error);
/* Signals */
void (*buffer_full) (MMSerialPort *port, const GByteArray *buffer);
};
GType mm_serial_port_get_type (void);