2011-09-28 09:16:26 -04:00
|
|
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
2011-01-25 22:08:12 +01:00
|
|
|
|
2011-08-16 14:28:53 +02:00
|
|
|
const Gio = imports.gi.Gio;
|
2011-12-10 14:54:39 +01:00
|
|
|
const GLib = imports.gi.GLib;
|
2011-01-25 22:08:12 +01:00
|
|
|
const Lang = imports.lang;
|
|
|
|
const Shell = imports.gi.Shell;
|
|
|
|
const Signals = imports.signals;
|
|
|
|
|
|
|
|
// The following are not the complete interfaces, just the methods we need
|
|
|
|
// (or may need in the future)
|
|
|
|
|
2011-08-16 14:28:53 +02:00
|
|
|
const ModemGsmNetworkInterface = <interface name="org.freedesktop.ModemManager.Modem.Gsm.Network">
|
|
|
|
<method name="GetRegistrationInfo">
|
2012-01-12 19:41:02 +01:00
|
|
|
<arg type="(uss)" direction="out" />
|
2011-08-16 14:28:53 +02:00
|
|
|
</method>
|
|
|
|
<method name="GetSignalQuality">
|
|
|
|
<arg type="u" direction="out" />
|
|
|
|
</method>
|
|
|
|
<property name="AccessTechnology" type="u" access="read" />
|
|
|
|
<signal name="SignalQuality">
|
|
|
|
<arg type="u" direction="out" />
|
|
|
|
</signal>
|
|
|
|
<signal name="RegistrationInfo">
|
|
|
|
<arg type="u" direction="out" />
|
|
|
|
<arg type="s" direction="out" />
|
|
|
|
<arg type="s" direction="out" />
|
|
|
|
</signal>
|
|
|
|
</interface>;
|
|
|
|
|
2011-12-10 14:54:39 +01:00
|
|
|
const ModemGsmNetworkProxy = new Gio.DBusProxyClass({
|
|
|
|
Name: 'ModemGsmNetworkProxy',
|
|
|
|
Interface: ModemGsmNetworkInterface,
|
|
|
|
|
|
|
|
_init: function(modem) {
|
|
|
|
this.parent({ g_bus_type: Gio.BusType.SYSTEM,
|
|
|
|
g_name: 'org.freedesktop.ModemManager',
|
|
|
|
g_object_path: modem });
|
|
|
|
}
|
|
|
|
});
|
2011-08-16 14:28:53 +02:00
|
|
|
|
|
|
|
const ModemCdmaInterface = <interface name="org.freedesktop.ModemManager.Modem.Cdma">
|
|
|
|
<method name="GetSignalQuality">
|
|
|
|
<arg type="u" direction="out" />
|
|
|
|
</method>
|
|
|
|
<method name="GetServingSystem">
|
2012-01-12 19:41:02 +01:00
|
|
|
<arg type="(usu)" direction="out" />
|
2011-08-16 14:28:53 +02:00
|
|
|
</method>
|
|
|
|
<signal name="SignalQuality">
|
|
|
|
<arg type="u" direction="out" />
|
|
|
|
</signal>
|
|
|
|
</interface>;
|
|
|
|
|
2011-12-10 14:54:39 +01:00
|
|
|
const ModemCdmaProxy = new Gio.DBusProxyClass({
|
|
|
|
Name: 'ModemCdmaProxy',
|
|
|
|
Interface: ModemCdmaInterface,
|
|
|
|
|
|
|
|
_init: function(modem) {
|
|
|
|
this.parent({ g_bus_type: Gio.BusType.SYSTEM,
|
|
|
|
g_name: 'org.freedesktop.ModemManager',
|
|
|
|
g_object_path: modem });
|
|
|
|
},
|
|
|
|
});
|
2011-01-25 22:08:12 +01:00
|
|
|
|
|
|
|
let _providersTable;
|
|
|
|
function _getProvidersTable() {
|
|
|
|
if (_providersTable)
|
|
|
|
return _providersTable;
|
|
|
|
let [providers, countryCodes] = Shell.mobile_providers_parse();
|
|
|
|
return _providersTable = providers;
|
|
|
|
}
|
|
|
|
|
2011-11-20 18:56:27 +01:00
|
|
|
const ModemGsm = new Lang.Class({
|
|
|
|
Name: 'ModemGsm',
|
2011-01-25 22:08:12 +01:00
|
|
|
|
|
|
|
_init: function(path) {
|
2011-12-10 14:54:39 +01:00
|
|
|
this._proxy = new ModemGsmNetworkProxy(path);
|
|
|
|
this._proxy.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(obj, result) {
|
|
|
|
obj.init_finish(result);
|
|
|
|
|
|
|
|
this._finishInit();
|
|
|
|
}));
|
2011-01-25 22:08:12 +01:00
|
|
|
|
|
|
|
this.signal_quality = 0;
|
|
|
|
this.operator_name = null;
|
2011-12-10 14:54:39 +01:00
|
|
|
},
|
2011-01-25 22:08:12 +01:00
|
|
|
|
2011-12-10 14:54:39 +01:00
|
|
|
_finishInit: function() {
|
2011-01-25 22:08:12 +01:00
|
|
|
// Code is duplicated because the function have different signatures
|
2011-08-16 14:28:53 +02:00
|
|
|
this._proxy.connectSignal('SignalQuality', Lang.bind(this, function(proxy, sender, [quality]) {
|
2011-01-25 22:08:12 +01:00
|
|
|
this.signal_quality = quality;
|
|
|
|
this.emit('notify::signal-quality');
|
|
|
|
}));
|
2011-08-16 14:28:53 +02:00
|
|
|
this._proxy.connectSignal('RegistrationInfo', Lang.bind(this, function(proxy, sender, [status, code, name]) {
|
2011-01-25 22:08:12 +01:00
|
|
|
this.operator_name = this._findOperatorName(name, code);
|
|
|
|
this.emit('notify::operator-name');
|
|
|
|
}));
|
2011-12-10 14:54:39 +01:00
|
|
|
this._proxy.GetRegistrationInfoRemote(null, Lang.bind(this, function(proxy, result) {
|
|
|
|
let [status, code, name] = proxy.GetRegistrationInfoFinish(result);
|
2011-01-25 22:08:12 +01:00
|
|
|
this.operator_name = this._findOperatorName(name, code);
|
|
|
|
this.emit('notify::operator-name');
|
|
|
|
}));
|
2011-12-10 14:54:39 +01:00
|
|
|
this._proxy.GetSignalQualityRemote(null, Lang.bind(this, function(proxy, result) {
|
|
|
|
try {
|
|
|
|
[this.signal_quality] = proxy.GetSignalQualityFinish(result);
|
|
|
|
} catch(e) {
|
2011-01-25 22:08:12 +01:00
|
|
|
// it will return an error if the device is not connected
|
|
|
|
this.signal_quality = 0;
|
|
|
|
}
|
2011-12-10 14:54:39 +01:00
|
|
|
|
2011-01-25 22:08:12 +01:00
|
|
|
this.emit('notify::signal-quality');
|
|
|
|
}));
|
|
|
|
},
|
|
|
|
|
|
|
|
_findOperatorName: function(name, opCode) {
|
|
|
|
if (name.length != 0 && (name.length > 6 || name.length < 5)) {
|
|
|
|
// this looks like a valid name, i.e. not an MCCMNC (that some
|
|
|
|
// devices return when not yet connected
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
if (isNaN(parseInt(name))) {
|
|
|
|
// name is definitely not a MCCMNC, so it may be a name
|
|
|
|
// after all; return that
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
|
|
|
let needle;
|
|
|
|
if (name.length == 0 && opCode)
|
|
|
|
needle = opCode;
|
|
|
|
else if (name.length == 6 || name.length == 5)
|
|
|
|
needle = name;
|
|
|
|
else // nothing to search
|
|
|
|
return null;
|
|
|
|
|
|
|
|
return this._findProviderForMCCMNC(needle);
|
|
|
|
},
|
|
|
|
|
|
|
|
_findProviderForMCCMNC: function(needle) {
|
|
|
|
let table = _getProvidersTable();
|
|
|
|
let needlemcc = needle.substring(0, 3);
|
|
|
|
let needlemnc = needle.substring(3, needle.length);
|
|
|
|
|
|
|
|
let name2, name3;
|
|
|
|
for (let iter in table) {
|
|
|
|
let providers = table[iter];
|
|
|
|
|
|
|
|
// Search through each country's providers
|
|
|
|
for (let i = 0; i < providers.length; i++) {
|
|
|
|
let provider = providers[i];
|
|
|
|
|
|
|
|
// Search through MCC/MNC list
|
|
|
|
let list = provider.get_gsm_mcc_mnc();
|
|
|
|
for (let j = 0; j < list.length; j++) {
|
|
|
|
let mccmnc = list[j];
|
|
|
|
|
|
|
|
// Match both 2-digit and 3-digit MNC; prefer a
|
|
|
|
// 3-digit match if found, otherwise a 2-digit one.
|
|
|
|
if (mccmnc.mcc != needlemcc)
|
|
|
|
continue; // MCC was wrong
|
|
|
|
|
|
|
|
if (!name3 && needle.length == 6 && needlemnc == mccmnc.mnc)
|
|
|
|
name3 = provider.name;
|
|
|
|
|
|
|
|
if (!name2 && needlemnc.substring(0, 2) == mccmnc.mnc.substring(0, 2))
|
|
|
|
name2 = provider.name;
|
|
|
|
|
|
|
|
if (name2 && name3)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return name3 || name2 || null;
|
|
|
|
}
|
2011-11-20 18:56:27 +01:00
|
|
|
});
|
2011-01-25 22:08:12 +01:00
|
|
|
Signals.addSignalMethods(ModemGsm.prototype);
|
|
|
|
|
2011-11-20 18:56:27 +01:00
|
|
|
const ModemCdma = new Lang.Class({
|
|
|
|
Name: 'ModemCdma',
|
2011-01-25 22:08:12 +01:00
|
|
|
|
|
|
|
_init: function(path) {
|
2011-12-10 14:54:39 +01:00
|
|
|
this._proxy = new ModemCdmaProxy(path);
|
|
|
|
this._proxy.init_async(GLib.PRIORITY_DEFAULT, null, Lang.bind(this, function(obj, result) {
|
|
|
|
obj.init_finish(result);
|
|
|
|
|
|
|
|
this._finishInit();
|
|
|
|
}));
|
2011-01-25 22:08:12 +01:00
|
|
|
|
|
|
|
this.signal_quality = 0;
|
|
|
|
this.operator_name = null;
|
2011-12-10 14:54:39 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
_finishInit: function() {
|
2012-01-27 14:57:46 -05:00
|
|
|
this._proxy.connectSignal('SignalQuality', Lang.bind(this, function(proxy, sender, params) {
|
2011-08-16 14:28:53 +02:00
|
|
|
this.signal_quality = params[0];
|
2011-01-25 22:08:12 +01:00
|
|
|
this.emit('notify::signal-quality');
|
|
|
|
|
|
|
|
// receiving this signal means the device got activated
|
|
|
|
// and we can finally call GetServingSystem
|
|
|
|
if (this.operator_name == null)
|
|
|
|
this._refreshServingSystem();
|
|
|
|
}));
|
2011-12-10 14:54:39 +01:00
|
|
|
this._proxy.GetSignalQualityRemote(null, Lang.bind(this, function(proxy, result) {
|
|
|
|
try {
|
|
|
|
[this.signal_quality] = proxy.GetSignalQualityFinish(result);
|
|
|
|
} catch(e) {
|
2011-01-25 22:08:12 +01:00
|
|
|
// it will return an error if the device is not connected
|
|
|
|
this.signal_quality = 0;
|
|
|
|
}
|
2011-12-10 14:54:39 +01:00
|
|
|
|
2011-01-25 22:08:12 +01:00
|
|
|
this.emit('notify::signal-quality');
|
|
|
|
}));
|
|
|
|
},
|
|
|
|
|
|
|
|
_refreshServingSystem: function() {
|
2011-12-10 14:54:39 +01:00
|
|
|
this._proxy.GetServingSystemRemote(null, Lang.bind(this, function(proxy, result) {
|
|
|
|
try {
|
|
|
|
let [bandClass, band, name] = proxy.GetServingSystemFinish(result);
|
2011-01-25 22:08:12 +01:00
|
|
|
if (name.length > 0)
|
2011-12-10 14:54:39 +01:00
|
|
|
this.operator_name = this._findProviderForSid(name);
|
2011-01-25 22:08:12 +01:00
|
|
|
else
|
|
|
|
this.operator_name = null;
|
2011-12-10 14:54:39 +01:00
|
|
|
} catch(e) {
|
|
|
|
// it will return an error if the device is not connected
|
|
|
|
this.operator_name = null;
|
2011-01-25 22:08:12 +01:00
|
|
|
}
|
2011-12-10 14:54:39 +01:00
|
|
|
|
2011-01-25 22:08:12 +01:00
|
|
|
this.emit('notify::operator-name');
|
|
|
|
}));
|
|
|
|
},
|
|
|
|
|
|
|
|
_findProviderForSid: function(sid) {
|
|
|
|
if (sid == 0)
|
|
|
|
return null;
|
|
|
|
|
|
|
|
let table = _getProvidersTable();
|
|
|
|
|
|
|
|
// Search through each country
|
|
|
|
for (let iter in table) {
|
|
|
|
let providers = table[iter];
|
|
|
|
|
|
|
|
// Search through each country's providers
|
|
|
|
for (let i = 0; i < providers.length; i++) {
|
|
|
|
let provider = providers[i];
|
|
|
|
let cdma_sid = provider.get_cdma_sid();
|
|
|
|
|
|
|
|
// Search through CDMA SID list
|
|
|
|
for (let j = 0; j < cdma_sid.length; j++) {
|
|
|
|
if (cdma_sid[j] == sid)
|
|
|
|
return provider.name;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
2011-11-20 18:56:27 +01:00
|
|
|
});
|
2011-01-25 22:08:12 +01:00
|
|
|
Signals.addSignalMethods(ModemCdma.prototype);
|