If the device only has one AT port that's being used for data and
thus we can't do more specific registration checking in MMGenericCdma
using AT commands, but generic registration checking was successful,
just use the less specific state.
Previously, an error would be returned when no AT port was available
even though less specific QCDM registration checking worked. That
was just stupid.
Pass the device's hardware IDs through modem creation and use them
when calculating the device's identifier. Add a bunch of testcases
for real hardware to ensure we don't break the device ID in the
future unless we really want to.
This is computed before any PIN is entered, and thus before we can
usually get IMEI or MEID/ESN out of the device in many cases. It's
therefore not the same as EquipmentIdentifier.
This is intended to be used by UI programs for matching devices with
PIN numbers for automatic unlocking. While the PIN number is actually
*SIM* specific, no modems allow access to the IMSI before the PIN is
entered, and thus we cannot actually match the PIN with the SIM. The
device ID is the next best thing we can use and should allow auto
unlocking in most cases.
Sometimes the primary mode will be 1X (and thus the Call Manager
will report 1X system mode) but the HDR subsystem will be registered
and idle. Figure that out and report that EVDO is registered too
in that case, since the modem will just flip over to EVDO when
the data call starts.
This specifically fixes a regression with Novatel GSM secondary
AT port enablement, where the inital pin check closed the port
before the Novatel plugin could send the command to flip secondary
ports to AT mode.
But it's useful elsewhere too, and simplifies a bunch of the PIN
checking code which had to use various ugly methods to track whether
to close the port or not after checking the PIN.
The generic CDMA superclass already checks minimal registration state,
and when some of the additional query_registration_state() subclass checks
were being performed, if the device returned an error (if it didn't support
the subclass' specific registration command like *STATE or ^SYSINFO) the
superclass' registration state checks would be thrown away.
Fix that by specifying the behavior of the subclass'
query_registration_state() methods to ignore most errors and leave the
superclass' registration state intact if a non-critical error occurs.
If the modem doesn't have two AT ports (so one can be used for AT+CSQ
while connected) get the 1x active pilot's EC/IO and use that for
signal strength.
This should solve problems with users who's providers are EVDO
only and thus the device isn't in 1X mode, but who's modems
don't set anything meaningful for CAD or CSS when the 1X radio
isn't registered. Previously, MM would just spin thinking it
wasn't registered when trying to connect.
This was mostly found with AnyDATA, Huawei, and some ZTE devices
from Russia and India.
Some modems turn E1 on and off random (Huawei EC168C) and sometimes
the echoed command confuses things. We have a parser just for that,
so let's use it. It should be safe to use with devices that repect
E0 too.
For QCDM devices we want most of what MMSerialPort does, but not
the AT command handling stuff since the commands and responses
aren't AT commands nor are they even strings. So convert everything
that MMSerialPort does into a GByteArray, and let MMAtSerialPort
handle the conversion to strings when necessary.
Some cards (Novatel S720 for example) can take a long time to start
a data call if the device isn't activated on the network or the
signal strength is low.
Some modems key the AT+CSS? response off their 1X state, so if the
modem has EVDO service but no 1X service, AT+CSS? will provide incorrect
registration state information and the registration checking will
end too early. Allow modems that can handle more specific registration
checking to skip the AT+CSS? part.
There are more places to handle, but these are the most critical. If
the modem is removed while a command is in-progress, the mm-callback-info
code will set info->modem to NULL. Make sure we check for that in
callbacks and return a reasonable error. Previous code would just
blindly forge ahead and die on a null dereference.
at!pcstate is what Sierra CDMA modems use instead of AT+CFUN for
powering the radio on and off. It doesn't turn the modem off completely
like AT+CFUN=0 does for many GSM devices though, so it's quite a lot nicer.
Most AT command references allow modems to report SID 0, even though
SID 0 is not a valid SID and is not assigned to any CDMA network.
Some Sierra 5725 cards have been seen to report valid class and band
from the +CSS response but a SID 0. Accept SID 0 when at least one
other element of the +CSS response indicates that the modem has service.
Otherwise, report "no service" as before.
We only want to ignore connected/connecting/disconnecting states
and update the state based on registration for unsolicited
registration changes. Basically, when disconnecting, the modem
will be in DISCONNECTING state, but after the disconnect has finished
we want to update the modem's state based on the current
registration status. But the previous check for >= DISCONNECTING
would prevent that from happening, so we need a slightly more specific
check in update_enabled_state().
Have to fall back to the previous state if the enable/disable
operation fails since we cannot assume anything about the new
modem state when a failure occurs.