Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomeu Vizoso <tomeu@sugarlabs.org>2010-01-23 15:39:03 (GMT)
committer Tomeu Vizoso <tomeu@sugarlabs.org>2010-01-29 11:54:37 (GMT)
commit35035af44de1f7929cf02cd165f82c93a98c9575 (patch)
tree8d29a46a8840be2268d18d3fb01058544718c421
parent017ac26575470f2d0b63b8d1d5e73097eede3676 (diff)
Implement support for 3G modems (tch) #1622
-rw-r--r--configure.ac1
-rw-r--r--data/icons/Makefile.am1
-rw-r--r--data/icons/module-modemconfiguration.svg1272
-rw-r--r--extensions/cpsection/Makefile.am3
-rw-r--r--extensions/cpsection/modemconfiguration/Makefile.am6
-rw-r--r--extensions/cpsection/modemconfiguration/__init__.py22
-rw-r--r--extensions/cpsection/modemconfiguration/model.py53
-rw-r--r--extensions/cpsection/modemconfiguration/view.py192
-rw-r--r--extensions/deviceicon/network.py214
-rw-r--r--src/jarabe/desktop/meshbox.py10
-rw-r--r--src/jarabe/model/network.py151
11 files changed, 1892 insertions, 33 deletions
diff --git a/configure.ac b/configure.ac
index f0db28e..6231d76 100644
--- a/configure.ac
+++ b/configure.ac
@@ -54,6 +54,7 @@ extensions/cpsection/datetime/Makefile
extensions/cpsection/frame/Makefile
extensions/cpsection/keyboard/Makefile
extensions/cpsection/language/Makefile
+extensions/cpsection/modemconfiguration/Makefile
extensions/cpsection/Makefile
extensions/cpsection/network/Makefile
extensions/cpsection/power/Makefile
diff --git a/data/icons/Makefile.am b/data/icons/Makefile.am
index d2f4ede..a35643a 100644
--- a/data/icons/Makefile.am
+++ b/data/icons/Makefile.am
@@ -7,6 +7,7 @@ sugar_DATA = \
module-frame.svg \
module-keyboard.svg \
module-language.svg \
+ module-modemconfiguration.svg \
module-network.svg \
module-power.svg \
module-updater.svg
diff --git a/data/icons/module-modemconfiguration.svg b/data/icons/module-modemconfiguration.svg
new file mode 100644
index 0000000..b62a12e
--- /dev/null
+++ b/data/icons/module-modemconfiguration.svg
@@ -0,0 +1,1272 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ sodipodi:docname="/home/latu/Desktop/Desarrollo/Cliente3G/Conexion3G.activity/activity/activity-Conexion3G.svg"
+ sodipodi:docbase="/home/latu/Desktop/Desarrollo/Cliente3G/Conexion3G.activity/activity/"
+ inkscape:version="0.43+devel"
+ sodipodi:version="0.34"
+ id="svg1288"
+ height="48px"
+ width="48px">
+ <defs
+ id="defs3">
+ <linearGradient
+ id="linearGradient6457"
+ inkscape:collect="always">
+ <stop
+ id="stop6459"
+ offset="0"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
+ <stop
+ id="stop6461"
+ offset="1"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient6444">
+ <stop
+ id="stop6446"
+ offset="0.0000000"
+ style="stop-color: rgb(184, 207, 231); stop-opacity: 1;" />
+ <stop
+ id="stop6448"
+ offset="1.0000000"
+ style="stop-color: rgb(114, 159, 207); stop-opacity: 1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient6187"
+ inkscape:collect="always">
+ <stop
+ id="stop6189"
+ offset="0"
+ style="stop-color: rgb(94, 94, 94); stop-opacity: 1;" />
+ <stop
+ id="stop6191"
+ offset="1"
+ style="stop-color: rgb(94, 94, 94); stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient6171"
+ inkscape:collect="always">
+ <stop
+ id="stop6173"
+ offset="0"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
+ <stop
+ id="stop6175"
+ offset="1"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient6151">
+ <stop
+ id="stop6153"
+ offset="0.0000000"
+ style="stop-color: rgb(224, 226, 226); stop-opacity: 1;" />
+ <stop
+ id="stop6155"
+ offset="1.0000000"
+ style="stop-color: rgb(191, 194, 194); stop-opacity: 1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient158">
+ <stop
+ style="stop-color: rgb(104, 104, 104); stop-opacity: 0;"
+ offset="0.0000000"
+ id="stop159" />
+ <stop
+ style="stop-color: rgb(104, 104, 104); stop-opacity: 1;"
+ offset="0.23762377"
+ id="stop162" />
+ <stop
+ style="stop-color: rgb(104, 104, 104); stop-opacity: 1;"
+ offset="0.78109992"
+ id="stop163" />
+ <stop
+ style="stop-color: rgb(104, 104, 104); stop-opacity: 0;"
+ offset="1.0000000"
+ id="stop160" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient272">
+ <stop
+ style="stop-color: rgb(71, 71, 71); stop-opacity: 0;"
+ offset="0.0000000"
+ id="stop273" />
+ <stop
+ style="stop-color: rgb(71, 71, 71); stop-opacity: 1;"
+ offset="0.10000000"
+ id="stop275" />
+ <stop
+ style="stop-color: rgb(71, 71, 71); stop-opacity: 1;"
+ offset="0.89999998"
+ id="stop276" />
+ <stop
+ style="stop-color: rgb(71, 71, 71); stop-opacity: 0;"
+ offset="1.0000000"
+ id="stop274" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient178">
+ <stop
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 0;"
+ offset="0.0000000"
+ id="stop179" />
+ <stop
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 0.706587;"
+ offset="0.10827128"
+ id="stop180" />
+ <stop
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 0.706587;"
+ offset="0.92053902"
+ id="stop181" />
+ <stop
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 0;"
+ offset="1.0000000"
+ id="stop182" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4543"
+ inkscape:collect="always">
+ <stop
+ id="stop4545"
+ offset="0"
+ style="stop-color: rgb(0, 0, 0); stop-opacity: 1;" />
+ <stop
+ id="stop4547"
+ offset="1"
+ style="stop-color: rgb(0, 0, 0); stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4509">
+ <stop
+ style="stop-color: rgb(0, 0, 0); stop-opacity: 1;"
+ offset="0.0000000"
+ id="stop4511" />
+ <stop
+ style="stop-color: rgb(0, 0, 0); stop-opacity: 0;"
+ offset="1.0000000"
+ id="stop4513" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4449"
+ inkscape:collect="always">
+ <stop
+ id="stop4451"
+ offset="0"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
+ <stop
+ id="stop4453"
+ offset="1"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4420"
+ inkscape:collect="always">
+ <stop
+ id="stop4422"
+ offset="0"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
+ <stop
+ id="stop4424"
+ offset="1"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4412"
+ inkscape:collect="always">
+ <stop
+ id="stop4414"
+ offset="0"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
+ <stop
+ id="stop4416"
+ offset="1"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4400">
+ <stop
+ id="stop4402"
+ offset="0"
+ style="stop-color: rgb(151, 151, 151); stop-opacity: 1;" />
+ <stop
+ id="stop4404"
+ offset="1.0000000"
+ style="stop-color: rgb(200, 200, 200); stop-opacity: 1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4386">
+ <stop
+ id="stop4388"
+ offset="0.0000000"
+ style="stop-color: rgb(210, 210, 210); stop-opacity: 1;" />
+ <stop
+ id="stop4390"
+ offset="1.0000000"
+ style="stop-color: rgb(223, 223, 223); stop-opacity: 1;" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="matrix(0.704136, 0, 0, 0.704136, -7.02064, 9.45973)"
+ gradientUnits="userSpaceOnUse"
+ y2="10.018264"
+ x2="23.233509"
+ y1="34.463955"
+ x1="24.349752"
+ id="linearGradient4392"
+ xlink:href="#linearGradient4386"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="matrix(0.658413, 0, 0, 0.688766, -6.06109, 9.52172)"
+ gradientUnits="userSpaceOnUse"
+ y2="26.786800"
+ x2="22.311644"
+ y1="26.887815"
+ x1="27.324621"
+ id="linearGradient4418"
+ xlink:href="#linearGradient4412"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="matrix(0.658413, 0, 0, 0.688766, -6.06109, 9.52172)"
+ gradientUnits="userSpaceOnUse"
+ y2="26.786800"
+ x2="22.311644"
+ y1="26.887815"
+ x1="27.324621"
+ id="linearGradient4426"
+ xlink:href="#linearGradient4420"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -4.79569, 9.52172)"
+ y2="30.928421"
+ x2="16.364470"
+ y1="39.918777"
+ x1="16.364470"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4459"
+ xlink:href="#linearGradient4449"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="30.928421"
+ x2="16.364470"
+ y1="39.918777"
+ x1="16.364470"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -3.41816, 9.52172)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4463"
+ xlink:href="#linearGradient4449"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="30.928421"
+ x2="16.364470"
+ y1="39.918777"
+ x1="16.364470"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -2.04063, 9.52172)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4467"
+ xlink:href="#linearGradient4449"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="30.928421"
+ x2="16.364470"
+ y1="39.918777"
+ x1="16.364470"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -0.6631, 9.52172)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4471"
+ xlink:href="#linearGradient4449"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="30.928421"
+ x2="16.364470"
+ y1="39.918777"
+ x1="16.364470"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, 0.714451, 9.52172)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4475"
+ xlink:href="#linearGradient4449"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="30.928421"
+ x2="16.364470"
+ y1="39.918777"
+ x1="16.364470"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, 2.09199, 9.52172)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4479"
+ xlink:href="#linearGradient4449"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -5.54704, 9.52172)"
+ y2="30.928421"
+ x2="16.364470"
+ y1="39.918777"
+ x1="16.364470"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4495"
+ xlink:href="#linearGradient4509"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="30.928421"
+ x2="16.364470"
+ y1="39.918777"
+ x1="16.364470"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -4.16951, 9.52172)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4497"
+ xlink:href="#linearGradient4509"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="30.928421"
+ x2="16.364470"
+ y1="39.918777"
+ x1="16.364470"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -2.79198, 9.52172)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4499"
+ xlink:href="#linearGradient4509"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="30.928421"
+ x2="16.364470"
+ y1="39.918777"
+ x1="16.364470"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -1.41445, 9.52172)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4501"
+ xlink:href="#linearGradient4509"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="30.928421"
+ x2="16.364470"
+ y1="39.918777"
+ x1="16.364470"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -0.0369197, 9.52172)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4503"
+ xlink:href="#linearGradient4509"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="30.928421"
+ x2="16.364470"
+ y1="39.918777"
+ x1="16.364470"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, 1.34067, 9.52172)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4505"
+ xlink:href="#linearGradient4509"
+ inkscape:collect="always" />
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1, 0, 0, 0.394366, 1.02097e-14, 23.442)"
+ r="14.344166"
+ fy="38.706596"
+ fx="23.536554"
+ cy="38.706596"
+ cx="23.536554"
+ id="radialGradient4549"
+ xlink:href="#linearGradient4543"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="117.82710"
+ x2="15.343062"
+ y1="117.82710"
+ x1="1.6422368"
+ gradientTransform="matrix(2.74016, 0, 0, 0.364942, 31.378, -10.3527)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient5397"
+ xlink:href="#linearGradient158"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="372.57819"
+ x2="5.0856376"
+ y1="372.57819"
+ x1="0.61210024"
+ gradientTransform="matrix(8.1686, 0, 0, 0.22121, 31.378, -48.2741)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient5399"
+ xlink:href="#linearGradient272"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="372.57819"
+ x2="5.0856376"
+ y1="372.57819"
+ x1="0.61210024"
+ gradientTransform="matrix(8.1686, 0, 0, 0.228621, 31.378, -46.2669)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient5401"
+ xlink:href="#linearGradient272"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="117.82710"
+ x2="15.343062"
+ y1="117.82710"
+ x1="1.6422368"
+ gradientTransform="matrix(2.74016, 0, 0, 0.147685, 31.378, 14.8331)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient5403"
+ xlink:href="#linearGradient178"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="31.565634"
+ x2="37.140110"
+ y1="10.655476"
+ x1="25.515011"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6210"
+ xlink:href="#linearGradient6171"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="28.554563"
+ x2="38.547222"
+ y1="28.554563"
+ x1="32.587322"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6212"
+ xlink:href="#linearGradient6187"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="31.565634"
+ x2="37.140110"
+ y1="10.655476"
+ x1="25.515011"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6240"
+ xlink:href="#linearGradient6171"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="28.554563"
+ x2="38.547222"
+ y1="28.554563"
+ x1="32.587322"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6242"
+ xlink:href="#linearGradient6187"
+ inkscape:collect="always" />
+ <radialGradient
+ r="14.344166"
+ fy="38.706596"
+ fx="23.536554"
+ cy="38.706596"
+ cx="23.536554"
+ gradientTransform="matrix(1, 0, 0, 0.394366, -7.98147e-15, 23.442)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient6246"
+ xlink:href="#linearGradient4543"
+ inkscape:collect="always" />
+ <radialGradient
+ r="14.344166"
+ fy="38.706596"
+ fx="23.536554"
+ cy="38.706596"
+ cx="23.536554"
+ gradientTransform="matrix(1, 0, 0, 0.394366, 5.34295e-16, 23.442)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient6250"
+ xlink:href="#linearGradient4543"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="117.82710"
+ x2="15.343062"
+ y1="117.82710"
+ x1="1.6422368"
+ gradientTransform="matrix(2.74016, -3.34247e-32, -7.06832e-33, 0.364942, 31.378, -10.3527)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6262"
+ xlink:href="#linearGradient158"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="372.57819"
+ x2="5.0856376"
+ y1="372.57819"
+ x1="0.61210024"
+ gradientTransform="matrix(8.1686, -9.9641e-32, -4.28449e-33, 0.22121, 31.378, -48.2741)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6264"
+ xlink:href="#linearGradient272"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="372.57819"
+ x2="5.0856376"
+ y1="372.57819"
+ x1="0.61210024"
+ gradientTransform="matrix(8.1686, -9.9641e-32, -4.42803e-33, 0.228621, 31.378, -46.2669)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6266"
+ xlink:href="#linearGradient272"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="117.82710"
+ x2="15.343062"
+ y1="117.82710"
+ x1="1.6422368"
+ gradientTransform="matrix(2.74016, -3.34247e-32, -2.86043e-33, 0.147685, 31.378, 14.8331)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6268"
+ xlink:href="#linearGradient178"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="matrix(0.953806, 0, 0, 1, 1.83218, -4.57479e-16)"
+ gradientUnits="userSpaceOnUse"
+ y2="26.435217"
+ x2="38.278458"
+ y1="19.061104"
+ x1="36.067482"
+ id="linearGradient6463"
+ xlink:href="#linearGradient6457"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="matrix(0.969204, 0, 0, 1, -5.81595, -9.8995)"
+ y2="26.435217"
+ x2="38.278458"
+ y1="19.061104"
+ x1="36.067482"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6467"
+ xlink:href="#linearGradient6457"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4386"
+ id="linearGradient4059"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.704136, 0, 0, 0.704136, -7.02064, 9.45973)"
+ x1="24.349752"
+ y1="34.463955"
+ x2="23.233509"
+ y2="10.018264" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4420"
+ id="linearGradient4061"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.658413, 0, 0, 0.688766, -6.06109, 9.52172)"
+ x1="27.324621"
+ y1="26.887815"
+ x2="22.311644"
+ y2="26.786800" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4412"
+ id="linearGradient4063"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.658413, 0, 0, 0.688766, -6.06109, 9.52172)"
+ x1="27.324621"
+ y1="26.887815"
+ x2="22.311644"
+ y2="26.786800" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4449"
+ id="linearGradient4065"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -4.79569, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4449"
+ id="linearGradient4067"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -3.41816, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4449"
+ id="linearGradient4069"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -2.04063, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4449"
+ id="linearGradient4071"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -0.6631, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4449"
+ id="linearGradient4073"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, 0.714451, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4449"
+ id="linearGradient4075"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, 2.09199, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4509"
+ id="linearGradient4077"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -5.54704, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4509"
+ id="linearGradient4079"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -4.16951, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4509"
+ id="linearGradient4081"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -2.79198, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4509"
+ id="linearGradient4083"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -1.41445, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4509"
+ id="linearGradient4085"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -0.0369197, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4509"
+ id="linearGradient4087"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, 1.34067, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4509"
+ id="linearGradient4127"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, 1.34067, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4509"
+ id="linearGradient4129"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -0.0369197, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4509"
+ id="linearGradient4131"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -1.41445, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4509"
+ id="linearGradient4133"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -2.79198, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4509"
+ id="linearGradient4135"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -4.16951, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4509"
+ id="linearGradient4137"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -5.54704, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4449"
+ id="linearGradient4139"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, 2.09199, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4449"
+ id="linearGradient4141"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, 0.714451, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4449"
+ id="linearGradient4143"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -0.6631, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4449"
+ id="linearGradient4145"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -2.04063, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4449"
+ id="linearGradient4147"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -3.41816, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4449"
+ id="linearGradient4149"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -4.79569, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4420"
+ id="linearGradient4151"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.658413, 0, 0, 0.688766, -6.06109, 9.52172)"
+ x1="27.324621"
+ y1="26.887815"
+ x2="22.311644"
+ y2="26.786800" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4412"
+ id="linearGradient4153"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.658413, 0, 0, 0.688766, -6.06109, 9.52172)"
+ x1="27.324621"
+ y1="26.887815"
+ x2="22.311644"
+ y2="26.786800" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4386"
+ id="linearGradient4155"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.704136, 0, 0, 0.704136, -7.02064, 9.45973)"
+ x1="24.349752"
+ y1="34.463955"
+ x2="23.233509"
+ y2="10.018264" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6171"
+ id="linearGradient4192"
+ gradientUnits="userSpaceOnUse"
+ x1="25.515011"
+ y1="10.655476"
+ x2="37.140110"
+ y2="31.565634" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6187"
+ id="linearGradient4194"
+ gradientUnits="userSpaceOnUse"
+ x1="32.587322"
+ y1="28.554563"
+ x2="38.547222"
+ y2="28.554563" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6171"
+ id="linearGradient4210"
+ gradientUnits="userSpaceOnUse"
+ x1="25.515011"
+ y1="10.655476"
+ x2="37.140110"
+ y2="31.565634" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6187"
+ id="linearGradient4212"
+ gradientUnits="userSpaceOnUse"
+ x1="32.587322"
+ y1="28.554563"
+ x2="38.547222"
+ y2="28.554563" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6457"
+ id="linearGradient4214"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.953806, 0, 0, 1, 1.83218, -4.56286e-16)"
+ x1="36.067482"
+ y1="19.061104"
+ x2="38.278458"
+ y2="26.435217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6187"
+ id="linearGradient4228"
+ gradientUnits="userSpaceOnUse"
+ x1="32.587322"
+ y1="28.554563"
+ x2="38.547222"
+ y2="28.554563" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4543"
+ id="radialGradient4272"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1, 0, 0, 0.394366, 5.34295e-16, 23.442)"
+ cx="23.536554"
+ cy="38.706596"
+ fx="23.536554"
+ fy="38.706596"
+ r="14.344166" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6171"
+ id="linearGradient4274"
+ gradientUnits="userSpaceOnUse"
+ x1="25.515011"
+ y1="10.655476"
+ x2="37.140110"
+ y2="31.565634" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6187"
+ id="linearGradient4276"
+ gradientUnits="userSpaceOnUse"
+ x1="32.587322"
+ y1="28.554563"
+ x2="38.547222"
+ y2="28.554563" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6457"
+ id="linearGradient4278"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.953806, 0, 0, 1, 1.83218, -4.5569e-16)"
+ x1="36.067482"
+ y1="19.061104"
+ x2="38.278458"
+ y2="26.435217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4543"
+ id="radialGradient4296"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1, 0, 0, 0.394366, 6.52257e-16, 23.442)"
+ cx="23.536554"
+ cy="38.706596"
+ fx="23.536554"
+ fy="38.706596"
+ r="14.344166" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6171"
+ id="linearGradient4298"
+ gradientUnits="userSpaceOnUse"
+ x1="25.515011"
+ y1="10.655476"
+ x2="37.140110"
+ y2="31.565634" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6187"
+ id="linearGradient4300"
+ gradientUnits="userSpaceOnUse"
+ x1="32.587322"
+ y1="28.554563"
+ x2="38.547222"
+ y2="28.554563" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6457"
+ id="linearGradient4302"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.953806, 0, 0, 1, 1.83218, -8.92136e-16)"
+ x1="36.067482"
+ y1="19.061104"
+ x2="38.278458"
+ y2="26.435217" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4543"
+ id="radialGradient4318"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1, 0, 0, 0.394366, -1.17961e-16, 23.442)"
+ cx="23.536554"
+ cy="38.706596"
+ fx="23.536554"
+ fy="38.706596"
+ r="14.344166" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6171"
+ id="linearGradient4320"
+ gradientUnits="userSpaceOnUse"
+ x1="25.515011"
+ y1="10.655476"
+ x2="37.140110"
+ y2="31.565634" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6187"
+ id="linearGradient4322"
+ gradientUnits="userSpaceOnUse"
+ x1="32.587322"
+ y1="28.554563"
+ x2="38.547222"
+ y2="28.554563" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6457"
+ id="linearGradient4324"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.953806, 0, 0, 1, 1.83218, -1.32799e-15)"
+ x1="36.067482"
+ y1="19.061104"
+ x2="38.278458"
+ y2="26.435217" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4509"
+ id="linearGradient4351"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -4.16951, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4509"
+ id="linearGradient4355"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -4.16951, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4449"
+ id="linearGradient4359"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -4.79569, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4449"
+ id="linearGradient4363"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -4.79569, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4449"
+ id="linearGradient4367"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -4.79569, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4509"
+ id="linearGradient4371"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -4.16951, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4509"
+ id="linearGradient4375"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -4.16951, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4509"
+ id="linearGradient4379"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -4.16951, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4509"
+ id="linearGradient4383"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.688766, 0, 0, 0.688766, -5.54704, 9.52172)"
+ x1="16.364470"
+ y1="39.918777"
+ x2="16.364470"
+ y2="30.928421" />
+ </defs>
+ <sodipodi:namedview
+ fill="#204a87"
+ inkscape:showpageshadow="false"
+ showborder="true"
+ inkscape:window-y="51"
+ inkscape:window-x="116"
+ inkscape:window-height="1068"
+ inkscape:window-width="1030"
+ inkscape:document-units="px"
+ inkscape:grid-bbox="true"
+ showgrid="true"
+ inkscape:current-layer="layer1"
+ inkscape:cy="24"
+ inkscape:cx="24"
+ inkscape:zoom="13.988095"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0.0"
+ borderopacity="0.81568627"
+ bordercolor="#666666"
+ pagecolor="#ffffff"
+ id="base"
+ gridempspacing="4" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Workgroup</dc:title>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Jakub Steiner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:source>http://jimmac.musichall.cz</dc:source>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by/2.0/" />
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>lan</rdf:li>
+ <rdf:li>workgroup</rdf:li>
+ <rdf:li>network</rdf:li>
+ <rdf:li>peer</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Garrett LeSage</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by/2.0/">
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Reproduction" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/Distribution" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Notice" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/Attribution" />
+ <cc:permits
+ rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://web.resource.org/cc/ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ transform="matrix(0.994775,0,0,0.504437,2.062737,21.5656)"
+ d="M 37.88072 38.7066 A 14.34417 5.656854 0 1 0 9.192389 38.7066 A 14.34417 5.656854 0 1 0 37.88072 38.7066 z"
+ sodipodi:ry="5.6568542"
+ sodipodi:rx="14.344166"
+ sodipodi:cy="38.706596"
+ sodipodi:cx="23.536554"
+ id="path4244"
+ style="font-size:12;opacity:0.4;color:#000000;fill-opacity:0.0368;fill-rule:evenodd;stroke-dashoffset:0;"
+ sodipodi:type="arc"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <rect
+ style="font-size:12;color:#000000;fill-opacity:0.0368;fill-rule:evenodd;stroke:#5e5e5e;stroke-width:1.836665;stroke-dashoffset:0;"
+ id="rect6216"
+ width="31.9577503"
+ height="6.57723284"
+ x="14.9798265"
+ y="34.610033"
+ rx="2.23386907"
+ ry="2.06891823"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <rect
+ ry="4.22821856"
+ rx="4.56532911"
+ y="6.65627432"
+ x="14.9798265"
+ height="27.7626915"
+ width="31.9577503"
+ id="rect6218"
+ style="font-size:12;color:#000000;fill-opacity:0.0368;fill-rule:evenodd;stroke:#5e5e5e;stroke-width:1.836665;stroke-dashoffset:0;"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <rect
+ ry="0.93960613"
+ rx="1.01451695"
+ y="10.8743858"
+ x="19.418328"
+ height="18.0874271"
+ width="24.8556874"
+ id="rect6220"
+ style="font-size:12;opacity:0.662857;color:#000000;fill-opacity:0.0368;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.708601;stroke-dashoffset:0;"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <rect
+ style="font-size:12;color:#000000;fill:#ffffff;fill-rule:evenodd;stroke:#5e5e5e;stroke-width:1.836665;stroke-dashoffset:0;font-family:Bitstream Vera Sans;"
+ id="rect6222"
+ width="24.8556874"
+ height="18.0874271"
+ x="18.5306389"
+ y="9.94545269"
+ rx="1.01451695"
+ ry="0.93960625"
+ inkscape:r_cx="true"
+ inkscape:r_cy="true" />
+ <path
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ sodipodi:nodetypes="ccccccc"
+ id="path3626"
+ d="M 5.501559 32.19438 L 14.09312 32.2397 L 14.13029 28.09275 L 5.486979 28.04718 L 4.393265 28.8044 L 4.369441 31.46357 L 5.501559 32.19438 z "
+ style="font-size:12;fill-opacity:0;fill-rule:evenodd;stroke:#5e5e5e;stroke-width:0.974231;stroke-linecap:round;stroke-linejoin:round;" />
+ <rect
+ inkscape:r_cy="true"
+ inkscape:r_cx="true"
+ style="font-size:12;opacity:0.2;color:#000000;fill-opacity:0.0368;fill-rule:evenodd;stroke-dashoffset:0;"
+ id="rect4357"
+ width="1.81095675"
+ height="11.3847269"
+ x="11.8748981"
+ y="32.5087579"
+ transform="matrix(0.999981,6.17421e-3,-7.655214e-3,0.999971,0,0)" />
+ <path
+ sodipodi:type="spiral"
+ style="font-size:12;fill:none;fill-rule:evenodd;stroke:#000000;stroke-opacity:0.1618;stroke-width:0.5198;stroke-dasharray:none;"
+ id="path914"
+ sodipodi:cx="2.61538482"
+ sodipodi:cy="13.8461494"
+ sodipodi:expansion="1"
+ sodipodi:radius="4.40817022"
+ sodipodi:argument="-18.3390675"
+ sodipodi:t0="0"
+ d="M 2.615385 13.84615 C 2.766369 13.9826 2.600902 14.15861 2.435898 14.16666 C 2.087394 14.18367 1.91242 13.78183 1.974359 13.48717 C 2.083986 12.96567 2.678387 12.73503 3.153847 12.88461 C 3.847221 13.10275 4.139604 13.91138 3.897436 14.5641 C 3.576101 15.4302 2.546791 15.7855 1.717948 15.44871 C 0.67854 15.02637 0.259858 13.77368 0.692307 12.76923 C 1.214578 11.55615 2.692022 11.07385 3.871796 11.60256 C 5.258776 12.22413 5.804839 13.92713 5.179488 15.28205 C 4.459004 16.84309 2.529944 17.45301 0.999999 16.73077 C -0.735208 15.91162 -1.409055 13.75616 -0.589744 12.05128 C 0.327875 10.14182 2.709978 9.404 4.589745 10.32051 C 6.673504 11.33647 7.47534 13.9454 6.46154 16 "
+ transform="matrix(1.519545,0,0,1.415876,2.298103,3.983214)"
+ sodipodi:revolution="4" />
+ <text
+ style="fill:#000000;stroke:none;font-family:DejaVu Serif;font-style:italic;font-weight:normal;font-size:6;fill-opacity:0.3456;stroke-opacity:1;stroke-width:1pt;stroke-linejoin:miter;stroke-linecap:butt;text-anchor:middle;writing-mode:lr;"
+ x="23.7343745"
+ y="15.8241341"
+ id="text763"
+ sodipodi:linespacing="100%"
+ xml:space="default"
+ transform="scale(1.298271,0.989396)">
+ <tspan
+ x="23.734375"
+ y="15.8241339"
+ sodipodi:role="line"
+ id="tspan826"
+ style="fill:#000000;fill-opacity:0.3456;">www</tspan>
+ </text>
+</svg>
diff --git a/extensions/cpsection/Makefile.am b/extensions/cpsection/Makefile.am
index dd0a6b8..a92b5dd 100644
--- a/extensions/cpsection/Makefile.am
+++ b/extensions/cpsection/Makefile.am
@@ -1,4 +1,5 @@
-SUBDIRS = aboutme aboutcomputer datetime frame keyboard language network power updater
+SUBDIRS = aboutme aboutcomputer datetime frame keyboard language \
+ modemconfiguration network power updater
sugardir = $(pkgdatadir)/extensions/cpsection
sugar_PYTHON = __init__.py
diff --git a/extensions/cpsection/modemconfiguration/Makefile.am b/extensions/cpsection/modemconfiguration/Makefile.am
new file mode 100644
index 0000000..3e2613e
--- /dev/null
+++ b/extensions/cpsection/modemconfiguration/Makefile.am
@@ -0,0 +1,6 @@
+sugardir = $(pkgdatadir)/extensions/cpsection/modemconfiguration
+
+sugar_PYTHON = \
+ __init__.py \
+ model.py \
+ view.py
diff --git a/extensions/cpsection/modemconfiguration/__init__.py b/extensions/cpsection/modemconfiguration/__init__.py
new file mode 100644
index 0000000..8a219dc
--- /dev/null
+++ b/extensions/cpsection/modemconfiguration/__init__.py
@@ -0,0 +1,22 @@
+# Copyright (C) 2009 Paraguay Educa, Martin Abente
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 US
+
+from gettext import gettext as _
+
+CLASS = 'ModemConfiguration'
+ICON = 'module-modemconfiguration'
+TITLE = _('Modem Configuration')
+
diff --git a/extensions/cpsection/modemconfiguration/model.py b/extensions/cpsection/modemconfiguration/model.py
new file mode 100644
index 0000000..f96e88f
--- /dev/null
+++ b/extensions/cpsection/modemconfiguration/model.py
@@ -0,0 +1,53 @@
+# Copyright (C) 2009 Paraguay Educa, Martin Abente
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 US
+
+import gconf
+
+from jarabe.model.network import GSM_USERNAME_PATH, GSM_PASSWORD_PATH, \
+ GSM_NUMBER_PATH, GSM_APN_PATH
+
+def get_username():
+ client = gconf.client_get_default()
+ return client.get_string(GSM_USERNAME_PATH) or ''
+
+def get_password():
+ client = gconf.client_get_default()
+ return client.get_string(GSM_PASSWORD_PATH) or ''
+
+def get_number():
+ client = gconf.client_get_default()
+ return client.get_string(GSM_NUMBER_PATH) or ''
+
+def get_apn():
+ client = gconf.client_get_default()
+ return client.get_string(GSM_APN_PATH) or ''
+
+def set_username(username):
+ client = gconf.client_get_default()
+ client.set_string(GSM_USERNAME_PATH, username)
+
+def set_password(password):
+ client = gconf.client_get_default()
+ client.set_string(GSM_PASSWORD_PATH, password)
+
+def set_number(number):
+ client = gconf.client_get_default()
+ client.set_string(GSM_NUMBER_PATH, number)
+
+def set_apn(apn):
+ client = gconf.client_get_default()
+ client.set_string(GSM_APN_PATH, apn)
+
diff --git a/extensions/cpsection/modemconfiguration/view.py b/extensions/cpsection/modemconfiguration/view.py
new file mode 100644
index 0000000..d66f1d5
--- /dev/null
+++ b/extensions/cpsection/modemconfiguration/view.py
@@ -0,0 +1,192 @@
+# Copyright (C) 2009 Paraguay Educa, Martin Abente
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 US
+
+import os
+import logging
+from gettext import gettext as _
+
+import gtk
+import gobject
+
+from sugar.graphics import style
+
+from jarabe.controlpanel.sectionview import SectionView
+
+APPLY_TIMEOUT = 1000
+
+class EntryWithLabel(gtk.HBox):
+ __gtype_name__ = "SugarEntryWithLabel"
+
+ def __init__(self, label_text):
+ gtk.HBox.__init__(self, spacing=style.DEFAULT_SPACING)
+
+ self._timeout_sid = 0
+ self._changed_handler = None
+ self._is_valid = True
+
+ label = gtk.Label(label_text)
+ label.modify_fg(gtk.STATE_NORMAL,
+ style.COLOR_SELECTION_GREY.get_gdk_color())
+ self.pack_start(label, True, True)
+ label.show()
+
+ self._entry = gtk.Entry(25)
+ self._entry.connect('changed', self.__entry_changed_cb)
+ self._entry.set_width_chars(25)
+ self.pack_start(self._entry, expand=False)
+ self._entry.show()
+
+ def __entry_changed_cb(self, widget, data=None):
+ if self._timeout_sid:
+ gobject.source_remove(self._timeout_sid)
+ self._timeout_sid = gobject.timeout_add(APPLY_TIMEOUT,
+ self.__timeout_cb)
+
+ def __timeout_cb(self):
+ self._timeout_sid = 0
+
+ if self._entry.get_text() == self.get_value():
+ return False
+
+ try:
+ self.set_value(self._entry.get_text())
+ except ValueError:
+ self._is_valid = False
+ else:
+ self._is_valid = True
+
+ self.notify('is-valid')
+
+ return False
+
+ def set_text_from_model(self):
+ self._entry.set_text(self.get_value())
+
+ def get_value(self):
+ raise NotImplementedError
+
+ def set_value(self):
+ raise NotImplementedError
+
+ def _get_is_valid(self):
+ return self._is_valid
+ is_valid = gobject.property(type=bool, getter=_get_is_valid, default=True)
+
+class UsernameEntry(EntryWithLabel):
+ def __init__(self, model):
+ EntryWithLabel.__init__(self, _('Username:'))
+ self._model = model
+
+ def get_value(self):
+ return self._model.get_username()
+
+ def set_value(self, username):
+ return self._model.set_username(username)
+
+class PasswordEntry(EntryWithLabel):
+ def __init__(self, model):
+ EntryWithLabel.__init__(self, _('Password:'))
+ self._model = model
+
+ def get_value(self):
+ return self._model.get_password()
+
+ def set_value(self, password):
+ return self._model.set_password(password)
+
+class NumberEntry(EntryWithLabel):
+ def __init__(self, model):
+ EntryWithLabel.__init__(self, _('Number:'))
+ self._model = model
+
+ def get_value(self):
+ return self._model.get_number()
+
+ def set_value(self, number):
+ return self._model.set_number(number)
+
+class ApnEntry(EntryWithLabel):
+ def __init__(self, model):
+ EntryWithLabel.__init__(self, _('APN:'))
+ self._model = model
+
+ def get_value(self):
+ return self._model.get_apn()
+
+ def set_value(self, apn):
+ return self._model.set_apn(apn)
+
+class ModemConfiguration(SectionView):
+ def __init__(self, model, alerts=None):
+ SectionView.__init__(self)
+
+ self._model = model
+ self.restart_alerts = alerts
+
+ self.set_border_width(style.DEFAULT_SPACING)
+ self.set_spacing(style.DEFAULT_SPACING)
+
+ self._username_entry = UsernameEntry(model)
+ self._username_entry.connect('notify::is-valid',
+ self.__notify_is_valid_cb)
+ self.pack_start(self._username_entry, expand=False)
+ self._username_entry.show()
+
+ self._password_entry = PasswordEntry(model)
+ self._password_entry.connect('notify::is-valid',
+ self.__notify_is_valid_cb)
+ self.pack_start(self._password_entry, expand=False)
+ self._password_entry.show()
+
+ self._number_entry = NumberEntry(model)
+ self._number_entry.connect('notify::is-valid',
+ self.__notify_is_valid_cb)
+ self.pack_start(self._number_entry, expand=False)
+ self._number_entry.show()
+
+ self._apn_entry = ApnEntry(model)
+ self._apn_entry.connect('notify::is-valid',
+ self.__notify_is_valid_cb)
+ self.pack_start(self._apn_entry, expand=False)
+ self._apn_entry.show()
+
+ self.setup()
+
+ def setup(self):
+ self._username_entry.set_text_from_model()
+ self._password_entry.set_text_from_model()
+ self._number_entry.set_text_from_model()
+ self._apn_entry.set_text_from_model()
+
+ self.needs_restart = False
+
+ def undo(self):
+ self._model.undo()
+
+ def _validate(self):
+ if self._username_entry.is_valid and \
+ self._password_entry.is_valid and \
+ self._number_entry.is_valid and \
+ self._apn_entry.is_valid:
+ self.props.is_valid = True
+ else:
+ self.props.is_valid = False
+
+ def __notify_is_valid_cb(self, entry, pspec):
+ if entry.is_valid:
+ self.needs_restart = True
+ self._validate()
+
diff --git a/extensions/deviceicon/network.py b/extensions/deviceicon/network.py
index e40e196..2ca6a88 100644
--- a/extensions/deviceicon/network.py
+++ b/extensions/deviceicon/network.py
@@ -1,6 +1,7 @@
#
# Copyright (C) 2008 One Laptop Per Child
# Copyright (C) 2009 Tomeu Vizoso, Simon Schampijer
+# Copyright (C) 2009 Paraguay Educa, Martin Abente
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -55,16 +56,10 @@ _NM_OLPC_MESH_IFACE = 'org.freedesktop.NetworkManager.Device.OlpcMesh'
_NM_ACCESSPOINT_IFACE = 'org.freedesktop.NetworkManager.AccessPoint'
_NM_ACTIVE_CONN_IFACE = 'org.freedesktop.NetworkManager.Connection.Active'
-_NM_DEVICE_STATE_UNKNOWN = 0
-_NM_DEVICE_STATE_UNMANAGED = 1
-_NM_DEVICE_STATE_UNAVAILABLE = 2
-_NM_DEVICE_STATE_DISCONNECTED = 3
-_NM_DEVICE_STATE_PREPARE = 4
-_NM_DEVICE_STATE_CONFIG = 5
-_NM_DEVICE_STATE_NEED_AUTH = 6
-_NM_DEVICE_STATE_IP_CONFIG = 7
-_NM_DEVICE_STATE_ACTIVATED = 8
-_NM_DEVICE_STATE_FAILED = 9
+_GSM_STATE_NOT_READY = 0
+_GSM_STATE_DISCONNECTED = 1
+_GSM_STATE_CONNECTING = 2
+_GSM_STATE_CONNECTED = 3
def frequency_to_channel(frequency):
ftoc = { 2412: 1, 2417: 2, 2422: 3, 2427: 4,
@@ -215,6 +210,65 @@ class WiredPalette(Palette):
ip_address_text = ""
self._ip_address_label.set_text(ip_address_text)
+class GsmPalette(Palette):
+ __gtype_name__ = 'SugarGsmPalette'
+
+ __gsignals__ = {
+ 'gsm-connect' : (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, ([])),
+ 'gsm-disconnect' : (gobject.SIGNAL_RUN_FIRST,
+ gobject.TYPE_NONE, ([])),
+ }
+
+ def __init__(self):
+ Palette.__init__(self, label=_('Wireless modem'))
+
+ self._current_state = None
+
+ self._toggle_state_item = gtk.MenuItem('')
+ self._toggle_state_item.connect('activate', self.__toggle_state_cb)
+ self.menu.append(self._toggle_state_item)
+ self._toggle_state_item.show()
+
+ self.set_state(_GSM_STATE_NOT_READY)
+
+ def set_state(self, state):
+ self._current_state = state
+ self._update_label_and_text()
+
+ def _update_label_and_text(self):
+ if self._current_state == _GSM_STATE_NOT_READY:
+ self._toggle_state_item.get_child().set_label('...')
+ self.props.secondary_text = _('Please wait...')
+
+ elif self._current_state == _GSM_STATE_DISCONNECTED:
+ self._toggle_state_item.get_child().set_label(_('Connect'))
+ self.props.secondary_text = _('Disconnected')
+
+ elif self._current_state == _GSM_STATE_CONNECTING:
+ self._toggle_state_item.get_child().set_label(_('Cancel'))
+ self.props.secondary_text = _('Connecting...')
+
+ elif self._current_state == _GSM_STATE_CONNECTED:
+ self._toggle_state_item.get_child().set_label(_('Disconnect'))
+ self.props.secondary_text = _('Connected')
+ else:
+ raise ValueError('Invalid GSM state while updating label and ' \
+ 'text, %s' % str(self._current_state))
+
+ def __toggle_state_cb(self, menuitem):
+ if self._current_state == _GSM_STATE_NOT_READY:
+ pass
+ elif self._current_state == _GSM_STATE_DISCONNECTED:
+ self.emit('gsm-connect')
+ elif self._current_state == _GSM_STATE_CONNECTING:
+ self.emit('gsm-disconnect')
+ elif self._current_state == _GSM_STATE_CONNECTED:
+ self.emit('gsm-disconnect')
+ else:
+ raise ValueError('Invalid GSM state while emitting signal, %s' % \
+ str(self._current_state))
+
class WirelessDeviceView(ToolButton):
@@ -451,11 +505,11 @@ class WirelessDeviceView(ToolButton):
connection_name = format % nick
connection_name += color_suffix
- connection = network.find_connection(connection_name)
+ connection = network.find_connection_by_ssid(connection_name)
if connection is None:
settings = Settings()
settings.connection.id = 'Auto ' + connection_name
- settings.connection.uuid = unique_id()
+ uuid = settings.connection.uuid = unique_id()
settings.connection.type = '802-11-wireless'
settings.wireless.ssid = dbus.ByteArray(connection_name)
settings.wireless.band = 'bg'
@@ -463,7 +517,7 @@ class WirelessDeviceView(ToolButton):
settings.ip4_config = IP4Config()
settings.ip4_config.method = 'link-local'
- connection = network.add_connection(connection_name, settings)
+ connection = network.add_connection(uuid, settings)
obj = self._bus.get_object(_NM_SERVICE, _NM_PATH)
netmgr = dbus.Interface(obj, _NM_IFACE)
@@ -623,6 +677,122 @@ class WiredDeviceView(TrayIcon):
self._palette.set_connected(speed, address)
+class GsmDeviceView(TrayIcon):
+
+ _ICON_NAME = 'gsm-device'
+ FRAME_POSITION_RELATIVE = 303
+
+ def __init__(self, device):
+ client = gconf.client_get_default()
+ color = xocolor.XoColor(client.get_string('/desktop/sugar/user/color'))
+
+ TrayIcon.__init__(self, icon_name=self._ICON_NAME, xo_color=color)
+
+ self._bus = dbus.SystemBus()
+ self._device = device
+ self._palette = None
+ self.set_palette_invoker(FrameWidgetInvoker(self))
+
+ self._bus.add_signal_receiver(self.__state_changed_cb,
+ signal_name='StateChanged',
+ path=self._device.object_path,
+ dbus_interface=_NM_DEVICE_IFACE)
+
+ def create_palette(self):
+ palette = GsmPalette()
+
+ palette.set_group_id('frame')
+ palette.connect('gsm-connect', self.__gsm_connect_cb)
+ palette.connect('gsm-disconnect', self.__gsm_disconnect_cb)
+
+ self._palette = palette
+
+ props = dbus.Interface(self._device, 'org.freedesktop.DBus.Properties')
+ props.GetAll(_NM_DEVICE_IFACE, byte_arrays=True,
+ reply_handler=self.__current_state_check_cb,
+ error_handler=self.__current_state_check_error_cb)
+
+ return palette
+
+ def __gsm_connect_cb(self, palette, data=None):
+ connection = network.find_gsm_connection()
+ if connection is not None:
+ obj = self._bus.get_object(_NM_SERVICE, _NM_PATH)
+ netmgr = dbus.Interface(obj, _NM_IFACE)
+ netmgr.ActivateConnection(network.SETTINGS_SERVICE,
+ connection.path,
+ self._device.object_path,
+ '/',
+ reply_handler=self.__connect_cb,
+ error_handler=self.__connect_error_cb)
+
+ def __connect_cb(self, active_connection):
+ logging.debug('Connected successfully to gsm device, %s',
+ active_connection)
+
+ def __connect_error_cb(self, error):
+ raise RuntimeError('Error when connecting to gsm device, %s' % error)
+
+ def __gsm_disconnect_cb(self, palette, data=None):
+ obj = self._bus.get_object(_NM_SERVICE, _NM_PATH)
+ netmgr = dbus.Interface(obj, _NM_IFACE)
+ netmgr_props = dbus.Interface(netmgr, 'org.freedesktop.DBus.Properties')
+ active_connections_o = netmgr_props.Get(_NM_IFACE, 'ActiveConnections')
+
+ for conn_o in active_connections_o:
+ obj = self._bus.get_object(_NM_IFACE, conn_o)
+ props = dbus.Interface(obj, 'org.freedesktop.DBus.Properties')
+ devices = props.Get(_NM_ACTIVE_CONN_IFACE, 'Devices')
+ if self._device.object_path in devices:
+ netmgr.DeactivateConnection(
+ conn_o,
+ reply_handler=self.__disconnect_cb,
+ error_handler=self.__disconnect_error_cb)
+ break
+
+ def __disconnect_cb(self):
+ logging.debug('Disconnected successfully gsm device')
+
+ def __disconnect_error_cb(self, error):
+ raise RuntimeError('Error when disconnecting gsm device, %s' % error)
+
+ def __state_changed_cb(self, new_state, old_state, reason):
+ self._update_state(int(new_state))
+
+ def __current_state_check_cb(self, properties):
+ self._update_state(int(properties['State']))
+
+ def __current_state_check_error_cb(self, error):
+ raise RuntimeError('Error when checking gsm device state, %s' % error)
+
+ def _update_state(self, state):
+ gsm_state = None
+
+ if state is network.DEVICE_STATE_ACTIVATED:
+ gsm_state = _GSM_STATE_CONNECTED
+
+ elif state is network.DEVICE_STATE_DISCONNECTED:
+ gsm_state = _GSM_STATE_DISCONNECTED
+
+ elif state in [network.DEVICE_STATE_UNMANAGED,
+ network.DEVICE_STATE_UNAVAILABLE,
+ network.DEVICE_STATE_UNKNOWN]:
+ gsm_state = _GSM_STATE_NOT_READY
+
+ elif state in [network.DEVICE_STATE_PREPARE,
+ network.DEVICE_STATE_CONFIG,
+ network.DEVICE_STATE_IP_CONFIG]:
+ gsm_state = _GSM_STATE_CONNECTING
+
+ if self._palette is not None:
+ self._palette.set_state(gsm_state)
+
+ def disconnect(self):
+ self._bus.remove_signal_receiver(self.__state_changed_cb,
+ signal_name='StateChanged',
+ path=self._device.object_path,
+ dbus_interface=_NM_DEVICE_IFACE)
+
class WirelessDeviceObserver(object):
def __init__(self, device, tray, device_type):
self._device = device
@@ -633,6 +803,8 @@ class WirelessDeviceObserver(object):
self._device_view = WirelessDeviceView(self._device)
elif device_type == network.DEVICE_TYPE_802_11_OLPC_MESH:
self._device_view = OlpcMeshDeviceView(self._device)
+ else:
+ raise ValueError('Unimplemented device type %d' % device_type)
self._tray.add_device(self._device_view)
@@ -691,6 +863,19 @@ class WiredDeviceObserver(object):
del self._device_view
self._device_view = None
+class GsmDeviceObserver(object):
+ def __init__(self, device, tray):
+ self._device = device
+ self._device_view = None
+ self._tray = tray
+
+ self._device_view = GsmDeviceView(device)
+ self._tray.add_device(self._device_view)
+
+ def disconnect(self):
+ self._device_view.disconnect()
+ self._tray.remove_device(self._device_view)
+ self._device_view = None
class NetworkManagerObserver(object):
def __init__(self, tray):
@@ -735,6 +920,9 @@ class NetworkManagerObserver(object):
network.DEVICE_TYPE_802_11_OLPC_MESH]:
device = WirelessDeviceObserver(nm_device, self._tray, device_type)
self._devices[device_op] = device
+ elif device_type == network.DEVICE_TYPE_GSM_MODEM:
+ device = GsmDeviceObserver(nm_device, self._tray)
+ self._devices[device_op] = device
def __device_added_cb(self, device_op):
self._check_device(device_op)
diff --git a/src/jarabe/desktop/meshbox.py b/src/jarabe/desktop/meshbox.py
index 38f1e71..43f0fe9 100644
--- a/src/jarabe/desktop/meshbox.py
+++ b/src/jarabe/desktop/meshbox.py
@@ -116,7 +116,7 @@ class WirelessNetworkView(CanvasPulsingIcon):
self.set_palette(self._palette)
self._palette_icon.props.xo_color = self._color
- if network.find_connection(self._name) is not None:
+ if network.find_connection_by_ssid(self._name) is not None:
self.props.badge_name = "emblem-favorite"
self._palette_icon.props.badge_name = "emblem-favorite"
elif initial_ap.flags == network.NM_802_11_AP_FLAGS_PRIVACY:
@@ -223,7 +223,7 @@ class WirelessNetworkView(CanvasPulsingIcon):
state = network.DEVICE_STATE_UNKNOWN
if state == network.DEVICE_STATE_ACTIVATED:
- connection = network.find_connection(self._name)
+ connection = network.find_connection_by_ssid(self._name)
if connection:
if self._mode == network.NM_802_11_MODE_INFRA:
connection.set_connected()
@@ -340,11 +340,11 @@ class WirelessNetworkView(CanvasPulsingIcon):
self._connect()
def _connect(self):
- connection = network.find_connection(self._name)
+ connection = network.find_connection_by_ssid(self._name)
if connection is None:
settings = Settings()
settings.connection.id = 'Auto ' + self._name
- settings.connection.uuid = unique_id()
+ uuid = settings.connection.uuid = unique_id()
settings.connection.type = '802-11-wireless'
settings.wireless.ssid = self._name
@@ -362,7 +362,7 @@ class WirelessNetworkView(CanvasPulsingIcon):
if wireless_security is not None:
settings.wireless.security = '802-11-wireless-security'
- connection = network.add_connection(self._name, settings)
+ connection = network.add_connection(uuid, settings)
obj = self._bus.get_object(_NM_SERVICE, _NM_PATH)
netmgr = dbus.Interface(obj, _NM_IFACE)
diff --git a/src/jarabe/model/network.py b/src/jarabe/model/network.py
index b3c30d9..696dc91 100644
--- a/src/jarabe/model/network.py
+++ b/src/jarabe/model/network.py
@@ -1,6 +1,7 @@
# Copyright (C) 2008 Red Hat, Inc.
# Copyright (C) 2009 Tomeu Vizoso, Simon Schampijer
# Copyright (C) 2009 One Laptop per Child
+# Copyright (C) 2009 Paraguay Educa, Martin Abente
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -23,12 +24,15 @@ import time
import dbus
import gobject
import ConfigParser
+import gconf
from sugar import dispatch
from sugar import env
+from sugar.util import unique_id
DEVICE_TYPE_802_3_ETHERNET = 1
DEVICE_TYPE_802_11_WIRELESS = 2
+DEVICE_TYPE_GSM_MODEM = 3
DEVICE_TYPE_802_11_OLPC_MESH = 6
DEVICE_STATE_UNKNOWN = 0
@@ -42,6 +46,9 @@ DEVICE_STATE_IP_CONFIG = 7
DEVICE_STATE_ACTIVATED = 8
DEVICE_STATE_FAILED = 9
+NM_CONNECTION_TYPE_802_11_WIRELESS = '802-11-wireless'
+NM_CONNECTION_TYPE_GSM = 'gsm'
+
NM_ACTIVE_CONNECTION_STATE_UNKNOWN = 0
NM_ACTIVE_CONNECTION_STATE_ACTIVATING = 1
NM_ACTIVE_CONNECTION_STATE_ACTIVATED = 2
@@ -81,6 +88,11 @@ NM_CONNECTION_IFACE = 'org.freedesktop.NetworkManagerSettings.Connection'
NM_SECRETS_IFACE = 'org.freedesktop.NetworkManagerSettings.Connection.Secrets'
NM_ACCESSPOINT_IFACE = 'org.freedesktop.NetworkManager.AccessPoint'
+GSM_USERNAME_PATH = '/sugar/network/gsm/username'
+GSM_PASSWORD_PATH = '/sugar/network/gsm/password'
+GSM_NUMBER_PATH = '/sugar/network/gsm/number'
+GSM_APN_PATH = '/sugar/network/gsm/apn'
+
_nm_settings = None
_conn_counter = 0
@@ -168,6 +180,44 @@ class IP4Config(object):
ip4_config['method'] = self.method
return ip4_config
+class Serial(object):
+ def __init__(self):
+ self.baud = None
+
+ def get_dict(self):
+ serial = {}
+
+ if self.baud is not None:
+ serial['baud'] = self.baud
+
+ return serial
+
+class Ppp(object):
+ def __init__(self):
+ pass
+
+ def get_dict(self):
+ ppp = {}
+ return ppp
+
+class Gsm(object):
+ def __init__(self):
+ self.apn = None
+ self.number = None
+ self.username = None
+
+ def get_dict(self):
+ gsm = {}
+
+ if self.apn is not None:
+ gsm['apn'] = self.apn
+ if self.number is not None:
+ gsm['number'] = self.number
+ if self.username is not None:
+ gsm['username'] = self.username
+
+ return gsm
+
class Settings(object):
def __init__(self, wireless_cfg=None):
self.connection = Connection()
@@ -215,6 +265,35 @@ class Secrets(object):
return settings
+class SettingsGsm(object):
+ def __init__(self):
+ self.connection = Connection()
+ self.ip4_config = IP4Config()
+ self.serial = Serial()
+ self.ppp = Ppp()
+ self.gsm = Gsm()
+
+ def get_dict(self):
+ settings = {}
+
+ settings['connection'] = self.connection.get_dict()
+ settings['serial'] = self.serial.get_dict()
+ settings['ppp'] = self.ppp.get_dict()
+ settings['gsm'] = self.gsm.get_dict()
+ settings['ipv4'] = self.ip4_config.get_dict()
+
+ return settings
+
+class SecretsGsm(object):
+ def __init__(self):
+ self.password = None
+
+ def get_dict(self):
+ secrets = {}
+ if self.password is not None:
+ secrets['password'] = self.password
+ return {'gsm': secrets}
+
class NMSettings(dbus.service.Object):
def __init__(self):
bus = dbus.SystemBus()
@@ -233,8 +312,8 @@ class NMSettings(dbus.service.Object):
def NewConnection(self, connection_path):
pass
- def add_connection(self, ssid, conn):
- self.connections[ssid] = conn
+ def add_connection(self, uuid, conn):
+ self.connections[uuid] = conn
conn.secrets_request.connect(self.__secrets_request_cb)
self.NewConnection(conn.path)
@@ -274,11 +353,13 @@ class NMSettingsConnection(dbus.service.Object):
if not self._settings.connection.autoconnect:
self._settings.connection.autoconnect = True
self._settings.connection.timestamp = int(time.time())
- self.save()
+ if self._settings.connection.type == NM_CONNECTION_TYPE_802_11_WIRELESS:
+ self.save()
def set_secrets(self, secrets):
self._secrets = secrets
- self.save()
+ if self._settings.connection.type == NM_CONNECTION_TYPE_802_11_WIRELESS:
+ self.save()
def get_settings(self):
return self._settings
@@ -467,7 +548,6 @@ class AccessPoint(gobject.GObject):
path=self.model.object_path,
dbus_interface=NM_ACCESSPOINT_IFACE)
-
def get_settings():
global _nm_settings
if _nm_settings is None:
@@ -478,24 +558,28 @@ def get_settings():
load_connections()
return _nm_settings
-def find_connection(ssid):
+def find_connection_by_ssid(ssid):
connections = get_settings().connections
- if ssid in connections:
- return connections[ssid]
- else:
- return None
-def add_connection(ssid, settings, secrets=None):
+ for conn_index in connections:
+ connection = connections[conn_index]
+ if connection._settings.connection.type == NM_CONNECTION_TYPE_802_11_WIRELESS:
+ if connection._settings.wireless.ssid == ssid:
+ return connection
+
+ return None
+
+def add_connection(uuid, settings, secrets=None):
global _conn_counter
path = NM_SETTINGS_PATH + '/' + str(_conn_counter)
_conn_counter += 1
conn = NMSettingsConnection(path, settings, secrets)
- _nm_settings.add_connection(ssid, conn)
+ _nm_settings.add_connection(uuid, conn)
return conn
-def load_connections():
+def load_wifi_connections():
profile_path = env.get_profile_path()
config_path = os.path.join(profile_path, 'nm', 'connections.cfg')
@@ -560,4 +644,43 @@ def load_connections():
except ConfigParser.Error:
logging.exception('Error reading section')
else:
- add_connection(ssid, settings, secrets)
+ add_connection(uuid, settings, secrets)
+
+
+def load_gsm_connection():
+ settings = SettingsGsm()
+ secrets = SecretsGsm()
+
+ client = gconf.client_get_default()
+ settings.gsm.username = client.get_string(GSM_USERNAME_PATH) or ''
+ settings.gsm.number = client.get_string(GSM_NUMBER_PATH) or ''
+ settings.gsm.apn = client.get_string(GSM_APN_PATH) or ''
+ password = client.get_string(GSM_PASSWORD_PATH) or ''
+
+ if password:
+ secrets.password = password
+
+ settings.connection.id = 'gsm'
+ settings.connection.type = NM_CONNECTION_TYPE_GSM
+ uuid = settings.connection.uuid = unique_id()
+ settings.connection.autoconnect = False
+ settings.ip4_config.method = 'auto'
+ settings.serial.baud = 115200
+
+ try:
+ add_connection(uuid, settings, secrets)
+ except Exception:
+ logging.exception('While adding gsm connection')
+
+def load_connections():
+ load_wifi_connections()
+ load_gsm_connection()
+
+def find_gsm_connection():
+ connections = get_settings().connections
+
+ for connection in connections.values():
+ if connection.get_settings().connection.type == NM_CONNECTION_TYPE_GSM:
+ return connection
+
+ return None