Please test and expand on the script below.
I don’t speak python well so I’m sure it can be improved. Also I could not actually test it, as I’m not currently within range of one of those countries.
What it does:
- listen on ofono interface for operator changes
- compare “current” (i.e. used) network ID with blacklist
- if net is blacklisted, disable roaming (actually, it just prints something, if you want to really disable roaming, uncomment the
connman.SetProperty
part).
It’s not ideal, because what we really want is to select an non-blacklisted operator instead of disabling Roaming, but I guess that’s within ofono…
This can be run from a systemd service, for now, just run from command line.
Config file
{
"providers": [
{ "name": "Albania", "mcc": "276", "networks": [ "01", "02", "03" ] },
{ "name": "Andorra", "mcc": "213", "networks": [ "03" ] },
{ "name": "Bosnia and Herzegovina", "mcc": "218", "networks": [ "90", "05", "03"] },
{ "name": "Faroe Islands", "mcc": "288", "networks": [ "01", "02", "03"] },
{ "name": "Isle of Man", "mcc": "234", "networks": [ "58", "36" ] },
{ "name": "Kosovo", "mcc": "221", "networks": [ "01", "02", "03" ] },
{ "name": "Macedonia", "mcc": "294", "networks": [ "01", "03" ] },
{ "name": "Moldova", "mcc": "259", "networks": [ "01", "02", "03", "05", "99", "06" ] },
{ "name": "Monaco", "mcc": "212", "networks": [ "10 "] },
{ "name": "Montenegro", "mcc": "297", "networks": [ "01", "02", "03" ] },
{ "name": "Russia", "mcc": "250", "networks": [ "01", "02", "99", "20" ] },
{ "name": "Switzerland", "mcc": "228", "networks": [ "01", "02", "03" ] },
{ "name": "San Marino", "mcc": "222", "networks": [ "01" ] },
{ "name": "Serbia", "mcc": "220", "networks": [ "01", "03", "05" ] },
{ "name": "Turkey", "mcc": "286", "networks": [ "01", "02" ] },
{ "name": "Ukraine", "mcc": "255", "networks": [ "03", "01", "06", "04", "07", "21" ] },
{ "name": "Belarus", "mcc": "257", "networks": [ "01" , "02", "04"] }
]
}
Python daemon
#!/usr/bin/python3
import sys
import dbus
import json
from gi.repository import GLib
import dbus.mainloop.glib
# load list of countries not in EU Roaming arreement
noneu_f = "./noneu.json"
f = open(noneu_f)
noneu = json.load(f)
f.close()
# array of string, countrycode dot networkcode
blacklist = []
print ("Blacklisted Non-Eu-Roaming Countries:", file=sys.stderr)
for p in noneu['providers']:
print ("%s" %(p['name']), file=sys.stderr)
ncc = p['mcc']
for net in p['networks']:
blacklist.append( ncc + "." + net )
# TODO: list could be crosschecked/updated from here:
#provinfo_file = "/usr/share/mobile-broadband-provider-info/serviceproviders.xml"
#print("Constructed Blacklist: %s" % (blacklist), file=sys.stderr)
### initialize DBus
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
manager = dbus.Interface(bus.get_object('org.ofono', '/'), 'org.ofono.Manager')
modems = manager.GetModems()
#### handle DBus signals from main loop:
def signal_handler(message):
print("Got Message: %s" % (message))
checkRoamingAllowed()
def checkRoamingAllowed():
for path, properties in modems:
if "org.ofono.ConnectionManager" not in properties["Interfaces"]:
continue
netreg = dbus.Interface(bus.get_object('org.ofono', path), 'org.ofono.NetworkRegistration')
ops = netreg.GetOperators()
code = ''
for op, properties in ops:
# Name Status MobileCountryCode MobileNetworkCode Technologies
#print("Operator: %s\n\tName: %s\n\tStatus: %s\n\tCountry: %s\n\tNetwork: %s\n\tTech: %s" % (op, properties.get('Name'), properties.get('Status'), properties.get('MobileCountryCode'), properties.get('MobileNetworkCode'), properties.get('Technologies')))
if properties.get('Status') == "current":
print("Current Operator:\n\tName: %s\n\tStatus: %s\n\tCountry: %s\n\tNetwork: %s\n" % (op, properties.get('Name'), properties.get('Status'), properties.get('MobileCountryCode'), properties.get('MobileNetworkCode')))
code = properties.get('MobileCountryCode') + "." + properties.get('MobileNetworkCode')
country = properties.get('MobileCountryCode')
if code in blacklist or country in blacklist:
print("Network or Country blacklisted, disabling roaming.")
allowed = dbus.Boolean(0)
else:
allowed = dbus.Boolean(1)
setRoaming(allowed)
def setRoaming(allowed):
for path, properties in modems:
if "org.ofono.ConnectionManager" not in properties["Interfaces"]:
continue
connman = dbus.Interface(bus.get_object('org.ofono', path),
'org.ofono.ConnectionManager')
print("Setting %s to RoamingAllowed=%d" % (path, allowed))
#connman.SetProperty("RoamingAllowed", allowed)
if __name__ == '__main__':
loop = GLib.MainLoop()
for path, properties in modems:
try:
object = bus.get_object("org.ofono", path)
object.connect_to_signal("OperatorsChanged", signal_handler, dbus_interface="org.ofono.NetworkRegistration")
print("Listening for operator changes on %s" % (path), file=sys.stderr)
except dbus.DBusException:
traceback.print_exc()
sys.exit(1)
loop.run()