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

View File

@@ -118,10 +118,30 @@
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_gsm_modem_get_reg_info"/>
<arg name="info" type="(uss)" direction="out">
<tp:docstring>
The returned information contains:
* Network status.
* Current operator code.
* Current operator name,
The returned information is composed of the following items in the
following order:
<ul>
<li>
Mobile registration status as defined in 3GPP TS 27.007 section
10.1.19. See the MM_MODEM_GSM_NETWORK_REG_STATUS enumeration for
possible values.
</li>
<li>
Current operator code of the operator to which the mobile is
currently registered. Returned in the format "MCCMNC", where MCC
is the three-digit ITU E.212 Mobile Country Code and MNC is the
two- or three-digit GSM Mobile Network Code. If the MCC and MNC
are not known or the mobile is not registered to a mobile network,
this value should be a zero-length (blank) string. e.g. "31026"
or "310260".
</li>
<li>
Current operator name of the operator to which the mobile is
currently registered. If the operator name is not knowon or the
mobile is not registered to a mobile network, this value should
be a zero-length (blank) string.
</li>
</ul>
</tp:docstring>
</arg>
</method>
@@ -174,17 +194,27 @@
</tp:docstring>
<arg name="status" type="u" tp:type="MM_MODEM_GSM_NETWORK_REG_STATUS">
<tp:docstring>
The network status.
Mobile registration status as defined in 3GPP TS 27.007 section
10.1.19.
</tp:docstring>
</arg>
<arg name="operator_code" type="s">
<tp:docstring>
The current operator code.
Current operator code of the operator to which the mobile is
currently registered. Returned in the format "MCCMNC", where MCC
is the three-digit ITU E.212 Mobile Country Code and MNC is the
two- or three-digit GSM Mobile Network Code. If the MCC and MNC
are not known or the mobile is not registered to a mobile network,
this value should be a zero-length (blank) string. e.g. "31026" or
"310260".
</tp:docstring>
</arg>
<arg name="operator_name" type="s">
<tp:docstring>
The current operator name.
Current operator name of the operator to which the mobile is
currently registered. If the operator name is not knowon or the
mobile is not registered to a mobile network, this value should
be a zero-length (blank) string.
</tp:docstring>
</arg>
</signal>
@@ -200,6 +230,9 @@
</signal>
<tp:enum name="MM_MODEM_GSM_NETWORK_REG_STATUS" type="u">
<tp:docstring>
GSM registration code as defined in 3GPP TS 27.007 section 10.1.19.
</tp:docstring>
<tp:enumvalue suffix="IDLE" value="0">
<tp:docstring>
Not registered, not searching for new operator to register.

View File

@@ -26,7 +26,9 @@
<method name="Enable">
<tp:docstring>
Enable or disable location information gathering. This method may
require the client to authenticate itself.
require the client to authenticate itself. This method may also cause
any necessary functionality of the mobile be be turned on, including
enabling the modem device itself.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_modem_location_enable"/>
@@ -92,28 +94,116 @@
</tp:docstring>
<tp:member type="u" name="Type" tp:type="MM_MODEM_LOCATION_CAPABILITIES">
<tp:docstring>
Identifies the type and format of the associated location information. Contrary to the value description, this is not a bitfield but uses the same values as the MM_MODEM_LOCATION_CAPABILITIES bitfield.
Identifies the type and format of the associated location information.
Contrary to the value description, this is not a bitfield but uses the
same values as the MM_MODEM_LOCATION_CAPABILITIES bitfield.
</tp:docstring>
</tp:member>
<tp:member type="v" name="Data">
<tp:docstring>
Contains type-specific location information. GSM_LAC_CI data is a string with the format "LAC,CI" (ex "84CD,00D30156") while GPS_NMEA is a string in NMEA-compatible format.
Contains type-specific location information. See the documentation for
each type for a description of its data format.
</tp:docstring>
</tp:member>
</tp:mapping>
<tp:flags name="MM_MODEM_LOCATION_CAPABILITIES" value-prefix="MM_MODEM_LOCATION_CAPABILITY" type="u">
<tp:flag suffix="UNKNOWN" value="0x0">
<tp:docstring>Unknown or no capabilties.</tp:docstring>
<tp:docstring><p>Unknown or no capabilties.</p></tp:docstring>
</tp:flag>
<tp:flag suffix="ANY" value="0x1">
<tp:docstring>Reserved.</tp:docstring>
<tp:flag suffix="GPS_NMEA" value="0x1">
<tp:docstring>
<p>For capability reporting, indicates the device is capable of
providing GPS NMEA-format location information.</p>
<p>For location reporting, devices supporting this capability return
an array mapping timestamps to specific NMEA sentences (D-Bus
signature 'a(ss)'). The manager will cache the most recent NMEA
sentence of each type for a period of time not less than 30 seconds
and must indicate the time that sentence was receieved from the device
using the timestamp. Timestamps are provided as strings in the "Unix
epoch" format (i.e. number of seconds since 1970-01-01 00:00:00 UTC
with microsecond resolution if available).
</p>
<p>
For example, if at time 1268336242.282202 the device sends a $GPRMC
sentence immediately followed by a $GPGGA sentence, the reported
location array would be:
<pre>
[ '1268336242.282202': '$GPRMC,134523.92,V,,,,,,,030136,,,N*73',
'1268336242.282202': '$GPGGA,,,,,,0,00,0.5,,M,0.0001999,M,0.0000099,0000*45' ]
</pre>
If the device sends a new $GPRMC three seconds later, the new $GPRMC
replaces the previously received $GPRMC sentence, and the updated array
would be:
<pre>
[ '1268336245.282202': '$GPRMC,134526.92,V,,,,,,,030136,,,N*76',
'1268336242.282202': '$GPGGA,,,,,,0,00,0.5,,M,0.0001999,M,0.0000099,0000*45' ]
</pre>
If the device then sends a $GPGSA sentence about 5 seconds later, the
$GPGSA sentence is added to the array (since no $GPGSA sentence was
previously received in this session), the updated array would be:
<pre>
[ '1268336245.282202': '$GPRMC,134526.92,V,,,,,,,030136,,,N*76',
'1268336242.282202': '$GPGGA,,,,,,0,00,0.5,,M,0.0001999,M,0.0000099,0000*45'
'1268336250.395423': '$GPGSA,A,1,,,,,,,,,,,,,1.1,0.5,1.0*34' ]
</pre>
The manager may discard any entries older than 30 seconds.
</p>
<p>This allows clients to read the latest positioning data as soon as
possible after they start, even if the device is not providing
frequent location data updates. Using the timestamp the client can
determine which data is most relevant to its particular uses.
</p>
</tp:docstring>
</tp:flag>
<tp:flag suffix="GPS_NMEA" value="0x2">
<tp:docstring>The device is capable of providing GPS NMEA-format location information.</tp:docstring>
</tp:flag>
<tp:flag suffix="GSM_LAC_CI" value="0x4">
<tp:docstring>The device is capable of providing GSM Location Area Code/Cell ID location information.</tp:docstring>
<tp:flag suffix="GSM_LAC_CI" value="0x2">
<tp:docstring>
<p>For capability reporting, indicates the device is capable of
providing GSM Location Area Code/Cell ID location information.</p>
<p>For location reporting, devices supporting this
capability return a string in the format "MCC,MNC,LAC,CI" (without the
quotes of course) where the following applies:</p>
<ul>
<li>
MCC is the three-digit ITU E.212 Mobile Country Code of the
network provider to which the mobile is currently registered.
This value should be the same MCC as reported by the
org.freedesktop.Modem.Gsm.Network.GetRegistrationInfo() method's
returned "operator code" argument.
e.g. "310"
</li>
<li>
MNC is the two- or three-digit GSM Mobile Network Code of the
network provider to which the mobile is currently registered.
This value should be the same MCC as reported by the
org.freedesktop.Modem.Gsm.Network.GetRegistrationInfo() method's
returned "operator code" argument.
e.g. "26" or "260"
</li>
<li>
LAC is the two-byte Location Area Code of the base station with
which the mobile is registered, in upper-case hexadecimal format
without leading zeros, as specified in 3GPP TS 27.007 section
10.1.19. e.g. "84CD".
</li>
<li>
CI is the two- or four-byte Cell Identifier with which the mobile
is registered, in upper-case hexadecimal format without leading
zeros, as specified in 3GPP TS 27.007. e.g. "2BAF" or "D30156".
</li>
</ul>
<p>The entire string may only be composed of the ASCII digits [0-9],
the alphabetical characters [A-F], and the comma (,) character. No
other characters are allowed. For example: "310,260,8BE3,2BAF" or
"250,40,CE00,1CEAD8F0".</p>
<p>If any of these four items (MCC,MNC,LAC,CI) is unknown or the
mobile is not registered with a network, then the GSM_LAC_CI location
information item should not be provided as a returned value from the
GetLocation() method or in the Location property.</p>
</tp:docstring>
</tp:flag>
</tp:flags>

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);
}

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)));

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);
}

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);