Initial commit after porting to TDE

master
Emanoil Kotsev 5 years ago
parent 5e92681985
commit c4d9c127ad

@ -0,0 +1,121 @@
AUTHORS OF UMTSMON
==================
Over 90% of umtsmon was written by Klaas van Gend in 2006, 2007, 2008 and 2009.
It is licensed under the GPLv2 License, see the file COPYING
However, Klaas is not the only copyright holder as some parts were derived
from or based on other sources. Also: several people gave advise on some
implementation topics or did supply patches or translations.
This file tries to list those contributions:
0)
Christofer Wesseling contributed to several parts of umtsmon as part
of his internship work at T-Mobile.
1)
the SerialPort class was based on COMGT 0.3 by Paul Hardwick
COMGT itself was based a package called dcon by Daniel Chouinard
See http://www.pharscape.org/content/view/46/70/
COMGT v0.3 was licensed under the GPLv2 or later.
Paul Hardwick also contributed to the DetectCard and Device classes.
2)
Debugging some issues in the SerialPort class was done with suggestions made by:
* Roel van den Broeck
* Martijn Wijms
* Tom Geelen
* Wouter Moors
3)
The image ok.png is taken from the tdelibs3 RPM from SuSE9.3
It is from the CrystalSVG icon set. According to the RPM, all files are
licensed through the GPL or LGPL.
4)
The UMTSmon logo as used on the website was drawn by 'Tazz_tux'.
5)
Autodetection for the Nozomi 2.2+ drivers and multiple pcmcia socket enumeration
was contributed by Stefan Seyfried [seife@suse.de]
Stefan also worked on several other issues related to card detection.
6)
The 'Runner' code to run other programs from umtsmon, specifically the piece to communicate
through pipes with the program run, was inspired by code from the following web page:
http://www.cryptnet.net/fdp/gtk/exec.html
the code on that page is GPL and copyrighted by V. Alex Brennen [vab@metanet.org] .
7)
Icons in the images/{16|22|SVG} directories come from the Tango icon
set, available at: http://tango.freedesktop.org/Tango_Icon_Library
These icons are licensed under the "Creative Commons Attribution Share-Alike license"
We think that we comply with the requirements of the license, even though we ship
the icons inside the umtsmon binary.
8)
Several compile-related and user interface issues were fixed by Gerald Pfeifer.
9)
fixup old/original Vodafone 3G detection, patch by dj9pz (Arnd Gronenberg)
10)
Huawei E220 fixes by Norbert Preining (norbusan)
11)
Lubomir Schmidt started translation into German and did lots of testing.
12)
additional German translations by Philipp Kießler, Dietmar Maurer and Thorsten Hesemeyer.
13)
translation work into Portugese (pt_PT) by Pedro Algarvio.
14)
some fixes by Carsten Clasohm.
15)
several UI improvements by Danny Kukawka.
16)
Translation into Norwegian Bokmaal by Klaus Ade Johnstad.
17)
comprehensive Sierra Wireless device support added by Phil Gorsuch
18)
Translation into Spanish by Emilio Arrufat, enhancements by Manuel Tornos
19)
Translation into Italian by Alessandro Briosi
20)
Translation into Polish by Tomasz Dominikowski
21)
Translation into Indonesian by Andika Triwidada
22)
The CID is now configurable from the config file thanks to Tobias Stober
23)
Michael Gisbers helped getting the HSO devices to work
24)
Till Busch provided tricks to add a "make install" target to umtsmon.
25)
Robert Verspuy fixed an issue with the Samsung Innov8 or i8510 mobile phone
26)
Martin Dummer provided the manpage and several fixes to umtsmon to allow
adding umtsmon to Debian. He also made gksu work with umtsmon.
27)
Dietmar Hillbrich implemented support for the Ericsson F3507g device.
If you have found any ommissions, please contact the author through the Sourceforge website:
http://www.sourceforge.net/projects/umtsmon

@ -0,0 +1,280 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS

@ -0,0 +1,51 @@
How to build umtsmon from source
================================
Prerequisites:
--------------
You need to have QT version 3 installed, including the development libs and
tools. Usually these are packages called qt-devel and such.
At this moment, umtsmon will not compile with QT4,
See the corresponding bug on sourceforge.
You need to have the header files for libusb installed. Some systems
such as OpenSUSE have this in a package called libusb-devel.
Make sure that you also have the related development tools installed: you
should have a directory with 'uic', 'qmake' and 'moc' in your search path.
Alternatively, you might want to call qmake with the full path and it will
adjust the Makefile to list full paths to the other binaries.
Also, the environment variable QTDIR should exist, nowadays usually something
like /usr/lib/qt3.
Steps to build & install:
-------------------------
tar xzvf <umtsmonfile.tar.gz>
cd <umtsmondirectory>
qmake
make clean all
make install
The make install will install the umtsmon application by default in
/usr/local/bin
Translations:
-------------
The above will build and install umtsmon.
During the build process, it will also build and install the
translations automatically.
Translation files end in .qm and by default are installed in:
/usr/local/share/umtsmon/translations
Config file location:
---------------------
umtsmon uses a configuration file in ~/.umtsmon/umtsmonrc .
If this file does not exist, it will be created.

@ -0,0 +1,31 @@
UMTSMON
=======
Welcome!
Thanks for giving umtsmon a try. umtsmon is a tool to handle UMTS (3G) devices in Linux.
At this moment, umtsmon is still a work in progress.
umtsmon 0.10 is a huge improvement over previous releases:
* UI starts immediately and starts worrying about devices later
* add support for HSO devices
* autoconnect
* and many smaller improvements, like improved logging, more info in system info dialog,
updated translations, add support for Ericsson F3507g, etc.
Known major bugs:
* umtsmon cannot perform autodetection correctly on some 2.6.20 Linux kernels.
* umtsmon doesn't work at all with bluetooth right now.
* the UI feels sluggish sometimes
Anyway, we hope you find this program useful.
NOTE for people using ZeroCD devices (usually on USB ports),
as supplied by Huawei or Option, umtsmon now should
find usb_modeswitch if it is in your path and use it.
If you don't have usb_modeswitch, please find it here:
http://www.draisberghof.de/usb_modeswitch/
Klaas van Gend and the umtsmon team

334
TODO

@ -0,0 +1,334 @@
TODO
This file contains a list of things to be done and a list of what's done
already.
Any entry starting with an X is completed.
Any entry starting with an / is "half" completed
--------------------------------------------------------------------------
For the 0.10 release:
X suspend logging during setting PIN/PUK.
X add checks whether user is part of 'dialout' and 'uucp' groups
X BUG TO BE REPORTED:
- even if *time* limit is hit, still data limit mentioned in warning dialog.
- that dialog is not i18n aware
X BUG:
X ###P1 t=935: ERROR: APN contains illegal character
this error should be visible to the GUI user, too.
X it also means that the checks in the profile dialog need to improve
X Create a new popup class that saves whether the customer wants to see the dialog again
X add a "welcome" at umtsmon start
X add a "please create a profile" at gui start
X Sierra Wireless Aircard 875 returns a number (I saw 23201 once) as operator - that should be masked...
- Novatel devices do this, too
- Huawei also sometimes
* (observed on Novatel cards only): if subsequent calls to AT+COPS do not return
the operator namei (but an empty string), make sure you cached the previous instance.
NOTE: first research why - this might be due to CREG/CGREG or so...
X implement number-to-operator cache
X use cache
X on single port cards (maybe also on multi-port cards)
not having autoupdate radio prefs on, will hang umtsmon after
shutting down the network connection
X I18n changes:
X make setting for non-en_US language persistent
X get list of all possible languages
X add menu option to set language from GUI
* Indonesian, thanks to Andika Triwidada
* Russian, thanks to Soussine Viktor
X auto connect option
X only allow auto connect when previously a connection was successful for that profile
X ensure device switching can be automated, too
X hardware enablement:
X finish Option HSO device support
X Solomon SCMi 250u
X Ericsson F3507g
X add Device class name and port info to System info dialog
X remember if roaming last time, so can show right stats at startup
* ConnectionInfo(ACM) - if a device doesn't work well on CGREG, we should make
the registration be part of the signal quality. i.e. always ask for signal quality
and make the registration depend on that. This requires changing the isDeviceRegistered()
and other members.
* ConnectionInfoACM seems to work as fine as ConnectionInfo does. Why have two?
- of course not entirely true: roaming info is missing
* BUG:
* Huawei modems no longer understand roaming vs home network
X various bugs fixed and optimizations around profiles:
- better handling of empty APN
- ability to set a profile from the command line
- immediately edit a profile after you create a new one
X CID is now configurable from the config file
X umtsmon no longer requires device to be fully operational at start
the device can now even be inserted after umtsmon has started
* The UI is sluggish
- move autodetection to a separate background thread
- fix the UIState to become a proper state machine
X allow for extra options in ppp through the /etc/ppp/peers file
--------------------------------------------------------------------------
For "FUTURE RELEASES":
* really make Aircard 875 (860/881U) work
* umtsmon crashes when a system comes out of suspend
* network operator wizard should also retrieve signal info for all operators
* check if the output of usb_modeswitch was good - or do we need to run again?
* auto update of stats should be always enabled until registered.
* check if UMTS card is forced to a specific network because if that
network is not available, you won't get a connection automatically
* Fix network selection of Novatel XU870
* move testersettings stuff from the various *_main.cpp files to TestFrame.cpp
* TO BE REPORTED BUG: when a usb serial plug is inserted *AND* a usb2serial-based card like the
Option, the new autodetection code will decide ttyUSB0 and ttyUSB3 first.
the test for AT will fail - the card will only use ttyUSB3. Not good.
/ Fix flickering of LCDDisplay
* add a dialog that shows the progress of AutoDetect
* on single port cards, a malfunctioning PPP might leave the port in undefined state
* fix operation on 2.6.20 kernels (Bug #1662877)
* check if HSDPA is used and show in display
* if multiple Profiles exist, make the "Connect" button a drop-down or add a dialog.
* show the currently selected Profile on the mainwindow
* add a "STOP" feature that kills all network connections and
performs a "cardctl eject" command - only if pcmcia kernel module is loaded
note: "cardctl eject" on Suse 9.3, "pccardctl eject" on Suse 10.1
note: on Suse, this command is suid root, but we can run things as root anyway now
-> this feature should only exist for PCMCIA, as it makes no sense on USB
-> this feature is dangerous on nozomi cards as it might freeze the whole system
* fix compilation for QT4 (Bug # 1527835)
-> only go to QT4 if it doesn't impact the amount of required libraries
* remove all assert(false) from the code
* Wizards for PPP configuration
* SMS handling:
* do code page translation as the character sets don't match
* add receiving SMS
* Make single serial port cards co-exist with PPP
(not by mutual exclusion as it is now, but by interrupting data streams)
See note in SerialPort.cpp: This code can be derived from modem.cpp in kppp.
Reportedly, also OpenMoko's gsmd can do this for us.
* more graphics
- animated connect and search network graphics?
- adjust font sizes for DPI settings in LCDDisplay
* diagnose more configuration errors
* installers
* (See Bug 1856802) for some device/operator, the MTU changes between GPRS and
UMTS operation. The only workaround is currently to set a fixed MTU in
the file /etc/ppp/options, which then is used for both radio modes.
* add location identification, like shown in this application:
http://www.ullihome.de/index.php/Hauptseite#Net_Monitor
--------------------------------------------------------------------------
History of releases:
What was in the 0.1 release:
X enter pin code during startup to unlock the card
X switching of network operators
X SMS sending
X some detection of Option GT cards
What was new in the 0.2 release:
X PCMCIA card autodetection
X Option GT autodetection + use
X Option Fusion(+) autodetection + use
/ SonyEricsson GC79 (autodetection only)
X command line override of autodetection
X create basic website
X if umtsmon is started immediately after card was inserted, the SIM
interface might not have been initialised yet. That's currently handled
incorrectly: we *should* allow some time and poll for the interface to
become available.
What was in the 0.3 release:
X card autodetection
X SonyEricsson GC79 autodetection (done)
X Option GT EDGE (Combo) autodetection (done)
X serial_cs-based cards autodetection (done)
X Sierra Wireless Aircard 775 EDGE
X Novatel Merlin UMTS Modem U630
X logging verbosity should be configurable
X create DEBUG macro's
X convert all existing printf's and cout's to DEBUG statements
X create a method to handle critical errors
X Add a technology selector - 3G only, 3G preferred, 2G only etc.
This is important for fringe network coverage.
X Make signal strength visible in title bar when minimized
X add checkbox to enable/disable the update of network stats
What was in the 0.4 release:
X Enhance PCMCIA detection to handle multiple PCMCIA slots.
(implemented by Stefan Seyfried)
X card autodetection
X Huawei Technologies Mobile E612
X Detect 'Holtzman' Nozomi drivers (which have different /dev interface names)
(implemented by Stefan Seyfried)
x add feature to issue commands as "root" user
X apply the trick from kppp to do this
X must clean up code for handling of error conditions first
X implement start/stop PPP connection from within umtsmon
X various interactions:
- not possible to switch radio type when connected - should be disabled
- not possible to connect when searching - connect should be disabled
- when connected - disable connect button or reuse as "disconnect" button
X implement configuration file for persistent settings
X add window to enter required PPP (APN, username, passwd) settings
X enter PUK code dialog
X improved PIN code dialog
What was in the 0.5 release:
X Fix security issues with respect to PPP by separating out the configuration
into a separate program that can modify system settings after asking for
a root password - the main UI doesn't need root privileges anymore.
X card autodetection
X Option 'ICON' USB box
X 4G Systems 'Web n Walk' USB box
X Original Option Vodafone 3G card
X implement changing of PIN code settings
X refactor PIN code enter thingie to separate widget that can be re-used
X make sure that the PIN dialogs use '*' instead of number for
increased security
X new dialog: change pin code
X new dialog: disable/enable use of pin code
X re-layout the UI
X separate out SMS code
X separate out network switching code
X separate out profile dialog
X create a menu and move functionality there
X add dialog check for suid of pppd
For the 0.6 release:
X back out patch to DetectCard to sudo /dev/noz*
X add dialog to check for correct suid of all helper binaries and serial devices
X Add detection of Kyocera device (won't work, though)
X Add detection of Novatel XU870 (operation not complete - delayed to 0.7)
X Make Sony Ericsson GC79 work (Bug #1499130)
X fix SMS sending
X fix about dialog (c) message and AUTHORS tab
X more graphical network strength view
X make PPPConnection more robust
X add 'noauth' to Profile
For the 0.6.9 release - will be in OpenSuse 10.3:
X rewrite autodetection
/ switch to use libusb
* and use current code as backup for non libusb systems
X usb detection first, pcmcia later
X add option to specify ppp port on command line
X attempt several baud rates if needed (Bug #1690898)
X test all ports to use (AT/PPP) before actually continuing - if there are
three ports but only one is usable - switch to single port!
/ finish getting the SonyEricsson GC79 to work (Bugs #1499130 and #1746965)
X make sure *all* AT commands are suppressed whilst PPP active
X show error log in case PPP fails
X move setRadioPreferences to its own dialog (Bug #1631291)
X Profile dialog: check for unsaved items if OK is pressed
/ add support for:
X Dell Wireless 5510 (bug #1785692)
/ Sony Ericsson GC86
Additional for the 'real' 0.7 release:
X a few bug fixes by Gerald and Seife.
X document-new.png and document-save.png in newprofiledialog.ui are missing
X make a real application icon
For the 0.7.91 release (i.e. 0.7-beta1):
X Sierra Wireless Aircard 875 support
X Huawei 220 doesn't like if you use the third port
/ fix GC86 port operation (bug #1792667)
* add umtsmon to Debian
X .deb package for umtsmon-0.6 Ubuntu already exists
* internationalization
/ dutch (nl) - Klaas
* brazilian portugese (pt-br) - Alvaro
/ german (de) - Lubomir
* french/polish/russian/spanish/korean/other languages only if volunteers
X fix the LCDDisplay to show "operator" "profile" and such i18n as well
X language selection from command line
X language selection through "LANG" environment variable
/ icons
X get more icons from the Tango series
/ move help/no/ok/services icons to the 22 and 16 directories
X add .desktop file
X improve Gentoo ebuild (needed for i18n and .desktop anyway)
X if usbserial card detected, but module not loaded, suggest to load module
X emit a message (other than just crashing :-() in the case nothing was detected
X added /etc/*-release to the info dialog, Bug# 1722979
X added the pppd version number to the info dialog, Bug# 1617912
X introduce manage profile dialog and fixup Profiles dialog
X FIX: on single port cards, a malfunctioning PPP might leave the port in undefined state
X maintain statistics and an alarm if you hit a percentage of bandwith per month
X add settings to Profile Dialog
X store traffic data in config file
X show sum & status in display
X throw warning if threshold hit
X solve the CGREG/CREG issue for ACM devices that don't answer that query well
(bug 1865927)
X add new advanced ppp option: No Compression Control Protocol negotiation
For the 0.8 (final) release:
X improve i18n - bring all languages up-to-date
X dutch is at 98%
X german is high too
X fixup MonthlyTraffic creation
- starting at GUI Start (logically - is part of mainwindow class)
- twice before creating connection
- before sending SMS
X merge Gerald's ctrl-c in ui (connect) patch
X merge Seife's ctrl-c on cmdline (sigint) patch
X sending SMS fails on Novatel U740
- card returns "CME Error 305" when over limit of max characters
- that's not a known error ?!?
X but the error was not even detected!
X allow to suppress PPP verbosity (Seife)
X Fix flickering of LCDDisplay - mostly done
X if single port device - don't show network strength when connected
For the 0.9 release:
X create a umtsmon-i18n mailing list
X work on commit list
X get all USB IDs from 2.6.24^H^H25 into the USB AutoDetector
X TODO: real Option (option.c)
X TODO: Sierra Wireless (sierra.c) - patches by Phil
X TODO: Huawei (only a few IDs in use)
X TODO: others
X make Huawei E220 work acceptably
X add ignores for unsollicited updates
X fix all oddities, including immediate return on network operator change
X make Sierra Wireless 8775 work acceptably
X create separate Sierra Wireless Device type - patch by Phil
X make TempSerial port class
X set CHAT stuff on same port as PPP connection
X switch AT and PPP ports if card says so (APP1 answer to ATI query) - patch by Danny
/ make Option HSO devices work acceptably
X new Device class
/ modify Autodetect_USB to also scan for HSO devices
X remove the 'nocompression' option from the Profile and
always make sure that "no header compression" is used. This fixes at least
50% of the recent bug reports and forum posts.
X Do not just look for icon_switch, but also for:
- HuaweiAktbo http://linux.frankenberger.at/Huawei_E220.html
- usb_modeswitch http://www.draisberghof.de/usb_modeswitch/
X use the above tools if needed
X Time limits (like we already have data limits)
X add to profile class & UI
X add to MonthlyTraffic
X add to LCDDisplay
X add alerts
/ new display
X display connected time
* show new icons for roaming/home
X show triangle for roaming
X i18n: spanish + norwegian bokmal + italian + polish
X optimize "select operators dialog"
X make it a wizard?
X separate model-view-controller to improve code.
* wizard also retrieves signal info for all operators
X card switching for ICON (ZeroCD device)
X the Huawei 220 is a ZeroCD device, that can be easily switched
X add autodetection for the usb_storage thingie
/ fixup bluetooth
X allow '/bin' and '/sbin' as part of a path for *su apps

@ -0,0 +1,22 @@
#!/bin/bash
#
# This script was written to get some data on how far the various translations are
# compared to each other
#
# This script is donated to the public domain
#
# Klaas van Gend, 2008
printf "\n translation file %%ready (unfinished/(total-obsolete))\n"
printf '=============================================================\n'
for I in `ls -1 *.ts`;
do
UNFINISHED=`grep 'type="unfinished"' $I | wc -l`;
OBSOLETE=`grep 'obsolete' $I | wc -l`;
MSGLINES=`grep '</message>' $I | wc -l`;
let REALLINES=$MSGLINES-$OBSOLETE;
let PERCENT=(100*$UNFINISHED)/$REALLINES;
let FINISHED=100-$PERCENT;
printf "% 18s : % 4d%% %d/(%d-%d)\n" $I $FINISHED $UNFINISHED $MSGLINES $OBSOLETE ;
done
printf "\n"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 796 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 863 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 911 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 932 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 619 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 635 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 820 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 935 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 912 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 786 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 912 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 924 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 692 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 946 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 685 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 798 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 960 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

@ -0,0 +1,999 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<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://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="744.09448819"
height="1052.3622047"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.43"
sodipodi:docbase="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay"
sodipodi:docname="LCDDisplay.svg"
inkscape:export-filename="/home/klaas//LCDDisplay4.png"
inkscape:export-xdpi="120.25"
inkscape:export-ydpi="120.25">
<defs
id="defs4">
<linearGradient
id="linearGradient2502">
<stop
style="stop-color:#8e8e64;stop-opacity:0;"
offset="0"
id="stop2504" />
<stop
style="stop-color:#8e8e64;stop-opacity:0.14432989;"
offset="1"
id="stop2506" />
</linearGradient>
<linearGradient
id="linearGradient2480">
<stop
id="stop2482"
offset="0"
style="stop-color:#8e8e64;stop-opacity:0.40206185;" />
<stop
id="stop2484"
offset="1"
style="stop-color:#ffffff;stop-opacity:0;" />
</linearGradient>
<linearGradient
id="linearGradient2447">
<stop
style="stop-color:#ffffc8;stop-opacity:0.50588238;"
offset="0"
id="stop2449" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop2451" />
</linearGradient>
<linearGradient
id="linearGradient2204">
<stop
style="stop-color:#ff2727;stop-opacity:1;"
offset="0"
id="stop2206" />
<stop
id="stop2212"
offset="0.27283096"
style="stop-color:#ffe544;stop-opacity:1;" />
<stop
style="stop-color:#ffff19;stop-opacity:1;"
offset="0.35394287"
id="stop2249" />
<stop
style="stop-color:#b8ff00;stop-opacity:1;"
offset="0.54589844"
id="stop2214" />
<stop
style="stop-color:#1ddb1d;stop-opacity:1;"
offset="1"
id="stop2208" />
</linearGradient>
<linearGradient
id="linearGradient2196">
<stop
style="stop-color:#ff6262;stop-opacity:1;"
offset="0"
id="stop2198" />
<stop
style="stop-color:#626262;stop-opacity:0;"
offset="1"
id="stop2200" />
</linearGradient>
<linearGradient
id="linearGradient2185">
<stop
style="stop-color:#626262;stop-opacity:1;"
offset="0"
id="stop2187" />
<stop
style="stop-color:#d8d8d8;stop-opacity:1;"
offset="1"
id="stop2189" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2185"
id="linearGradient2191"
x1="330.54587"
y1="172.88142"
x2="353.25989"
y2="272.12656"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2204"
id="linearGradient2210"
x1="224.12621"
y1="195.36161"
x2="341.2953"
y2="195.36161"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-1.463555,-117.516)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2185"
id="linearGradient2325"
gradientUnits="userSpaceOnUse"
x1="330.54587"
y1="172.88142"
x2="353.25989"
y2="272.12656"
gradientTransform="translate(1.619802,227.732)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2204"
id="linearGradient2327"
gradientUnits="userSpaceOnUse"
x1="224.12621"
y1="195.36161"
x2="341.2953"
y2="195.36161"
gradientTransform="translate(1.619802,227.732)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2204"
id="linearGradient2331"
gradientUnits="userSpaceOnUse"
x1="224.12621"
y1="195.36161"
x2="341.2953"
y2="195.36161"
gradientTransform="translate(-0.304544,24.91138)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2204"
id="linearGradient2417"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-0.304544,20.91138)"
x1="224.12621"
y1="195.36161"
x2="341.2953"
y2="195.36161" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2204"
id="linearGradient2448"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-0.304544,24.91138)"
x1="224.12621"
y1="195.36161"
x2="341.2953"
y2="195.36161" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2204"
id="linearGradient2451"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-0.304544,4.91138)"
x1="224.12621"
y1="195.36161"
x2="341.2953"
y2="195.36161" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2204"
id="linearGradient2457"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-2.294762,-83.34651)"
x1="224.12621"
y1="195.36161"
x2="341.2953"
y2="195.36161" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2204"
id="linearGradient1412"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0.937888,214.9539)"
x1="224.12621"
y1="195.36161"
x2="341.2953"
y2="195.36161" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2447"
id="radialGradient2453"
cx="233.54359"
cy="207.02036"
fx="233.54359"
fy="207.02036"
r="48.873814"
gradientTransform="matrix(1,-1.151694e-16,3.183949e-17,0.429967,1.076132e-14,118.0084)"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2480"
id="radialGradient2478"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.05783,-0.153262,7.192799e-2,0.478065,-30.48594,143.8229)"
cx="240.71082"
cy="230.30884"
fx="240.71082"
fy="230.30884"
r="48.873814" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2502"
id="linearGradient2510"
x1="515.43231"
y1="231.00233"
x2="529.56763"
y2="269.87433"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2502"
id="linearGradient2514"
gradientUnits="userSpaceOnUse"
x1="497.76324"
y1="209.29462"
x2="547.74146"
y2="230.49751"
gradientTransform="translate(9.384766e-6,-2.260742e-6)" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.9808614"
inkscape:cx="369.78137"
inkscape:cy="850.11204"
inkscape:document-units="px"
inkscape:current-layer="layer1"
inkscape:window-width="1280"
inkscape:window-height="961"
inkscape:window-x="0"
inkscape:window-y="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
style="display:none"
sodipodi:insensitive="true">
<rect
style="opacity:1;fill:#bab9bc;fill-opacity:1;stroke:#626262;stroke-width:0.25383553;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect2271"
width="598.47559"
height="291.80283"
x="70.543579"
y="56.348728" />
<rect
style="opacity:1;fill:#bab9bc;fill-opacity:1;stroke:none;stroke-width:0.1610509;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect1307"
width="426.54916"
height="164.8118"
x="150.58717"
y="138.10469"
inkscape:export-filename="/home/klaas/text2265.png"
inkscape:export-xdpi="79.967331"
inkscape:export-ydpi="79.967331" />
<text
xml:space="preserve"
style="font-size:12px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="76.836647"
y="339.61081"
id="text1414"><tspan
sodipodi:role="line"
id="tspan1416"
x="76.836647"
y="339.61081">make sure you export at 80.00 dpi!!!</tspan></text>
</g>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="base"
style="display:inline">
<rect
style="opacity:1;fill:#e6eb94;fill-opacity:1;stroke:url(#linearGradient2191);stroke-width:2.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect1310"
width="375.11786"
height="96.745125"
x="174.16035"
y="174.13142"
ry="17.199133"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002" />
<path
sodipodi:type="arc"
style="opacity:1;fill:url(#radialGradient2453);fill-opacity:1;stroke:none;stroke-width:2.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.47843137"
id="path1572"
sodipodi:cx="233.54359"
sodipodi:cy="207.02036"
sodipodi:rx="48.873814"
sodipodi:ry="21.014147"
d="M 282.41741 207.02036 A 48.873814 21.014147 0 1 1 184.66978,207.02036 A 48.873814 21.014147 0 1 1 282.41741 207.02036 z"
transform="matrix(1.875405,-0.585753,0.81176,1.353264,-336.4109,72.07636)"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002" />
<rect
style="opacity:1;fill:url(#linearGradient2510);fill-opacity:1;stroke:none;stroke-width:2.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.47843137"
id="rect2486"
width="186.28259"
height="94.908203"
x="361.45889"
y="174.96611"
ry="13.665317"
rx="17.199133"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002" />
<rect
style="opacity:1;fill:url(#linearGradient2514);fill-opacity:1;stroke:none;stroke-width:2.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.47843137;display:inline"
id="rect2512"
width="186.28259"
height="94.908203"
x="361.45889"
y="174.96611"
ry="13.665317"
rx="17.199133"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002" />
</g>
<g
inkscape:groupmode="layer"
id="layer3"
inkscape:label="top"
style="display:inline">
<g
id="g2236"
transform="matrix(1.397052,0,0,1.152482,-73.66561,-25.05499)"
style="stroke:#000000;stroke-opacity:0.47843137"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002">
<path
id="path2230"
d="M 196.26871,183.47474 L 196.26871,206.47025"
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.47843137" />
<path
id="path2232"
d="M 196.26871,191.34163 L 190.21726,183.97903 L 190.21726,183.97903"
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.47843137" />
<path
id="path2234"
d="M 196.067,191.34163 L 202.11845,183.97903 L 202.11845,183.97903"
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.47843137" />
</g>
<path
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.14367813"
d="M 357.4195,180.58111 L 357.4195,263.35194"
id="path2259"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002" />
<path
style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.26900005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47843137;display:inline"
d="M 200.38508,225.69472 L 196.51323,228.83985 L 192.65337,231.9751 L 196.48926,231.9751 L 196.48926,238.09723 C 196.54241,238.10636 198.25962,238.10712 200.38508,238.10712 C 202.47681,238.10712 204.17691,238.10616 204.28091,238.09723 L 204.28091,231.9751 L 208.12878,231.9751 L 204.25693,228.83985 L 200.38508,225.69472 z "
id="rect1608"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002" />
<path
style="opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.26900005;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47843137;display:inline"
d="M 200.39707,259.26874 L 204.26892,256.12361 L 208.12878,252.98836 L 204.29289,252.98836 L 204.29289,246.86623 C 204.23974,246.8571 202.52253,246.85634 200.39707,246.85634 C 198.30534,246.85634 196.60524,246.8573 196.50124,246.86623 L 196.50124,252.98836 L 192.65337,252.98836 L 196.52522,256.12361 L 200.39707,259.26874 z "
id="path4238"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002" />
<text
xml:space="preserve"
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:0.47843137;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Bitstream Vera Sans"
x="277.84296"
y="256.24368"
id="text1575"
sodipodi:linespacing="125%"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002"><tspan
sodipodi:role="line"
id="tspan1577"
x="277.84296"
y="256.24368">/</tspan></text>
<text
xml:space="preserve"
style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:0.47843137;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Bitstream Vera Sans"
x="277.5451"
y="235.08208"
id="text1579"
sodipodi:linespacing="125%"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002"><tspan
sodipodi:role="line"
id="tspan1581"
x="277.5451"
y="235.08208">/</tspan></text>
<path
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.14367813;display:inline"
d="M 542.79268,238.91403 L 363.11356,238.91403"
id="path4351"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002" />
<path
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.04197061;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.47843137;display:inline"
d="M 374.34514,247.65999 L 366.43596,247.65999 L 370.4282,253.55597 L 366.51128,259.61802 L 374.19449,259.61802"
id="path4311"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002" />
<rect
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.75937557;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.05098039;display:inline"
id="rect2605"
width="31.92832"
height="21.176598"
x="504.89227"
y="185.17754"
rx="65.727791"
ry="0.053212948"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002" />
<path
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:0.86785781px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.05098039;display:inline"
d="M 505.54385,186.49649 C 505.54385,186.49649 517.94232,197.59772 520.67542,197.56109 C 523.40851,197.52445 536.16898,186.64305 536.16898,186.64305"
id="path2609"
sodipodi:nodetypes="czc"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002" />
<path
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:0.86785781px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.05098039;display:inline"
d="M 524.29541,196.82834 L 536.02418,205.47483"
id="path2613"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002" />
<path
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:0.86785781px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.05098039;display:inline"
d="M 517.48982,196.82834 L 505.76105,205.47483"
id="path2615"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002" />
<g
style="display:inline"
id="g2459"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002">
<path
id="rect5233"
d="M 516.7885,223.81657 L 516.7885,230.94422 L 503.97404,230.94422 L 503.97404,223.81657"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.93842661;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.05882353;display:inline" />
<path
id="path6131"
d="M 501.34362,225.20523 L 510.39412,218.86002 L 519.41892,225.20523"
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:0.93842661;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.05882353;display:inline" />
<path
id="path6146"
d="M 505.63747,221.69881 L 505.63747,219.4939 C 505.63747,219.48416 506.07897,219.47632 506.62737,219.47632 L 506.62736,219.47632 C 507.17578,219.47632 507.61726,219.48416 507.61726,219.49389 L 507.61726,220.31449"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.93842661;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.05882353;display:inline" />
<path
transform="matrix(0.123502,4.792431e-2,-4.782368e-2,0.123762,482.8701,191.714)"
d="M 473.02652 102.7753 A 45.93961 45.93961 0 1 1 381.1473,102.7753 A 45.93961 45.93961 0 1 1 473.02652 102.7753 z"
sodipodi:ry="45.93961"
sodipodi:rx="45.93961"
sodipodi:cy="102.7753"
sodipodi:cx="427.08691"
id="path1595"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:6.24312925;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.05882353"
sodipodi:type="arc" />
<path
transform="matrix(8.77706e-2,3.405885e-2,-4.782368e-2,0.123762,498.1305,197.6358)"
d="M 473.02652 102.7753 A 45.93961 45.93961 0 1 1 381.1473,102.7753 A 45.93961 45.93961 0 1 1 473.02652 102.7753 z"
sodipodi:ry="45.93961"
sodipodi:rx="45.93961"
sodipodi:cy="102.7753"
sodipodi:cx="427.08691"
id="path1597"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:7.40567732;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.05882353;display:inline"
sodipodi:type="arc" />
<path
transform="matrix(4.400164e-2,1.707469e-2,-4.782368e-2,0.123762,516.8236,204.8895)"
d="M 473.02652 102.7753 A 45.93961 45.93961 0 1 1 381.1473,102.7753 A 45.93961 45.93961 0 1 1 473.02652 102.7753 z"
sodipodi:ry="45.93961"
sodipodi:rx="45.93961"
sodipodi:cy="102.7753"
sodipodi:cx="427.08691"
id="path1599"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:10.45934963;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.05882353;display:inline"
sodipodi:type="arc" />
<path
id="path1603"
d="M 536.39333,222.85746 C 534.85025,223.12629 533.08414,222.96056 531.35229,222.28852 C 529.84378,221.70315 528.57421,220.81627 527.63743,219.7777"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.82769686;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.05882353" />
<path
id="path1610"
d="M 533.55937,230.37405 C 532.41911,229.60044 530.89425,228.8104 529.1624,228.13837 C 527.65389,227.553 526.20128,227.13979 524.95108,226.9123"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.82769686;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.05882353;display:inline" />
<path
id="path1612"
d="M 536.57802,226.39402 C 534.82755,226.62361 532.61487,226.33006 530.37707,225.46169 C 528.23175,224.62922 526.45856,223.42183 525.31153,222.13305"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.82769686;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.05882353" />
</g>
<g
style="display:inline"
id="g4300"
transform="matrix(1.001463,0,0,1.001456,-15.79491,27.49496)"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002">
<path
transform="matrix(0.345511,0,0,0.345511,324.895,151.8508)"
d="M 495.7759 214.0417 A 17.338099 17.338099 0 1 1 461.09971,214.0417 A 17.338099 17.338099 0 1 1 495.7759 214.0417 z"
sodipodi:ry="17.338099"
sodipodi:rx="17.338099"
sodipodi:cy="214.0417"
sodipodi:cx="478.43781"
id="path4286"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2.89426374;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47843137"
sodipodi:type="arc" />
<path
id="path4288"
d="M 490.25777,225.92226 L 490.14328,220.427"
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.47843137" />
<path
id="path4290"
d="M 490.76883,227.0671 L 492.37161,229.01334"
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.47843137" />
</g>
</g>
<g
inkscape:groupmode="layer"
id="layer4"
inkscape:label="changing content"
style="display:inline">
<g
id="g4244"
transform="translate(141.5207,36.20695)"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002">
<text
inkscape:export-ydpi="79.120003"
inkscape:export-xdpi="79.120003"
inkscape:export-filename="/home/klaas/text2265.png"
sodipodi:linespacing="125%"
id="text2224"
y="193.56868"
x="223.11839"
style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="193.56868"
x="223.11839"
id="tspan2226"
sodipodi:role="line">HSDPA</tspan></text>
<text
inkscape:export-ydpi="79.120003"
inkscape:export-xdpi="79.120003"
inkscape:export-filename="/home/klaas/text2265.png"
sodipodi:linespacing="125%"
id="text2261"
y="194.55565"
x="224.39421"
style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:0.33333333;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="194.55565"
x="224.39421"
id="tspan2263"
sodipodi:role="line">HSDPA</tspan></text>
</g>
<g
style="display:inline"
id="g1519"
transform="translate(-16.25462,-24.58114)"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002">
<text
inkscape:export-ydpi="79.120003"
inkscape:export-xdpi="79.120003"
inkscape:export-filename="/home/klaas/text2265.png"
sodipodi:linespacing="125%"
id="text2255"
y="254.45259"
x="444.77972"
style="font-size:11px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="254.45259"
x="444.77972"
id="tspan2257"
sodipodi:role="line">Default</tspan></text>
<text
inkscape:export-ydpi="79.120003"
inkscape:export-xdpi="79.120003"
sodipodi:linespacing="125%"
id="text2265"
y="255.37206"
x="446.3425"
style="font-size:11px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:0.3372549;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="255.37206"
x="446.3425"
id="tspan2267"
sodipodi:role="line">Default</tspan></text>
</g>
<path
style="fill:#000000;fill-opacity:0.33333333;stroke:none;stroke-width:2.5;stroke-miterlimit:4;stroke-opacity:0.47843137;display:inline"
d="M 341.90625,191.25 L 337.40625,191.78125 L 337.40625,212.5625 L 341.90625,212.5625 L 341.90625,191.25 z M 335.96875,191.9375 L 331.46875,192.46875 L 331.46875,212.5625 L 335.96875,212.5625 L 335.96875,191.9375 z M 330.03125,192.625 L 325.53125,193.15625 L 325.53125,212.5625 L 330.03125,212.5625 L 330.03125,192.625 z M 324.09375,193.3125 L 319.59375,193.8125 L 319.59375,212.5625 L 324.09375,212.5625 L 324.09375,193.3125 z M 318.1875,194 L 313.6875,194.5 L 313.6875,212.5625 L 318.1875,212.5625 L 318.1875,194 z M 312.25,194.6875 L 307.75,195.1875 L 307.75,212.5625 L 312.25,212.5625 L 312.25,194.6875 z M 306.3125,195.34375 L 301.8125,195.875 L 301.8125,212.5625 L 306.3125,212.5625 L 306.3125,195.34375 z M 300.375,196.03125 L 295.875,196.5625 L 295.875,212.5625 L 300.375,212.5625 L 300.375,196.03125 z M 294.46875,196.71875 L 289.96875,197.25 L 289.96875,212.5625 L 294.46875,212.5625 L 294.46875,196.71875 z M 288.53125,197.40625 L 284.03125,197.9375 L 284.03125,212.5625 L 288.53125,212.5625 L 288.53125,197.40625 z M 282.59375,198.09375 L 278.09375,198.625 L 278.09375,212.5625 L 282.59375,212.5625 L 282.59375,198.09375 z M 276.65625,198.78125 L 272.15625,199.3125 L 272.15625,212.5625 L 276.65625,212.5625 L 276.65625,198.78125 z M 270.71875,199.46875 L 266.21875,199.96875 L 266.21875,212.5625 L 270.71875,212.5625 L 270.71875,199.46875 z M 264.8125,200.15625 L 260.3125,200.65625 L 260.3125,212.5625 L 264.8125,212.5625 L 264.8125,200.15625 z M 258.875,200.84375 L 254.375,201.34375 L 254.375,212.5625 L 258.875,212.5625 L 258.875,200.84375 z M 252.9375,201.5 L 248.4375,202.03125 L 248.4375,212.5625 L 252.9375,212.5625 L 252.9375,201.5 z M 247,202.1875 L 242.5,202.71875 L 242.5,212.5625 L 247,212.5625 L 247,202.1875 z M 241.09375,202.875 L 236.59375,203.40625 L 236.59375,212.5625 L 241.09375,212.5625 L 241.09375,202.875 z M 235.15625,203.5625 L 230.65625,204.09375 L 230.65625,212.5625 L 235.15625,212.5625 L 235.15625,203.5625 z M 229.21875,204.25 L 224.71875,204.78125 L 224.71875,212.5625 L 229.21875,212.5625 L 229.21875,204.25 z "
id="path2443"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002" />
<path
style="opacity:1;fill:url(#linearGradient2451);fill-opacity:1;stroke:none;stroke-width:2.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
d="M 341,191 L 336.5,191.53125 L 336.5,211.28125 L 341,211.28125 L 341,191 z M 335.0625,191.6875 L 330.5625,192.21875 L 330.5625,211.28125 L 335.0625,211.28125 L 335.0625,191.6875 z M 329.125,192.375 L 324.625,192.90625 L 324.625,211.28125 L 329.125,211.28125 L 329.125,192.375 z M 323.1875,193.0625 L 318.6875,193.59375 L 318.6875,211.28125 L 323.1875,211.28125 L 323.1875,193.0625 z M 317.28125,193.75 L 312.78125,194.28125 L 312.78125,211.28125 L 317.28125,211.28125 L 317.28125,193.75 z M 311.34375,194.4375 L 306.84375,194.9375 L 306.84375,211.28125 L 311.34375,211.28125 L 311.34375,194.4375 z M 305.40625,195.125 L 300.90625,195.625 L 300.90625,211.28125 L 305.40625,211.28125 L 305.40625,195.125 z M 299.46875,195.8125 L 294.96875,196.3125 L 294.96875,211.28125 L 299.46875,211.28125 L 299.46875,195.8125 z M 293.5625,196.46875 L 289.0625,197 L 289.0625,211.28125 L 293.5625,211.28125 L 293.5625,196.46875 z M 287.625,197.15625 L 283.125,197.6875 L 283.125,211.28125 L 287.625,211.28125 L 287.625,197.15625 z M 281.6875,197.84375 L 277.1875,198.375 L 277.1875,211.28125 L 281.6875,211.28125 L 281.6875,197.84375 z M 275.75,198.53125 L 271.25,199.0625 L 271.25,211.28125 L 275.75,211.28125 L 275.75,198.53125 z M 269.84375,199.21875 L 265.34375,199.75 L 265.34375,211.28125 L 269.84375,211.28125 L 269.84375,199.21875 z M 263.90625,199.90625 L 259.40625,200.40625 L 259.40625,211.28125 L 263.90625,211.28125 L 263.90625,199.90625 z M 257.96875,200.59375 L 253.46875,201.09375 L 253.46875,211.28125 L 257.96875,211.28125 L 257.96875,200.59375 z M 252.03125,201.28125 L 247.53125,201.78125 L 247.53125,211.28125 L 252.03125,211.28125 L 252.03125,201.28125 z M 246.125,201.9375 L 241.625,202.46875 L 241.625,211.28125 L 246.125,211.28125 L 246.125,201.9375 z M 240.1875,202.625 L 235.6875,203.15625 L 235.6875,211.28125 L 240.1875,211.28125 L 240.1875,202.625 z M 234.25,203.3125 L 229.75,203.84375 L 229.75,211.28125 L 234.25,211.28125 L 234.25,203.3125 z M 228.3125,204 L 223.8125,204.53125 L 223.8125,211.28125 L 228.3125,211.28125 L 228.3125,204 z "
id="rect2329"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002" />
<g
style="display:inline"
id="g1513"
transform="translate(-19.20344,-0.525199)"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002">
<text
inkscape:export-ydpi="79.120003"
inkscape:export-xdpi="79.120003"
inkscape:export-filename="/home/klaas/text2265.png"
sodipodi:linespacing="125%"
id="text1483"
y="236.06721"
x="243.14836"
style="font-size:11px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="236.06721"
x="243.14836"
id="tspan1485"
sodipodi:role="line">5.23 MiB</tspan></text>
<text
inkscape:export-ydpi="79.120003"
inkscape:export-xdpi="79.120003"
sodipodi:linespacing="125%"
id="text1487"
y="236.98668"
x="244.71114"
style="font-size:11px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:0.3372549;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="236.98668"
x="244.71114"
id="tspan1489"
sodipodi:role="line">5.23 MiB</tspan></text>
</g>
<g
style="display:inline"
id="g1507"
transform="translate(-23.39259,1.70507)"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002">
<text
inkscape:export-ydpi="79.120003"
inkscape:export-xdpi="79.120003"
inkscape:export-filename="/home/klaas/text2265.png"
sodipodi:linespacing="125%"
id="text1499"
y="254.99857"
x="247.33751"
style="font-size:11px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="254.99857"
x="247.33751"
id="tspan1501"
sodipodi:role="line">5.23 MiB</tspan></text>
<text
inkscape:export-ydpi="79.120003"
inkscape:export-xdpi="79.120003"
sodipodi:linespacing="125%"
id="text1503"
y="255.91803"
x="248.90028"
style="font-size:11px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:0.3372549;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="255.91803"
x="248.90028"
id="tspan1505"
sodipodi:role="line">5.23 MiB</tspan></text>
</g>
<g
id="g4280"
transform="translate(6,2)"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002">
<text
inkscape:export-ydpi="79.967331"
inkscape:export-xdpi="79.967331"
inkscape:export-filename="/home/klaas/text2265.png"
sodipodi:linespacing="125%"
id="text2220"
y="201.506"
x="373.29575"
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:0.33333333;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="201.506"
x="373.29575"
id="tspan2222"
sodipodi:role="line">T-Mobile</tspan></text>
<text
inkscape:export-ydpi="79.967331"
inkscape:export-xdpi="79.967331"
inkscape:export-filename="/home/klaas/text2265.png"
sodipodi:linespacing="125%"
id="text2216"
y="200.91589"
x="371.92639"
style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="200.91589"
x="371.92639"
id="tspan2218"
sodipodi:role="line">T-Mobile</tspan></text>
</g>
<g
id="g1423"
transform="translate(85.28446,4.743845)"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002">
<text
inkscape:export-ydpi="79.120003"
inkscape:export-xdpi="79.120003"
sodipodi:linespacing="125%"
id="text1433"
y="254.45566"
x="296.56879"
style="font-size:11px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:0.3372549;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="254.45566"
x="296.56879"
id="tspan1435"
sodipodi:role="line">684 MiB</tspan></text>
<text
inkscape:export-ydpi="79.120003"
inkscape:export-xdpi="79.120003"
inkscape:export-filename="/home/klaas/text2265.png"
sodipodi:linespacing="125%"
id="text1429"
y="253.53619"
x="295.00601"
style="font-size:11px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#a70000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="253.53619"
x="295.00601"
id="tspan1431"
sodipodi:role="line">684 MiB</tspan></text>
</g>
<text
xml:space="preserve"
style="font-size:11px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:0.3372549;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="489.8541"
y="258.88687"
id="text1543"
sodipodi:linespacing="125%"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"><tspan
sodipodi:role="line"
id="tspan1545"
x="489.8541"
y="258.88687">32m 15s</tspan></text>
<text
xml:space="preserve"
style="font-size:11px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
x="488.29132"
y="257.96741"
id="text1547"
sodipodi:linespacing="125%"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002"><tspan
sodipodi:role="line"
id="tspan1549"
x="488.29132"
y="257.96741">32m 15s</tspan></text>
<g
id="g1587"
transform="translate(-4,-2.113121)"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002">
<text
inkscape:export-ydpi="79.120003"
inkscape:export-xdpi="79.120003"
sodipodi:linespacing="125%"
id="text1561"
y="238.14223"
x="292.44498"
style="font-size:11px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:0.3372549;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="238.14223"
x="292.44498"
id="tspan1563"
sodipodi:role="line">24.6 kiB/s</tspan></text>
<text
inkscape:export-ydpi="79.120003"
inkscape:export-xdpi="79.120003"
inkscape:export-filename="/home/klaas/text2265.png"
sodipodi:linespacing="125%"
id="text1557"
y="237.22276"
x="290.8822"
style="font-size:11px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="237.22276"
x="290.8822"
id="tspan1559"
sodipodi:role="line">24.6 kiB/s</tspan></text>
</g>
<g
style="display:inline"
id="g1598"
transform="translate(-3.793473,19.0485)"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002">
<text
inkscape:export-ydpi="79.120003"
inkscape:export-xdpi="79.120003"
sodipodi:linespacing="125%"
id="text1600"
y="238.14223"
x="292.44498"
style="font-size:11px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:0.3372549;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="238.14223"
x="292.44498"
id="tspan1602"
sodipodi:role="line">24.6 kiB/s</tspan></text>
<text
inkscape:export-ydpi="79.120003"
inkscape:export-xdpi="79.120003"
inkscape:export-filename="/home/klaas/text2265.png"
sodipodi:linespacing="125%"
id="text1604"
y="237.22276"
x="290.8822"
style="font-size:11px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
xml:space="preserve"><tspan
y="237.22276"
x="290.8822"
id="tspan1606"
sodipodi:role="line">24.6 kiB/s</tspan></text>
</g>
<g
id="g1552"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002">
<path
id="path6226"
d="M 516.0365,222.76531 L 516.0365,229.89296 L 503.22204,229.89296 L 503.22204,222.76531"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.93842661;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<path
id="path6228"
d="M 500.59162,224.15397 L 509.64212,217.80876 L 518.66692,224.15397"
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:0.93842661;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path6230"
d="M 504.88547,220.64755 L 504.88547,218.44264 C 504.88547,218.4329 505.32697,218.42506 505.87537,218.42506 L 505.87536,218.42506 C 506.42378,218.42506 506.86526,218.4329 506.86526,218.44263 L 506.86526,219.26323"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.93842661;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
</g>
<g
id="g2590"
transform="translate(15.45324,21.79293)"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002">
<path
transform="matrix(0.123502,4.792431e-2,-4.782368e-2,0.123762,466.5917,169.0395)"
d="M 473.02652 102.7753 A 45.93961 45.93961 0 1 1 381.1473,102.7753 A 45.93961 45.93961 0 1 1 473.02652 102.7753 z"
sodipodi:ry="45.93961"
sodipodi:rx="45.93961"
sodipodi:cy="102.7753"
sodipodi:cx="427.08691"
id="path2572"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:6.24312925;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
sodipodi:type="arc" />
<path
transform="matrix(8.77706e-2,3.405885e-2,-4.782368e-2,0.123762,481.8521,174.9613)"
d="M 473.02652 102.7753 A 45.93961 45.93961 0 1 1 381.1473,102.7753 A 45.93961 45.93961 0 1 1 473.02652 102.7753 z"
sodipodi:ry="45.93961"
sodipodi:rx="45.93961"
sodipodi:cy="102.7753"
sodipodi:cx="427.08691"
id="path2574"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:7.40567732;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline"
sodipodi:type="arc" />
<path
transform="matrix(4.400164e-2,1.707469e-2,-4.782368e-2,0.123762,500.5452,182.215)"
d="M 473.02652 102.7753 A 45.93961 45.93961 0 1 1 381.1473,102.7753 A 45.93961 45.93961 0 1 1 473.02652 102.7753 z"
sodipodi:ry="45.93961"
sodipodi:rx="45.93961"
sodipodi:cy="102.7753"
sodipodi:cx="427.08691"
id="path2576"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:10.45934963;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline"
sodipodi:type="arc" />
<path
id="path2578"
d="M 520.11495,200.18299 C 518.57188,200.45182 516.80576,200.28609 515.07391,199.61405 C 513.5654,199.02868 512.29583,198.1418 511.35905,197.10323"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.82769686;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<path
id="path2580"
d="M 517.28099,207.69958 C 516.14073,206.92597 514.61587,206.13593 512.88402,205.4639 C 511.37551,204.87852 509.92291,204.46532 508.6727,204.23783"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.82769686;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" />
<path
id="path2582"
d="M 520.29964,203.71955 C 518.54917,203.94914 516.33649,203.65559 514.09869,202.78722 C 511.95338,201.95475 510.18018,200.74736 509.03315,199.45857"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.82769686;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
</g>
<g
id="g3195"
inkscape:export-filename="/home/klaas/DevRocketWorkspaces/Klaas51/umtsmon-cvs/images/LCDDisplay/LCDBackground.png"
inkscape:export-xdpi="80.080002"
inkscape:export-ydpi="80.080002">
<path
transform="matrix(5.277036e-2,0,0,0.131627,355.3176,184.7067)"
d="M 334.03328,132.29519 L 277.65698,132.29519 L 221.28069,132.29518 L 249.46883,83.471881 L 277.65698,34.648575 L 305.84513,83.471879 L 334.03328,132.29519 z "
inkscape:randomized="0"
inkscape:rounded="0"
inkscape:flatsided="false"
sodipodi:arg2="1.5707963"
sodipodi:arg1="0.52359878"
sodipodi:r2="32.54887"
sodipodi:r1="65.09774"
sodipodi:cy="99.746315"
sodipodi:cx="277.65698"
sodipodi:sides="3"
id="path1445"
style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.05098039"
sodipodi:type="star" />
<path
transform="matrix(5.277036e-2,0,0,0.131627,356.2219,186.0123)"
d="M 334.03328,132.29519 L 277.65698,132.29519 L 221.28069,132.29518 L 249.46883,83.471881 L 277.65698,34.648575 L 305.84513,83.471879 L 334.03328,132.29519 z "
inkscape:randomized="0"
inkscape:rounded="0"
inkscape:flatsided="false"
sodipodi:arg2="1.5707963"
sodipodi:arg1="0.52359878"
sodipodi:r2="32.54887"
sodipodi:r1="65.09774"
sodipodi:cy="99.746315"
sodipodi:cx="277.65698"
sodipodi:sides="3"
id="path2320"
style="opacity:1;fill:#000000;fill-opacity:0.46927377;fill-rule:evenodd;stroke:none;stroke-width:0.60000002;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.05098039;display:inline"
sodipodi:type="star" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -0,0 +1,387 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<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"
width="48px"
height="48px"
id="svg1256"
sodipodi:version="0.32"
inkscape:version="0.43+devel"
sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
sodipodi:docname="address-book-new.svg">
<defs
id="defs3">
<linearGradient
inkscape:collect="always"
id="linearGradient5060">
<stop
style="stop-color:black;stop-opacity:1;"
offset="0"
id="stop5062" />
<stop
style="stop-color:black;stop-opacity:0;"
offset="1"
id="stop5064" />
</linearGradient>
<linearGradient
id="linearGradient5048">
<stop
style="stop-color:black;stop-opacity:0;"
offset="0"
id="stop5050" />
<stop
id="stop5056"
offset="0.5"
style="stop-color:black;stop-opacity:1;" />
<stop
style="stop-color:black;stop-opacity:0;"
offset="1"
id="stop5052" />
</linearGradient>
<linearGradient
id="linearGradient12512">
<stop
style="stop-color:#ffffff;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop12513" />
<stop
style="stop-color:#fff520;stop-opacity:0.89108908;"
offset="0.50000000"
id="stop12517" />
<stop
style="stop-color:#fff300;stop-opacity:0.0000000;"
offset="1.0000000"
id="stop12514" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient12512"
id="radialGradient278"
gradientUnits="userSpaceOnUse"
cx="55.000000"
cy="125.00000"
fx="55.000000"
fy="125.00000"
r="14.375000" />
<linearGradient
inkscape:collect="always"
id="linearGradient2116">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop2118" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop2120" />
</linearGradient>
<linearGradient
id="linearGradient2094">
<stop
style="stop-color:#d6e3f0;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop2096" />
<stop
style="stop-color:#95b1cf;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop2098" />
</linearGradient>
<linearGradient
id="linearGradient2803">
<stop
id="stop2805"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
id="stop2807"
offset="1.0000000"
style="stop-color:#cbcbcb;stop-opacity:1.0000000;" />
</linearGradient>
<linearGradient
id="linearGradient2795">
<stop
id="stop2797"
offset="0.0000000"
style="stop-color:#000000;stop-opacity:0.068627454;" />
<stop
id="stop2799"
offset="1.0000000"
style="stop-color:#ffffff;stop-opacity:1.0000000;" />
</linearGradient>
<linearGradient
gradientUnits="userSpaceOnUse"
y2="4.9530048"
x2="41.219128"
y1="4.9530050"
x1="35.433035"
gradientTransform="matrix(0.254000,0.000000,1.822151e-16,3.759813,0.788629,0.148567)"
id="linearGradient2801"
xlink:href="#linearGradient2795"
inkscape:collect="always" />
<linearGradient
gradientUnits="userSpaceOnUse"
y2="84.287079"
x2="10.219901"
y1="93.338043"
x1="10.496115"
gradientTransform="matrix(2.262742,0.000000,0.000000,0.441942,1.000000,-0.875000)"
id="linearGradient2813"
xlink:href="#linearGradient2803"
inkscape:collect="always" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2094"
id="linearGradient2100"
gradientTransform="matrix(0.957750,0.000000,0.000000,1.027989,1.000000,-0.571911)"
x1="6.5871811"
y1="22.132999"
x2="14.511404"
y2="22.132999"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2116"
id="linearGradient2112"
gradientTransform="matrix(1.025428,0.000000,0.000000,0.957303,0.000000,-0.806758)"
x1="73.361984"
y1="26.652197"
x2="-2.7582901"
y2="21.270376"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5060"
id="radialGradient5013"
gradientUnits="userSpaceOnUse"
cx="605.71429"
cy="486.64789"
fx="605.71429"
fy="486.64789"
r="117.14286"
gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5048"
id="linearGradient5016"
gradientUnits="userSpaceOnUse"
x1="302.85715"
y1="366.64789"
x2="302.85715"
y2="609.50507"
gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5060"
id="radialGradient5020"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
cx="605.71429"
cy="486.64789"
fx="605.71429"
fy="486.64789"
r="117.14286" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5048"
id="linearGradient5027"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
x1="302.85715"
y1="366.64789"
x2="302.85715"
y2="609.50507" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5060"
id="radialGradient5029"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
cx="605.71429"
cy="486.64789"
fx="605.71429"
fy="486.64789"
r="117.14286" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5060"
id="radialGradient5031"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
cx="605.71429"
cy="486.64789"
fx="605.71429"
fy="486.64789"
r="117.14286" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="0.27843137"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="50.475782"
inkscape:cy="10.167608"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="872"
inkscape:window-height="659"
inkscape:window-x="679"
inkscape:window-y="221"
fill="#ef2929"
stroke="#cc0000"
inkscape:showpageshadow="false" />
<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>Addess Book - New</dc:title>
<dc:date />
<dc:creator>
<cc:Agent>
<dc:title>Jakub Steiner</dc:title>
</cc:Agent>
</dc:creator>
<dc:source>http://jimmac.musichall.cz</dc:source>
<dc:subject>
<rdf:Bag>
<rdf:li>address</rdf:li>
<rdf:li>contact</rdf:li>
<rdf:li>book</rdf:li>
</rdf:Bag>
</dc:subject>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/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>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
style="opacity:1;color:#000000;fill:#edd400;fill-opacity:1;fill-rule:evenodd;stroke:#c4a000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 33.096456,4.6520202 L 40.521077,4.6520202 C 41.228184,4.6520202 41.758513,4.8287969 41.93529,5.71268 L 42.819174,12.606972 C 42.907562,13.667632 42.443523,14.021185 41.493349,14.021185 L 32.919679,14.021185 L 33.096456,4.6520202 z "
id="path21630"
sodipodi:nodetypes="ccccccc" />
<path
sodipodi:nodetypes="ccccccc"
id="path21632"
d="M 34.10295,5.638875 L 40.463507,5.638875 C 40.771656,5.638875 40.940266,5.669037 40.986054,5.960473 L 41.777489,12.344449 C 41.847258,12.775421 41.959897,13.019804 41.637211,13.034341 L 33.963412,13.034341 L 34.10295,5.638875 z "
style="opacity:0.48538011;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.0000006;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<path
sodipodi:nodetypes="ccccccc"
id="path21634"
d="M 35.596456,12.40202 L 43.021077,12.40202 C 43.728184,12.40202 44.258513,12.578797 44.43529,13.46268 L 45.319174,20.356972 C 45.407562,21.417632 44.943523,21.771185 43.993349,21.771185 L 35.419679,21.771185 L 35.596456,12.40202 z "
style="opacity:1;color:#000000;fill:#9db029;fill-opacity:1;fill-rule:evenodd;stroke:#727e0a;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<path
style="opacity:0.48538011;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.0000006;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 36.60295,13.388875 L 42.963507,13.388875 C 43.271656,13.388875 43.440266,13.419037 43.486054,13.710473 L 44.277489,20.094449 C 44.347258,20.525421 44.459897,20.769804 44.137211,20.784341 L 36.463412,20.784341 L 36.60295,13.388875 z "
id="path21636"
sodipodi:nodetypes="ccccccc" />
<path
style="opacity:1;color:#000000;fill:#ef2929;fill-opacity:1;fill-rule:evenodd;stroke:#cc0000;stroke-width:0.99999988;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 36.06451,20.776498 L 44.50992,20.776498 C 45.314245,20.776498 45.917487,20.995896 46.118569,22.092882 L 47.123975,30.649381 C 47.224515,31.965765 46.696677,32.40456 45.615866,32.40456 L 35.863428,32.40456 L 36.06451,20.776498 z "
id="path21638"
sodipodi:nodetypes="ccccccc" />
<path
sodipodi:nodetypes="ccccccc"
id="path21640"
d="M 37.209384,21.763574 L 44.444435,21.763574 C 44.79495,21.763574 44.986742,21.801928 45.038825,22.172513 L 45.939072,30.290267 C 46.018433,30.838284 46.146559,31.149038 45.779508,31.167522 L 37.050661,31.167522 L 37.209384,21.763574 z "
style="opacity:0.48538011;color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000072;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<g
id="g5022"
transform="matrix(2.165152e-2,0,0,4.307902e-2,43.08625,34.04509)">
<rect
y="-150.69685"
x="-1559.2523"
height="478.35718"
width="1339.6335"
id="rect4173"
style="opacity:0.40206185;color:black;fill:url(#linearGradient5027);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<path
sodipodi:nodetypes="cccc"
id="path5058"
d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
style="opacity:0.40206185;color:black;fill:url(#radialGradient5029);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<path
style="opacity:0.40206185;color:black;fill:url(#radialGradient5031);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
id="path5018"
sodipodi:nodetypes="cccc" />
</g>
<path
style="color:#000000;fill:#5b6b94;fill-opacity:1;fill-rule:nonzero;stroke:#364878;stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 6.3643222,5.5185897 C 6.4551049,3.6036003 7.3719758,2.5542814 9.0788784,2.549044 L 38.405776,2.4590577 C 38.652361,2.4583011 38.974317,2.6592071 38.999012,2.9089888 L 42.257491,35.867228 L 40.942189,35.923862 L 41.571429,42.369516 C 41.632441,42.994499 41.390059,43.52882 40.5,43.533035 L 9.7893046,43.678474 C 7.25676,43.690468 4.6538454,41.59976 4.7759337,39.024403 L 6.3643222,5.5185897 z "
id="rect1408"
sodipodi:nodetypes="csssccsssss" />
<path
id="path2489"
d="M 40.125,34.875 L 10.9375,35 C 9.3809819,35.177868 8.125,36.39612 8.125,38 C 8.125,39.60388 9.3809819,40.822132 10.9375,41 L 40.125,41.125 L 40.125,41.0625 C 38.469378,40.984348 37.125,39.674851 37.125,38 C 37.125,36.325149 38.469378,35.015652 40.125,34.9375 L 40.125,34.875 z "
style="color:#000000;fill:url(#linearGradient2813);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<path
sodipodi:nodetypes="ccccccssc"
id="path2784"
d="M 9.6875,2.8125 C 7.9805897,2.8125 7.050103,3.8215062 6.96875,5.6738658 L 5.3125,37.825772 C 5.22054,40.904199 7.1393732,42.654485 9.125,43.15625 C 4.875,41.525579 5.4375,34.164455 10.75,34.195222 L 41.648286,34.195222 L 38.335786,3.2432432 C 38.310025,3.0025304 37.987878,2.8125 37.742036,2.8125 L 9.6875,2.8125 z "
style="color:#000000;fill:url(#linearGradient2100);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<rect
y="3.968539"
x="9.7886267"
height="29.604792"
width="2"
id="rect2793"
style="opacity:0.48044691;color:#000000;fill:url(#linearGradient2801);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:0.60818715;visibility:visible;display:inline;overflow:visible"
transform="matrix(1.000000,0.000000,-3.582731e-2,0.999358,0.000000,0.000000)" />
<path
style="color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient2112);stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:20;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 9.8751008,3.3336831 C 8.1912014,3.3336831 7.5384236,4.0658459 7.4581673,5.887831 L 6.1592633,35.777198 C 7.0925916,34.170451 8.5988591,33.594437 11.011665,33.594437 L 40.963081,33.594437 L 38.137179,3.7573631 C 38.114727,3.5203092 37.793961,3.3336831 37.551434,3.3336831 L 9.8751008,3.3336831 z "
id="path2104"
sodipodi:nodetypes="cccscssc" />
<path
style="font-size:12px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:120.00000477%;writing-mode:lr-tb;text-anchor:start;fill:#ad7fa8;fill-opacity:1;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
d="M 21.12553,18.381288 C 21.050283,19.50227 21.269376,20.384155 21.782812,21.026947 C 22.296751,21.661909 23.039741,21.979388 24.011788,21.979387 C 24.97597,21.979388 25.754005,21.65799 26.345892,21.01519 C 26.945589,20.372398 27.282799,19.49443 27.357529,18.381288 C 27.431173,17.283839 27.207372,16.413709 26.686123,15.770905 C 26.165371,15.120279 25.426826,14.794959 24.470482,14.79495 C 23.521952,14.794959 22.743917,15.11636 22.136378,15.759145 C 21.536656,16.401952 21.199707,17.275998 21.12553,18.381288 M 27.29793,21.897075 C 26.787062,22.500679 26.216183,22.947501 25.58529,23.237544 C 24.962734,23.519747 24.247754,23.66085 23.44035,23.660849 C 22.092032,23.66085 21.027197,23.174832 20.245835,22.202797 C 19.472826,21.222925 19.138938,19.949092 19.244172,18.381288 C 19.349395,16.813498 19.858197,15.539665 20.770584,14.559781 C 21.682954,13.579917 22.809375,13.089981 24.149854,13.089969 C 24.957257,13.089981 25.656689,13.238924 26.24815,13.536791 C 26.840107,13.826846 27.347352,14.269749 27.76988,14.865501 L 27.873267,13.325141 L 29.554732,13.325141 L 28.973868,21.979387 C 30.129917,21.806931 31.058551,21.285637 31.759769,20.415508 C 32.469312,19.537544 32.870659,18.404812 32.963808,17.017304 C 33.020082,16.178542 32.947536,15.390722 32.746168,14.653848 C 32.552597,13.916994 32.226018,13.235002 31.766435,12.607873 C 31.020085,11.580979 30.077151,10.79708 28.937625,10.256176 C 27.806428,9.707462 26.551007,9.433097 25.171361,9.433081 C 24.207151,9.433097 23.27347,9.56244 22.370314,9.821111 C 21.467662,10.071974 20.623234,10.448244 19.837027,10.949925 C 18.552629,11.749517 17.517932,12.79994 16.732929,14.101199 C 15.956279,15.394643 15.517185,16.797819 15.415642,18.310738 C 15.331983,19.557142 15.476998,20.725151 15.85069,21.814765 C 16.232213,22.904387 16.822316,23.864664 17.621,24.695594 C 18.389368,25.51085 19.300238,26.130129 20.353615,26.553435 C 21.406448,26.984578 22.54823,27.20015 23.778962,27.200153 C 24.790178,27.20015 25.793384,27.027692 26.788584,26.682781 C 27.791068,26.345701 28.72125,25.859684 29.579139,25.224728 L 30.549801,26.529919 C 29.518874,27.2903 28.409917,27.870384 27.222932,28.270174 C 26.043227,28.677799 24.857618,28.881612 23.666104,28.881616 C 22.215881,28.881612 20.865341,28.622926 19.614483,28.105557 C 18.36308,27.596019 17.268571,26.851316 16.330955,25.871444 C 15.393328,24.89157 14.705054,23.758838 14.266133,22.47324 C 13.827731,21.179813 13.658252,19.792311 13.757696,18.310738 C 13.853452,16.88405 14.211263,15.523986 14.831129,14.230542 C 15.450993,12.937121 16.287663,11.800469 17.34115,10.820582 C 18.419191,9.825045 19.638236,9.0646655 20.998287,8.5394366 C 22.358842,8.0064001 23.779908,7.7398759 25.261489,7.7398585 C 26.923341,7.7398759 28.440813,8.080872 29.813913,8.7628469 C 31.194815,9.444854 32.325282,10.41297 33.205316,11.667193 C 33.741656,12.435425 34.132443,13.270279 34.377679,14.171752 C 34.630708,15.073243 34.724877,16.006082 34.660187,16.970271 C 34.521787,19.031929 33.789414,20.658519 32.463064,21.850041 C 31.136671,23.04157 29.374449,23.66085 27.17639,23.707883 L 27.29793,21.897075"
id="text21625" />
<path
sodipodi:type="arc"
style="color:#000000;fill:url(#radialGradient278);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.25000024;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block"
id="path12511"
sodipodi:cx="55"
sodipodi:cy="125"
sodipodi:rx="14.375"
sodipodi:ry="14.375"
d="M 69.375 125 A 14.375 14.375 0 1 1 40.625,125 A 14.375 14.375 0 1 1 69.375 125 z"
transform="matrix(0.611127,0.000000,0.000000,0.611127,-24.94992,-67.63529)"
inkscape:export-filename="/home/jimmac/ximian_art/icons/nautilus/suse93/stock_new-16.png"
inkscape:export-xdpi="33.852203"
inkscape:export-ydpi="33.852203" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 22 KiB

@ -0,0 +1,245 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<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://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="48.000000px"
height="48.000000px"
id="svg53383"
sodipodi:version="0.32"
inkscape:version="0.43+devel"
sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/categories"
sodipodi:docname="applications-system.svg">
<defs
id="defs3">
<linearGradient
id="linearGradient3264">
<stop
style="stop-color:#c9c9c9;stop-opacity:1;"
offset="0"
id="stop3266" />
<stop
id="stop3276"
offset="0.25"
style="stop-color:#f8f8f8;stop-opacity:1;" />
<stop
id="stop3272"
offset="0.5"
style="stop-color:#e2e2e2;stop-opacity:1;" />
<stop
style="stop-color:#b0b0b0;stop-opacity:1;"
offset="0.75"
id="stop3274" />
<stop
style="stop-color:#c9c9c9;stop-opacity:1;"
offset="1"
id="stop3268" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3264"
id="linearGradient3281"
gradientUnits="userSpaceOnUse"
x1="14.462892"
y1="12.284524"
x2="34.534348"
y2="39.684914"
gradientTransform="matrix(1.241935,0,0,1.241935,-5.027508,-7.208988)" />
<linearGradient
id="linearGradient2300">
<stop
id="stop2302"
offset="0.0000000"
style="stop-color:#000000;stop-opacity:0.32673267;" />
<stop
id="stop2304"
offset="1"
style="stop-color:#000000;stop-opacity:0;" />
</linearGradient>
<linearGradient
id="aigrd1"
gradientUnits="userSpaceOnUse"
x1="99.7773"
y1="15.4238"
x2="153.0005"
y2="248.6311">
<stop
offset="0"
style="stop-color:#184375"
id="stop53300" />
<stop
offset="1"
style="stop-color:#C8BDDC"
id="stop53302" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#aigrd1"
id="linearGradient53551"
gradientUnits="userSpaceOnUse"
x1="99.7773"
y1="15.4238"
x2="153.0005"
y2="248.6311"
gradientTransform="matrix(0.200685,0.000000,0.000000,0.200685,-0.585758,-1.050787)" />
<radialGradient
gradientUnits="userSpaceOnUse"
r="11.689870"
fy="72.568001"
fx="14.287618"
cy="68.872971"
cx="14.287618"
gradientTransform="matrix(1.399258,-2.234445e-7,8.196178e-8,0.513264,4.365074,4.839285)"
id="radialGradient2308"
xlink:href="#linearGradient2300"
inkscape:collect="always" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3264"
id="linearGradient3760"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.241935,0,0,1.241935,-5.027508,-7.208988)"
x1="14.462892"
y1="12.284524"
x2="34.534348"
y2="39.684914" />
<linearGradient
inkscape:collect="always"
xlink:href="#aigrd1"
id="linearGradient3773"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.200685,0,0,0.200685,-54.33576,-1.050787)"
x1="99.7773"
y1="15.4238"
x2="153.0005"
y2="248.6311" />
</defs>
<sodipodi:namedview
inkscape:showpageshadow="false"
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="0.11764706"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.6568542"
inkscape:cx="43.652227"
inkscape:cy="21.164787"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="872"
inkscape:window-height="697"
inkscape:window-x="2398"
inkscape:window-y="249" />
<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>System Applications</dc:title>
<dc:creator>
<cc:Agent>
<dc:title>Jakub Steiner</dc:title>
</cc:Agent>
</dc:creator>
<dc:source>http://jimmac.musichall.cz/</dc:source>
<dc:subject>
<rdf:Bag>
<rdf:li>system</rdf:li>
<rdf:li>applications</rdf:li>
<rdf:li>group</rdf:li>
<rdf:li>category</rdf:li>
<rdf:li>admin</rdf:li>
<rdf:li>root</rdf:li>
</rdf:Bag>
</dc:subject>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by/2.0/" />
</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>
<g
inkscape:label="shadow"
id="layer2"
inkscape:groupmode="layer">
<path
transform="matrix(1.186380,0.000000,0.000000,1.186380,-4.539687,-7.794678)"
d="M 44.285715 38.714287 A 19.928572 9.8372450 0 1 1 4.4285717,38.714287 A 19.928572 9.8372450 0 1 1 44.285715 38.714287 z"
sodipodi:ry="9.8372450"
sodipodi:rx="19.928572"
sodipodi:cy="38.714287"
sodipodi:cx="24.357143"
id="path1538"
style="color:#000000;fill:url(#radialGradient2308);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.50000042;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:inline;overflow:visible"
sodipodi:type="arc" />
</g>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
inkscape:r_cy="true"
inkscape:r_cx="true"
style="opacity:1;color:#000000;fill:url(#linearGradient3773);fill-opacity:1;fill-rule:nonzero;stroke:#3f4561;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 22.699525,0.94746963 C 22.22635,0.97984519 21.766437,1.0531317 21.301673,1.1063165 L 21.269903,1.1063165 L 20.157975,7.1742671 C 18.345621,7.5870046 16.640562,8.2874574 15.106644,9.2392765 L 10.118853,5.6493371 C 8.770521,6.6961412 7.543552,7.9170049 6.465374,9.2392765 L 9.928236,14.290607 C 8.876814,15.89739 8.086153,17.732094 7.640841,19.659632 C 7.640765,19.668743 7.640779,19.689813 7.640841,19.691401 L 1.60466,20.644482 C 1.494303,21.545851 1.445813,22.477386 1.445813,23.408418 C 1.445813,24.170171 1.466846,24.921747 1.541121,25.664043 L 7.577303,26.744202 C 8.0066,28.840363 8.822112,30.797987 9.960006,32.526228 L 6.370066,37.450482 C 7.398201,38.726866 8.585171,39.888962 9.864698,40.913343 L 14.947798,37.418712 C 16.724273,38.551956 18.707343,39.346604 20.856901,39.737877 L 21.809983,45.742288 C 22.487237,45.803935 23.181758,45.805827 23.874992,45.805827 C 24.853677,45.805826 25.788512,45.768738 26.734236,45.64698 L 27.877933,39.515491 C 29.91886,39.007587 31.836112,38.126493 33.501113,36.942172 L 38.393596,40.500342 C 39.662366,39.420897 40.822583,38.180154 41.824689,36.846863 L 38.266519,31.700225 C 39.230125,30.036028 39.897817,28.199859 40.23622,26.235892 L 46.240632,25.282811 C 46.29329,24.656221 46.30417,24.048546 46.30417,23.408418 C 46.30417,22.296018 46.174875,21.205317 46.018246,20.136172 L 39.918526,19.024244 C 39.440518,17.259164 38.656214,15.612364 37.662901,14.13176 L 41.25284,9.2075071 C 40.140075,7.8466524 38.870718,6.5895264 37.472284,5.5222596 L 32.293876,9.0804296 C 30.805549,8.200202 29.203897,7.5248159 27.464931,7.1424978 L 26.51185,1.1063165 C 25.644369,1.0042729 24.769749,0.94746963 23.874992,0.94746963 C 23.633166,0.94746964 23.384286,0.93986063 23.144296,0.94746963 C 23.027301,0.95117908 22.911525,0.94066346 22.794833,0.94746963 C 22.763228,0.94931296 22.73107,0.94531125 22.699525,0.94746963 z M 23.525529,16.387386 C 23.641592,16.381497 23.757473,16.387386 23.874992,16.387386 C 27.635598,16.387386 30.705408,19.457196 30.705408,23.217802 C 30.705409,26.978407 27.635597,30.016448 23.874992,30.016448 C 20.114387,30.016449 17.076346,26.978407 17.076346,23.217802 C 17.076347,19.574716 19.927558,16.569963 23.525529,16.387386 z "
id="path3243" />
<path
inkscape:r_cy="true"
inkscape:r_cx="true"
sodipodi:type="arc"
style="opacity:0.64772728;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.62180054;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path3283"
sodipodi:cx="23.511301"
sodipodi:cy="23.781593"
sodipodi:rx="12.727922"
sodipodi:ry="12.727922"
d="M 36.239223 23.781593 A 12.727922 12.727922 0 1 1 10.783379,23.781593 A 12.727922 12.727922 0 1 1 36.239223 23.781593 z"
transform="matrix(0.616598,0,0,0.616598,9.38202,8.539674)" />
<path
inkscape:r_cy="true"
inkscape:r_cx="true"
id="path3285"
d="M 21.995808,2.1484671 L 21.103024,8.0235243 C 19.404254,8.4103946 16.279442,9.5936035 14.841657,10.485771 L 10.091975,6.9406268 C 8.828145,7.9218257 8.741474,7.9883656 7.730867,9.2277688 L 11.165063,14.320988 C 10.179537,15.827071 8.995796,18.510982 8.570778,20.42893 C 8.570778,20.42893 2.552988,21.443355 2.552988,21.443355 C 2.449547,22.288234 2.49926,24.096528 2.56888,24.792303 L 8.317097,25.82782 C 8.71949,27.79261 10.225324,30.955232 11.291904,32.575161 L 7.656902,37.377719 C 8.620601,38.57411 8.813474,38.683589 10.01281,39.64377 L 14.873441,36.082733 C 16.538581,37.144954 19.84373,38.437109 21.858571,38.80386 L 22.656299,44.604952 C 23.291109,44.662736 25.044829,44.824827 25.931283,44.710701 L 26.824066,38.671821 C 28.737084,38.195749 32.042539,36.838896 33.603191,35.728798 L 38.458624,39.236958 C 39.647878,38.225166 39.658533,38.072709 40.597835,36.822978 L 36.999815,31.708667 C 37.90303,30.148767 39.070902,27.098068 39.388097,25.257187 L 45.279046,24.279744 C 45.328399,23.692424 45.330802,22.054578 45.18399,21.052439 L 39.182092,20.016922 C 38.73404,18.362463 37.196418,15.381153 36.265359,13.993342 L 40.080075,9.1907857 C 39.037052,7.915218 38.64924,7.7402002 37.338448,6.7398212 L 32.313994,10.337839 C 30.918941,9.5127782 28.137095,8.2550417 26.507114,7.8966842 L 25.619528,2.1484671 C 24.806414,2.0528187 22.460488,2.0952921 21.995808,2.1484671 z "
style="opacity:0.34659089;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.99999923;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
sodipodi:nodetypes="ccccccccccccccccccccccccccccccccc" />
<path
style="opacity:0.5;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 10.102903,6.2970655 C 8.7545689,7.3438694 8.1656464,7.9719226 7.0874684,9.2941942 L 10.489927,14.259153 C 9.4385072,15.857755 8.3316275,18.426114 8.1423859,19.987706 C 8.1423859,19.987706 2.0798859,21.0319 2.0798859,21.0319 C 2.0109129,21.595256 1.90625,22.884803 1.90625,22.884803 L 2.0830267,24.447303 C 2.5107567,24.535638 2.9231817,24.617818 3.3642767,24.666053 L 3.8642767,23.134803 C 4.2083177,23.163279 4.5439297,23.197303 4.8955267,23.197303 C 5.2467347,23.197303 5.6139847,23.163473 5.9580267,23.134803 L 6.4267767,24.666053 C 6.8680647,24.617818 7.3115487,24.535638 7.7392767,24.447303 L 7.7392767,22.884803 C 8.4250337,22.72518 9.0712777,22.497045 9.7080267,22.228553 L 10.645527,23.509803 C 11.047878,23.327709 11.421123,23.133984 11.801777,22.916053 L 11.301777,21.416053 C 11.89901,21.053803 12.463529,20.620706 12.989277,20.166053 L 14.270527,21.103553 C 14.596162,20.806973 14.91164,20.491691 15.208027,20.166053 L 14.270527,18.916053 C 14.725373,18.390305 15.127027,17.826171 15.489277,17.228553 L 16.989277,17.697303 C 17.207208,17.316456 17.432571,16.943209 17.614277,16.541053 L 16.333027,15.603553 C 16.601517,14.966804 16.798016,14.320561 16.958027,13.634803 L 18.551777,13.634803 C 18.640112,13.207076 18.691236,12.763591 18.739277,12.322303 L 17.239277,11.853553 C 17.268139,11.509705 17.301777,11.142456 17.301777,10.791053 C 17.301776,10.43965 17.267753,10.104039 17.239277,9.7598034 L 18.739277,9.2910534 C 18.69373,8.8711662 18.633686,8.4490548 18.551777,8.0410534 C 17.404349,8.4403544 15.999117,9.1941729 14.983265,9.8245243 L 10.102903,6.2970655 z "
id="path3767"
inkscape:r_cx="true"
inkscape:r_cy="true"
sodipodi:nodetypes="cccccccccsccccccccccccccccccccsccccc" />
<path
style="opacity:0.5;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 37.236641,17.217754 C 36.85286,17.39913 36.490003,17.603509 36.123236,17.813295 L 36.692886,19.548136 C 35.995792,19.970436 35.338156,20.467825 34.725008,20.998151 L 33.249099,19.910639 C 32.869013,20.256538 32.507327,20.618223 32.161588,20.998151 L 33.249099,22.474059 C 32.718773,23.087371 32.221547,23.745002 31.799084,24.441937 L 31.255328,24.260685 C 31.207646,24.960968 31.018949,25.62217 30.737466,26.228563 L 30.841038,26.306242 C 30.527881,27.048922 30.27649,27.83664 30.090137,28.636624 L 28.614229,28.636624 C 28.477946,28.722076 28.343676,28.821684 28.199938,28.895555 C 28.121568,29.310822 28.065026,29.712881 28.018687,30.138426 L 29.77942,30.708074 C 29.746033,31.10935 29.727633,31.515269 29.727633,31.925052 C 29.727631,32.334993 29.746034,32.740753 29.77942,33.142029 L 28.018687,33.711677 C 28.074705,34.226432 28.148678,34.740347 28.251725,35.239372 L 30.090137,35.213479 C 30.218255,35.763466 30.393202,36.320918 30.582107,36.844746 C 31.327023,36.557466 32.05594,36.214561 32.731236,35.809021 C 32.319649,34.59298 32.083908,33.279913 32.083908,31.925052 C 32.083909,26.727119 35.376289,22.288397 39.981313,20.583861 L 38.893802,20.402608 C 38.671014,19.579946 38.382478,18.774017 38.013435,18.020441 C 38.002581,17.998277 37.99851,17.96486 37.987542,17.942761 L 37.935756,17.890975 L 37.236641,17.217754 z "
id="path3770"
inkscape:r_cx="true"
inkscape:r_cy="true" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 44 KiB

@ -0,0 +1,376 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<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://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="48.000000px"
height="48.000000px"
id="svg249"
sodipodi:version="0.32"
inkscape:version="0.43+devel"
sodipodi:docbase="/home/tigert/cvs/freedesktop.org/tango-icon-theme/scalable/actions"
sodipodi:docname="document-new.svg"
inkscape:export-filename="/home/jimmac/gfx/novell/pdes/trunk/docs/BIGmime-text.png"
inkscape:export-xdpi="240.00000"
inkscape:export-ydpi="240.00000"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs3">
<linearGradient
inkscape:collect="always"
id="linearGradient4542">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop4544" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop4546" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4542"
id="radialGradient4548"
cx="24.306795"
cy="42.07798"
fx="24.306795"
fy="42.07798"
r="15.821514"
gradientTransform="matrix(1.000000,0.000000,0.000000,0.284916,-6.310056e-16,30.08928)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient15662">
<stop
style="stop-color:#ffffff;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop15664" />
<stop
style="stop-color:#f8f8f8;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop15666" />
</linearGradient>
<radialGradient
gradientUnits="userSpaceOnUse"
fy="64.5679"
fx="20.8921"
r="5.257"
cy="64.5679"
cx="20.8921"
id="aigrd3">
<stop
id="stop15573"
style="stop-color:#F0F0F0"
offset="0" />
<stop
id="stop15575"
style="stop-color:#9a9a9a;stop-opacity:1.0000000;"
offset="1.0000000" />
</radialGradient>
<radialGradient
gradientUnits="userSpaceOnUse"
fy="114.5684"
fx="20.8921"
r="5.256"
cy="114.5684"
cx="20.8921"
id="aigrd2">
<stop
id="stop15566"
style="stop-color:#F0F0F0"
offset="0" />
<stop
id="stop15568"
style="stop-color:#9a9a9a;stop-opacity:1.0000000;"
offset="1.0000000" />
</radialGradient>
<linearGradient
id="linearGradient269">
<stop
style="stop-color:#a3a3a3;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop270" />
<stop
style="stop-color:#4c4c4c;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop271" />
</linearGradient>
<linearGradient
id="linearGradient259">
<stop
style="stop-color:#fafafa;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop260" />
<stop
style="stop-color:#bbbbbb;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop261" />
</linearGradient>
<linearGradient
id="linearGradient12512">
<stop
style="stop-color:#ffffff;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop12513" />
<stop
style="stop-color:#fff520;stop-opacity:0.89108908;"
offset="0.50000000"
id="stop12517" />
<stop
style="stop-color:#fff300;stop-opacity:0.0000000;"
offset="1.0000000"
id="stop12514" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient12512"
id="radialGradient278"
gradientUnits="userSpaceOnUse"
cx="55.000000"
cy="125.00000"
fx="55.000000"
fy="125.00000"
r="14.375000" />
<radialGradient
r="37.751713"
fy="3.7561285"
fx="8.8244190"
cy="3.7561285"
cx="8.8244190"
gradientTransform="matrix(0.968273,0.000000,0.000000,1.032767,3.353553,0.646447)"
gradientUnits="userSpaceOnUse"
id="radialGradient15656"
xlink:href="#linearGradient269"
inkscape:collect="always" />
<radialGradient
r="86.708450"
fy="35.736916"
fx="33.966679"
cy="35.736916"
cx="33.966679"
gradientTransform="scale(0.960493,1.041132)"
gradientUnits="userSpaceOnUse"
id="radialGradient15658"
xlink:href="#linearGradient259"
inkscape:collect="always" />
<radialGradient
r="38.158695"
fy="7.2678967"
fx="8.1435566"
cy="7.2678967"
cx="8.1435566"
gradientTransform="matrix(0.968273,0.000000,0.000000,1.032767,3.353553,0.646447)"
gradientUnits="userSpaceOnUse"
id="radialGradient15668"
xlink:href="#linearGradient15662"
inkscape:collect="always" />
<radialGradient
inkscape:collect="always"
xlink:href="#aigrd2"
id="radialGradient2283"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.229703,0.000000,0.000000,0.229703,4.613529,3.979808)"
cx="20.8921"
cy="114.5684"
fx="20.8921"
fy="114.5684"
r="5.256" />
<radialGradient
inkscape:collect="always"
xlink:href="#aigrd3"
id="radialGradient2285"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.229703,0.000000,0.000000,0.229703,4.613529,3.979808)"
cx="20.8921"
cy="64.5679"
fx="20.8921"
fy="64.5679"
r="5.257" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="0.32941176"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="11.89103"
inkscape:cy="19.443159"
inkscape:current-layer="layer6"
showgrid="false"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="812"
inkscape:window-height="636"
inkscape:window-x="166"
inkscape:window-y="151"
inkscape:showpageshadow="false" />
<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>New Document</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-sa/2.0/" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/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>
<g
inkscape:label="Shadow"
id="layer6"
inkscape:groupmode="layer">
<path
sodipodi:type="arc"
style="opacity:0.56725147;color:#000000;fill:url(#radialGradient4548);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path3667"
sodipodi:cx="24.306795"
sodipodi:cy="42.07798"
sodipodi:rx="15.821514"
sodipodi:ry="4.5078058"
d="M 40.128309 42.07798 A 15.821514 4.5078058 0 1 1 8.485281,42.07798 A 15.821514 4.5078058 0 1 1 40.128309 42.07798 z"
transform="matrix(1.167598,0.000000,0.000000,1.000000,-4.692487,0.618717)" />
</g>
<g
id="layer1"
inkscape:label="Base"
inkscape:groupmode="layer"
style="display:inline">
<rect
ry="1.1490486"
y="3.6464462"
x="6.6035528"
height="40.920494"
width="34.875000"
id="rect15391"
style="color:#000000;fill:url(#radialGradient15658);fill-opacity:1.0000000;fill-rule:nonzero;stroke:url(#radialGradient15656);stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible" />
<rect
rx="0.14904857"
ry="0.14904857"
y="4.5839462"
x="7.6660538"
height="38.946384"
width="32.775887"
id="rect15660"
style="color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:nonzero;stroke:url(#radialGradient15668);stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block;overflow:visible" />
<g
id="g2270"
transform="translate(0.646447,-3.798933e-2)">
<g
transform="matrix(0.229703,0.000000,0.000000,0.229703,4.967081,4.244972)"
style="fill:#ffffff;fill-opacity:1.0000000;fill-rule:nonzero;stroke:#000000;stroke-miterlimit:4.0000000"
id="g1440">
<radialGradient
gradientUnits="userSpaceOnUse"
fy="114.56840"
fx="20.892099"
r="5.2560000"
cy="114.56840"
cx="20.892099"
id="radialGradient1442">
<stop
id="stop1444"
style="stop-color:#F0F0F0"
offset="0" />
<stop
id="stop1446"
style="stop-color:#474747"
offset="1" />
</radialGradient>
<path
id="path1448"
d="M 23.428000,113.07000 C 23.428000,115.04300 21.828000,116.64200 19.855000,116.64200 C 17.881000,116.64200 16.282000,115.04200 16.282000,113.07000 C 16.282000,111.09600 17.882000,109.49700 19.855000,109.49700 C 21.828000,109.49700 23.428000,111.09700 23.428000,113.07000 z "
style="stroke:none" />
<radialGradient
gradientUnits="userSpaceOnUse"
fy="64.567902"
fx="20.892099"
r="5.2570000"
cy="64.567902"
cx="20.892099"
id="radialGradient1450">
<stop
id="stop1452"
style="stop-color:#F0F0F0"
offset="0" />
<stop
id="stop1454"
style="stop-color:#474747"
offset="1" />
</radialGradient>
<path
id="path1456"
d="M 23.428000,63.070000 C 23.428000,65.043000 21.828000,66.643000 19.855000,66.643000 C 17.881000,66.643000 16.282000,65.043000 16.282000,63.070000 C 16.282000,61.096000 17.882000,59.497000 19.855000,59.497000 C 21.828000,59.497000 23.428000,61.097000 23.428000,63.070000 z "
style="stroke:none" />
</g>
<path
id="path15570"
d="M 9.9950109,29.952326 C 9.9950109,30.405530 9.6274861,30.772825 9.1742821,30.772825 C 8.7208483,30.772825 8.3535532,30.405301 8.3535532,29.952326 C 8.3535532,29.498892 8.7210780,29.131597 9.1742821,29.131597 C 9.6274861,29.131597 9.9950109,29.499122 9.9950109,29.952326 z "
style="fill:url(#radialGradient2283);fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000" />
<path
id="path15577"
d="M 9.9950109,18.467176 C 9.9950109,18.920380 9.6274861,19.287905 9.1742821,19.287905 C 8.7208483,19.287905 8.3535532,18.920380 8.3535532,18.467176 C 8.3535532,18.013742 8.7210780,17.646447 9.1742821,17.646447 C 9.6274861,17.646447 9.9950109,18.013972 9.9950109,18.467176 z "
style="fill:url(#radialGradient2285);fill-rule:nonzero;stroke:none;stroke-miterlimit:4.0000000" />
</g>
<path
sodipodi:nodetypes="cc"
id="path15672"
d="M 11.505723,5.4942766 L 11.505723,43.400869"
style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.98855311;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:0.017543854" />
<path
sodipodi:nodetypes="cc"
id="path15674"
d="M 12.500000,5.0205154 L 12.500000,43.038228"
style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:0.20467831" />
</g>
<g
inkscape:groupmode="layer"
id="layer4"
inkscape:label="new"
style="display:inline">
<path
sodipodi:type="arc"
style="color:#000000;fill:url(#radialGradient278);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.2500002;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;display:block"
id="path12511"
sodipodi:cx="55.000000"
sodipodi:cy="125.00000"
sodipodi:rx="14.375000"
sodipodi:ry="14.375000"
d="M 69.375000 125.00000 A 14.375000 14.375000 0 1 1 40.625000,125.00000 A 14.375000 14.375000 0 1 1 69.375000 125.00000 z"
transform="matrix(0.783292,0.000000,0.000000,0.783292,-6.340883,-86.65168)"
inkscape:export-filename="/home/jimmac/ximian_art/icons/nautilus/suse93/stock_new-16.png"
inkscape:export-xdpi="33.852203"
inkscape:export-ydpi="33.852203" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 14 KiB

@ -0,0 +1,546 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<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://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
sodipodi:docname="document-save.svg"
sodipodi:docbase="/home/jimmac/gfx/ximian/tango-icon-theme/scalable/actions"
inkscape:version="0.42+devel"
sodipodi:version="0.32"
id="svg2913"
height="48px"
width="48px">
<defs
id="defs3">
<linearGradient
inkscape:collect="always"
id="linearGradient6925">
<stop
style="stop-color:#204a87;stop-opacity:1;"
offset="0"
id="stop6927" />
<stop
style="stop-color:#204a87;stop-opacity:0;"
offset="1"
id="stop6929" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient6901">
<stop
style="stop-color:#3465a4;stop-opacity:1;"
offset="0"
id="stop6903" />
<stop
style="stop-color:#3465a4;stop-opacity:0;"
offset="1"
id="stop6905" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient4991">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop4993" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop4995" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4991"
id="radialGradient4997"
cx="23.447077"
cy="6.4576745"
fx="23.447077"
fy="6.4576745"
r="19.0625"
gradientTransform="matrix(-1.314471,-1.006312e-2,-1.022964e-2,1.336221,46.22108,-4.909887)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient2187"
inkscape:collect="always">
<stop
id="stop2189"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
id="stop2191"
offset="1"
style="stop-color:#ffffff;stop-opacity:0;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2187"
id="linearGradient1764"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.914114,1.412791e-16,-1.412791e-16,0.914114,-3.868698,-2.706902)"
x1="33.059906"
y1="27.394117"
x2="12.624337"
y2="12.583769" />
<linearGradient
inkscape:collect="always"
id="linearGradient8662">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop8664" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop8666" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8662"
id="radialGradient8668"
cx="24.837126"
cy="36.421127"
fx="24.837126"
fy="36.421127"
r="15.644737"
gradientTransform="matrix(1.000000,-7.816467e-32,-1.132409e-32,0.536723,-5.897962e-14,16.87306)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient2555">
<stop
id="stop2557"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
style="stop-color:#e6e6e6;stop-opacity:1.0000000;"
offset="0.50000000"
id="stop2561" />
<stop
id="stop2563"
offset="0.75000000"
style="stop-color:#ffffff;stop-opacity:1.0000000;" />
<stop
style="stop-color:#e1e1e1;stop-opacity:1.0000000;"
offset="0.84166664"
id="stop2565" />
<stop
id="stop2559"
offset="1.0000000"
style="stop-color:#ffffff;stop-opacity:1.0000000;" />
</linearGradient>
<linearGradient
id="linearGradient4274">
<stop
style="stop-color:#ffffff;stop-opacity:0.25490198;"
offset="0.0000000"
id="stop4276" />
<stop
style="stop-color:#ffffff;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop4278" />
</linearGradient>
<linearGradient
id="linearGradient4264"
inkscape:collect="always">
<stop
id="stop4266"
offset="0"
style="stop-color:#000000;stop-opacity:1;" />
<stop
id="stop4268"
offset="1"
style="stop-color:#000000;stop-opacity:0;" />
</linearGradient>
<linearGradient
id="linearGradient4254"
inkscape:collect="always">
<stop
id="stop4256"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
id="stop4258"
offset="1"
style="stop-color:#ffffff;stop-opacity:0;" />
</linearGradient>
<linearGradient
id="linearGradient4244">
<stop
id="stop4246"
offset="0.0000000"
style="stop-color:#e4e4e4;stop-opacity:1.0000000;" />
<stop
id="stop4248"
offset="1.0000000"
style="stop-color:#d3d3d3;stop-opacity:1.0000000;" />
</linearGradient>
<linearGradient
id="linearGradient4236"
inkscape:collect="always">
<stop
id="stop4238"
offset="0"
style="stop-color:#eeeeee;stop-opacity:1;" />
<stop
id="stop4240"
offset="1"
style="stop-color:#eeeeee;stop-opacity:0;" />
</linearGradient>
<linearGradient
id="linearGradient4228">
<stop
id="stop4230"
offset="0.0000000"
style="stop-color:#bbbbbb;stop-opacity:1.0000000;" />
<stop
id="stop4232"
offset="1.0000000"
style="stop-color:#9f9f9f;stop-opacity:1.0000000;" />
</linearGradient>
<linearGradient
id="linearGradient4184">
<stop
id="stop4186"
offset="0.0000000"
style="stop-color:#838383;stop-opacity:1.0000000;" />
<stop
id="stop4188"
offset="1.0000000"
style="stop-color:#bbbbbb;stop-opacity:0.0000000;" />
</linearGradient>
<linearGradient
gradientTransform="translate(0.795493,3.799180)"
y2="35.281250"
x2="24.687500"
y1="35.281250"
x1="7.0625000"
gradientUnits="userSpaceOnUse"
id="linearGradient4209"
xlink:href="#linearGradient4184"
inkscape:collect="always" />
<linearGradient
gradientUnits="userSpaceOnUse"
y2="40.943935"
x2="36.183067"
y1="28.481176"
x1="7.6046205"
id="linearGradient4234"
xlink:href="#linearGradient4228"
inkscape:collect="always"
gradientTransform="translate(0.000000,5.125000)" />
<linearGradient
gradientUnits="userSpaceOnUse"
y2="33.758667"
x2="12.221823"
y1="37.205811"
x1="12.277412"
id="linearGradient4242"
xlink:href="#linearGradient4236"
inkscape:collect="always"
gradientTransform="translate(0.000000,5.125000)" />
<radialGradient
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.286242,0.781698,-0.710782,1.169552,-2.354348,0.248140)"
r="20.935817"
fy="2.9585190"
fx="15.571491"
cy="2.9585190"
cx="15.571491"
id="radialGradient4250"
xlink:href="#linearGradient4244"
inkscape:collect="always" />
<linearGradient
gradientUnits="userSpaceOnUse"
y2="47.620636"
x2="44.096100"
y1="4.4331360"
x1="12.378357"
id="linearGradient4260"
xlink:href="#linearGradient4254"
inkscape:collect="always"
gradientTransform="translate(0.000000,5.125000)" />
<radialGradient
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.000000,0.000000,0.000000,0.651032,-2.885063e-16,9.455693)"
r="23.555494"
fy="27.096155"
fx="23.201941"
cy="27.096155"
cx="23.201941"
id="radialGradient4270"
xlink:href="#linearGradient4264"
inkscape:collect="always" />
<linearGradient
gradientUnits="userSpaceOnUse"
y2="26.357183"
x2="23.688078"
y1="11.318835"
x1="23.688078"
id="linearGradient4272"
xlink:href="#linearGradient4274"
inkscape:collect="always"
gradientTransform="translate(0.000000,5.125000)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2555"
id="linearGradient2553"
x1="33.431175"
y1="31.964777"
x2="21.747974"
y2="11.780679"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient6901"
id="linearGradient6907"
x1="14.751649"
y1="15.868432"
x2="8.8953285"
y2="16.743431"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient6925"
id="linearGradient6931"
x1="12.25"
y1="18.25"
x2="7"
y2="21.118431"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
inkscape:window-y="178"
inkscape:window-x="462"
inkscape:window-height="907"
inkscape:window-width="999"
inkscape:document-units="px"
inkscape:grid-bbox="true"
showgrid="true"
inkscape:current-layer="layer1"
inkscape:cy="11.891468"
inkscape:cx="28.318495"
inkscape:zoom="16"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
borderopacity="0.22745098"
bordercolor="#666666"
pagecolor="#ffffff"
id="base"
inkscape:showpageshadow="false"
fill="#3465a4"
stroke="#204a87" />
<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>Save</dc:title>
<dc:creator>
<cc:Agent>
<dc:title>Jakub Steiner</dc:title>
</cc:Agent>
</dc:creator>
<dc:subject>
<rdf:Bag>
<rdf:li>hdd</rdf:li>
<rdf:li>hard drive</rdf:li>
<rdf:li>save</rdf:li>
<rdf:li>io</rdf:li>
<rdf:li>store</rdf:li>
</rdf:Bag>
</dc:subject>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
<dc:identifier />
<dc:source>http://jimmac.musichall.cz</dc:source>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/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>
<g
inkscape:label="pix"
id="layer2"
inkscape:groupmode="layer">
<path
transform="matrix(1.052533,0.000000,0.000000,0.363113,-0.511757,31.99486)"
d="M 46.757435 27.096155 A 23.555494 15.335379 0 1 1 -0.35355377,27.096155 A 23.555494 15.335379 0 1 1 46.757435 27.096155 z"
sodipodi:ry="15.335379"
sodipodi:rx="23.555494"
sodipodi:cy="27.096155"
sodipodi:cx="23.201941"
id="path4262"
style="opacity:0.56000001;color:#000000;fill:url(#radialGradient4270);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
sodipodi:type="arc" />
<path
sodipodi:nodetypes="cccsccccccccc"
id="path4196"
d="M 11.28569,13.087628 C 10.66069,13.087628 10.254441,13.377808 10.004442,13.931381 C 10.004441,13.931381 3.5356915,31.034938 3.5356915,31.034938 C 3.5356915,31.034938 3.2856915,31.706497 3.2856915,32.816188 C 3.2856915,32.816188 3.2856915,42.466156 3.2856915,42.466156 C 3.2856915,43.548769 3.943477,44.091158 4.9419415,44.091156 L 43.50444,44.091156 C 44.489293,44.091156 45.09819,43.372976 45.09819,42.247406 L 45.09819,32.597438 C 45.09819,32.597438 45.204153,31.827015 45.00444,31.284938 L 38.28569,14.087631 C 38.101165,13.575725 37.648785,13.099533 37.16069,13.087628 L 11.28569,13.087628 z "
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#535353;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccccccccc"
id="path4170"
d="M 3.2735915,32.121812 L 4.0381936,31.429597 L 41.647883,31.492097 L 45.11029,31.809395 L 45.11029,42.247927 C 45.11029,43.373496 44.503272,44.091258 43.518419,44.091258 L 4.9354314,44.091258 C 3.9369667,44.091258 3.2735915,43.549207 3.2735915,42.466594 L 3.2735915,32.121812 z "
style="fill:url(#linearGradient4234);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.02044296px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="csccccccs"
id="path3093"
d="M 3.5490842,31.039404 C 2.8347985,32.50369 3.5484686,33.432261 4.5847985,33.432261 C 4.5847985,33.432261 43.584797,33.432261 43.584797,33.432261 C 44.703844,33.408451 45.430035,32.420356 45.013368,31.289403 L 38.299082,14.078704 C 38.114558,13.566798 37.64432,13.090606 37.156225,13.078701 L 11.299083,13.078701 C 10.674083,13.078701 10.263369,13.382274 10.01337,13.935847 C 10.01337,13.935847 3.5490842,31.039404 3.5490842,31.039404 z "
style="fill:url(#radialGradient4250);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<rect
y="36.299183"
x="7.857996"
height="5.5625"
width="17.625"
id="rect4174"
style="opacity:1;color:#000000;fill:url(#linearGradient4209);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.40899992;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<path
sodipodi:nodetypes="cscc"
id="path4194"
d="M 7.8579947,41.86168 C 7.8579947,41.86168 7.8579947,37.850195 7.8579947,37.850195 C 9.6935221,41.029421 16.154485,41.86168 20.795492,41.86168 C 20.795492,41.86168 7.8579947,41.86168 7.8579947,41.86168 z "
style="opacity:0.81142853;fill:url(#linearGradient4242);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccccccc"
id="path4201"
d="M 44.796162,30.753688 C 44.859684,32.003662 44.382159,33.069528 43.474046,33.097438 C 43.474046,33.097438 5.3553296,33.097437 5.3553297,33.097438 C 4.0660978,33.097438 3.4875937,32.772491 3.271279,32.229382 C 3.3630404,33.173714 4.0970964,33.878688 5.3553297,33.878688 C 5.3553296,33.878687 43.474046,33.878688 43.474046,33.878688 C 44.550053,33.845617 45.226851,32.454664 44.82621,30.883897 L 44.796162,30.753688 z "
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
id="path4211"
d="M 10.96875,15.28125 C 10.922675,15.481571 10.78125,15.668047 10.78125,15.875 C 10.78125,16.823605 11.37223,17.664474 12.125,18.46875 C 12.365268,18.314675 12.490117,18.114342 12.75,17.96875 C 11.809691,17.152746 11.196604,16.252168 10.96875,15.28125 z M 37.625,15.28125 C 37.396273,16.250866 36.782988,17.153676 35.84375,17.96875 C 36.117894,18.122332 36.247738,18.33699 36.5,18.5 C 37.257262,17.693344 37.8125,16.826956 37.8125,15.875 C 37.8125,15.668047 37.670906,15.481571 37.625,15.28125 z M 39.8125,23.71875 C 39.198709,27.758861 32.513887,30.96875 24.28125,30.96875 C 16.068996,30.968751 9.4211001,27.775964 8.78125,23.75 C 8.7488928,23.947132 8.65625,24.141882 8.65625,24.34375 C 8.6562503,28.661697 15.645354,32.187501 24.28125,32.1875 C 32.917146,32.1875 39.937499,28.661698 39.9375,24.34375 C 39.9375,24.130826 39.848449,23.926394 39.8125,23.71875 z "
style="opacity:0.69142857;color:#000000;fill:url(#linearGradient4272);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<path
transform="translate(8.838843e-2,5.301780)"
d="M 8.5736699 25.593554 A 1.3700194 1.016466 0 1 1 5.833631,25.593554 A 1.3700194 1.016466 0 1 1 8.5736699 25.593554 z"
sodipodi:ry="1.016466"
sodipodi:rx="1.3700194"
sodipodi:cy="25.593554"
sodipodi:cx="7.2036505"
id="path4224"
style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:0.45762706;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
sodipodi:type="arc" />
<path
sodipodi:type="arc"
style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:0.45762706;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path4226"
sodipodi:cx="7.2036505"
sodipodi:cy="25.593554"
sodipodi:rx="1.3700194"
sodipodi:ry="1.016466"
d="M 8.5736699 25.593554 A 1.3700194 1.016466 0 1 1 5.833631,25.593554 A 1.3700194 1.016466 0 1 1 8.5736699 25.593554 z"
transform="translate(33.96705,5.213390)" />
<path
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4260);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 11.642515,13.540723 C 11.040823,13.540723 10.649724,13.820081 10.409049,14.35301 C 10.409048,14.35301 3.9940341,30.943732 3.9940341,30.943732 C 3.9940341,30.943732 3.7533573,31.590247 3.7533573,32.658555 C 3.7533573,32.658555 3.7533573,41.948651 3.7533573,41.948651 C 3.7533573,43.303391 4.1974134,43.57555 5.3478414,43.57555 L 43.034746,43.57555 C 44.357872,43.57555 44.569062,43.259153 44.569062,41.738058 L 44.569062,32.447962 C 44.569062,32.447962 44.671072,31.706271 44.478807,31.184409 L 37.885616,14.378434 C 37.707973,13.885617 37.334964,13.552184 36.865071,13.540723 L 11.642515,13.540723 z "
id="path4252"
sodipodi:nodetypes="cccsccccccccc" />
<path
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000048px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:0.42372885"
d="M 40.5,36.554166 L 40.5,41.575101"
id="path4282" />
<path
id="path4284"
d="M 38.5,36.613943 L 38.5,41.634878"
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000048px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:0.42372885" />
<path
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000048px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:0.42372885"
d="M 36.5,36.613943 L 36.5,41.634878"
id="path4286" />
<path
id="path4288"
d="M 34.5,36.613943 L 34.5,41.634878"
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000048px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:0.42372885" />
<path
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000048px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:0.42372885"
d="M 32.5,36.613943 L 32.5,41.634878"
id="path4290" />
<path
id="path4292"
d="M 30.5,36.613943 L 30.5,41.634878"
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.00000048px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:0.42372885" />
<path
id="path4294"
d="M 39.5,36.604065 L 39.5,41.625"
style="opacity:0.09714284;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000048px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="opacity:0.09714284;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000048px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
d="M 37.5,36.663842 L 37.5,41.684777"
id="path4296" />
<path
id="path4298"
d="M 35.5,36.663842 L 35.5,41.684777"
style="opacity:0.09714284;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000048px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="opacity:0.09714284;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000048px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1"
d="M 33.5,36.663842 L 33.5,41.684777"
id="path4300" />
<path
id="path4302"
d="M 31.5,36.663842 L 31.5,41.684777"
style="opacity:0.09714284;fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000048px;stroke-linecap:square;stroke-linejoin:miter;stroke-opacity:1" />
<path
id="path4572"
d="M 7.875,36.3125 L 7.875,41.84375 L 20.4375,41.84375 L 8.21875,41.5 L 7.875,36.3125 z "
style="opacity:0.43999999;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:type="arc"
style="opacity:0.20571427;color:#000000;fill:url(#linearGradient2553);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.93365198;stroke-linecap:square;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.42372879;visibility:visible;display:inline;overflow:visible"
id="path2545"
sodipodi:cx="25"
sodipodi:cy="19.5625"
sodipodi:rx="14.875"
sodipodi:ry="6.6875"
d="M 39.875 19.5625 A 14.875 6.6875 0 1 1 10.125,19.5625 A 14.875 6.6875 0 1 1 39.875 19.5625 z"
transform="matrix(1.037815,0.000000,0.000000,1.060747,-1.632878,3.030370)" />
</g>
<g
inkscape:groupmode="layer"
id="layer1"
inkscape:label="down">
<path
transform="matrix(1.130190,1.178179e-16,7.918544e-17,-0.759601,-3.909725,53.66554)"
d="M 40.481863 36.421127 A 15.644737 8.3968935 0 1 1 9.1923885,36.421127 A 15.644737 8.3968935 0 1 1 40.481863 36.421127 z"
sodipodi:ry="8.3968935"
sodipodi:rx="15.644737"
sodipodi:cy="36.421127"
sodipodi:cx="24.837126"
id="path8660"
style="opacity:0.14117647;color:#000000;fill:url(#radialGradient8668);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
sodipodi:type="arc" />
<path
style="opacity:1;color:#000000;fill:url(#linearGradient6907);fill-opacity:1.0;fill-rule:nonzero;stroke:url(#linearGradient6931);stroke-width:0.99999982;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
d="M 3.2034501,25.835194 C 2.1729477,-5.3853369 28.741616,-0.4511153 28.582416,15.788689 L 35.89533,15.788689 L 24.517652,28.774671 L 12.585426,15.788689 C 12.585426,15.788689 20.126859,15.788689 20.126859,15.788689 C 20.583921,4.8193225 3.4092324,1.6100346 3.2034501,25.835194 z "
id="path1432"
sodipodi:nodetypes="ccccccc" />
<path
sodipodi:nodetypes="ccccccc"
id="path2177"
d="M 7.6642103,9.1041047 C 12.40638,-0.0400306 28.122336,2.7175443 27.761604,16.579393 L 34.078976,16.579393 C 34.078976,16.579393 24.513151,27.536769 24.513151,27.536769 L 14.41668,16.579393 C 14.41668,16.579393 20.87332,16.579393 20.87332,16.579393 C 21.144975,5.0041615 10.922265,5.5345215 7.6642103,9.1041047 z "
style="opacity:0.47159091;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient1764);stroke-width:0.99999934;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible" />
<path
style="opacity:0.49431817;color:#000000;fill:url(#radialGradient4997);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.9999997;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 34.767155,16.211613 L 32.782979,18.757322 C 27.372947,17.241029 24.896829,21.486664 17.109284,20.489112 L 13.247998,16.080077 L 20.434468,16.162862 C 20.483219,4.3164571 8.3443098,4.998966 5.0292663,13.627829 C 8.8372201,-1.2611216 27.893316,0.8064118 28.28332,16.114112 L 34.767155,16.211613 z "
id="path4989"
sodipodi:nodetypes="cccccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 26 KiB

@ -0,0 +1,213 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<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://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="48.000000px"
height="48.000000px"
id="svg6361"
sodipodi:version="0.32"
inkscape:version="0.43+devel"
sodipodi:docbase="/home/tigert/cvs/freedesktop.org/tango-icon-theme/scalable/apps"
sodipodi:docname="help-browser.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs3">
<linearGradient
id="linearGradient2431">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop2433" />
<stop
style="stop-color:#b8b8b8;stop-opacity:1;"
offset="1"
id="stop2435" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient21644">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop21646" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop21648" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient21644"
id="radialGradient21650"
cx="25.125"
cy="36.75"
fx="25.125"
fy="36.75"
r="15.75"
gradientTransform="matrix(1.000000,0.000000,0.000000,0.595238,3.369686e-16,14.87500)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient2933">
<stop
id="stop2935"
offset="0"
style="stop-color:#9cbcde;stop-opacity:1" />
<stop
id="stop2937"
offset="1"
style="stop-color:#204a87" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2933"
id="radialGradient2207"
cx="26.544321"
cy="28.458725"
fx="26.544321"
fy="28.458725"
r="22.376116"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.238342,5.954846e-3,-6.507762e-3,1.351272,-6.992513,-9.744842)" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient2431"
id="radialGradient2437"
cx="-19.515638"
cy="16.855663"
fx="-19.515638"
fy="16.855663"
r="8.7536434"
gradientTransform="matrix(4.445991,-8.852599e-16,1.367217e-15,6.8665,67.25071,-104.6679)"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
inkscape:guide-bbox="true"
showguides="true"
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="0.15294118"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="25.160747"
inkscape:cy="22.523569"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1014"
inkscape:window-height="1122"
inkscape:window-x="178"
inkscape:window-y="25"
inkscape:showpageshadow="false"
fill="#deb887"
gridcolor="#7171cd"
gridopacity="0.12156863"
gridempcolor="#7b7bc3"
gridempopacity="0.5372549"
gridempspacing="10"
stroke="#204a87" />
<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>Help Browser</dc:title>
<dc:date>2005-11-06</dc:date>
<dc:creator>
<cc:Agent>
<dc:title>Tuomas Kuosmanen</dc:title>
</cc:Agent>
</dc:creator>
<dc:subject>
<rdf:Bag>
<rdf:li>help</rdf:li>
<rdf:li>browser</rdf:li>
<rdf:li>documentation</rdf:li>
<rdf:li>docs</rdf:li>
<rdf:li>man</rdf:li>
<rdf:li>info</rdf:li>
</rdf:Bag>
</dc:subject>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
<dc:contributor>
<cc:Agent>
<dc:title>Jakub Steiner, Andreas Nilsson</dc:title>
</cc:Agent>
</dc:contributor>
<dc:source>http://tigert.com</dc:source>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/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>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
sodipodi:type="arc"
style="opacity:0.63068181;color:#000000;fill:url(#radialGradient21650);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
id="path21642"
sodipodi:cx="25.125000"
sodipodi:cy="36.750000"
sodipodi:rx="15.750000"
sodipodi:ry="9.3750000"
d="M 40.875000 36.750000 A 15.750000 9.3750000 0 1 1 9.3750000,36.750000 A 15.750000 9.3750000 0 1 1 40.875000 36.750000 z"
transform="matrix(1.173803,0.000000,0.000000,0.600000,-5.004403,20.32500)" />
<path
sodipodi:type="arc"
style="fill:url(#radialGradient2207);fill-opacity:1.0000000;stroke:#204a87"
id="path2093"
sodipodi:cx="23.909048"
sodipodi:cy="23.825787"
sodipodi:rx="21.876116"
sodipodi:ry="21.876116"
d="M 45.785164 23.825787 A 21.876116 21.876116 0 1 1 2.0329323,23.825787 A 21.876116 21.876116 0 1 1 45.785164 23.825787 z"
transform="matrix(0.938442,0.000000,0.000000,0.938680,1.564075,1.633906)" />
<path
transform="matrix(0.855103,0.000000,0.000000,0.855213,3.555288,3.625019)"
d="M 45.785164 23.825787 A 21.876116 21.876116 0 1 1 2.0329323,23.825787 A 21.876116 21.876116 0 1 1 45.785164 23.825787 z"
sodipodi:ry="21.876116"
sodipodi:rx="21.876116"
sodipodi:cy="23.825787"
sodipodi:cx="23.909048"
id="path2209"
style="fill:none;fill-opacity:1.0000000;stroke:#ffffff;stroke-width:3.0307744;stroke-miterlimit:4.0000000;stroke-dasharray:none;stroke-opacity:1.0000000;opacity:0.96022727"
sodipodi:type="arc" />
<path
sodipodi:type="inkscape:offset"
inkscape:radius="0.13495015"
inkscape:original="M -20.25 6 C -21.298341 6.000026 -22.372769 6.1244771 -23.5 6.34375 C -24.627244 6.563073 -25.886043 6.8832479 -27.25 7.34375 L -27.25 12.5 C -26.100219 11.776335 -24.997109 11.236862 -23.9375 10.875 C -22.877902 10.502213 -21.881822 10.312521 -20.96875 10.3125 C -19.999334 10.312521 -19.259834 10.530174 -18.71875 10.96875 C -18.177686 11.396402 -17.906262 12.013726 -17.90625 12.78125 C -17.906261 13.285654 -18.039408 13.776881 -18.34375 14.28125 C -18.636843 14.785651 -19.107484 15.33609 -19.75 15.90625 L -20.84375 16.84375 C -22.038631 17.918325 -22.815518 18.829509 -23.1875 19.53125 C -23.559495 20.22205 -23.750005 21.007137 -23.75 21.90625 L -23.75 22.71875 L -17.65625 22.71875 L -17.65625 21.96875 C -17.656262 21.475338 -17.517981 21.030712 -17.28125 20.625 C -17.044542 20.208345 -16.547785 19.648586 -15.78125 18.96875 L -14.71875 18.03125 C -13.659161 17.055386 -12.908389 16.156813 -12.46875 15.3125 C -12.029144 14.457253 -11.781268 13.480828 -11.78125 12.40625 C -11.781268 10.311973 -12.525902 8.7417969 -13.96875 7.65625 C -15.41163 6.559783 -17.499549 6.0000261 -20.25 6 z M -23.75 25.15625 L -23.75 31 L -17.65625 31 L -17.65625 25.15625 L -23.75 25.15625 z "
xlink:href="#text2215"
style="font-size:34.15322876px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:url(#radialGradient2437);fill-opacity:1;stroke:#ffffff;stroke-width:1.09947276px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.78612713;font-family:Bitstream Vera Sans"
id="path1554"
d="M -20.25,5.875 C -21.309019,5.8750263 -22.397637,5.9982356 -23.53125,6.21875 C -24.664175,6.4391783 -25.911412,6.7562625 -27.28125,7.21875 C -27.291632,7.21754 -27.302118,7.21754 -27.3125,7.21875 C -27.324563,7.2273788 -27.335121,7.237937 -27.34375,7.25 C -27.355813,7.2586288 -27.366371,7.269187 -27.375,7.28125 C -27.37621,7.2916315 -27.37621,7.3021185 -27.375,7.3125 C -27.37621,7.3228815 -27.37621,7.3333685 -27.375,7.34375 L -27.375,12.5 C -27.37621,12.510382 -27.37621,12.520868 -27.375,12.53125 C -27.37621,12.541632 -27.37621,12.552118 -27.375,12.5625 C -27.366371,12.574563 -27.355813,12.585121 -27.34375,12.59375 C -27.335121,12.605813 -27.324563,12.616371 -27.3125,12.625 C -27.302118,12.62621 -27.291632,12.62621 -27.28125,12.625 C -27.270868,12.62621 -27.260382,12.62621 -27.25,12.625 C -27.239618,12.62621 -27.229132,12.62621 -27.21875,12.625 C -27.208368,12.62621 -27.197882,12.62621 -27.1875,12.625 C -26.045062,11.905957 -24.954148,11.357862 -23.90625,11 C -22.858109,10.631244 -21.863134,10.437521 -20.96875,10.4375 C -20.019532,10.437521 -19.323825,10.648045 -18.8125,11.0625 C -18.303777,11.46459 -18.031262,12.04554 -18.03125,12.78125 C -18.03126,13.261907 -18.175438,13.73266 -18.46875,14.21875 C -18.751741,14.705766 -19.209015,15.249245 -19.84375,15.8125 L -20.9375,16.75 C -22.138959,17.83049 -22.926743,18.741022 -23.3125,19.46875 C -23.695613,20.180196 -23.875005,20.988074 -23.875,21.90625 L -23.875,22.71875 C -23.87621,22.729132 -23.87621,22.739618 -23.875,22.75 C -23.87621,22.760382 -23.87621,22.770868 -23.875,22.78125 C -23.866371,22.793313 -23.855813,22.803871 -23.84375,22.8125 C -23.835121,22.824563 -23.824563,22.835121 -23.8125,22.84375 C -23.802118,22.84496 -23.791632,22.84496 -23.78125,22.84375 C -23.770868,22.84496 -23.760382,22.84496 -23.75,22.84375 L -17.65625,22.84375 C -17.645868,22.84496 -17.635382,22.84496 -17.625,22.84375 C -17.614618,22.84496 -17.604132,22.84496 -17.59375,22.84375 C -17.581687,22.835121 -17.571129,22.824563 -17.5625,22.8125 C -17.550437,22.803871 -17.539879,22.793313 -17.53125,22.78125 C -17.53004,22.770868 -17.53004,22.760382 -17.53125,22.75 C -17.53004,22.739618 -17.53004,22.729132 -17.53125,22.71875 L -17.53125,21.96875 C -17.531261,21.500554 -17.38288,21.075901 -17.15625,20.6875 C -16.933955,20.296216 -16.448177,19.737141 -15.6875,19.0625 L -14.625,18.125 C -13.558412,17.14269 -12.794341,16.240346 -12.34375,15.375 C -11.894481,14.500954 -11.656268,13.50158 -11.65625,12.40625 C -11.656268,10.279985 -12.400019,8.6722224 -13.875,7.5625 C -15.350197,6.4414748 -17.48124,5.8750263 -20.25,5.875 z M -23.8125,25.03125 C -23.824563,25.039879 -23.835121,25.050437 -23.84375,25.0625 C -23.855813,25.071129 -23.866371,25.081687 -23.875,25.09375 C -23.87621,25.104132 -23.87621,25.114618 -23.875,25.125 C -23.87621,25.135382 -23.87621,25.145868 -23.875,25.15625 L -23.875,31 C -23.87621,31.010382 -23.87621,31.020868 -23.875,31.03125 C -23.87621,31.041632 -23.87621,31.052118 -23.875,31.0625 C -23.866371,31.074563 -23.855813,31.085121 -23.84375,31.09375 C -23.835121,31.105813 -23.824563,31.116371 -23.8125,31.125 C -23.802118,31.12621 -23.791632,31.12621 -23.78125,31.125 C -23.770868,31.12621 -23.760382,31.12621 -23.75,31.125 L -17.65625,31.125 C -17.645868,31.12621 -17.635382,31.12621 -17.625,31.125 C -17.614618,31.12621 -17.604132,31.12621 -17.59375,31.125 C -17.581687,31.116371 -17.571129,31.105813 -17.5625,31.09375 C -17.550437,31.085121 -17.539879,31.074563 -17.53125,31.0625 C -17.53004,31.052118 -17.53004,31.041632 -17.53125,31.03125 C -17.53004,31.020868 -17.53004,31.010382 -17.53125,31 L -17.53125,25.15625 C -17.53004,25.145868 -17.53004,25.135382 -17.53125,25.125 C -17.53004,25.114618 -17.53004,25.104132 -17.53125,25.09375 C -17.539879,25.081687 -17.550437,25.071129 -17.5625,25.0625 C -17.571129,25.050437 -17.581687,25.039879 -17.59375,25.03125 C -17.604132,25.03004 -17.614618,25.03004 -17.625,25.03125 C -17.635382,25.03004 -17.645868,25.03004 -17.65625,25.03125 L -23.75,25.03125 C -23.760382,25.03004 -23.770868,25.03004 -23.78125,25.03125 C -23.791632,25.03004 -23.802118,25.03004 -23.8125,25.03125 z "
transform="matrix(0.849895,0,0,0.835205,41.72981,8.548327)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

@ -0,0 +1,462 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<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="mail-message-new.svg"
sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
inkscape:version="0.43+devel"
sodipodi:version="0.32"
id="svg5816"
height="48px"
width="48px">
<defs
id="defs3">
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5060"
id="radialGradient5031"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
cx="605.71429"
cy="486.64789"
fx="605.71429"
fy="486.64789"
r="117.14286" />
<linearGradient
inkscape:collect="always"
id="linearGradient5060">
<stop
style="stop-color:black;stop-opacity:1;"
offset="0"
id="stop5062" />
<stop
style="stop-color:black;stop-opacity:0;"
offset="1"
id="stop5064" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5060"
id="radialGradient5029"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
cx="605.71429"
cy="486.64789"
fx="605.71429"
fy="486.64789"
r="117.14286" />
<linearGradient
id="linearGradient5048">
<stop
style="stop-color:black;stop-opacity:0;"
offset="0"
id="stop5050" />
<stop
id="stop5056"
offset="0.5"
style="stop-color:black;stop-opacity:1;" />
<stop
style="stop-color:black;stop-opacity:0;"
offset="1"
id="stop5052" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5048"
id="linearGradient5027"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
x1="302.85715"
y1="366.64789"
x2="302.85715"
y2="609.50507" />
<linearGradient
id="linearGradient2274">
<stop
style="stop-color:#000000;stop-opacity:0.12871288;"
offset="0.0000000"
id="stop2276" />
<stop
style="stop-color:#000000;stop-opacity:0.0000000;"
offset="1.0000000"
id="stop2278" />
</linearGradient>
<linearGradient
id="linearGradient9749">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop9751" />
<stop
style="stop-color:#ededed;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop9753" />
</linearGradient>
<linearGradient
id="linearGradient2152">
<stop
style="stop-color:#9aa29a;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop2154" />
<stop
style="stop-color:#b5beb5;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop2156" />
</linearGradient>
<linearGradient
id="linearGradient2166">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop2168" />
<stop
style="stop-color:#dcdcdc;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop2170" />
</linearGradient>
<linearGradient
id="linearGradient18913">
<stop
style="stop-color:#ededed;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop18915" />
<stop
style="stop-color:#c8c8c8;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop18917" />
</linearGradient>
<linearGradient
id="linearGradient2136">
<stop
style="stop-color:#989690;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop2138" />
<stop
style="stop-color:#656460;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop2140" />
</linearGradient>
<linearGradient
id="linearGradient15107">
<stop
style="stop-color:#ffffff;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop15109" />
<stop
style="stop-color:#e2e2e2;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop15111" />
</linearGradient>
<linearGradient
id="linearGradient10691"
inkscape:collect="always">
<stop
id="stop10693"
offset="0"
style="stop-color:#000000;stop-opacity:1;" />
<stop
id="stop10695"
offset="1"
style="stop-color:#000000;stop-opacity:0;" />
</linearGradient>
<radialGradient
r="7.2284161"
fy="73.615714"
fx="6.7027131"
cy="73.615714"
cx="6.7027131"
gradientTransform="scale(1.902215,0.525703)"
gradientUnits="userSpaceOnUse"
id="radialGradient11382"
xlink:href="#linearGradient10691"
inkscape:collect="always" />
<linearGradient
y2="32.203162"
x2="9.7619219"
y1="37.784682"
x1="8.7803760"
gradientTransform="matrix(2.394900,0.000000,0.000000,0.781058,2.879512,0.343005)"
gradientUnits="userSpaceOnUse"
id="linearGradient27463"
xlink:href="#linearGradient2274"
inkscape:collect="always" />
<linearGradient
y2="24.132717"
x2="21.111549"
y1="13.686079"
x1="11.233107"
gradientTransform="matrix(1.370928,0.000000,0.000000,1.443758,2.431133,-0.140786)"
gradientUnits="userSpaceOnUse"
id="linearGradient27468"
xlink:href="#linearGradient9749"
inkscape:collect="always" />
<linearGradient
y2="52.090678"
x2="9.8855033"
y1="37.197018"
x1="8.9156475"
gradientTransform="matrix(2.454781,0.000000,0.000000,0.762004,2.879512,0.343005)"
gradientUnits="userSpaceOnUse"
id="linearGradient27471"
xlink:href="#linearGradient2152"
inkscape:collect="always" />
<linearGradient
y2="52.090678"
x2="9.8855033"
y1="37.197018"
x1="8.9156475"
gradientTransform="matrix(2.454781,0.000000,0.000000,0.762004,2.879512,0.343005)"
gradientUnits="userSpaceOnUse"
id="linearGradient27474"
xlink:href="#linearGradient2152"
inkscape:collect="always" />
<linearGradient
y2="29.568739"
x2="15.310744"
y1="15.148383"
x1="10.184240"
gradientTransform="matrix(1.819266,0.000000,0.000000,1.028193,2.879512,0.343005)"
gradientUnits="userSpaceOnUse"
id="linearGradient27477"
xlink:href="#linearGradient2166"
inkscape:collect="always" />
<linearGradient
y2="17.876846"
x2="13.467486"
y1="7.2310905"
x1="5.8266134"
gradientTransform="matrix(1.570607,0.000000,0.000000,1.190976,2.879512,0.343005)"
gradientUnits="userSpaceOnUse"
id="linearGradient27483"
xlink:href="#linearGradient18913"
inkscape:collect="always" />
<linearGradient
y2="26.022910"
x2="18.475286"
y1="4.7461626"
x1="11.572842"
gradientTransform="matrix(1.343475,0.000000,0.000000,1.417854,2.879511,0.314599)"
gradientUnits="userSpaceOnUse"
id="linearGradient27486"
xlink:href="#linearGradient15107"
inkscape:collect="always" />
<linearGradient
y2="15.257116"
x2="30.599684"
y1="15.257116"
x1="2.0618774"
gradientTransform="matrix(1.343475,0.000000,0.000000,1.417854,2.879511,0.314599)"
gradientUnits="userSpaceOnUse"
id="linearGradient27488"
xlink:href="#linearGradient2136"
inkscape:collect="always" />
<linearGradient
id="linearGradient12512">
<stop
id="stop12513"
offset="0.0000000"
style="stop-color:#ffffff;stop-opacity:1.0000000;" />
<stop
id="stop12517"
offset="0.50000000"
style="stop-color:#fff520;stop-opacity:0.89108908;" />
<stop
id="stop12514"
offset="1.0000000"
style="stop-color:#fff300;stop-opacity:0.0000000;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient12512"
id="radialGradient1558"
gradientUnits="userSpaceOnUse"
cx="55.000000"
cy="125.00000"
fx="55.000000"
fy="125.00000"
r="14.375000" />
</defs>
<sodipodi:namedview
inkscape:window-y="0"
inkscape:window-x="89"
inkscape:window-height="743"
inkscape:window-width="872"
inkscape:document-units="px"
inkscape:grid-bbox="true"
showgrid="false"
inkscape:current-layer="layer1"
inkscape:cy="18.816166"
inkscape:cx="28.384904"
inkscape:zoom="1"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
borderopacity="1.0"
bordercolor="#666666"
pagecolor="#ffffff"
id="base"
inkscape:showpageshadow="false" />
<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>Mail New</dc:title>
<dc:creator>
<cc:Agent>
<dc:title>Jakub Steiner</dc:title>
</cc:Agent>
</dc:creator>
<dc:contributor>
<cc:Agent>
<dc:title>Andreas Nilsson, Steven Garrity</dc:title>
</cc:Agent>
</dc:contributor>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
<dc:subject>
<rdf:Bag>
<rdf:li>mail</rdf:li>
<rdf:li>e-mail</rdf:li>
<rdf:li>MUA</rdf:li>
</rdf:Bag>
</dc:subject>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/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>
<g
inkscape:groupmode="layer"
inkscape:label="Layer 1"
id="layer1">
<g
style="display:inline"
id="g5022"
transform="matrix(2.312904e-2,0,0,1.485743e-2,45.32054,39.61432)">
<rect
y="-150.69685"
x="-1559.2523"
height="478.35718"
width="1339.6335"
id="rect4173"
style="opacity:0.40206185;color:black;fill:url(#linearGradient5027);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<path
sodipodi:nodetypes="cccc"
id="path5058"
d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
style="opacity:0.40206185;color:black;fill:url(#radialGradient5029);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<path
style="opacity:0.40206185;color:black;fill:url(#radialGradient5031);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
id="path5018"
sodipodi:nodetypes="cccc" />
</g>
<path
style="fill:url(#linearGradient27486);fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient27488);stroke-width:0.85660440;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
d="M 6.3334395,16.972251 L 6.3334395,41.481799 L 43.305555,41.481799 L 43.244499,17.089859 C 43.241050,15.712272 31.395999,2.4121110 29.210877,2.4121110 L 20.659391,2.4121110 C 18.362072,2.4121110 6.3334395,15.673953 6.3334395,16.972251 z "
id="path12723"
sodipodi:nodetypes="ccczzzz" />
<path
style="fill:url(#linearGradient27483);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.25000000pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
d="M 6.9230610,16.787103 C 6.5250222,16.356975 18.809966,3.0935378 20.667210,3.0935378 L 29.042965,3.0935378 C 30.790449,3.0935378 43.079567,16.221603 42.470079,16.978956 L 31.608858,30.475150 L 19.295373,30.156846 L 6.9230610,16.787103 z "
id="path18153"
sodipodi:nodetypes="czzzccz" />
<path
style="fill:#000000;fill-opacity:0.14619882;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
d="M 19.077530,30.017590 L 11.744526,21.271586 L 36.562951,14.335513 L 39.592221,20.551966 L 32.175956,29.992298"
id="path2164"
sodipodi:nodetypes="ccccc" />
<path
style="fill:#000000;fill-opacity:0.14619882;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
d="M 18.291767,29.836259 L 10.809167,21.026146 L 35.456637,14.132812 L 38.630714,20.403811 L 31.390193,29.810968"
id="path2162"
sodipodi:nodetypes="ccccc" />
<path
style="fill:#000000;fill-opacity:0.14619882;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
d="M 18.775313,29.957146 L 11.100386,21.296624 L 36.068405,14.232329 L 39.354114,20.824726 L 31.873739,29.931855"
id="path2160"
sodipodi:nodetypes="ccccc" />
<path
style="fill:url(#linearGradient27477);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
d="M 18.593984,30.440693 L 11.260975,21.694689 L 35.972554,14.801355 L 39.083369,21.188770 L 31.963198,30.174701"
id="path15105"
sodipodi:nodetypes="ccccc" />
<path
style="fill:url(#linearGradient27474);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
d="M 20.488434,29.064331 L 7.0924698,40.036319 L 21.001312,30.432013 L 30.019470,30.432013 L 42.438517,39.914206 L 30.575092,29.064331 L 20.488434,29.064331 z "
id="path14245"
sodipodi:nodetypes="ccccccc" />
<path
style="color:#000000;fill:url(#linearGradient27471);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
d="M 6.9634751,16.885144 L 18.479648,31.201334 L 19.548151,30.346532 L 6.9634751,16.885144 z "
id="path14339"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-opacity:0.75000000;fill-rule:evenodd;stroke:url(#linearGradient27468);stroke-width:0.85660428;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
d="M 7.3077115,17.131415 L 7.3388644,40.342421 L 42.283659,40.342421 L 42.221353,17.257512 C 42.219329,16.508413 31.005032,3.4591863 28.837233,3.4591863 L 20.941579,3.4591863 C 18.689313,3.4591863 7.3066655,16.351067 7.3077115,17.131415 z "
id="path15103"
sodipodi:nodetypes="ccczzzz" />
<path
style="fill:#ffffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4.0000000;stroke-opacity:1.0000000"
d="M 20.957271,30.452732 L 9.0157722,38.723588 L 11.235205,38.729695 L 21.233330,31.860755 L 30.055238,30.437917 L 20.957271,30.452732 z "
id="path17393"
sodipodi:nodetypes="cccccc" />
<path
style="fill:#ffffff;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
d="M 11.427536,21.670296 L 12.752479,23.080719 L 35.543311,16.196529 L 38.458445,21.878896 L 39.072496,21.166981 L 36.003081,14.789145 L 11.427536,21.670296 z "
id="path2174"
sodipodi:nodetypes="ccccccc" />
<path
style="fill:url(#linearGradient27463);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1.0000000"
d="M 13.308098,23.636340 L 19.334450,30.090093 L 20.531174,29.064331 L 30.617831,29.107071 L 31.429893,29.833651 L 35.404721,25.089502 C 34.250740,23.679081 13.308098,23.636340 13.308098,23.636340 z "
id="path2272"
sodipodi:nodetypes="ccccccc" />
<path
sodipodi:nodetypes="cccc"
id="path27492"
d="M 41.812936,17.847945 L 31.861315,30.479232 L 30.792812,29.624431 L 41.812936,17.847945 z "
style="color:#000000;fill:#b1b1b1;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
<g
id="layer4"
inkscape:label="new"
style="display:inline"
transform="translate(5.000000e-7,2.500000e-6)">
<path
sodipodi:type="arc"
style="color:#000000;fill:url(#radialGradient1558);fill-opacity:1.0000000;fill-rule:nonzero;stroke:none;stroke-width:1.2500002;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4.0000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:block"
id="path12511"
sodipodi:cx="55.000000"
sodipodi:cy="125.00000"
sodipodi:rx="14.375000"
sodipodi:ry="14.375000"
d="M 69.375000 125.00000 A 14.375000 14.375000 0 1 1 40.625000,125.00000 A 14.375000 14.375000 0 1 1 69.375000 125.00000 z"
transform="matrix(0.783292,0.000000,0.000000,0.783292,-6.340883,-86.65168)"
inkscape:export-filename="/home/jimmac/ximian_art/icons/nautilus/suse93/stock_new-16.png"
inkscape:export-xdpi="33.852203"
inkscape:export-ydpi="33.852203" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 20 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 72 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 61 KiB

@ -0,0 +1,323 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<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"
inkscape:export-ydpi="90.000000"
inkscape:export-xdpi="90.000000"
inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
width="48px"
height="48px"
id="svg11300"
sodipodi:version="0.32"
inkscape:version="0.43+devel"
sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/devices"
sodipodi:docname="network-wireless.svg">
<defs
id="defs3">
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5060"
id="radialGradient6719"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
cx="605.71429"
cy="486.64789"
fx="605.71429"
fy="486.64789"
r="117.14286" />
<linearGradient
inkscape:collect="always"
id="linearGradient5060">
<stop
style="stop-color:black;stop-opacity:1;"
offset="0"
id="stop5062" />
<stop
style="stop-color:black;stop-opacity:0;"
offset="1"
id="stop5064" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5060"
id="radialGradient6717"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
cx="605.71429"
cy="486.64789"
fx="605.71429"
fy="486.64789"
r="117.14286" />
<linearGradient
id="linearGradient5048">
<stop
style="stop-color:black;stop-opacity:0;"
offset="0"
id="stop5050" />
<stop
id="stop5056"
offset="0.5"
style="stop-color:black;stop-opacity:1;" />
<stop
style="stop-color:black;stop-opacity:0;"
offset="1"
id="stop5052" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5048"
id="linearGradient6715"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
x1="302.85715"
y1="366.64789"
x2="302.85715"
y2="609.50507" />
<linearGradient
id="linearGradient11520">
<stop
id="stop11522"
offset="0.0000000"
style="stop-color:#ffffff;stop-opacity:1.0000000;" />
<stop
id="stop11524"
offset="1.0000000"
style="stop-color:#dcdcdc;stop-opacity:1.0000000;" />
</linearGradient>
<linearGradient
id="linearGradient11508"
inkscape:collect="always">
<stop
id="stop11510"
offset="0"
style="stop-color:#000000;stop-opacity:1;" />
<stop
id="stop11512"
offset="1"
style="stop-color:#000000;stop-opacity:0;" />
</linearGradient>
<linearGradient
id="linearGradient11494"
inkscape:collect="always">
<stop
id="stop11496"
offset="0"
style="stop-color:#ef2929;stop-opacity:1;" />
<stop
id="stop11498"
offset="1"
style="stop-color:#ef2929;stop-opacity:0;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient11508"
id="radialGradient1348"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.000000,0.000000,0.000000,0.338462,-1.435476e-15,29.48178)"
cx="30.203562"
cy="44.565483"
fx="30.203562"
fy="44.565483"
r="6.5659914" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient11494"
id="radialGradient1352"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.243453,2.106784e-16,-2.106784e-16,1.243453,-6.713754,-3.742847)"
cx="27.577173"
cy="16.049133"
fx="27.577173"
fy="16.049133"
r="3.8335034" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient11494"
id="radialGradient1354"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.243453,2.106784e-16,-2.106784e-16,1.243453,-6.713754,-3.742847)"
cx="27.577173"
cy="15.048258"
fx="27.577173"
fy="15.048258"
r="3.8335034" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient11508"
id="radialGradient1356"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.000000,0.000000,0.000000,0.338462,2.220359e-14,29.48178)"
cx="30.203562"
cy="44.565483"
fx="30.203562"
fy="44.565483"
r="6.5659914" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient11520"
id="radialGradient1366"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.995058,-1.651527e-32,0.000000,1.995058,-24.32488,-35.70087)"
cx="24.445690"
cy="35.878170"
fx="24.445690"
fy="35.878170"
r="20.530962" />
</defs>
<sodipodi:namedview
stroke="#ef2929"
fill="#eeeeec"
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="0.25490196"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="7.0000000"
inkscape:cx="23.818102"
inkscape:cy="22.612601"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:showpageshadow="false"
inkscape:window-width="876"
inkscape:window-height="875"
inkscape:window-x="198"
inkscape:window-y="115" />
<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: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-sa/2.0/" />
<dc:title>Wi-Fi network</dc:title>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/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>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<g
transform="matrix(2.243425e-2,0,0,2.086758e-2,44.31095,40.86789)"
id="g6707">
<rect
style="opacity:0.40206185;color:black;fill:url(#linearGradient6715);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="rect6709"
width="1339.6335"
height="478.35718"
x="-1559.2523"
y="-150.69685" />
<path
style="opacity:0.40206185;color:black;fill:url(#radialGradient6717);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
id="path6711"
sodipodi:nodetypes="cccc" />
<path
sodipodi:nodetypes="cccc"
id="path6713"
d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
style="opacity:0.40206185;color:black;fill:url(#radialGradient6719);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
</g>
<rect
ry="5.4548240"
rx="5.4548240"
y="3.5233452"
x="4.4147282"
height="40.061924"
width="40.061924"
id="rect11518"
style="opacity:1.0000000;color:#000000;fill:url(#radialGradient1366);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#9b9b9b;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
<path
style="opacity:1.0000000;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:1.0000004;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
d="M 20.224903,38.955668 L 24.819938,24.359674 L 30.135763,38.955668"
id="path11486"
sodipodi:nodetypes="ccc" />
<path
transform="matrix(0.689220,0.000000,0.000000,0.689220,5.768155,11.06900)"
d="M 30.910667 18.604561 A 3.3335035 3.3335035 0 1 1 24.243660,18.604561 A 3.3335035 3.3335035 0 1 1 30.910667 18.604561 z"
sodipodi:ry="3.3335035"
sodipodi:rx="3.3335035"
sodipodi:cy="18.604561"
sodipodi:cx="27.577164"
id="path11482"
style="opacity:1.0000000;color:#000000;fill:#ef2929;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:0.99999982;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
sodipodi:type="arc" />
<path
sodipodi:type="arc"
style="opacity:1.0000000;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#radialGradient1352);stroke-width:1.1812764;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
id="path11488"
sodipodi:cx="27.577164"
sodipodi:cy="18.604561"
sodipodi:rx="3.3335035"
sodipodi:ry="3.3335035"
d="M 30.910667 18.604561 A 3.3335035 3.3335035 0 1 1 24.243660,18.604561 A 3.3335035 3.3335035 0 1 1 30.910667 18.604561 z"
transform="matrix(2.382303,0.000000,0.000000,2.382303,-40.92229,-20.43007)" />
<path
transform="matrix(4.657608,0.000000,0.000000,4.657608,-103.6690,-62.76113)"
d="M 30.910667 18.604561 A 3.3335035 3.3335035 0 1 1 24.243660,18.604561 A 3.3335035 3.3335035 0 1 1 30.910667 18.604561 z"
sodipodi:ry="3.3335035"
sodipodi:rx="3.3335035"
sodipodi:cy="18.604561"
sodipodi:cx="27.577164"
id="path11490"
style="opacity:1.0000000;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#radialGradient1354);stroke-width:0.60420674;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
sodipodi:type="arc" />
<path
transform="matrix(1.567741,0.000000,0.000000,1.567741,-22.25656,-31.99559)"
d="M 36.769553 44.565483 A 6.5659914 2.2223356 0 1 1 23.637570,44.565483 A 6.5659914 2.2223356 0 1 1 36.769553 44.565483 z"
sodipodi:ry="2.2223356"
sodipodi:rx="6.5659914"
sodipodi:cy="44.565483"
sodipodi:cx="30.203562"
id="path11506"
style="opacity:0.17647059;color:#000000;fill:url(#radialGradient1356);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:2.8141584;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
sodipodi:type="arc" />
<path
id="path11516"
d="M 23.812108,28.571856 L 26.719573,29.426992 L 22.443890,32.334457 L 28.258818,33.873702 L 21.075671,36.781167 L 29.627037,37.636304"
style="opacity:1.0000000;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#000000;stroke-width:1.0000004;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
<rect
style="opacity:1.0000000;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.99999976;stroke-linecap:butt;stroke-linejoin:bevel;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
id="rect11528"
width="37.696587"
height="37.696587"
x="5.5973887"
y="4.7060070"
rx="4.2426391"
ry="4.2426391" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 15 KiB

@ -0,0 +1,362 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<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://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:export-ydpi="90.000000"
inkscape:export-xdpi="90.000000"
inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
width="48px"
height="48px"
id="svg11300"
sodipodi:version="0.32"
inkscape:version="0.43+devel"
sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
sodipodi:docname="system-log-out.svg">
<defs
id="defs3">
<linearGradient
id="linearGradient9896">
<stop
id="stop9898"
offset="0"
style="stop-color:#cecece;stop-opacity:1;" />
<stop
id="stop9900"
offset="1.0000000"
style="stop-color:#9e9e9e;stop-opacity:1.0000000;" />
</linearGradient>
<linearGradient
id="linearGradient9888"
inkscape:collect="always">
<stop
id="stop9890"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
id="stop9892"
offset="1"
style="stop-color:#ffffff;stop-opacity:0;" />
</linearGradient>
<linearGradient
id="linearGradient9880"
inkscape:collect="always">
<stop
id="stop9882"
offset="0"
style="stop-color:#525252;stop-opacity:1;" />
<stop
id="stop9884"
offset="1"
style="stop-color:#525252;stop-opacity:0;" />
</linearGradient>
<linearGradient
id="linearGradient9868">
<stop
style="stop-color:#4e4e4e;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop9870" />
<stop
style="stop-color:#616161;stop-opacity:0.0000000;"
offset="1.0000000"
id="stop9872" />
</linearGradient>
<linearGradient
id="linearGradient9854">
<stop
id="stop9856"
offset="0.0000000"
style="stop-color:#4e4e4e;stop-opacity:1.0000000;" />
<stop
id="stop9858"
offset="1.0000000"
style="stop-color:#ababab;stop-opacity:1.0000000;" />
</linearGradient>
<linearGradient
id="linearGradient9842"
inkscape:collect="always">
<stop
id="stop9844"
offset="0"
style="stop-color:#727e0a;stop-opacity:1;" />
<stop
id="stop9846"
offset="1"
style="stop-color:#727e0a;stop-opacity:0;" />
</linearGradient>
<linearGradient
id="linearGradient9830">
<stop
id="stop9832"
offset="0.0000000"
style="stop-color:#505050;stop-opacity:1.0000000;" />
<stop
id="stop9834"
offset="1.0000000"
style="stop-color:#181818;stop-opacity:1.0000000;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient8662">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop8664" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop8666" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient8650">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop8652" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop8654" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8650"
id="radialGradient8656"
cx="19.701141"
cy="2.8969381"
fx="19.701141"
fy="2.8969381"
r="17.171415"
gradientTransform="matrix(1.253442,-2.296195e-16,1.747460e-16,0.953900,-15.47908,11.27663)"
gradientUnits="userSpaceOnUse" />
<radialGradient
r="15.644737"
fy="36.421127"
fx="24.837126"
cy="36.421127"
cx="24.837126"
gradientTransform="matrix(1.000000,0.000000,0.000000,0.536723,1.673575e-15,16.87306)"
gradientUnits="userSpaceOnUse"
id="radialGradient9826"
xlink:href="#linearGradient8662"
inkscape:collect="always" />
<radialGradient
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.017991,4.461116e-16,-5.888254e-16,2.64016,-144.5498,-62.03367)"
r="16.321514"
fy="40.545052"
fx="93.780037"
cy="40.545052"
cx="93.780037"
id="radialGradient9836"
xlink:href="#linearGradient9830"
inkscape:collect="always" />
<linearGradient
gradientTransform="matrix(1.025512,0,0,0.648342,-0.865496,15.63026)"
gradientUnits="userSpaceOnUse"
y2="28.112619"
x2="30.935921"
y1="43.757359"
x1="30.935921"
id="linearGradient9848"
xlink:href="#linearGradient9842"
inkscape:collect="always" />
<linearGradient
gradientUnits="userSpaceOnUse"
y2="27.759069"
x2="18.031221"
y1="19.804117"
x1="46.845825"
id="linearGradient9864"
xlink:href="#linearGradient9854"
inkscape:collect="always" />
<radialGradient
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.565823,5.084556e-18,-2.416266e-14,1.403262,-37.78323,-9.483303)"
r="9.7227182"
fy="7.1396070"
fx="27.883883"
cy="7.1396070"
cx="27.883883"
id="radialGradient9876"
xlink:href="#linearGradient9868"
inkscape:collect="always" />
<linearGradient
gradientTransform="translate(-1.116120,0.000000)"
gradientUnits="userSpaceOnUse"
y2="24.764584"
x2="34.007416"
y1="19.107729"
x1="31.852951"
id="linearGradient9886"
xlink:href="#linearGradient9880"
inkscape:collect="always" />
<linearGradient
gradientUnits="userSpaceOnUse"
y2="43.449947"
x2="19.755548"
y1="13.663074"
x1="8.7600641"
id="linearGradient9894"
xlink:href="#linearGradient9888"
inkscape:collect="always" />
<linearGradient
gradientUnits="userSpaceOnUse"
y2="18.064039"
x2="33.710651"
y1="21.511185"
x1="31.078955"
id="linearGradient9902"
xlink:href="#linearGradient9896"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
stroke="#a40000"
fill="#727e0a"
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="0.25490196"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="20.295477"
inkscape:cy="1.9717815"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:showpageshadow="false"
inkscape:window-width="1039"
inkscape:window-height="938"
inkscape:window-x="485"
inkscape:window-y="137" />
<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: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-sa/2.0/" />
<dc:title>System Log Out</dc:title>
<dc:subject>
<rdf:Bag>
<rdf:li>log out</rdf:li>
<rdf:li>logout</rdf:li>
<rdf:li>exit</rdf:li>
</rdf:Bag>
</dc:subject>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/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>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<rect
ry="0.7071048"
rx="0.70710522"
y="2.5692098"
x="13.501722"
height="41.942028"
width="31.99555"
id="rect9828"
style="opacity:1;color:#000000;fill:url(#radialGradient9836);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000048;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
inkscape:r_cx="true"
inkscape:r_cy="true" />
<rect
y="31.736542"
x="14"
height="12.263458"
width="30.999998"
id="rect9840"
style="opacity:1;color:#000000;fill:url(#linearGradient9848);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
inkscape:r_cx="true"
inkscape:r_cy="true" />
<path
sodipodi:nodetypes="ccccc"
id="path9852"
d="M 14.037662,43.944859 L 13.998829,3.0545252 L 33.941125,3.0987194 L 33.985319,33.018175 L 14.037662,43.944859 z "
style="overflow:visible;display:inline;visibility:visible;stroke-opacity:1.0000000;stroke-dashoffset:0.0000000;stroke-dasharray:none;stroke-miterlimit:10.000000;marker-end:none;marker-mid:none;marker-start:none;marker:none;stroke-linejoin:miter;stroke-linecap:butt;stroke-width:1.0000000;stroke:none;fill-rule:evenodd;fill-opacity:1.0;fill:url(#linearGradient9864);color:#000000;opacity:1.0000000" />
<path
style="opacity:0.42222222;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
d="M 13.969801,43.944859 L 34.117903,33.062369 L 15.556349,41.989592 L 15.556349,3.0103306 L 13.985886,3.0103306 L 13.969801,43.944859 z "
id="path1360"
inkscape:r_cx="true"
inkscape:r_cy="true"
sodipodi:nodetypes="cccccc" />
<path
sodipodi:type="arc"
style="opacity:0.29946521;color:#000000;fill:url(#radialGradient9826);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
id="path8660"
sodipodi:cx="24.837126"
sodipodi:cy="36.421127"
sodipodi:rx="15.644737"
sodipodi:ry="8.3968935"
d="M 40.481863 36.421127 A 15.644737 8.3968935 0 1 1 9.1923885,36.421127 A 15.644737 8.3968935 0 1 1 40.481863 36.421127 z"
transform="matrix(0.778490,0.000000,0.000000,0.778490,-7.579815,1.598139)" />
<path
style="opacity:1.0000000;color:#000000;fill:#cc0000;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#a40000;stroke-width:0.99999982;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
d="M 1.7317981,17.593819 L 1.7317981,30.355364 L 9.6641034,30.355364 L 9.6641034,36.176147 L 21.887745,23.952503 L 9.5913424,11.656101 L 9.5913424,17.597067 L 1.7317981,17.593819 z "
id="path8643"
sodipodi:nodetypes="cccccccc" />
<path
style="opacity:0.50802141;color:#000000;fill:url(#radialGradient8656);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible"
d="M 9.9240084,12.478043 L 9.9240084,17.865661 L 2.0746151,17.865661 L 2.0746151,24.531440 C 12.332521,20.703863 11.954992,27.773987 21.294280,23.946410 L 9.9240084,12.478043 z "
id="path8645"
sodipodi:nodetypes="cccccc" />
<path
sodipodi:nodetypes="cccccccc"
id="path8658"
d="M 2.7193259,18.399985 L 2.7193259,29.536029 L 10.553144,29.536029 L 10.553144,33.793979 L 20.404597,23.948406 L 10.488577,13.684714 L 10.488577,18.402867 L 2.7193259,18.399985 z "
style="overflow:visible;display:inline;visibility:visible;stroke-opacity:1.0000000;stroke-dashoffset:0.0000000;stroke-dasharray:none;stroke-miterlimit:10.000000;marker-end:none;marker-mid:none;marker-start:none;marker:none;stroke-linejoin:miter;stroke-linecap:butt;stroke-width:1.0000000;stroke:url(#linearGradient9894);fill-rule:evenodd;fill-opacity:1.0000000;fill:none;color:#000000;opacity:0.48128340" />
<path
style="opacity:1;color:#000000;fill:url(#radialGradient9876);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 14.044811,43.757359 L 14,3.0545252 L 33.941125,3.0545252 L 33.761879,33.681088 L 14.044811,43.757359 z "
id="path9866"
sodipodi:nodetypes="ccccc"
inkscape:r_cx="true"
inkscape:r_cy="true" />
<path
sodipodi:nodetypes="cccsscc"
id="path9878"
d="M 29.643025,18.456195 L 31.565472,20.908971 L 30.107064,25.726136 C 30.107064,25.726136 30.372229,27.228738 31.145627,26.212272 C 31.919025,25.195806 34.118082,22.630218 33.730986,20.754291 C 33.443724,19.362175 32.648229,18.699263 32.648229,18.699263 L 29.643025,18.456195 z "
style="opacity:1.0000000;color:#000000;fill:url(#linearGradient9886);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible" />
<path
sodipodi:nodetypes="csccscs"
id="path9862"
d="M 31.477084,17.351340 C 31.477084,17.351340 33.640354,18.353058 33.708889,19.229593 C 33.810670,20.531315 29.466248,24.665476 29.466248,24.665476 C 28.958015,25.284194 28.118326,24.731767 28.582365,24.135146 C 28.582365,24.135146 32.048969,20.017173 31.830637,19.693631 C 31.557026,19.288174 29.863996,18.655068 29.863996,18.655068 C 28.847530,17.903768 30.131617,16.349605 31.477084,17.351340 z "
style="overflow:visible;display:inline;visibility:visible;stroke-opacity:1.0000000;stroke-dashoffset:0.0000000;stroke-dasharray:none;stroke-miterlimit:10.000000;marker-end:none;marker-mid:none;marker-start:none;marker:none;stroke-linejoin:miter;stroke-linecap:butt;stroke-width:1.0000000;stroke:none;fill-rule:evenodd;fill-opacity:1.0;fill:url(#linearGradient9902);color:#000000;opacity:1.0000000" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

@ -0,0 +1,312 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<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://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
sodipodi:docname="system-search.svg"
sodipodi:docbase="/home/tigert/cvs/freedesktop.org/tango-icon-theme/scalable/actions"
inkscape:version="0.43+devel"
sodipodi:version="0.32"
id="svg11300"
height="48px"
width="48px"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs3">
<linearGradient
id="linearGradient2846">
<stop
id="stop2848"
offset="0.0000000"
style="stop-color:#8a8a8a;stop-opacity:1.0000000;" />
<stop
id="stop2850"
offset="1.0000000"
style="stop-color:#484848;stop-opacity:1.0000000;" />
</linearGradient>
<linearGradient
id="linearGradient2366">
<stop
id="stop2368"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
style="stop-color:#ffffff;stop-opacity:0.21904762;"
offset="0.50000000"
id="stop2374" />
<stop
id="stop2370"
offset="1.0000000"
style="stop-color:#ffffff;stop-opacity:1.0000000;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient4487">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop4489" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop4491" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient4477">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop4479" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop4481" />
</linearGradient>
<linearGradient
id="linearGradient4467">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop4469" />
<stop
style="stop-color:#ffffff;stop-opacity:0.24761905;"
offset="1.0000000"
id="stop4471" />
</linearGradient>
<linearGradient
id="linearGradient4454">
<stop
style="stop-color:#729fcf;stop-opacity:0.20784314;"
offset="0.0000000"
id="stop4456" />
<stop
style="stop-color:#729fcf;stop-opacity:0.67619050;"
offset="1.0000000"
id="stop4458" />
</linearGradient>
<linearGradient
id="linearGradient4440">
<stop
style="stop-color:#7d7d7d;stop-opacity:1;"
offset="0"
id="stop4442" />
<stop
id="stop4448"
offset="0.50000000"
style="stop-color:#b1b1b1;stop-opacity:1.0000000;" />
<stop
style="stop-color:#686868;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop4444" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4440"
id="linearGradient4446"
x1="30.656250"
y1="34.000000"
x2="33.218750"
y2="31.062500"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.334593,0.000000,0.000000,1.291292,-6.973842,-7.460658)" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4454"
id="radialGradient4460"
cx="18.240929"
cy="21.817987"
fx="18.240929"
fy="21.817987"
r="8.3085051"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4467"
id="radialGradient4473"
cx="15.414371"
cy="13.078408"
fx="15.414371"
fy="13.078408"
r="6.6562500"
gradientTransform="matrix(2.592963,-7.746900e-24,-5.714443e-24,2.252104,-25.05975,-18.94100)"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4487"
id="radialGradient4493"
cx="24.130018"
cy="37.967922"
fx="24.130018"
fy="37.967922"
r="16.528622"
gradientTransform="matrix(1.000000,0.000000,0.000000,0.237968,3.152859e-15,28.93278)"
gradientUnits="userSpaceOnUse" />
<linearGradient
gradientUnits="userSpaceOnUse"
y2="25.743469"
x2="17.500893"
y1="13.602121"
x1="18.292673"
id="linearGradient2372"
xlink:href="#linearGradient2366"
inkscape:collect="always" />
<radialGradient
r="16.528622"
fy="37.967922"
fx="24.130018"
cy="37.967922"
cx="24.130018"
gradientTransform="matrix(1.000000,0.000000,0.000000,0.237968,-2.471981e-16,28.93278)"
gradientUnits="userSpaceOnUse"
id="radialGradient2842"
xlink:href="#linearGradient4477"
inkscape:collect="always" />
<linearGradient
gradientUnits="userSpaceOnUse"
y2="30.557772"
x2="31.335964"
y1="26.580296"
x1="27.366341"
id="linearGradient2852"
xlink:href="#linearGradient2846"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
stroke="#3465a4"
inkscape:window-y="187"
inkscape:window-x="239"
inkscape:window-height="754"
inkscape:window-width="691"
inkscape:showpageshadow="false"
inkscape:document-units="px"
inkscape:grid-bbox="true"
showgrid="false"
inkscape:current-layer="layer1"
inkscape:cy="23.070520"
inkscape:cx="23.821561"
inkscape:zoom="11.313708"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
borderopacity="0.25490196"
bordercolor="#666666"
pagecolor="#ffffff"
id="base"
fill="#729fcf" />
<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: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-sa/2.0/" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/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>
<g
inkscape:groupmode="layer"
inkscape:label="Layer 1"
id="layer1">
<g
id="g1772">
<path
sodipodi:type="arc"
style="opacity:0.17112298;color:#000000;fill:url(#radialGradient2842);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;"
id="path4475"
sodipodi:cx="24.130018"
sodipodi:cy="37.967922"
sodipodi:rx="16.528622"
sodipodi:ry="3.9332814"
d="M 40.658640 37.967922 A 16.528622 3.9332814 0 1 1 7.6013966,37.967922 A 16.528622 3.9332814 0 1 1 40.658640 37.967922 z"
transform="matrix(1.446431,0.000000,0.000000,1.519990,-10.97453,-17.75168)" />
<path
sodipodi:nodetypes="csscccscccscczzzz"
id="path2844"
d="M 18.627569,3.1435548 C 10.488439,3.1435548 3.8827682,9.7492259 3.8827682,17.888356 C 3.8827682,26.027486 10.488439,32.633158 18.627569,32.633158 C 22.107124,32.633158 25.178570,31.248765 27.701292,29.230511 C 27.495915,30.237392 27.623257,31.265879 28.457436,31.990436 L 39.421520,41.517846 C 40.654936,42.589175 42.508982,42.448806 43.580310,41.215389 C 44.651638,39.981971 44.511269,38.127927 43.277853,37.056599 L 32.313769,27.529188 C 31.642242,26.945909 30.820891,26.773219 30.007531,26.886466 C 31.994231,24.374044 33.372370,21.337663 33.372370,17.888356 C 33.372370,9.7492259 26.766699,3.1435548 18.627569,3.1435548 z M 18.551954,4.3697381 C 26.191413,4.3697381 31.843729,9.1586886 31.843729,17.661513 C 31.843729,26.336626 26.027039,30.953288 18.551954,30.953288 C 11.249005,30.953288 5.2601806,25.475196 5.2601806,17.661513 C 5.2601806,9.6774061 11.084819,4.3697380 18.551954,4.3697381 z "
style="opacity:1.0000000;color:#000000;fill:#dcdcdc;fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2852);stroke-width:2.0000010;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;" />
<path
style="opacity:1.0000000;color:#000000;fill:#dcdcdc;fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000004;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;"
d="M 18.602905,3.0803551 C 10.437465,3.0803551 3.8104408,9.7073791 3.8104408,17.872819 C 3.8104408,26.038259 10.437465,32.665283 18.602905,32.665283 C 22.093708,32.665283 25.175082,31.276416 27.705960,29.251638 C 27.499919,30.261774 27.627672,31.293585 28.464547,32.020484 L 39.464073,41.578691 C 40.701476,42.653483 42.561515,42.512661 43.636306,41.275256 C 44.711097,40.037852 44.570274,38.177814 43.332871,37.103023 L 32.333346,27.544815 C 31.659648,26.959651 30.835642,26.786402 30.019653,26.900016 C 32.012775,24.379472 33.395369,21.333276 33.395369,17.872819 C 33.395369,9.7073791 26.768345,3.0803551 18.602905,3.0803551 z M 18.527046,6.2664243 C 24.808154,6.2664245 29.905864,11.364135 29.905864,17.645243 C 29.905864,23.926351 24.808154,29.024061 18.527046,29.024061 C 12.245938,29.024061 7.1482276,23.926351 7.1482276,17.645243 C 7.1482278,11.364135 12.245938,6.2664243 18.527046,6.2664243 z "
id="path4430" />
<path
style="opacity:1.0000000;color:#000000;fill:url(#linearGradient4446);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;"
d="M 39.507004,41.577690 C 39.028332,39.304503 40.904334,36.766268 43.091057,36.789315 C 43.091057,36.789315 32.330690,27.531204 32.330690,27.531204 C 29.385899,27.474498 28.061188,29.803820 28.553876,32.131126 L 39.507004,41.577690 z "
id="path4438"
sodipodi:nodetypes="ccccc" />
<path
sodipodi:type="arc"
style="opacity:1.0000000;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:url(#linearGradient2372);stroke-width:0.80273360;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;"
id="path4450"
sodipodi:cx="17.500893"
sodipodi:cy="18.920233"
sodipodi:rx="11.048544"
sodipodi:ry="11.048544"
d="M 28.549437 18.920233 A 11.048544 11.048544 0 1 1 6.4523487,18.920233 A 11.048544 11.048544 0 1 1 28.549437 18.920233 z"
transform="matrix(1.245743,0.000000,0.000000,1.245743,-3.425346,-6.177033)" />
<path
transform="matrix(0.497764,0.000000,0.000000,0.609621,8.973526,15.61929)"
d="M 40.658640 37.967922 A 16.528622 3.9332814 0 1 1 7.6013966,37.967922 A 16.528622 3.9332814 0 1 1 40.658640 37.967922 z"
sodipodi:ry="3.9332814"
sodipodi:rx="16.528622"
sodipodi:cy="37.967922"
sodipodi:cx="24.130018"
id="path4485"
style="opacity:1.0000000;color:#000000;fill:url(#radialGradient4493);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;"
sodipodi:type="arc" />
<rect
style="opacity:0.43315509;color:#000000;fill:none;fill-opacity:1.0000000;fill-rule:evenodd;stroke:#ffffff;stroke-width:1.0000311;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;"
id="rect4495"
width="19.048439"
height="4.4404783"
x="40.373337"
y="0.14086054"
rx="2.1366608"
ry="1.8879365"
transform="matrix(0.752986,0.658037,-0.648902,0.760872,0.000000,0.000000)" />
<path
sodipodi:type="arc"
style="color:#000000;fill:url(#radialGradient4460);fill-opacity:1.0000000;fill-rule:evenodd;stroke:#3063a3;stroke-width:0.71499395;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10.000000;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;visibility:visible;"
id="path4452"
sodipodi:cx="17.589281"
sodipodi:cy="18.478292"
sodipodi:rx="8.3085051"
sodipodi:ry="8.3085051"
d="M 25.897786 18.478292 A 8.3085051 8.3085051 0 1 1 9.2807760,18.478292 A 8.3085051 8.3085051 0 1 1 25.897786 18.478292 z"
transform="matrix(1.398614,0.000000,0.000000,1.398614,-6.224338,-8.298958)" />
<path
style="opacity:0.83422458;color:#000000;fill:url(#radialGradient4473);fill-opacity:1.0000000;fill-rule:evenodd;stroke:none;stroke-width:1.0000000;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10.000000;stroke-dasharray:none;stroke-dashoffset:0.0000000;stroke-opacity:1.0000000;visibility:visible;display:inline;overflow:visible;"
d="M 18.156915,7.3966938 C 12.949325,7.3966938 8.7323681,11.613651 8.7323681,16.821241 C 8.7323681,18.325216 9.1526753,19.709014 9.7795400,20.971144 C 11.031920,21.432757 12.362297,21.746827 13.774307,21.746827 C 19.945262,21.746827 24.873589,16.885190 25.254413,10.809698 C 23.523449,8.7641668 21.044374,7.3966938 18.156915,7.3966938 z "
id="path4462" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 15 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 47 KiB

@ -0,0 +1,391 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<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://inkscape.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:export-ydpi="90.000000"
inkscape:export-xdpi="90.000000"
inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
width="48px"
height="48px"
id="svg11300"
sodipodi:version="0.32"
inkscape:version="0.43+devel"
sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/actions"
sodipodi:docname="view-refresh.svg">
<defs
id="defs3">
<linearGradient
inkscape:collect="always"
id="linearGradient2690">
<stop
style="stop-color:#c4d7eb;stop-opacity:1;"
offset="0"
id="stop2692" />
<stop
style="stop-color:#c4d7eb;stop-opacity:0;"
offset="1"
id="stop2694" />
</linearGradient>
<linearGradient
id="linearGradient2682">
<stop
style="stop-color:#3977c3;stop-opacity:1;"
offset="0"
id="stop2684" />
<stop
style="stop-color:#89aedc;stop-opacity:0;"
offset="1"
id="stop2686" />
</linearGradient>
<linearGradient
id="linearGradient2402">
<stop
style="stop-color:#729fcf;stop-opacity:1;"
offset="0"
id="stop2404" />
<stop
style="stop-color:#528ac5;stop-opacity:1;"
offset="1"
id="stop2406" />
</linearGradient>
<linearGradient
id="linearGradient2380">
<stop
style="stop-color:#b9cfe7;stop-opacity:1"
offset="0"
id="stop2382" />
<stop
style="stop-color:#729fcf;stop-opacity:1"
offset="1"
id="stop2384" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient2871">
<stop
style="stop-color:#3465a4;stop-opacity:1;"
offset="0"
id="stop2873" />
<stop
style="stop-color:#3465a4;stop-opacity:1"
offset="1"
id="stop2875" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient2847">
<stop
style="stop-color:#3465a4;stop-opacity:1;"
offset="0"
id="stop2849" />
<stop
style="stop-color:#3465a4;stop-opacity:0;"
offset="1"
id="stop2851" />
</linearGradient>
<linearGradient
id="linearGradient2831">
<stop
style="stop-color:#3465a4;stop-opacity:1;"
offset="0"
id="stop2833" />
<stop
id="stop2855"
offset="0.33333334"
style="stop-color:#5b86be;stop-opacity:1;" />
<stop
style="stop-color:#83a8d8;stop-opacity:0;"
offset="1"
id="stop2835" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient2797">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop2799" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop2801" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient8662">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop8664" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop8666" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2831"
id="linearGradient1486"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(0.465413,-0.277593)"
x1="13.478554"
y1="10.612206"
x2="15.419417"
y2="19.115122" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2847"
id="linearGradient1488"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1,0,0,-1,47.52791,45.84741)"
x1="37.128052"
y1="29.729605"
x2="37.065414"
y2="26.194071" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2797"
id="linearGradient1491"
gradientUnits="userSpaceOnUse"
x1="5.9649176"
y1="26.048164"
x2="52.854097"
y2="26.048164" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2797"
id="linearGradient1493"
gradientUnits="userSpaceOnUse"
x1="5.9649176"
y1="26.048164"
x2="52.854097"
y2="26.048164" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2871"
id="linearGradient1501"
gradientUnits="userSpaceOnUse"
x1="46.834816"
y1="45.264122"
x2="45.380436"
y2="50.939667" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8662"
id="radialGradient1503"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.536723,-9.680928e-14,16.87306)"
cx="24.837126"
cy="36.421127"
fx="24.837126"
fy="36.421127"
r="15.644737" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2380"
id="linearGradient2386"
x1="62.513836"
y1="36.061237"
x2="15.984863"
y2="20.60858"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2402"
id="linearGradient2408"
x1="18.935766"
y1="23.667896"
x2="53.588622"
y2="26.649362"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2682"
id="linearGradient2688"
x1="36.713837"
y1="31.455952"
x2="37.124462"
y2="24.842253"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2690"
id="linearGradient2696"
x1="32.647972"
y1="30.748846"
x2="37.124462"
y2="24.842253"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
stroke="#3465a4"
fill="#729fcf"
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="0.25490196"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.6568542"
inkscape:cx="31.08169"
inkscape:cy="18.153347"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:showpageshadow="false"
inkscape:window-width="891"
inkscape:window-height="932"
inkscape:window-x="666"
inkscape:window-y="184" />
<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: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-sa/2.0/" />
<dc:title>View Refresh</dc:title>
<dc:subject>
<rdf:Bag>
<rdf:li>reload</rdf:li>
<rdf:li>refresh</rdf:li>
<rdf:li>view</rdf:li>
</rdf:Bag>
</dc:subject>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/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>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
transform="matrix(-1.489736,0,0,-1.001252,61.20865,75.2819)"
d="M 40.481863 36.421127 A 15.644737 8.3968935 0 1 1 9.1923885,36.421127 A 15.644737 8.3968935 0 1 1 40.481863 36.421127 z"
sodipodi:ry="8.3968935"
sodipodi:rx="15.644737"
sodipodi:cy="36.421127"
sodipodi:cx="24.837126"
id="path8660"
style="opacity:0.38333333;color:#000000;fill:url(#radialGradient1503);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
sodipodi:type="arc"
inkscape:r_cx="true"
inkscape:r_cy="true" />
<path
style="color:#000000;fill:url(#linearGradient1486);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient1488);stroke-width:0.99999958;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
d="M 20.152913,10.409904 C 20.152913,10.409904 11.215413,9.784904 13.965413,20.284904 L 6.2779132,20.284904 C 6.2779132,20.284904 6.7779132,8.409904 20.152913,10.409904 z "
id="path2865"
inkscape:r_cx="true"
inkscape:r_cy="true"
sodipodi:nodetypes="cccc" />
<g
id="g1878"
transform="matrix(-0.579051,-0.489228,-0.489228,0.579051,56.91585,13.37137)"
inkscape:r_cx="true"
inkscape:r_cy="true"
style="fill:url(#linearGradient2386);fill-opacity:1.0;stroke:#3465a4;stroke-opacity:1">
<path
sodipodi:nodetypes="ccccccc"
id="path1880"
d="M 44.306783,50.229694 C 62.821497,35.818859 49.664587,13.411704 22.462411,12.49765 L 22.113843,3.1515478 L 7.6245439,20.496754 L 22.714328,33.219189 C 22.714328,33.219189 22.462411,23.337969 22.462411,23.337969 C 41.292171,24.336946 55.444038,37.409698 44.306783,50.229694 z "
style="opacity:1;color:#000000;fill:url(#linearGradient2386);fill-opacity:1.0;fill-rule:nonzero;stroke:url(#linearGradient1501);stroke-width:1.31916928;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
inkscape:r_cx="true"
inkscape:r_cy="true" />
</g>
<path
sodipodi:nodetypes="cccc"
inkscape:r_cy="true"
inkscape:r_cx="true"
id="path2839"
d="M 28.375,33.4375 C 28.375,33.4375 37.3125,34.0625 34.5625,23.5625 L 42.338388,23.5625 C 42.338388,25.065102 41.75,35.4375 28.375,33.4375 z "
style="color:#000000;fill:url(#linearGradient2696);fill-opacity:1.0;fill-rule:nonzero;stroke:url(#linearGradient2688);stroke-width:0.99999958;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible" />
<g
style="color:#000000;fill:url(#linearGradient2408);fill-opacity:1.0;fill-rule:nonzero;stroke:url(#linearGradient1501);stroke-width:1.31916928;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible;opacity:1"
inkscape:r_cy="true"
inkscape:r_cx="true"
transform="matrix(0.579051,0.489228,0.489228,-0.579051,-7.921023,30.53599)"
id="g2779">
<path
inkscape:r_cy="true"
inkscape:r_cx="true"
style="opacity:1;color:#000000;fill:url(#linearGradient2408);fill-opacity:1.0;fill-rule:nonzero;stroke:url(#linearGradient1501);stroke-width:1.31916928;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
d="M 44.306783,50.229694 C 62.821497,35.818859 49.664587,13.411704 22.462411,12.49765 L 22.399432,3.0690297 L 7.793943,20.424005 L 22.462411,33.006349 C 22.462411,33.006349 22.462411,23.337969 22.462411,23.337969 C 41.292171,24.336946 55.444038,37.409698 44.306783,50.229694 z "
id="path2781"
sodipodi:nodetypes="ccccccc" />
</g>
<path
style="opacity:0.27222224;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999982;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 7.0625,38.1875 L 7.125,23.3125 L 20.0625,22.9375 L 15.673627,28.116317 L 19.540852,30.489516 C 16.540852,32.739516 14.991304,32.911644 13.991304,35.474144 L 11.174446,33.363872 L 7.0625,38.1875 z "
id="path2791"
inkscape:r_cx="true"
inkscape:r_cy="true"
sodipodi:nodetypes="cccccccc" />
<g
id="g2793"
transform="matrix(0.508536,0.429651,0.429651,-0.508536,-3.973188,30.54119)"
inkscape:r_cx="true"
inkscape:r_cy="true"
style="opacity:0.5;fill:none;fill-opacity:1;stroke:#ffffff;stroke-opacity:1">
<path
sodipodi:nodetypes="ccccccc"
id="path2795"
d="M 51.090265,45.943705 C 60.210465,30.723955 46.631614,12.20113 19.485058,11.948579 L 19.513464,3.7032834 L 6.5341979,19.296639 L 19.367661,30.26876 C 19.367661,30.26876 19.423281,21.261882 19.423281,21.261882 C 36.951096,21.037973 54.618466,31.365254 51.090265,45.943705 z "
style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient1493);stroke-width:1.50208926;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
inkscape:r_cx="true"
inkscape:r_cy="true" />
</g>
<g
style="opacity:0.5;fill:none;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"
inkscape:r_cy="true"
inkscape:r_cx="true"
transform="matrix(-0.508536,-0.429651,-0.429651,0.508536,53.049,13.36548)"
id="g2805">
<path
inkscape:r_cy="true"
inkscape:r_cx="true"
style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient1491);stroke-width:1.50208926;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
d="M 51.389927,46.505946 C 60.510127,31.286196 47.050763,12.432359 19.628482,12.069755 L 19.342824,4.0507204 L 6.3413093,19.379475 L 19.809059,30.764589 C 19.809059,30.764589 19.627294,21.311346 19.627294,21.311346 C 37.872231,21.693318 54.411175,32.236592 51.389927,46.505946 z "
id="path2807"
sodipodi:nodetypes="ccccccc" />
</g>
<path
style="opacity:0.27222224;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999982;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M 6.8125,16.5 C 10.405935,6.0587275 23.256282,10.355393 27,12 C 31.175307,12.211475 32.674736,9.164996 36,9 C 21.950264,-0.7899963 7.1875,2.5 6.8125,16.5 z "
id="path2811"
inkscape:r_cx="true"
inkscape:r_cy="true"
sodipodi:nodetypes="cccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

@ -0,0 +1,213 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
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"
width="744.09448819"
height="1052.3622047"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.46"
sodipodi:docname="NetworkOperatorWizard.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
inkscape:export-filename="/home/klaas/DevRocket/Klaas/umtsmon-cvs/images/Wizard/NetworkOperatorWizard.png"
inkscape:export-xdpi="78.958351"
inkscape:export-ydpi="78.958351">
<defs
id="defs4">
<linearGradient
id="linearGradient3218">
<stop
style="stop-color:#00ff00;stop-opacity:1;"
offset="0"
id="stop3220" />
<stop
style="stop-color:#d0c93a;stop-opacity:1;"
offset="1"
id="stop3222" />
</linearGradient>
<linearGradient
id="linearGradient3157">
<stop
style="stop-color:#00aaff;stop-opacity:1;"
offset="0"
id="stop3159" />
<stop
style="stop-color:#c5ffff;stop-opacity:1;"
offset="1"
id="stop3161" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3157"
id="linearGradient3163"
x1="225.79482"
y1="65.440369"
x2="228.89639"
y2="368.1543"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.8714249,8.5714147,19.121821)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3218"
id="linearGradient3224"
x1="190.75793"
y1="372.47186"
x2="194.59889"
y2="414.90411"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
gridtolerance="10000"
guidetolerance="10"
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.9112933"
inkscape:cx="228.56474"
inkscape:cy="835.90335"
inkscape:document-units="px"
inkscape:current-layer="layer2"
showgrid="false"
inkscape:window-width="1280"
inkscape:window-height="968"
inkscape:window-x="0"
inkscape:window-y="0" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="background"
style="display:inline"
sodipodi:insensitive="true">
<rect
style="fill:url(#linearGradient3163);fill-opacity:1"
id="rect2385"
width="291.42859"
height="351.05981"
x="82.857132"
y="67.241318" />
<path
style="fill:url(#linearGradient3224);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 228.5625,358.0625 C 169.09837,358.0625 116.24636,371.62426 82.84375,392.59375 L 82.84375,418.3125 L 374.28125,418.3125 L 374.28125,392.59375 C 340.87777,371.62987 288.01731,358.0625 228.5625,358.0625 z"
id="path2383" />
</g>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g3209"
transform="matrix(0.9862805,0.1650781,-0.1650781,0.9862805,-116.58636,35.187787)">
<path
id="path3185"
d="M 454.77675,42.643776 L 424.3813,257.89323"
style="fill:#ff0000;fill-rule:evenodd;stroke:#ff0000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path3187"
d="M 455.39707,42.643776 L 485.79252,257.89323"
style="fill:#ff0000;fill-rule:evenodd;stroke:#ff0000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path3203"
d="M 449.03427,81.685054 L 465.8339,115.8538 L 439.63787,150.02255 L 475.51505,183.05233 L 429.95672,217.22108 L 485.48093,255.94566"
style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path3205"
d="M 461.54234,81.685051 L 444.74271,115.8538 L 470.93874,150.02255 L 435.06156,183.05233 L 480.61989,217.22108 L 425.09568,255.94566"
style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path3207"
d="M 455.03126,44.4478 L 455.03126,20.68953"
style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<path
sodipodi:type="arc"
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path3216"
sodipodi:cx="114.20045"
sodipodi:cy="316.34552"
sodipodi:rx="11.524817"
sodipodi:ry="13.620237"
d="M 125.72526,316.34552 A 11.524817,13.620237 0 1 1 102.67563,316.34552 A 11.524817,13.620237 0 1 1 125.72526,316.34552 z" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 113.15274,329.96575 L 112.10503,376.58887 L 130.96382,356.68237 L 141.44093,367.15947"
id="path3226"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 125.20141,352.49152 L 144.58406,346.72912 L 148.25105,322.63177"
id="path3228" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 114.20045,340.96671 L 131.48768,346.20526"
id="path3230" />
<g
id="g3306"
transform="translate(-2,-2)">
<path
id="path3252"
d="M 147.91628,310.49099 C 155.556,314.51615 160.36829,321.57585 160.08836,328.69709"
style="fill:none;stroke:#ff2a2a;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path3254"
d="M 150.35589,300.76334 C 162.91707,306.42977 170.60757,318.66092 168.961,330.92635"
style="fill:none;stroke:#ff2a2a;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path3256"
d="M 148.55471,307.87745 C 157.40515,312.30369 162.88085,320.73105 162.11248,329.19823"
style="fill:none;stroke:#ff2a2a;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path3258"
d="M 149.28436,305.02717 C 159.67957,309.97959 166.07509,319.94312 164.91826,329.91562"
style="fill:none;stroke:#ff2a2a;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<g
id="g3312"
transform="matrix(-1.3262657,-0.4466994,0.3888586,-1.1545343,385.42505,586.61747)">
<path
id="path3314"
d="M 147.91628,310.49099 C 155.556,314.51615 160.36829,321.57585 160.08836,328.69709"
style="fill:none;stroke:#ff2a2a;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path3316"
d="M 150.35589,300.76334 C 162.91707,306.42977 170.60757,318.66092 168.961,330.92635"
style="fill:none;stroke:#ff2a2a;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path3318"
d="M 148.55471,307.87745 C 157.40515,312.30369 162.88085,320.73105 162.11248,329.19823"
style="fill:none;stroke:#ff2a2a;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path3320"
d="M 149.28436,305.02717 C 159.67957,309.97959 166.07509,319.94312 164.91826,329.91562"
style="fill:none;stroke:#ff2a2a;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 661 B

@ -0,0 +1,404 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2006, 2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "mainwindow.h"
#include "TheDeviceManagerSingleton.h"
#include "Runner.h"
#include "Popup.h"
#include "Internationalisation.h"
#include <ntqapplication.h>
#include <ntqmessagebox.h>
#include <ntqtextcodec.h>
#include <assert.h>
#include <signal.h>
#include <stdlib.h>
// forward declarations
void popupAbortMessageBox(int);
void printAbortMessage(int);
static const int MAXLONGCOMMANDSIZE = 20;
static const int MAXSHORTCOMMANDSIZE = 4;
// oops global variable declared here...
// let's make sure they do not multiply :-)
int theVerbosity = 1;
int thePPPVerbosity = 0;
static char* theLocale = NULL;
static bool setDefProfile(char* anArgument)
{
DEBUG5("setDefProfile: '%s'\n", anArgument);
// all argument checking is done in in the class :-D
if (Profile::setActiveProfile(anArgument) == false)
{
printf("ERROR: Profile \"%s\" does not exist\n", anArgument);
exit(2);
}
return true;
}
static bool setForceAutodetection( __attribute__ ((unused)) char* anArgument)
{
TheDeviceManagerSingleton::me().setForceAutodetection();
return true;
}
static bool setLocale(char* anArgument)
{
// will be parsed/verified later in main()
theLocale = anArgument;
return true;
}
static bool setAutoConnect(__attribute__ ((unused)) char* anArgument)
{
DEBUG5("setautoconnect\n");
TheSettingsSingleton::getTQSRef().writeEntry(theGeneralAutoConnectSettingName, true);
return true;
}
static bool setNoAutoConnect(__attribute__ ((unused)) char* anArgument)
{
DEBUG5("setNOautoconnect\n");
TheSettingsSingleton::getTQSRef().writeEntry(theGeneralAutoConnectSettingName, false);
return true;
}
static bool setSerial(char* anArgument)
{
DEBUG5("setSerial: '%s'\n", anArgument);
// no need to do advanced parameter checking
// - that'll be done later on, right?
// is there a comma in? in that case we neet to set both AT and PPP
TQStringList myList = TQStringList::split(',', anArgument);
switch (myList.count())
{
case 1:
TheDeviceManagerSingleton::me().setSuggestedAT(myList[0]);
TheDeviceManagerSingleton::me().setSuggestedPPP("");
TheDeviceManagerSingleton::me().setSuggestedDeviceType(DeviceCapabilities::GENERIC_USER_SERIAL);
break;
case 2:
TheDeviceManagerSingleton::me().setSuggestedAT(myList[0]);
TheDeviceManagerSingleton::me().setSuggestedPPP(myList[1]);
TheDeviceManagerSingleton::me().setSuggestedDeviceType(DeviceCapabilities::GENERIC_USER_SERIAL);
break;
default:
printf("ERROR: supply max 2 devices to --serial\n");
exit(2);
break;
}
return true;
}
static bool setVerbosity(char* anArgument)
{
DEBUG1("setVerbosity: '%s'\n", anArgument);
// the argument should be a number. Let's parse.
int myNumber = atoi(anArgument);
if (myNumber < 1 || myNumber > MAX_VERBOSITY)
{
printf("ERROR: verbosity argument should be between 1 and 5\n");
return false;
}
theVerbosity = myNumber;
DEBUG2("set verbosity level to %d\n", theVerbosity);
// check if we have a second argument after a comma (ppp-verbosity)
char* comma = strchr(anArgument, ',');
if (comma != NULL)
{
myNumber = atoi(comma + 1);
if (myNumber < 0 || myNumber > 2)
{
printf("ERROR: PPP verbosity argument should be between 0 and 2\n");
return false;
}
thePPPVerbosity = myNumber;
}
else
{
// verbosity > 2 => pppverbosity = 1; verbosity > 4 => pppverbosity = 2
thePPPVerbosity = (theVerbosity - 1) / 2;
}
DEBUG2("set PPP verbosity level to %d\n", thePPPVerbosity);
return true;
}
static bool help( __attribute__ ((unused)) char* anArgument)
{
printf(APPNAME " " APPRELEASE "" APPFLAVOUR "\n\nhelp text\n\n");
printf(" --help gives this help text\n");
printf(" -h gives this help text\n");
printf(" --force-autodetect force autodetection (don't use info from config file)\n");
printf(" --serial <at>[,ppp] will prevent autodetection of devices and use serial port <at>[,<ppp>]\n");
printf(" -s <at>[,<ppp>] will prevent autodetection of devices and use serial port <at>[,<ppp>]\n");
printf(" --verbosity <lvl>[,ppplvl] set verbosity, 1=little (default), %d=all\n", MAX_VERBOSITY);
printf(" -v <lvl>[,ppplvl] set verbosity\n");
printf(" --language <locale> set the language, e.g. nl or pt_BR\n");
printf(" --autoconnect set autoconnect to true (persistant!)\n");
printf(" --no-autoconnect set autoconnect to false (persistant!)\n");
printf(" --default-profile <profilename> sets the default profile to connect with (persistant!)\n");
printf("\n(parameters in <> are required, parameters in [] are optional)\n");
printf("\n");
exit(1);
}
/// the formatting for theArgsTable
struct ArgsStruct
{
char theFullCommand [MAXLONGCOMMANDSIZE];
char theShortCommand[MAXSHORTCOMMANDSIZE];
bool needsArgument;
bool (*theFunctionPtr)(char* anArgument);
};
static ArgsStruct theArgsTable[] =
{
// long, short, has args, function name
{ "--help", "-h", false, help, },
{ "--serial", "-s", true, setSerial, },
{ "--verbosity", "-v", true, setVerbosity, },
{ "--force-autodetect", "", false, setForceAutodetection, },
{ "--language", "", true, setLocale, },
{ "--autoconnect", "", false, setAutoConnect, },
{ "--no-autoconnect", "", false, setNoAutoConnect, },
{ "--default-profile", "-p", true, setDefProfile, },
// keep this one last
{ "\0", "\0", false, NULL, },
};
/** compare strings.
* @returns If 0, no match, if positive nonzero: the character at this index is extra
*/
static int compareStrings(const char* anArgument, const char* aCommand)
{
int i=0;
while(true)
{
// we're at the end of the command - a match, maybe with info left...
if (aCommand[i] == 0)
return i;
// the argument is shorter than the command - cannot be a match :-(
if (anArgument[i] == 0)
break;
if (anArgument[i] != aCommand[i])
break;
i++;
}
// if we get here, it was no match :-(
return 0;
}
int main( int argc, char **argv )
{
TQApplication myTQApp( argc, argv );
puts( APPNAME " version " APPRELEASE "" APPFLAVOUR " ." );
// perform command line parsing
// skip argv[0] because we know what's in there
for ( int i = 1; i < myTQApp.argc(); i++ )
{
int myMatchPoint = 0;
char* myArgvPtr = myTQApp.argv()[i];
ArgsStruct* myTEntry;
for (int j = 0; theArgsTable[j].theFullCommand[0]!='\0'; j++)
{
myTEntry = &(theArgsTable[j]);
myMatchPoint = compareStrings(myArgvPtr, myTEntry->theFullCommand);
if (myMatchPoint)
break;
myMatchPoint = compareStrings(myArgvPtr, myTEntry->theShortCommand);
if (myMatchPoint)
break;
} // end of the 'j' loop
if (myMatchPoint)
{
char* anArgument = NULL;
// there are several cases:
// 1) -s 3
// 2) -s3
// 3) -s=3
// 4) --serial=3
// 5) --serial 3
// 6) --help (no arguments)
// 7) -h (no arguments)
// cases 1,2,3,4,5:
if (myTEntry->needsArgument)
{
// is there extra data in this argument (i.e. cases 2,3,4)
if (myArgvPtr[myMatchPoint] != 0)
{
// is it a '=' (case3,4) - then advance one character
if (myArgvPtr[myMatchPoint] == '=')
myMatchPoint++;
anArgument = &myArgvPtr[myMatchPoint];
}
else
{
// case 1,5:
// is there a next argument to parse?
if ( (i+1) < myTQApp.argc())
{
anArgument = myTQApp.argv()[i+1];
i++;
}
else
anArgument = NULL;
}
}
if (myTEntry->needsArgument==true && anArgument==NULL)
{
printf("parsing error: missing argument to '%s'!\n", myArgvPtr);
exit(3);
}
if (myTEntry->theFunctionPtr(anArgument) == false)
{
printf("...\nExiting gracefully\n\n");
help(NULL);
// this should never be reached:
exit(1);
}
}
else
{
printf("ERROR: unknown argument '%s'\n", myArgvPtr);
exit(2);
}
} // end of the 'i' loop
// If a user who doesn't run umtsmon from the command line hits an assert,
// the program stops without a visible UI message.
// let's fix that here: if no verbosity is set, register a SIGABRT handler to pop up a dialog
if (theVerbosity <= 1)
{
printf("installing GUI SIGABRT handler\n");
signal(SIGABRT, popupAbortMessageBox);
}
else
{
// also register a handler explaining what to do
// if the users enabled lots of verbosity
if (theVerbosity >= 5)
{
printf("installing text SIGABRT handler\n");
signal(SIGABRT, printAbortMessage);
}
}
// Setup translations
// * we may have a valid theLocale (i.e. specified on command line), we should check it
// * we may have a valid locale as a setting, we should check it
// * we may have a valid locale in the environment
Internationalisation myI18n( &myTQApp );
bool myI18nResult = false;
if (theLocale!=NULL)
{
myI18nResult = myI18n.tryLocale(theLocale);
if (myI18nResult == false)
{
DEBUG1("ERROR: your specified locale (\"%s\") is not valid\n", theLocale);
exit(1);
}
}
else
myI18nResult = myI18n.trySavedLocale();
if (myI18nResult == false)
myI18nResult = myI18n.tryLocale(TQTextCodec::locale());
if (myI18nResult == false)
DEBUG5("Running on the default (en_US) locale\n");
Popup::WarningWithMemory("WelcomeMsg", TQObject::tr("Welcome to umtsmon."));
// check for rootness - useful for the logs if users do odd things
if (Runner::amIRoot())
DEBUG1(APPNAME " is running as root!!!\n");
////////////////////////////////////
// and start the application
// do not forget to pass on some initialised classes
mainwindow w;
myTQApp.setMainWidget( &w );
w.setI18nRef(myI18n);
w.show();
return myTQApp.exec();
}
void popupAbortMessageBox(__attribute__ ((unused)) int aSignalNumber)
{
static bool isFirstTimeHere=true;
if ( !isFirstTimeHere )
return;
isFirstTimeHere=false;
TQMessageBox::critical (NULL,
APPNAME " assert error",
APPNAME " ran into a problem and unfortunately had to close. "
"It is highly likely that if you run " APPNAME "from a command line, like:\n"
APPNAME " -v5\n"
"you will get information on what went wrong, including"
" information on how to help us solve it.\n"
"We thank you in advance for helping us improve " APPNAME "!",
TQMessageBox::Ok | TQMessageBox::Default,
TQMessageBox::NoButton,
TQMessageBox::NoButton);
// do not call exit here - or the signal will not be handled correctly
}
void printAbortMessage(__attribute__ ((unused)) int aSignalNumber)
{
printf("\n\n *** " APPNAME " version " APPRELEASE "" APPFLAVOUR " closed due to an"
" unrecoverable program error.\n"
" *** Please e-mail all of the above output to"
" umtsmon-develop@lists.sourceforge.net,\n"
" *** Or go to the " APPNAME " website and file a bug.\n\n\n");
// do not call exit here - or the signal will not be handled correctly
}

@ -0,0 +1,744 @@
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
<class>mainwindow</class>
<widget class="TQMainWindow">
<property name="name">
<cstring>mainwindow</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>358</width>
<height>227</height>
</rect>
</property>
<property name="caption">
<string>umtsmon mainwindow</string>
</property>
<property name="icon">
<pixmap>umtsmon-22x22.png</pixmap>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<spacer row="0" column="0">
<property name="name">
<cstring>spacer11_2</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Fixed</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>2</height>
</size>
</property>
</spacer>
<spacer row="2" column="0">
<property name="name">
<cstring>spacer11_3</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Fixed</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>2</height>
</size>
</property>
</spacer>
<widget class="LCDDisplay" row="1" column="0">
<property name="name">
<cstring>theLCDDisplay</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>0</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>336</width>
<height>88</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>336</width>
<height>88</height>
</size>
</property>
</widget>
</grid>
</widget>
<menubar>
<property name="name">
<cstring>MenuBar</cstring>
</property>
<property name="frameShape">
<enum>MenuBarPanel</enum>
</property>
<item text="&amp;Connection" name="Connection">
<action name="menu_connection_managerprofile"/>
<action name="menu_connection_radiopreferences"/>
<action name="menu_connection_select_nw_operator"/>
<separator/>
<action name="menu_connection_connect"/>
<action name="menu_connection_disconnect"/>
<separator/>
<action name="menu_connection_ejectcard"/>
<action name="menu_connection_resetcard"/>
<separator/>
<action name="menu_connection_exit"/>
</item>
<item text="&amp;SMS" name="SMS_Manager">
<action name="menu_sms_sendsms"/>
</item>
<item text="Se&amp;ttings" name="Settings">
<separator/>
<action name="menu_pin_settings"/>
<action name="menu_pin_change"/>
<action name="menu_pin_enable"/>
<action name="menu_pin_disable"/>
<separator/>
<action name="menu_settings_SetLanguage"/>
<separator/>
<action name="menu_settings_AutoConnect"/>
</item>
<item text="&amp;Help" name="helpMenu">
<separator/>
<action name="menu_help_help"/>
<action name="menu_help_about"/>
<separator/>
<action name="menu_help_systeminfo"/>
<action name="menu_help_autodetectionlog"/>
</item>
</menubar>
<toolbars>
<toolbar dock="2">
<property name="name">
<cstring>Toolbar</cstring>
</property>
<property name="horizontallyStretchable">
<bool>false</bool>
</property>
<property name="label">
<string>Toolbar</string>
</property>
<widget class="TQPushButton">
<property name="name">
<cstring>toolbar_button_profiles</cstring>
</property>
<property name="text">
<string></string>
</property>
<property name="pixmap">
<pixmap>address-book-new-22x22.png</pixmap>
</property>
<property name="toolTip" stdset="0">
<string>manage profiles</string>
</property>
</widget>
<separator/>
<widget class="TQPushButton">
<property name="name">
<cstring>toolbar_button_connect</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string></string>
</property>
<property name="pixmap">
<pixmap>network-transmit-receive-22x22.png</pixmap>
</property>
<property name="toolTip" stdset="0">
<string>Connect with default Profile</string>
</property>
</widget>
<widget class="TQPushButton">
<property name="name">
<cstring>toolbar_button_disconnect</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string></string>
</property>
<property name="iconSet">
<iconset>network-offline-22x22.png</iconset>
</property>
<property name="toolTip" stdset="0">
<string>disconnect</string>
</property>
</widget>
<separator/>
<widget class="TQPushButton">
<property name="name">
<cstring>toolbar_button_sms</cstring>
</property>
<property name="text">
<string></string>
</property>
<property name="pixmap">
<pixmap>mail-message-new-22x22.png</pixmap>
</property>
<property name="toolTip" stdset="0">
<string>create a new sms</string>
</property>
</widget>
<separator/>
<widget class="TQPushButton">
<property name="name">
<cstring>toolbar_button_sysInfo</cstring>
</property>
<property name="text">
<string></string>
</property>
<property name="pixmap">
<pixmap>applications-system-22x22.png</pixmap>
</property>
<property name="toolTip" stdset="0">
<string>pops up a dialog with system information.</string>
</property>
</widget>
</toolbar>
</toolbars>
<customwidgets>
<customwidget>
<class>LCDDisplay</class>
<header location="local">LCDDisplay.h</header>
<sizehint>
<width>336</width>
<height>88</height>
</sizehint>
<container>0</container>
<sizepolicy>
<hordata>1</hordata>
<verdata>1</verdata>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
<pixmap>image0</pixmap>
</customwidget>
</customwidgets>
<actions>
<action>
<property name="name">
<cstring>menu_connection_connect</cstring>
</property>
<property name="toggleAction">
<bool>true</bool>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="iconSet">
<iconset></iconset>
</property>
<property name="text">
<string>Connect</string>
</property>
<property name="menuText">
<string>&amp;Connect</string>
</property>
<property name="accel">
<string>Ctrl+C</string>
</property>
</action>
<action>
<property name="name">
<cstring>menu_connection_disconnect</cstring>
</property>
<property name="toggleAction">
<bool>true</bool>
</property>
<property name="on">
<bool>true</bool>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="iconSet">
<iconset></iconset>
</property>
<property name="text">
<string>Disconnect</string>
</property>
<property name="menuText">
<string>&amp;Disconnect</string>
</property>
<property name="accel">
<string>Ctrl+D</string>
</property>
</action>
<action>
<property name="name">
<cstring>menu_connection_ejectcard</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Power down card</string>
</property>
<property name="menuText">
<string>P&amp;ower down card</string>
</property>
</action>
<action>
<property name="name">
<cstring>menu_connection_resetcard</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Reset card</string>
</property>
<property name="menuText">
<string>R&amp;eset card</string>
</property>
<property name="accel">
<string></string>
</property>
</action>
<action>
<property name="name">
<cstring>menu_sms_sendsms</cstring>
</property>
<property name="iconSet">
<iconset>mail-message-new-16x16.png</iconset>
</property>
<property name="text">
<string>New SMS</string>
</property>
<property name="menuText">
<string>&amp;New SMS...</string>
</property>
<property name="accel">
<string>Ctrl+S</string>
</property>
</action>
<action>
<property name="name">
<cstring>menu_pin_settings</cstring>
</property>
<property name="toggleAction">
<bool>false</bool>
</property>
<property name="on">
<bool>false</bool>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>PIN Settings</string>
</property>
<property name="menuText">
<string>PIN Settings</string>
</property>
</action>
<action>
<property name="name">
<cstring>menu_pin_enable</cstring>
</property>
<property name="toggleAction">
<bool>true</bool>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Enable PIN</string>
</property>
<property name="menuText">
<string> &amp;Enable PIN...</string>
</property>
</action>
<action>
<property name="name">
<cstring>menu_pin_disable</cstring>
</property>
<property name="toggleAction">
<bool>true</bool>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Disable PIN</string>
</property>
<property name="menuText">
<string> &amp;Disable PIN...</string>
</property>
</action>
<action>
<property name="name">
<cstring>menu_pin_change</cstring>
</property>
<property name="toggleAction">
<bool>false</bool>
</property>
<property name="on">
<bool>false</bool>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Change PIN</string>
</property>
<property name="menuText">
<string> &amp;Change PIN...</string>
</property>
</action>
<action>
<property name="name">
<cstring>menu_help_systeminfo</cstring>
</property>
<property name="iconSet">
<iconset>applications-system-16x16.png</iconset>
</property>
<property name="text">
<string>System Info</string>
</property>
<property name="menuText">
<string>System &amp;Info</string>
</property>
<property name="accel">
<string>F2</string>
</property>
</action>
<action>
<property name="name">
<cstring>menu_help_autodetectionlog</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Autodetection log</string>
</property>
<property name="menuText">
<string>Autodetection &amp;log</string>
</property>
</action>
<action>
<property name="name">
<cstring>menu_help_about</cstring>
</property>
<property name="iconSet">
<iconset>dialog-information-16x16.png</iconset>
</property>
<property name="text">
<string>About</string>
</property>
<property name="menuText">
<string></string>
</property>
<property name="accel">
<string>F3</string>
</property>
</action>
<action>
<property name="name">
<cstring>menu_help_help</cstring>
</property>
<property name="enabled">
<bool>true</bool>
</property>
<property name="iconSet">
<iconset>help-browser-16x16.png</iconset>
</property>
<property name="text">
<string>Help</string>
</property>
<property name="menuText">
<string>&amp;Help</string>
</property>
<property name="accel">
<string>F1</string>
</property>
</action>
<action>
<property name="name">
<cstring>menu_connection_managerprofile</cstring>
</property>
<property name="iconSet">
<iconset>address-book-new-16x16.png</iconset>
</property>
<property name="text">
<string>Manage Profiles</string>
</property>
<property name="menuText">
<string>Manage &amp;Profiles...</string>
</property>
<property name="accel">
<string>Ctrl+P</string>
</property>
</action>
<action>
<property name="name">
<cstring>menu_connection_exit</cstring>
</property>
<property name="iconSet">
<iconset>system-log-out-16x16.png</iconset>
</property>
<property name="text">
<string>Quit</string>
</property>
<property name="menuText">
<string></string>
</property>
<property name="accel">
<string>Ctrl+Q</string>
</property>
</action>
<action>
<property name="name">
<cstring>menu_connection_select_nw_operator</cstring>
</property>
<property name="text">
<string>Select network operator</string>
</property>
<property name="menuText">
<string>&amp;Select network operator...</string>
</property>
</action>
<action>
<property name="name">
<cstring>menu_connection_radiopreferences</cstring>
</property>
<property name="iconSet">
<iconset>network-wireless-16x16.png</iconset>
</property>
<property name="text">
<string>Radio Preferences</string>
</property>
<property name="menuText">
<string>&amp;Radio Preferences...</string>
</property>
</action>
<action>
<property name="name">
<cstring>menu_settings_SetLanguage</cstring>
</property>
<property name="text">
<string>Set the language</string>
</property>
<property name="menuText">
<string>Set Language...</string>
</property>
</action>
<action>
<property name="name">
<cstring>menu_settings_AutoConnect</cstring>
</property>
<property name="text">
<string>Automatically connect when network is found</string>
</property>
<property name="menuText">
<string>Autoconnect</string>
</property>
</action>
</actions>
<connections>
<connection>
<sender>menu_help_about</sender>
<signal>activated()</signal>
<receiver>mainwindow</receiver>
<slot>showAboutDialog()</slot>
</connection>
<connection>
<sender>menu_connection_exit</sender>
<signal>activated()</signal>
<receiver>mainwindow</receiver>
<slot>close()</slot>
</connection>
<connection>
<sender>menu_help_systeminfo</sender>
<signal>activated()</signal>
<receiver>mainwindow</receiver>
<slot>showInfoDialog()</slot>
</connection>
<connection>
<sender>menu_pin_change</sender>
<signal>activated()</signal>
<receiver>mainwindow</receiver>
<slot>ChangePIN()</slot>
</connection>
<connection>
<sender>menu_pin_disable</sender>
<signal>activated()</signal>
<receiver>mainwindow</receiver>
<slot>DisablePINProtection()</slot>
</connection>
<connection>
<sender>menu_pin_enable</sender>
<signal>activated()</signal>
<receiver>mainwindow</receiver>
<slot>EnablePINProtection()</slot>
</connection>
<connection>
<sender>menu_sms_sendsms</sender>
<signal>activated()</signal>
<receiver>mainwindow</receiver>
<slot>PushButtonCreateSMS_clicked()</slot>
</connection>
<connection>
<sender>menu_connection_connect</sender>
<signal>activated()</signal>
<receiver>mainwindow</receiver>
<slot>ConnectPPP()</slot>
</connection>
<connection>
<sender>menu_connection_disconnect</sender>
<signal>activated()</signal>
<receiver>mainwindow</receiver>
<slot>DisconnectPPP()</slot>
</connection>
<connection>
<sender>menu_connection_managerprofile</sender>
<signal>activated()</signal>
<receiver>mainwindow</receiver>
<slot>showProfileDialog()</slot>
</connection>
<connection>
<sender>menu_connection_select_nw_operator</sender>
<signal>activated()</signal>
<receiver>mainwindow</receiver>
<slot>showNetworkOperatorDialog()</slot>
</connection>
<connection>
<sender>toolbar_button_profiles</sender>
<signal>clicked()</signal>
<receiver>mainwindow</receiver>
<slot>showProfileDialog()</slot>
</connection>
<connection>
<sender>toolbar_button_connect</sender>
<signal>clicked()</signal>
<receiver>mainwindow</receiver>
<slot>ConnectPPP()</slot>
</connection>
<connection>
<sender>toolbar_button_disconnect</sender>
<signal>clicked()</signal>
<receiver>mainwindow</receiver>
<slot>DisconnectPPP()</slot>
</connection>
<connection>
<sender>toolbar_button_sms</sender>
<signal>clicked()</signal>
<receiver>mainwindow</receiver>
<slot>PushButtonCreateSMS_clicked()</slot>
</connection>
<connection>
<sender>toolbar_button_sysInfo</sender>
<signal>clicked()</signal>
<receiver>mainwindow</receiver>
<slot>showInfoDialog()</slot>
</connection>
<connection>
<sender>menu_connection_radiopreferences</sender>
<signal>activated()</signal>
<receiver>mainwindow</receiver>
<slot>showRadioPreferences()</slot>
</connection>
<connection>
<sender>menu_settings_SetLanguage</sender>
<signal>activated()</signal>
<receiver>mainwindow</receiver>
<slot>menu_settings_SetLanguage_activated()</slot>
</connection>
<connection>
<sender>menu_settings_AutoConnect</sender>
<signal>activated()</signal>
<receiver>mainwindow</receiver>
<slot>menu_settings_AutoConnect_activated()</slot>
</connection>
</connections>
<includes>
<include location="local" impldecl="in implementation">Query.h</include>
<include location="global" impldecl="in implementation">ntqtimer.h</include>
<include location="global" impldecl="in implementation">ProgressDialog.h</include>
<include location="local" impldecl="in declaration">infodialog.h</include>
<include location="local" impldecl="in declaration">aboutdialog.h</include>
<include location="local" impldecl="in declaration">enterpindialog.h</include>
<include location="local" impldecl="in declaration">enterpukdialog.h</include>
<include location="local" impldecl="in implementation">Internationalisation.h</include>
<include location="local" impldecl="in declaration">smsdialog.h</include>
<include location="local" impldecl="in declaration">Profile.h</include>
<include location="local" impldecl="in declaration">MonthlyTraffic.h</include>
<include location="local" impldecl="in declaration">manageprofiles.h</include>
<include location="local" impldecl="in declaration">networkoperatorwizard.h</include>
<include location="local" impldecl="in declaration">PPPConnection.h</include>
<include location="local" impldecl="in implementation">PPPErrorLogsDialog.h</include>
<include location="local" impldecl="in implementation">radiopreferences.h</include>
<include location="local" impldecl="in declaration">SetLanguageDialog.h</include>
<include location="local" impldecl="in implementation">mainwindow.ui.h</include>
</includes>
<forwards>
<forward>class TQTimer;</forward>
<forward>class Device;</forward>
<forward>class UIState;</forward>
<forward>class Internationalisation;</forward>
</forwards>
<variables>
<variable>int receivedBytes;</variable>
<variable>int sendBytes;</variable>
<variable access="private">ConnectionBaseClass* theConnectionPtr;</variable>
<variable access="private">Internationalisation* myI18n;</variable>
<variable access="private">UIState* theUIStatePtr;</variable>
<variable access="private">friend class UIState;</variable>
<variable>enum PINState {ALL_ENTRIES_OFF, PIN_ENABLED, PIN_DISABLED};</variable>
</variables>
<slots>
<slot>showAboutDialog()</slot>
<slot>showInfoDialog()</slot>
<slot>DisablePINProtection()</slot>
<slot>EnablePINProtection()</slot>
<slot>ChangePIN()</slot>
<slot>PushButtonCreateSMS_clicked()</slot>
<slot access="private">showPPPErrorLogsDialog()</slot>
<slot returnType="bool">DisconnectPPP()</slot>
<slot returnType="bool">ConnectPPP()</slot>
<slot>showProfileDialog()</slot>
<slot>showNetworkOperatorDialog()</slot>
<slot>showRadioPreferences()</slot>
<slot>menu_settings_SetLanguage_activated()</slot>
<slot>menu_settings_AutoConnect_activated()</slot>
</slots>
<functions>
<function access="private" specifier="non virtual">updateNetworkData()</function>
<function access="private" specifier="non virtual">init()</function>
<function access="private" specifier="non virtual" returnType="bool">checkRegistered(bool isShowPopups=true)</function>
<function access="private" specifier="non virtual" returnType="bool">ifATPortAvailableRunExec( TQDialog * aDialogToExecPtr )</function>
<function access="private" specifier="non virtual" returnType="bool">ifPPPInactiveRunExec( TQDialog * aDialogToExecPtr )</function>
<function>setI18nRef( Internationalisation&amp; anI18nRef )</function>
<function access="private" specifier="non virtual">setPINmenu(PINState myPINState)</function>
<function access="private" specifier="non virtual">setConnectButtons(void)</function>
<function access="public" specifier="non virtual">setNewConnectionBasePtr(void)</function>
</functions>
<pixmapinproject/>
<layoutdefaults spacing="6" margin="11"/>
<includehints>
<includehint>src/view/LCDDisplay.h</includehint>
</includehints>
</UI>

@ -0,0 +1,557 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006, 2007, 2008, 2009 Klaas van Gend, Christofer Wesseling
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/****************************************************************************
** ui.h extension file, included from the uic-generated form implementation.
**
** If you want to add, delete, or rename functions or slots, use
** TQt Designer to update this file, preserving your code.
**
** You should not define a constructor or destructor in this file.
** Instead, write your code in functions called init() and destroy().
** These will automatically be called by the form's constructor and
** destructor.
*****************************************************************************/
#include "umtsmon_global.h"
#include "TheDeviceManagerSingleton.h"
#include "PPPConnection.h"
#include "Popup.h"
#include "UIState.h"
#include "ntqlabel.h"
#include "ntqlineedit.h"
#include "ntqtextedit.h"
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
// it's actually defined in main.cpp
extern const char* theGeneralAutoConnectSettingName;
void mainwindow::init()
{
theConnectionPtr = new DummyConnection();
setCaption("UMTSmon");
menu_help_about->setMenuText( tr("&About %1").arg(APPNAME) );
menu_connection_exit->setMenuText(tr("&Quit %1").arg(APPNAME) );
Toolbar->setCaption(APPNAME" Toolbar");
// FIXME: for now, this will automatically handle the SIMHandler.askforPIN().
theUIStatePtr = new UIState(this);
theConnectionPtr->attach(theUIStatePtr);
// the autoconnect item is a toggle one
menu_settings_AutoConnect->setToggleAction(true);
menu_settings_AutoConnect->setOn(TheSettingsSingleton::getTQSRef().readBoolEntry(theGeneralAutoConnectSettingName, false));
}
void mainwindow::showAboutDialog()
{
DEBUG5("About dialog clicked\n");
AboutDialogUmtsmon myDialog;
myDialog.versionlabel->setText("<b>"APPNAME"</b> version <b>"APPRELEASE "" APPFLAVOUR "</b>");
// no AT commands in this dialog - no exec() prevention needed
myDialog.exec();
}
void mainwindow::showInfoDialog()
{
DEBUG5("info dialog clicked\n");
if (theUIStatePtr->getState() > UIState::REGISTERED)
{
Popup::Info(tr("Sorry, the Info dialog cannot be shown\nwhilst a PPP connection exists."), this);
return;
}
if (theUIStatePtr->getState() < UIState::REGISTERING)
{
Popup::Info(tr("Sorry, the Info dialog cannot be shown right now."), this);
return;
}
InfoDialogUmtsmon myDialog;
myDialog.lbl_pppd_version->setText(theConnectionPtr->getPPPVersion());
myDialog.exec();
}
void mainwindow::setPINmenu(PINState myPINState)
{
bool isOn = (myPINState == PIN_ENABLED);
bool isEnabled = (myPINState == PIN_DISABLED);
menu_pin_enable->setOn(isOn);
menu_pin_enable->setEnabled(isEnabled);
menu_pin_disable->setOn(isEnabled);
menu_pin_disable->setEnabled(isOn);
menu_pin_change->setEnabled(isOn);
}
void mainwindow::DisablePINProtection()
{
SIMHandler mySIMHandler;
EnterPIN myPIN;
myPIN.enableValidator();
myPIN.setSIMHandlerPtr(&mySIMHandler);
myPIN.exec(); // shows the dialog, blocking all other..
if(myPIN.result() == TQDialog::Rejected)
return;
if(!mySIMHandler.setPINActive(false,myPIN.pinField->text(),this))
Popup::Warning(tr("Disabling PIN protection failed.\n"
"Try again, and be sure to use the correct current PIN!"), this);
else
{
//switch the toggle state....
setPINmenu(PIN_DISABLED);
Popup::Info(tr("Disabling PIN protection was successful."), this);
}
}
void mainwindow::EnablePINProtection()
{
SIMHandler mySIMHandler;
EnterPIN myPIN;
myPIN.enableValidator();
myPIN.setSIMHandlerPtr(&mySIMHandler);
myPIN.exec(); // shows the dialog, blocking all other..
if(myPIN.result() == TQDialog::Rejected)
return;
if(!mySIMHandler.setPINActive(true,myPIN.pinField->text(),this))
Popup::Warning(tr("Enabling PIN protection failed.\n"
"Try again, and be sure to use the correct current PIN!"), this);
else
{
setPINmenu(PIN_ENABLED);
Popup::Info(tr("Enabling PIN protection was successful."), this);
}
}
void mainwindow::ChangePIN()
{
DEBUG5("change PIN settings clicked\n");
SIMHandler mySIMHandler;
EnterPIN myCurrentPIN;
myCurrentPIN.enableValidator();
myCurrentPIN.setSIMHandlerPtr(&mySIMHandler);
myCurrentPIN.errorMessage->setText(tr("Please enter your current PIN."));
myCurrentPIN.exec(); // shows the dialog, blocking all other..
if(myCurrentPIN.result() == TQDialog::Rejected) return;
EnterPIN myNewPIN;
myNewPIN.enableValidator();
myNewPIN.setSIMHandlerPtr(&mySIMHandler);
myNewPIN.errorMessage->setText(tr("Please enter your NEW pin."));
myNewPIN.exec(); // shows the dialog, blocking all other..
if(myNewPIN.result() == TQDialog::Rejected) return;
EnterPIN myNewPINsec;
myNewPINsec.enableValidator();
myNewPINsec.setSIMHandlerPtr(&mySIMHandler);
myNewPINsec.errorMessage->setText(tr("Please enter your NEW pin again."));
myNewPINsec.exec(); // shows the dialog, blocking all other..
if(myNewPINsec.result() == TQDialog::Rejected) return;
if(!myNewPINsec.pinField->text().contains(myNewPIN.pinField->text() ) )
{
Popup::Warning(tr("Changing PIN failed.\n"
"New PIN and verify PIN were not same, please try again!"), this);
}
else if(! mySIMHandler.setNewPIN(myCurrentPIN.pinField->text(),myNewPIN.pinField->text(),this))
{
Popup::Warning(tr("Changing PIN failed.\n"
"Try again, and be sure to use the correct current PIN!"), this);
}
else
{
Popup::Info(tr("PIN changed successfully."), this);
}
}
void mainwindow::PushButtonCreateSMS_clicked()
{
DEBUG5("mainwindow::PushButtonCreateSMS_clicked()\n");
if (checkRegistered()==true)
{
Popup::WarningWithMemory("SMSMayFailMsg", tr("The text message (SMS) part"
" of umtsmon is not very stable. It may not work at all.\n"
"Please set your expectations accordingly..."), this);
smsdialog myDialog;
ifATPortAvailableRunExec(&myDialog);
}
else
{
Popup::Warning(tr("You are not connected to a network yet.\n"
"SMS functions are unavailable."), this);
}
}
void mainwindow::showPPPErrorLogsDialog()
{
PPPErrorLogsDialog myPPPDialog;
TQStringList::Iterator it;
if (theConnectionPtr->thePPPDStdOut.count() > 0)
{
for (it = theConnectionPtr->thePPPDStdOut.begin();
it != theConnectionPtr->thePPPDStdOut.end(); ++it )
{
myPPPDialog.StdOutTextBox->append(*it);
}
}
else
myPPPDialog.StdOutTextBox->append(
tr("<<PPP did not provide any stdout information>>"));
if (theConnectionPtr->thePPPDStdErr.count() > 0)
{
for (it = theConnectionPtr->thePPPDStdErr.begin();
it != theConnectionPtr->thePPPDStdErr.end(); ++it )
{
myPPPDialog.StdErrTextBox->append(*it);
}
}
else
myPPPDialog.StdErrTextBox->append(
tr("<<PPP did not provide any stderr information>>"));
myPPPDialog.exec();
}
void mainwindow::updateNetworkData()
{
DEBUG5("mainwindow::updateNetworkData()\n");
const int mySecondsSinceRefresh=UIState::SEC_REFRESH;
ConnectionInfo* myCIPtr = TheDeviceManagerSingleton::getConnectionInfoPtr();
if (myCIPtr == NULL)
return;
// there's three situations here:
// 1) minimized - display in title bar
// 2) maximized, in network tab - update fields inside that tab
// 3) maximized, not in network - do nothing
theConnectionPtr->isConnectionActive();
try { myCIPtr->refresh(); }
catch (MonthRolloverException)
{
Popup::Warning(tr("Your computer just ran into a new month.\n"
"Due to limitations of pppd, we cannot account new "
"traffic to the new month. Please close the connection "
"and reconnect at your earliest convenience."));
}
catch (OverThresholdException e)
{
if (e.getThreshReached()==OverThresholdException::TRAFFIC)
Popup::Warning(tr("You are over your data limit treshold."));
else
Popup::Warning(tr("You are over your time limit treshold."));
}
// and update title bar or fields with data
if (isMinimized())
{
DEBUG5("umtsmon minimized - change titlebar\n");
TQString myRT = myCIPtr->getRadiotype();
TQString myTotalName = APPNAME " " + myRT + " " + myCIPtr->getSignalQualityString();
setCaption( myTotalName );
}
else
{
setCaption(APPNAME);
// only the last one needs to have the LCDDisplay redraw
theLCDDisplay->setStrength(myCIPtr->getSignalQuality(), false);
theLCDDisplay->setRoaming( myCIPtr->isRoaming());
theLCDDisplay->setOperatorName( myCIPtr->getOperatorName(), false);
theLCDDisplay->setRadioType( myCIPtr->getRadiotype(), false );
theLCDDisplay->setUpload(myCIPtr->getCounterBytesSent(),
myCIPtr->getUploadDelta() / mySecondsSinceRefresh, false);
theLCDDisplay->setDownload(myCIPtr->getCounterBytesReceived(),
myCIPtr->getDownloadDelta() / mySecondsSinceRefresh, false);
theLCDDisplay->setConnectedTime(myCIPtr->getSecondsConnected(), false);
// alternate in the display between the total time and total bytes
static int theVisualCounter = 0;
theVisualCounter++;
if (theVisualCounter < 3)
theLCDDisplay->setTotalTraffic(
myCIPtr->getTotalTraffic(),
myCIPtr->getTrafficThresholdStatus(), true);
else
{
theLCDDisplay->setTotalTime(
myCIPtr->getTotalSecondsConnected(),
myCIPtr->getTimeThresholdStatus(), true);
if (theVisualCounter >4)
theVisualCounter = 0;
}
}
}
// no need to pass any state info - we can get that from
// the UIState class :-D
void mainwindow::setConnectButtons(void)
{
bool isConnectEnabled = false;
bool isConnectOn = false;
bool isDisconnectEnabled = false;
switch(theUIStatePtr->getState())
{
case UIState::NO_DEVICE:
case UIState::DETECTING_DEVICE:
case UIState::DEVICE_UNUSABLE:
case UIState::SIM_CHECK:
case UIState::REGISTERING:
case UIState::PPPDISCONNECTING:
// these seven states all have none of the buttons enabled
break;
case UIState::REGISTERED:
isConnectEnabled = true;
break;
case UIState::PPPCONNECTED:
isDisconnectEnabled = true;
// deliberately no break here
case UIState::PPPCONNECTING:
isConnectOn = true;
break;
}
// and set all UI items in the right state:
menu_connection_connect->setOn( isConnectOn );
menu_connection_connect->setEnabled( isConnectEnabled );
menu_connection_disconnect->setOn( !isConnectOn );
menu_connection_disconnect->setEnabled( isDisconnectEnabled );
toolbar_button_connect->setEnabled( isConnectEnabled );
toolbar_button_disconnect->setEnabled( isDisconnectEnabled );
}
bool mainwindow::DisconnectPPP()
{
DEBUG4("umtsmonmain::DisconnectPPP\n");
theUIStatePtr->setState(UIState::PPPDISCONNECTING);
theConnectionPtr->stopConnection();
return true;
}
bool mainwindow::checkRegistered(bool isShowPopups)
{
if (theUIStatePtr->getState()==UIState::REGISTERED)
return true;
if (theUIStatePtr->getState()==UIState::REGISTERING && isShowPopups)
Popup::Info("There is no connection with a mobile network yet.\n"
"Please wait a few more seconds. If the problem remains,"
"try selecting another network operator.");
return false;
}
bool mainwindow::ConnectPPP()
{
DEBUG3("umtsmonmain::ConnectPPP\n");
// check if we are registered on a network already
if (checkRegistered()==false)
return false;
// we are - let's start the PPP!
// startConnection doesn't block for more than 6 seconds
// - so we can do relatively adequate progress reports
ProgressDialog myProgress(this, tr("Setting up Internet Connection"));
myProgress.setMaxTime(30);
// connection will take time anyway, so better show progress from start
myProgress.start(0);
// FIXME: all the tricks are still here in the UI code :-(
theUIStatePtr->setState(UIState::PPPCONNECTING);
if(theConnectionPtr->startConnection()==false)
goto problems;
DEBUG2("thePPPConnection.startConnection() returned without indicating problems\n");
while (theConnectionPtr->isConnectionStarting())
{
if (myProgress.runOneSecond() == false)
{
// Apparently, the user pressed cancel?!
goto cleanup;
}
}
myProgress.finish();
if (theConnectionPtr->hasErrors())
goto problems;
emit theUIStatePtr->update();
return true;
//---------------------
problems:
DEBUG1("start PPP NOT successful :-(\n");
// FIXME: Do we still need this warning message?
Popup::Warning(tr("Failed to start PPP.\n"
"Please re-run umtsmon from the commandline with -v5 and check the output."), this);
cleanup:
sleep(1);
DisconnectPPP();
emit theUIStatePtr->update();
return false;
}
void mainwindow::showProfileDialog()
{
DEBUG5(" profile dialog button clicked\n");
if (theUIStatePtr->getState() <= UIState::REGISTERED)
{
ManageProfiles myDialog;
myDialog.exec();
}
else
{
// FIXME: it's better to adjust the button state
Popup::Warning(tr("Please do not change\nthe profile whilst connected."), this);
}
}
void mainwindow::showNetworkOperatorDialog()
{
DEBUG5(" network operator button clicked\n");
// Only allow switching of operator if no connection active
if (theUIStatePtr->getState() <= UIState::REGISTERED)
{
NetworkOperatorWizard myDialog;
myDialog.exec();
if(myDialog.result() == TQDialog::Accepted)
emit theUIStatePtr->update();
}
}
/** executes the dialog (i.e. aDialogToExecPtr->exec())
* if either of these conditions is met:
* a) the card has more than one serial port
* b) there is no running PPP session.
* Otherwise it will throw a warning dialog.
* @param aDialogToExecPtr TQDialog subclass to run exec() on
* @returns true if dialog was executed, false if not
*/
bool mainwindow::ifATPortAvailableRunExec( TQDialog* aDialogToExecPtr)
{
DEBUG5("mainwindow::ifATPortAvailableRunExec()\n");
// test for condition A)
if (TheDeviceManagerSingleton::getDeviceCapsRef().isSinglePort()==false)
{
if (aDialogToExecPtr!=NULL)
aDialogToExecPtr->exec();
return true;
}
// test for condition B)
DEBUG5("only one port available - check if PPP is running?\n");
return ifPPPInactiveRunExec(aDialogToExecPtr);
}
/** executes the dialog (i.e. aDialogToExecPtr->exec())
* IF AND ONLY IF there is no running PPP session.
* Otherwise it will throw a warning dialog.
* @param aDialogToExecPtr TQDialog subclass to run exec() on
* @returns true if dialog was executed, false if not
*/
bool mainwindow::ifPPPInactiveRunExec(TQDialog* aDialogToExecPtr)
{
DEBUG5("mainwindow::ifPPPInactiveRunExec()\n");
if (theUIStatePtr->getState()==UIState::REGISTERED)
{
ConnectionInfoInhibitor myParallelATPreventer;
if (aDialogToExecPtr!=NULL)
aDialogToExecPtr->exec();
return true;
}
Popup::Warning(tr("PPP is active, cannot run this in parallel."), this);
return false;
}
void mainwindow::showRadioPreferences()
{
DEBUG1(" showRadioPreferences dialog requested\n");
// this window is modeless - one can keep it open
RadioPreferences myDialog;
myDialog.exec();
myDialog.disconnect();
}
void mainwindow::menu_settings_SetLanguage_activated()
{
SetLanguageDialog myDialog;
myDialog.setI18nPtr(myI18n);
myDialog.exec();
}
void mainwindow::setI18nRef( Internationalisation& anI18nRef )
{
myI18n = &anI18nRef;
}
void mainwindow::menu_settings_AutoConnect_activated()
{
Profile myProfile;
if (myProfile.getWasConnectionSuccess())
TheSettingsSingleton::getTQSRef().writeEntry(theGeneralAutoConnectSettingName,
menu_settings_AutoConnect->isOn());
else
Popup::Info(tr("You can only enable autoconnect"
" once you have made a successful connection."), this);
}
void mainwindow::setNewConnectionBasePtr(void)
{
// this function is called by UIState
// if so - we'd better update the Connection pointer
ConnectionBaseClass* newPtr;
if (TheDeviceManagerSingleton::getDeviceCapsRef().getDeviceType()
== DeviceCapabilities::OPTION_HSO)
newPtr = new HSOConnection(*theConnectionPtr);
else
newPtr = new PPPConnection(*theConnectionPtr);
delete theConnectionPtr;
theConnectionPtr = newPtr;
}

@ -0,0 +1,77 @@
ADVANCED TRICKS FOR UMTSMON
===========================
WARNING: Do not use these tricks unless you need to.
CONTENTS:
---------
1. override autodetection ports
2. non-gui things
a. set custom CID
b. use priviledged pppd options and 'call'
1. override autodetection ports
-------------------------------
To be written, see the man page for --serial=
2a. Set custom CID
-------------------
For connections with some USB connections to cell phones, one needs to set
the "CID" to a different number than 1 - because "1" is already taken by
the phone.
WHEN DO YOU NEED IT:
if you cannot make a connection and looking at the log, you see
ERROR as answer following the "AT+CGDCONT=1," Query...
WHAT TO DO:
* open ~/.umtsmon/umtsmonrc
* find your profile. It should be in the [ConnectionProfiles] Section.
* it has entries in the form of PROFILENAME/prof/KEY=VALUE
* add the following two lines in there (and replace PROFILENAME):
PROFILENAME/prof/CIDprefix=###
PROFILENAME/prof/CID=2
Where the ### should be replaced by your CID. The most obvious candidates
are:
*99
*99*** (umtsmon uses this one as default)
*99*
Examples & more info at: http://www.to-st.de/download/linux/eeepc/umtsmon
or ask Tobias Stoeber <tobi@to-st.de>
2b. Use priviledged pppd options and 'call'
-------------------------------------------
WHEN DO YOU NEED IT:
* If you need "noauth" or other priviledged options to pppd
* If you need other pppd options that the umtsmon Profile dialog does
not provide.
WHAT TO DO:
The below explains what to do for adding noauth. If you need other
things, please think first and then do what you need.
(as root):
* go to /etc/ppp/peers
* echo "noauth" > umtsmoncustom
(as yourself, i.e. a normal user):
* open ~/.umtsmon/umtsmonrc
* find the Section [ConnectionProfiles]
* add the following for your active profile (identified in that section as
ActiveProfile=...)
PROFILENAME/prof/call=umtsmoncustom
If you now start umtsmon with the -v5 option, make a connection and quit
umtsmon, you should now see in the logs that pppd also used the above.

@ -0,0 +1,96 @@
.\" Hey, EMACS: -*- nroff -*-
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.TH UMTSMON 1 "March 20, 2009"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
.\" .nh disable hyphenation
.\" .hy enable hyphenation
.\" .ad l left justify
.\" .ad b justify to both left and right margins
.\" .nf disable filling
.\" .fi enable filling
.\" .br insert line break
.\" .sp <n> insert n+1 empty lines
.\" for manpage-specific macros, see man(7)
.SH NAME
umtsmon \- a tool to handle UMTS (3G) devices in Linux
.SH SYNOPSIS
.B umtsmon
.RI [ options ]
.br
.SH DESCRIPTION
.PP
.\" TeX users may be more comfortable with the \fB<whatever>\fP and
.\" \fI<whatever>\fP escape sequences to invode bold face and italics,
.\" respectively.
\fBumtsmon\fP is a program that handles your UMTS (3G) devices for you. You can configure PPP settings, and \fBumtsmon\fP connects you to the internet with your umts card/usb-stick. Sending and receiving SMS is also possible.
.TP
Most of the recent UMTS devices (especially the USB stick look-alikes) need an extra application to switch off the virtual CDROM-device before the modem devices show up. There are at least two candiates for this job: usb_modeswitch and ozerocdoff. \fBumtsmon\fP tries to find and execute usb_modeswitch when it thinks it is necessary for the current device.
.TP
\fBumtsmon\fP can use two types of UMTS devices: those who offer one or more serial interfaces (internally) and the newer UMTS cards made by Option (a belgian hardware manufacturer) driven by the "hso" driver.
.TP
For the serial type devices the internet connection is made by the ppp daemon "pppd". \fBumtsmon\fP calls "pppd" with all necessary parameters. It's not necessary to edit any extra configuration files for ppp outside \fBumtsmon\fP.
.TP
The hso devices bring along their own network interface, so "pppd" is not used here. The ppp options described below are silently ignored if a hso device is used.
.SH OPTIONS
The program follows the usual GNU command line syntax, with long
options starting with two dashes ('-').
.TP
.B \-h, \-\-help
Show summary of options.
.TP
.B \-\-force-autodetect
force autodetection of the modem devices, don't use info from config file.
.TP
.B \-\-autoconnect
set autoconnect to true (persistent!).
.TP
.B \-\-no-autoconnect
set autoconnect to false (persistent!).
.TP
.B \-\-language <locale>
set the language, e.g. nl or pt_BR
.TP
.B \-s <at>[,ppp], \-\-serial <at>[,ppp]
will prevent autodetection of devices and use serial port <at>[,<ppp>], where <at> is the device name to be used sending AT commands to the modem and (if necessary) a device name <ppp> for use with the ppp daemon.
.TP
.B \-v <lvl>[,ppplvl], \-\-verbosity <lvl>[,ppplvl]
set verbosity level, 1=little (default), 6=all, separate verbosity level can be set for ppp daemon.
.TP
.B \-\-default-profile <profilename>
sets the default profile to connect with (persistent!)
.SH FILES
.TP
.I ~/.umtsmon/umtsmonrc
The settings of \fBumtsmon\fP are stored in a configuration file, usually under the user's home directory.
It contains the defined profiles, the device configuration and the traffic statistics.
If you encounter problems with your modem device, after replacing it or doing a firmware upgrade, try starting \fBumtsmon\fP with the option \-\-force-autodetect to ignore the saved device settings and do the autodetection.
.I ~/.umtsmon/.umtsmonrc.lock
is used as a lock file during some critical internal tasks. It has a length of zero bytes.
.SH UMTSMON AS ROOT
Please do not run \fBumtsmon\fP as root. Even though it can operate as root,
it is designed not to do so. If you cannot use \fBumtsmon\fP as normal user,
you probably need to add yourself to the \fBdialout\fP and/or \fBuucp\fP groups.
.SH BUGS
There are of course a lot, as \fBumtsmon\fP is still under heavy development.
If you think you suffer from a bug you can contact the developer mailing list
<umtsmon-develop@lists.sourceforge.net>, describe your problem and attach a
copy of the debug output you receive from \fBumtsmon -v 5\fP.
.TP
Known major bugs:
* umtsmon cannot perform autodetection correctly on some 2.6.20 Linux kernels.
* umtsmon doesn't work at all with bluetooth right now.
.SH SEE ALSO
.BR usb_modeswitch (8),
.BR ozerocdoff (8)
.br
.SH AUTHOR
umtsmon was written by Klaas van Gend and others in 2006, 2007, 2008 and 2009.
.PP
This manual page was written by Martin Dummer <martin.dummer@gmx.net>,
for the Debian project (but may be used by others).

@ -0,0 +1,65 @@
# Copyright 1999-2007 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: /cvsroot/umtsmon/umtsmon/packaging/umtsmon.ebuild,v 1.1 2008/02/08 20:57:36 kvangend Exp $
inherit eutils qt3
DESCRIPTION="UMTSmon is a tool to control and monitor a wireless mobile network card (GPRS, EDGE, WCDMA, UMTS, EV-DO, HSDPA)"
HOMEPAGE="http://umtsmon.sourceforge.net/"
SRC_URI="mirror://sourceforge/umtsmon/${P}.src.tar.gz"
LICENSE="GPL-2"
SLOT="0"
KEYWORDS="~amd64 ~x86"
IUSE=""
DEPEND="$(qt_min_version 3.3)
dev-libs/libusb"
RDEPEND="${DEPEND}
net-dialup/ppp
sys-apps/pcmciautils"
# for i18n support
# Supported languages and translated documentation
# Be sure all languages are prefixed with a single space!
MY_AVAILABLE_LINGUAS=" nl de pt_PT pt_BR"
IUSE="${IUSE} ${MY_AVAILABLE_LINGUAS// / linguas_}"
src_compile() {
eqmake3 || die "eqmake3 failed"
emake || die "emake failed"
#for i18n support
local MY_LINGUAS="" lang
for lang in ${MY_AVAILABLE_LINGUAS} ; do
if use linguas_${lang} ; then
MY_LINGUAS="${MY_LINGUAS} ${lang}"
fi
done
if [[ -z "${MY_LINGUAS}" ]] ; then
#If no language is selected, install 'em all
MY_LINGUAS="${MY_AVAILABLE_LINGUAS}"
fi
einfo "Following langpacks will be installed:"
einfo " ${MY_LINGUAS}"
for lang in ${MY_LINGUAS}; do
lrelease i18n/umtsmon_${lang}.ts \
|| die "failed to install langpack for ${lang} language"
done
}
src_install() {
dobin umtsmon || die "dobin failed"
domenu umtsmon.desktop
doicon images/128
# for i18n support
insinto /usr/share/umtsmon/translations
doins i18n/*.qm
dodoc AUTHORS README TODO
}

@ -0,0 +1,153 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "FileStuff.h"
#include <ntqdir.h>
#include <ntqstring.h>
#include <ntqregexp.h>
TQString
FileStuff::getFileFirstLine(const TQString& aFileName)
{
TQFile myFile(aFileName);
if (myFile.open(IO_ReadOnly))
{
TQTextStream in(&myFile);
TQString myLine = in.readLine().stripWhiteSpace();
myFile.close();
return myLine;
}
return NULL;
}
bool
FileStuff::doesFileContainString(
const TQString& aFileName,
const TQRegExp& aSubString)
{
TQFile myFile(aFileName);
if (myFile.open(IO_ReadOnly) != true)
{
return false;
}
TQString myLine;
bool myResult = false;
TQTextStream in(&myFile);
while(!in.atEnd())
{
myLine = in.readLine().stripWhiteSpace();
// perform substring searching
if (aSubString.search(myLine,0) != -1)
{
myResult = true;
break; // breaks while loop
}
}
myFile.close();
return myResult;
}
bool
FileStuff::doesFileExist(const TQString& aFileName)
{
return TQFile::exists(aFileName);
}
FileStuff::ReadWrite
FileStuff::isFileReadWrite(const TQString& aFileName)
{
TQFile myFile(aFileName);
if (myFile.open(IO_ReadWrite))
{
myFile.close();
return READWRITE;
}
if (myFile.open(IO_ReadOnly))
{
myFile.close();
return READ;
}
if (myFile.open(IO_WriteOnly))
{
myFile.close();
return WRITE;
}
return NOTHING;
}
bool
FileStuff::checkForRunningProcess(const TQString& aProcessName)
{
// retrieve a sorted list of all entries in the proc filesystem
TQString myBaseDirName="/proc/";
TQDir myProcDir(myBaseDirName);
myProcDir.setFilter( TQDir::Dirs );
const TQFileInfoList* myList = myProcDir.entryInfoList();
TQFileInfoListIterator myIterator( *myList );
TQFileInfo* myFileInfo;
while ( (myFileInfo = myIterator.current()) != 0 )
{
++myIterator;
// if the dirname contains any non-number characters, including dots, skip it.
TQRegExp myNonNumberRegExp("\\D");
if (myFileInfo->fileName().contains(myNonNumberRegExp))
continue;
// and check for the ProcessName on the command line
TQString myCmdName = myBaseDirName + myFileInfo->fileName() + "/cmdline";
if (FileStuff::doesFileContainString(myCmdName, aProcessName) == true)
return true;
}
return false;
}
FileStuff::FindInDir::FindInDir(
const TQString& aDirName,
const TQString& aNameFilter,
TQDir::FilterSpec aWhatEntriesToReturn)
{
theDir.setPath(aDirName);
theDir.setNameFilter(aNameFilter);
theDir.setFilter(aWhatEntriesToReturn);
theFIListPtr = theDir.entryInfoList();
theFILIPtr = new TQFileInfoListIterator(*theFIListPtr);
}
FileStuff::FindInDir::~FindInDir()
{
delete theFILIPtr;
}
TQString
FileStuff::FindInDir::getNextEntry(void)
{
TQFileInfo* myEntryInfoPtr = theFILIPtr->current();
if (myEntryInfoPtr == NULL)
return "";
TQString myFileName = myEntryInfoPtr->absFilePath();
++(*theFILIPtr);
return myFileName;
}

@ -0,0 +1,87 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef FILESTUFF_CLASS
#define FILESTUFF_CLASS
#include <ntqregexp.h>
#include <ntqstring.h>
#include <ntqdir.h>
class FileStuff
{
public:
/** checks if a file contains a certain (sub)string.
* @returns false if file does not exist or on other errors, true if the substring was found
*/
static bool doesFileContainString(const TQString& aFileName, const TQRegExp& aSubString);
/** checks if the file exists
* @returns true if the file exists
*/
static bool doesFileExist(const TQString& aFileName);
/** reads the first line of the file
* precondition: the file must exist - check with "doesFileExist()"
* @returns NULL if file does not exist or other errors,
* a TQString with the first line (max 255 chars) otherwise
*/
static TQString getFileFirstLine(const TQString& aFileName);
/** checks if the file is readable and/or writable by the user
* @returns the corresponding value out of the enum ReadWrite. If file doesn't exist, returns NOTHING
*/
enum ReadWrite { NOTHING, READ, WRITE, READWRITE };
static ReadWrite isFileReadWrite(const TQString& aFileName);
/** checks if process is running
* @param aProcessName process name to look for
* @returns true if found at least once
*/
static bool checkForRunningProcess(const TQString& aProcessName);
/// this class abstracts the TQDir class and iterating through its output
class FindInDir
{
public:
/** constructor
* @param aDirName directory where you want to iterate through
* @param aNameFilter wildcards to limit to certain names
* @param aWhatEntriesToReturn limit to certain types of entries
* (examples are TQDir::All, TQDir::Dirs, TQDir::Files)
* (see TQDir::FilterSpec for the full list)
*/
FindInDir(const TQString& aDirName, const TQString& aNameFilter,
TQDir::FilterSpec aWhatEntriesToReturn = TQDir::All);
virtual ~FindInDir();
/** returns the (first or next) entry in the directory,
* returns an empty string if no (more) entries.
*/
TQString getNextEntry(void);
private:
TQDir theDir;
const TQFileInfoList* theFIListPtr;
TQFileInfoListIterator* theFILIPtr;
}; // end-of-class FindInDir
};
#endif // defined FILESTUFF_CLASS

@ -0,0 +1,236 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "Internationalisation.h"
#include "TheSettingsSingleton.h"
#include "FileStuff.h"
#include <ntqapplication.h>
#include <ntqtranslator.h>
#include <ntqtextcodec.h>
#include <ntqregexp.h>
#include <assert.h>
#include <stdlib.h>
bool
Internationalisation::tryLoad(TQTranslator* aTranslatorPtr, const TQString& aFileName, const TQString& aPath)
{
DEBUG5(" . searching for %s.qm in %s\n", aFileName.ascii(), aPath.ascii());
assert(aTranslatorPtr!=NULL);
if (aTranslatorPtr->load( aFileName, aPath))
{
DEBUG4(" .. found in '%s'\n", aPath.ascii());
theTranslationsDirectory= aPath;
return true;
}
return false;
}
TQTranslator*
Internationalisation::createTranslator(const TQString& aFileName, const TQString& aLocale)
{
DEBUG4("loadTranslator('%s', '%s')\n", aFileName.ascii(), aLocale.ascii());
// basic sanity check first
if (aFileName.isEmpty() || aLocale.isEmpty())
return NULL;
if (validateLocale(aLocale) == false && !aLocale.isEmpty())
{
DEBUG1("aLocale '%s' denied\n", aLocale.ascii());
return NULL;
}
// Fix up the locale if required
// i.e. pt_pt is not allowed, should be pt_PT :-(
TQString myLocale;
if (aLocale.length()>3)
{
myLocale = aLocale.left(2).lower() + "_" + aLocale.right(aLocale.length()-3).upper();
}
else
myLocale = aLocale.lower();
TQTranslator* myTranslator = new TQTranslator(0);
TQString myTQMFile = aFileName + "_" + myLocale;
DEBUG5("Translation filename: '%s'\n", myTQMFile.ascii());
// try in several locations:
// note that TQTranslator itself already tries several permutations,
// including aLocale equal to "de" if "de_AT" is not found
if (tryLoad(myTranslator, myTQMFile, "."))
goto done;
if (tryLoad(myTranslator, myTQMFile, "i18n"))
goto done;
if (tryLoad(myTranslator, myTQMFile, "/usr/local/share/" + aFileName + "/translations"))
goto done;
if (tryLoad(myTranslator, myTQMFile, "/usr/share/" + aFileName + "/translations"))
goto done;
if (tryLoad(myTranslator, myTQMFile, "/usr/lib/qt3/translations"))
goto done;
// failed:
DEBUG5(" ... NOT FOUND\n");
delete myTranslator;
myTranslator = NULL;
// just one extra: if "pt" doesn't work, try for "pt_PT"
// don't be afraid of a little recursion :-D
if (aLocale.length() == 2)
return createTranslator(aFileName, aLocale + "_" + aLocale);
return NULL;
done:
theLocale = myLocale;
return myTranslator;
}
const TQStringList
Internationalisation::getAllSupportedLocales()
{
TQStringList mySupported;
// is theTranslationsDirectory filled in?
// if not: let's try to do that ourselves... 'nl' should exist :-D
if (theTranslationsDirectory.isEmpty())
{
TQString myTempLocale = theLocale;
delete createTranslator(APPNAME, "nl");
theLocale = myTempLocale;
}
// is it still empty? Not good...
if (theTranslationsDirectory.isEmpty()==false)
{
TQString myFileName;
FileStuff::FindInDir myDir = FileStuff::FindInDir(theTranslationsDirectory,
"*.qm", TQDir::Files);
while( !( (myFileName=myDir.getNextEntry()) .isEmpty()) )
{
// remove everything before 'mon_' and everything after '.'
TQString myLang = TQStringList::split("mon_", myFileName)[1];
myLang = TQStringList::split(".", myLang)[0];
mySupported.push_back(myLang);
DEBUG5("Found i18n file %s\n", myLang.ascii());
}
}
// whatever happens, we support (American) English
mySupported.push_back("en_US");
DEBUG5("Internationalisation::getAllSupportedLocales returns a list with %d entries\n",
mySupported.count());
return mySupported;
}
void
Internationalisation::saveLocale(void)
{
assert(!theLocale.isEmpty());
assert(validateLocale(theLocale));
TheSettingsSingleton::getTQSRef().writeEntry(theLanguageSetting, theLocale);
}
bool
Internationalisation::setLocale(void)
{
TQTranslator* myTQTTranslator = createTranslator("qt", theLocale);
TQTranslator* myOwnTranslator = createTranslator(APPNAME, theLocale);
if (myOwnTranslator == NULL)
return false;
// it makes only sense to install the QT translator if we have our own
// translator. We might have our own translator without a QT translator
if (myTQTTranslator != NULL)
{
theApplicationPtr->installTranslator(myTQTTranslator);
DEBUG3("Will use specified (%s) locale for QT-internal strings\n", theLocale.ascii());
// FIXME: outcommenting the next two lines fixes i18n within valgrind...
// delete myTQTTranslator;
// myTQTTranslator = NULL;
}
else
DEBUG3("Will use default (en_US) locale for QT-internal strings\n");
theApplicationPtr->installTranslator(myOwnTranslator);
DEBUG3("Will use specified (%s) locale for " APPNAME " strings\n", theLocale.ascii());
// FIXME: outcommenting the next two lines fixes i18n within valgrind...
// delete myOwnTranslator;
// myOwnTranslator = NULL;
return true;
}
bool
Internationalisation::tryLocale(const TQString& aSuggestedLocale)
{
// If ever someone wants to make e.g. en_GB, this has to change
if (aSuggestedLocale.left(2) == "en")
{
DEBUG5("\"en\" is default language - no need to do something\n");
theLocale = "en_US";
return true;
}
if (validateLocale(aSuggestedLocale)==true)
{
theLocale = aSuggestedLocale;
if (setLocale())
{
saveLocale();
return true;
}
}
return false;
}
bool
Internationalisation::trySavedLocale(void)
{
TQString mySaved = TheSettingsSingleton::getTQSRef().readEntry(theLanguageSetting, "");
if (mySaved.isEmpty())
{
DEBUG3("No locale suggestion found in config file\n");
return false;
}
DEBUG5("Trying locale '%s' from settings file...\n", mySaved.ascii());
return tryLocale(mySaved);
}
bool
Internationalisation::validateLocale(const TQString& aLocale)
{
// allowed formats are: nl, nl_NL or nl_nl.
// No numbers, no dots, etc.
TQRegExp myRegExp_nl("^[a-z]{2}$");
TQRegExp myRegExp_nl_nl("^[a-z]{2}_[a-zA-Z0-9.\\-@]{0,15}$");
if (myRegExp_nl.search(aLocale) == 0)
return true;
if (myRegExp_nl_nl.search(aLocale) == 0)
return true;
return false;
}

@ -0,0 +1,102 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef INTERNATIONALISATION_H_
#define INTERNATIONALISATION_H_
#include <ntqapplication.h>
#include <ntqstringlist.h>
// Forward declarations
class TQTranslator;
/** this class contains all code to verify, find and load a translation file
* for umtsmon
*/
class Internationalisation
{
public:
/// constructor
Internationalisation(TQApplication* aTQApplicationPtr)
: theApplicationPtr(aTQApplicationPtr), theLocale("") {};
/// virtual destructor
virtual ~Internationalisation() {;};
/// get the currently running Locale
TQString getLocale(void)
{ if (theLocale.isEmpty()) return "en_US"; else return theLocale; };
/** searches for all available translations
* @returns a TQStringList contaning all supported i18n codes
*/
const TQStringList getAllSupportedLocales(void);
/** called by main() and SetLanguageDialog only
* Try the suggested locale
* @param aSuggestedLocale locale to validate and attempt to load
* @returns true if a suggestion was valid and installed
*/
bool tryLocale(const TQString& aSuggestedLocale);
/** called by main() only
* Try the saved setting from config file - if there is one
* @returns true if a valid setting was found and installed
*/
bool trySavedLocale(void);
private:
TQApplication* theApplicationPtr;
TQString theLocale;
/// the directory containing all translations
TQString theTranslationsDirectory;
/** internal member - some sanity checks
* @param aLocale locale to check
* @returns true if all sanity checks passed OK
*/
bool validateLocale(const TQString& aLocale);
/** internal member - actually sets the locale defined in theLocale
* @returns true if setting "theLocale" succeeded
*/
bool setLocale(void);
/// writes locale setting to config file
void saveLocale(void);
/** tries different locations for a locale file and creates the corresponding
* TQTranslator.
* the i18n file usually looks like: aFileName+"_"+aLocale+".qm"
* @param aFileName base for file name
* @param aLocale base for locale
* @returns pointer to TQTranslator instance if success, or NULL on problems
*/
TQTranslator* createTranslator(const TQString& aFileName, const TQString& aLocale);
/** (use only by createTranslator)
* try to load a translator with the filename and path
*/
bool tryLoad(TQTranslator* aTranslatorPtr, const TQString& aFileName, const TQString& aPath);
};
#endif /*INTERNATIONALISATION_H_*/

@ -0,0 +1,144 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2007 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef OBSERVERMANAGER_CLASS
#define OBSERVERMANAGER_CLASS
#include <list>
/** The ObserverManager is a class that - once inherited from -
* will take care of the administration associated to observers
* to your state.
* 0) you have a class A that has state changes
* 1) create your observer interface - usually an abstract base class
* 2) implement the observer interface in class B that needs to be
* aware of the state changes
* 3) use attach() and detach() to add/remove class B's new interface
* 4) in class A, create a notify() that uses firstObserver() and
* nextObserver() to cycle through all attached observers
*
* See also the (slightly abstracted) test/example implementation code
* in ObserverManagerTester
*/
template<class ObserverInterface>
class ObserverManager
{
public:
ObserverManager()
: theObserverListIterator(theObserverList.begin())
{DEBUG3("ObserverManager constructor\n");};
virtual ~ObserverManager()
{DEBUG3("ObserverManager destructor\n");};
/** attach yourself as an ObserverInterface
* if you attach yourself twice, you will be notified twice
* @param anObserver pointer to yourself implementing the ObserverInterface
*/
void attach(ObserverInterface* anObserver)
{
DEBUG5("ObserverManager::attach(%p)\n", anObserver);
if (anObserver != NULL)
theObserverList.push_back(anObserver);
// list change - invalidate our iterator
theObserverListIterator = theObserverList.begin();
// and give our observer it's initial state
notifyObserver(anObserver);
};
/** detach yourself as an ObserverInterface
* note: calling detach will remove *all* your ObserverInterfaces, so if you were
* attached twice, both entries will vanish
* @param anObserver pointer to yourself implementing the ObserverInterface
*/
void detach(ObserverInterface* anObserver)
{
DEBUG5("ObserverManager::detach(%p)\n", anObserver);
if (anObserver != NULL)
theObserverList.remove(anObserver);
// list change - invalidate our iterator
theObserverListIterator = theObserverList.begin();
};
protected:
/** pure virtual function, to be implemented by the inherited class
* the implementation should perform the notification of the observer pointed to.
*/
virtual void notifyObserver(ObserverInterface* anObserver) const = 0;
/** this member returns a pointer to the first Observer that is attached.
* this is definitely not re-entrant safe code
*/
ObserverInterface* firstObserver(void)
{
theObserverListIterator = theObserverList.begin();
if (theObserverListIterator != theObserverList.end())
return *theObserverListIterator;
else
return NULL;
};
/** this member returns a pointer to the next Observer that is attached.
* Only call *after* you called firstObserver().
* this is definitely not re-entrant safe code
*/
ObserverInterface* nextObserver(void)
{
theObserverListIterator++;
if (theObserverListIterator != theObserverList.end())
return *theObserverListIterator;
else
return NULL;
};
/** Copy constructor - we need to make sure that our member is copied!
*
*/
ObserverManager(const ObserverManager& anOldManager)
: theObserverListIterator(theObserverList.begin())
{
DEBUG3("ObserverManager COPY constructor\n");
// note: we only need to *copy* - it's a list of pointers!
theObserverList = anOldManager.theObserverList;
}
private:
/** in order for the automated Tester, we allow this one class to view
* our private data - if you want to add a different class, you probably
* haven't understood the design pattern completely yet.
*/
friend class OMTester;
typedef std::list<ObserverInterface*> ObserverList;
/// this is the actual list of pointers to observers
ObserverList theObserverList;
/// this iterator is used for the first/nextObserver() calls
typename ObserverList::iterator theObserverListIterator;
/** assign operator is private and not implemented
* to prevent duplication of this class instance (EffC++ item27)
* DO NOT IMPLEMENT THIS MEMBER
*/
ObserverManager& operator=(const ObserverManager& anOldManagerRef);
};
#endif // defined OBSERVERMANAGER_CLASS

@ -0,0 +1,454 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006,2007,2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "Runner.h"
#include "FileStuff.h"
#include <ntqstringlist.h>
#include <ntqfile.h>
#include <ntqfileinfo.h>
#include <ntqdir.h>
#include <assert.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
TQString Runner::theSU;
TQString Runner::thePPPD;
TQString Runner::theCHAT;
TQString Runner::thePCCARDCTL;
TQString Runner::theUSBMODESWITCH;
TQString Runner::theRUNNERTESTER;
static const char* PPPDSEARCHPATH = "/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin";
Runner::Runner(void)
{
// as all location strings are static, we only need to locate the binaries
// when the first constructor is run
if (theSU.isEmpty())
findBinaries();
memset(theStdOutPipe, 0, sizeof(theStdOutPipe));
memset(theStdErrPipe, 0, sizeof(theStdErrPipe));
}
TQString Runner::lookThroughPath(const TQString& anAppName, const char* aPath = PPPDSEARCHPATH )
{
DEBUG5("lookThroughPath(%s)\n", anAppName.ascii());
TQStringList myPathList = TQStringList::split(":", aPath);
TQStringList::Iterator myI = myPathList.begin();
for(; myI != myPathList.end(); ++myI)
{
// security: if the caller specified a custom search path,
// let's only allow paths that start with /usr or /opt...
TQString myPath = *myI;
TQFile myFile ( myPath + "/" + anAppName);
if ( myPath.startsWith("/bin",true)==false &&
myPath.startsWith("/sbin",true)==false &&
myPath.startsWith("/usr",true)==false &&
myPath.startsWith("/opt",true)==false )
{
DEBUG5(" * ignoring entry '%s' as it is not in a safe path\n",
myPath.ascii());
if (myFile.exists())
DEBUG5(" * HOWEVER, THE BINARY DID EXIST THERE\n");
continue;
}
if (myFile.exists())
{
DEBUG5(" * found %s\n", myFile.name().ascii());
return myFile.name();
}
}
DEBUG5(" *** searching %s really failed :-(\n", anAppName.ascii());
return "";
}
bool Runner::findBinaries(void)
{
DEBUG5("Runner::findBinaries()\n");
bool isEverythingPresent = true;
// for debugging / automated test purposes
theRUNNERTESTER="./RunnerTester";
///////////////////////////////////////
// find pccardctl
thePCCARDCTL = lookThroughPath("pccardctl"); // post-2.6.13
if (thePCCARDCTL.isEmpty())
thePCCARDCTL = lookThroughPath("cardctl"); // pre-2.6.13
if (thePCCARDCTL.isEmpty())
{
DEBUG2("Helper binary pccardctl/cardctl is missing\n");
isEverythingPresent = false;
}
///////////////////////////////////////
// find PPPD and CHAT
thePPPD = lookThroughPath("pppd");
theCHAT = lookThroughPath("chat");
if (thePPPD.isEmpty())
{
DEBUG2("Helper binary pppd is missing\n");
isEverythingPresent = false;
}
///////////////////////////////////////
// find tdesu/gnomesu, etc
// we have to look on the regular PATH to find those
// lookThroughPath contains some code against unsafe directories
char* myPath = getenv("PATH");
theSU = lookThroughPath("tdesu", myPath);
if (theSU.isEmpty())
theSU = lookThroughPath("gnomesu", myPath);
if (theSU.isEmpty())
theSU = lookThroughPath("gksu", myPath);
if (theSU.isEmpty())
theSU = lookThroughPath("tdesudo", myPath);
if (theSU.isEmpty())
{
DEBUG2("Helper binary *su (i.e. any known GUI frontend to su) is missing\n");
isEverythingPresent = false;
}
///////////////////////////////////////
// find icon_switch and comparable
// note that icon_switch itself is outdated, let's look for the
// best option first.
theUSBMODESWITCH = lookThroughPath("usb_modeswitch");
if (theUSBMODESWITCH.isEmpty())
theUSBMODESWITCH = lookThroughPath("huaweiAktBbo");
if (theUSBMODESWITCH.isEmpty())
theUSBMODESWITCH = lookThroughPath("icon_switch");
if (isEverythingPresent)
DEBUG5("Runner::findBinaries() completed successfully\n");
return isEverythingPresent;
}
const TQString& Runner::getPath(BinariesToRun aProgram)
{
switch(aProgram)
{
case SOMESU:
return theSU;
case PPPD:
return thePPPD;
case CHAT:
return theCHAT;
case PCCARDCTL:
return thePCCARDCTL;
case USBMODESWITCH:
return theUSBMODESWITCH;
case RUNNERTESTER:
return theRUNNERTESTER;
}
// UH-OH if we get here, something very wrong...
assert(false);
// in case of a release build... let's limit the damage
// we cannot return "" as that will be a temp object
const static TQString myEmpty = "";
return myEmpty;
}
bool Runner::isSUID(BinariesToRun aProgram)
{
DEBUG5("Runner::isSUID()\n");
if (amIRoot())
{
DEBUG2("isSUID: i am root => SUID checks skipped\n");
return true;
}
struct stat myBuf;
if (stat(getPath(aProgram).ascii(), &myBuf) != 0)
{
return false;
}
// if the file is not owned by root
// then I don't care for checking suid bits
if ( myBuf.st_uid != 0 )
return false;
// and the real check itself
if ( myBuf.st_mode & S_ISUID )
return true;
// if we're still here - it is not SUID
return false;
}
int Runner::doesPPPDexist(void)
{
TQString myPPPDPath = getPath(PPPD);
TQDir myProc("/proc");
myProc.setFilter( TQDir::Dirs );
myProc.setNameFilter ( "[0-9]*" );
const TQFileInfoList* myList = myProc.entryInfoList();
TQFileInfoListIterator myIterator( *myList );
TQFileInfo* myFileInfo =myIterator.current();
for (;(myFileInfo=myIterator.current()) != 0; ++myIterator)
{
TQString myDirName = myFileInfo->fileName();
// be warned: if you don't use the .ascii()
// myCmdLine will contain all arguments as well, separated by \0...
TQString myCmdLine = FileStuff::getFileFirstLine("/proc/"+myDirName+"/cmdline").ascii();
if (myCmdLine == myPPPDPath || myCmdLine == "pppd")
return myDirName.toLong(NULL, 10);
}
return -1;
}
bool Runner::amIRoot(void)
{
if ( geteuid()==0 || getuid()==0 )
return true;
else
return false;
}
int Runner::runCommand(BinariesToRun aProgram,
TQStringList anArgumentStringList,
bool isToDetach)
{
DEBUG5("Runner::runCommand(%d, list[%d items], %d)\n",
aProgram, anArgumentStringList.size(), isToDetach);
if (getPath(aProgram).isEmpty())
{
DEBUG2("Runner::runCommand - attempting to run command with empty path\n");
return 1;
}
// if we are running pccardctl or icon_switch and they are not suid, we need
// to run them through SOMESU
if (aProgram==PCCARDCTL || aProgram==USBMODESWITCH)
{
if (!isSUID(aProgram))
{
// FIXME: I'd prefer to keep the TQStringList as it is!
TQString myNewArgumentString = getPath(aProgram)+" "+ anArgumentStringList.join(" ");
return runCommand(SOMESU, myNewArgumentString);
}
}
// for *su, we need to apply an extra parameter "-c" that specifies that the next
// argument contains the command to execute
if (aProgram == SOMESU)
{
if (! theSU.endsWith("gksu"))
{
anArgumentStringList.push_front("-c");
}
else
{
// but gksu does not like that extra "-c"
// gksu likes "--" instead
anArgumentStringList.push_front("--");
}
}
// setup the pipes and clean the stringlists
if (pipe(theStdOutPipe)!=0 || pipe(theStdErrPipe)!=0)
{
assert(false);
return 1;
}
theStdOutTexts.clear();
theStdErrTexts.clear();
// start a second (child) process
pid_t myChildPID = fork();
if (myChildPID == -1)
{
DEBUG1("fork() returns error\n");
return -2;
}
// only the child process executes the command
if (myChildPID == 0)
execChild(aProgram, anArgumentStringList);
// if we're still here, we're the parent...
DEBUG3("INSIDE PARENT, uid=%d, pid=%d\n", getuid(), getpid());
// Close STDERR for write
close(theStdErrPipe[1]);
// Close the write end of STDOUT
close(theStdOutPipe[1]);
// and the parent waits for the child to finish...
DEBUG5("Parent with pipes to not detached child\n");
char buffer[BUFSIZ+1];
memset(buffer, '\0', sizeof(buffer));
int myStatus = -1;
// just to make sure that we read everything, we check on 3 different conditions to be met
// 1) stdout is empty
// 2) stderr is empty
// 3) waitpid thinks the app has died
int hasAppDied = 0;
while (hasAppDied != 7)
{
fd_set myReadFDs;
FD_ZERO(&myReadFDs);
FD_SET(theStdOutPipe[0], &myReadFDs);
FD_SET(theStdErrPipe[0], &myReadFDs);
struct timeval myTimeVal;
myTimeVal.tv_sec = 1;
myTimeVal.tv_usec= 0;
int n = (theStdOutPipe[0]>theStdErrPipe[0])?theStdOutPipe[0]:theStdErrPipe[0];
int myRetVal = select(n+1, &myReadFDs, NULL, NULL, &myTimeVal);
if (myRetVal == -1)
{
perror("select()");
break;
}
if (FD_ISSET(theStdOutPipe[0], &myReadFDs))
if (readPipe(theStdOutTexts, theStdOutPipe[0]) == false)
hasAppDied |= 1;
if (FD_ISSET(theStdErrPipe[0], &myReadFDs))
if (readPipe(theStdErrTexts, theStdErrPipe[0]) == false)
hasAppDied |= 2;
// has program state finished? if yes: that's one out of 3 things
// to stop the while loop
if (waitpid(myChildPID, &myStatus, WNOHANG | WUNTRACED) > 0)
hasAppDied |= 4;
// sleep for 10 ms
struct timespec sleep_time;
sleep_time.tv_sec=0;
sleep_time.tv_nsec=10*1000*1000;
nanosleep(&sleep_time,NULL);
DEBUG5("child read pipe loop end, flags: %d\n", hasAppDied);
}
// Close STDOUT/STDERR for reading
close(theStdOutPipe[0]);
close(theStdErrPipe[0]);
// the child is dead now
myChildPID = -1;
return myStatus;
}
bool Runner::readPipe(TQStringList& aStringList, int anFD)
{
TQFile myFile;
myFile.open(IO_ReadOnly, anFD);
TQString myString;
myFile.readLine(myString, 1024);
if (myString.length() == 0)
{
myFile.close();
return false;
}
while (myString.length() != 0)
{
myString = myString.stripWhiteSpace();
aStringList.push_back(myString);
myFile.readLine(myString, 1024);
}
myFile.close();
return true;
}
////////////////////////////////////////////////////////////////////////////
void Runner::execChild(BinariesToRun aProgram,
TQStringList anArgumentStringList)
{
DEBUG3("INSIDE CHILD, uid=%d, pid=%d\n", getuid(), getpid());
DEBUG5("INSIDE CHILD, Prog: %s\n", getPath(aProgram).ascii());
int myDebugArgs = anArgumentStringList.size();
for (int i=0; i < myDebugArgs; i++)
{
DEBUG5("INSIDE CHILD, arg%02d: '%s'\n",i,anArgumentStringList[i].ascii());
}
// connect stdout to the pipe and close the original stuff
// Close the Child process' STDOUT
// and close the accompanying pipe for reading
close(STDOUT_FILENO);
int myDummy = dup(theStdOutPipe[1]);
close(theStdOutPipe[0]);
close(theStdOutPipe[1]);
// Close the Child process' STDERR
// and close the accompanying pipe for reading
close(STDERR_FILENO);
myDummy = dup(theStdErrPipe[1]);
close(theStdErrPipe[0]);
close(theStdErrPipe[1]);
TQString myCmd = getPath(aProgram);
int myNumArgs = anArgumentStringList.size();
char** myArgv = new char*[myNumArgs+2];
myArgv[0] = const_cast<char*>(myCmd.ascii());
for (int i=1; i < myNumArgs+1; i++)
{
myArgv[i] = const_cast<char*>(anArgumentStringList[i-1].ascii());
}
myArgv[myNumArgs+1] = NULL;
// FIXME: we apparently need several things from 'environ'...
// But I'd prefer to just limit the environment to DISPLAY...
// alas: it doesn't work then :-(
execve(myArgv[0], myArgv, environ);
// as execve shouldn't return, we shouldn't get here
// but to prevent static code checkers from complaining,
// let's just be correct
delete myArgv;
// don't use exit() here, right after a fork() one uses _exit().
_exit(127);
}

@ -0,0 +1,154 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006,2007,2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef RUNNER_H
#define RUNNER_H
#include <ntqstring.h>
#include <ntqstringlist.h>
/** Runner is a class to start external programs with
* Just instantiate the class and run a command and delete the class afterwards
* Settings like where to find the binaries are kept static - so creation/deletion of the class
* is not really expensive.
*
* WARNING: do not keep two detached class instances in parallel !!!
*/
class Runner
{
public:
Runner();
virtual ~Runner() {};
enum BinariesToRun
{
SOMESU,
PPPD,
CHAT,
PCCARDCTL,
USBMODESWITCH,
RUNNERTESTER // do not touch - only for RunnerTester
};
static const TQString& getPath(BinariesToRun aProgram);
/** returns true if aProgram is suid root
* @param AProgram entry from the enum to check for suid
* @returns true if suid, false if not (or not found)
*/
static bool isSUID(BinariesToRun aProgram);
/// returns true if umtsmon is run as root or is suid root
static bool amIRoot(void);
/** runs a program with specified argument string
* the program will be run *without* any environment or search path
* and the calling thread will be paused until the program returns
* @param aProgram choose from the enum the program to run
* @param anArgumentStringList the arguments to the program
* in case of SOMESU, this will binary plus args in a single item
* @returns the return value of the program
*/
int runCommand(BinariesToRun aProgram, TQStringList anArgumentStringList)
// asking for out-of-process operation is not possible for external callers
{ return runCommand(aProgram, anArgumentStringList, false); };
/** checks if the PPPD process exists
* @returns -1 if process does not exist or return PID if found
*/
static int doesPPPDexist(void);
const TQStringList& getStdOutStringList(void) const
{return theStdOutTexts;};
const TQStringList& getStdErrStringList(void) const
{return theStdErrTexts;};
private:
/** this function tries to locate e.g. tdesu/gnomesu, pppd, chat, pccardctl
* on a fixed, pre-defined path to make sure that we use the reliable ones
* Note: this is the actual function setting the internal strings below
* @returns true if everything went OK, false on errors
*/
bool findBinaries(void);
/** checks if I am allowed to run a certain command
* i.e. the x bit is set for either me, my group of the whole world
* @param anExecutable the name of the executable to test
* @returns true if I'm allowed to execute it
*/
bool isExecutableByMe(const TQString& anExecutable) const;
/** looks through the specified path or the default search path
* /bin:/usr/bin:/sbin:/usr/sbin for the application
* @param anAppName the name of the binary to look for
* @param aPath (optional) the path to search on - note that anyting not
* in /opt or /usr will be ignored
* @returns an empty TQString if nothing found, or the path to the binary
* plus the appname if found
*/
TQString lookThroughPath(const TQString& anAppName, const char* aPath);
/** runs a program with specified argument string
* the program will be run *without* any environment or search path
* and the calling thread will be paused until the program returns
* @param aProgram choose from the enum the program to run
* @param anArgumentStringList the arguments to the program
* @param isToDetach true if you do not want to wait for the program to end
* @returns the return value of the program
*/
int runCommand(BinariesToRun aProgram, TQStringList anArgumentStringList, bool isToDetach);
/** this member is executed in the child process of Runner.
* THIS MEMBER SHOULD ONLY BE CALLED FROM runCommand()!!!
* @param aProgram choose from the enum the program to run
* @param anArgumentStringList the arguments to the program
*/
void execChild(BinariesToRun aProgram, TQStringList anArgumentStringList);
private:
static TQString theSU;
static TQString thePPPD;
static TQString theCHAT;
static TQString thePCCARDCTL;
static TQString theUSBMODESWITCH;
static TQString theRUNNERTESTER;
/// used for creating a pipe between the program and Runner
int theStdOutPipe[2];
/// used for creating a pipe between the program and Runner
int theStdErrPipe[2];
/** read all lines from a pipe into a string list
* @param aStringList string list to store read data into
* @param anFD file descriptor to read from
* @returns true if data read, false if not
*/
bool readPipe(TQStringList& aStringList, int anFD);
/// contains the output over stdout of a run program
TQStringList theStdOutTexts;
/// contains the output over stderr of a run program
TQStringList theStdErrTexts;
};
#endif // RUNNER_H

@ -0,0 +1,356 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2006,2007,2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "SerialPort.h"
#include "Query.h"
#include "Popup.h"
#include <stdio.h>
#include <termio.h>
#include <fcntl.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
bool SerialPort::closeDev()
{
DEBUG3("SerialPort::closeDev() for FD %d\n", theComFD);
if (theComFD != -1)
close(theComFD);
theComFD=-1;
return true;
}
void SerialPort::doSmallSleep(unsigned long microsecs)
{
// the below statement was taken from comgt:
// I use select() 'cause CX/UX 6.2 doesn't have usleep().
// On Linux, usleep() uses select() anyway.
struct timeval timeout;
timeout.tv_sec=microsecs/1000000L;
timeout.tv_usec=microsecs-(timeout.tv_sec*1000000L);
// select() is notorious for returning early. That's why I specifically check&retry
while (timeout.tv_sec + timeout.tv_usec != 0)
{
DEBUG6("dosmallsleep of %ld s, %ld us\n", timeout.tv_sec, timeout.tv_usec);
select(1,0,0,0,&timeout);
}
}
bool SerialPort::resetDev(void)
{
if (closeDev()==false)
return false;
sleep(1);
if (openDev(theDevName, thePortSpeed, theSleepTime)==false)
return false;
int ch=1;
while (ch > 0)
{
ch = getOneByte();
DEBUG6("read after reset: '%c' %d\n", ch, ch);
}
return true;
}
bool SerialPort::openDev(const TQString& aDeviceName, int aSpeed, long aSleepTime)
{
if ((theComFD = open(aDeviceName.ascii(),
O_RDWR|O_EXCL|O_NONBLOCK|O_NOCTTY)) < 0)
{
TQString myErrorMsg = TQString("Serial::openDev-open(\"%1\") failed").arg(aDeviceName);
perror(myErrorMsg.ascii());
theComFD = -1;
return false;
}
theSleepTime = aSleepTime;
thePortSpeed = aSpeed;
theDevName = aDeviceName;
// for security:
// let's check first if this is actually a character device node.
struct stat myStatBuf;
if (fstat(theComFD, &myStatBuf) != 0)
{
TQString myErrorMsg = TQString("Serial::openDev-fstat(\"%1\") failed").arg(aDeviceName);
perror(myErrorMsg.ascii());
theComFD = -1;
return false;
}
if (!S_ISCHR(myStatBuf.st_mode))
{
Popup::Critical(TQObject::tr("SECURITY ERROR: You are trying to open something that is not a character device\n" APPNAME " will close now."));
return false;
}
struct termio myTermIo;
if (ioctl (theComFD, TCGETA, &myTermIo) < 0)
{
TQString myErrorMsg = TQString("Serial::openDev-ioctl(\"%1\") get termio buf failed").arg(aDeviceName);
perror(myErrorMsg.ascii());
theComFD = -1;
return false;
}
myTermIo.c_iflag &= ~(IGNCR | ICRNL | IGNBRK | IUCLC | INPCK | IXON | IXANY | IGNPAR );
myTermIo.c_oflag &= ~(OPOST | OLCUC | OCRNL | ONLCR | ONLRET);
myTermIo.c_lflag &= ~(ICANON | XCASE | ECHO | ECHOE | ECHONL);
myTermIo.c_lflag |= ISIG | IEXTEN | ECHOK | ECHOKE | ECHOCTL;
myTermIo.c_cc[VMIN] = 1;
myTermIo.c_cc[VTIME] = 5;
myTermIo.c_cc[VEOF] = 1;
myTermIo.c_cflag &= ~(CBAUD | CSIZE | CSTOPB | CLOCAL | PARENB);
myTermIo.c_cflag |= CLOCAL | HUPCL;
myTermIo.c_cflag |= (aSpeed | CS8 | CREAD );
if (ioctl(theComFD, TCSETA, &myTermIo) < 0)
{
TQString myErrorMsg = TQString("Serial::openDev-ioctl(\"%1\") set termio failed").arg(aDeviceName);
perror(myErrorMsg.ascii());
theComFD = -1;
return false;
}
doSmallSleep(200000L); /* Wait a bit (DTR raise) */
DEBUG3("Serial::openDev('%s') as FD %d - Serial instance %p\n", aDeviceName.ascii(), theComFD, this);
return true;
}
/* Write a null-terminated string to communication device */
bool SerialPort::writeDev(const TQString& aString)
{
const char* myStringPtr = aString.ascii();
long myLen = aString.length();
int myTryCount = 0;
if (theComFD == -1)
return false;
while (myLen > 0)
{
int myResult = write(theComFD, myStringPtr, myLen);
if (myResult <= 0)
{
if (++myTryCount > 10)
{
closeDev();
perror("Could not write to serial device");
Popup::Critical(TQObject::tr("Could not write to device (anymore)"));
return false;
}
DEBUG4("write '%s' failed for the %d time, re = %d\n. Trying again.",
myStringPtr, myTryCount, myResult);
doSmallSleep(10000);
myResult = 0;
}
if (myResult > myLen)
myResult = myLen; // (catch possible errors in write function)
myLen -= myResult;
myStringPtr += myResult;
}
doSmallSleep(20000);
return true;
}
/** Gets a single byte from comm. device.
* @returns byte if available, -1 if none, 0 if byte should be there but isn't
*/
int SerialPort::getOneByte(void)
{
if (theComFD == -1)
{
return -1;
}
char myChar = 0;
struct timeval myTimeOut;
myTimeOut.tv_sec = 0L;
myTimeOut.tv_usec = theSleepTime;
fd_set myFDset;
FD_ZERO(&myFDset);
FD_SET(theComFD, &myFDset);
int myResult = select(theComFD+1, &myFDset, NULL, NULL, &myTimeOut);
if (myResult == -1)
{
perror("SerialPort::getOneByte::select");
myChar = 0;
}
if (myResult != 0)
{
myResult=read(theComFD, &myChar, 1);
if (myResult != 1)
{
// nothing read
myChar=0;
}
}
return myChar;
}
//-----------------------------------------------------------------
#define MAXTHESTRING 511
static char theString[MAXTHESTRING];
static char* convertToReadable(const TQString& aString)
{
unsigned int myDestPos = 0;
unsigned int mySourcePos = 0;
for (; mySourcePos < aString.length();)
{
theString[myDestPos] = aString[mySourcePos];
if (theString[myDestPos] == '\r')
{
theString[myDestPos] = '\\';
myDestPos ++;
theString[myDestPos] = 'r';
}
if (theString[myDestPos] == '\n')
{
theString[myDestPos] = '\\';
myDestPos ++;
theString[myDestPos] = 'n';
}
if (theString[myDestPos] == '\0')
{
theString[myDestPos] = '\\';
myDestPos ++;
theString[myDestPos] = '0';
}
mySourcePos ++;
myDestPos++;
if (myDestPos > MAXTHESTRING-1)
break;
}
theString[myDestPos]=0;
return theString;
}
void SimulatedSerialPort::addSerialStatement(const TQString& aQueryString,
const TQString& aResponse)
{
keydata* myPairPtr = new keydata;
myPairPtr->key = "\r"+aQueryString+"\r";
myPairPtr->data = aQueryString+"\r\n" + aResponse+"\r\n";
theQueryList.push_back(myPairPtr);
}
bool SimulatedSerialPort::openDev(
__attribute__ ((unused)) const TQString& aDevName,
__attribute__ ((unused)) int aPortSpeed,
__attribute__ ((unused)) long aSleepTime)
{
theDevName = aDevName;
return true;
}
bool SimulatedSerialPort::closeDev()
{
return true;
}
bool SimulatedSerialPort::writeDev(const TQString& aString)
{
// let's look up the aString
for (theCurrentItem = theQueryList.begin(); theCurrentItem != theQueryList.end(); theCurrentItem++)
if ((*theCurrentItem)->key==aString)
break;
// did we find it?
if (theCurrentItem == theQueryList.end())
{
// no :-(
DEBUG2("SimulatedSerialPort::writeDev : '%s' not found\n", convertToReadable(aString));
theItemIndex = -1;
isAllSatisfied = false;
return false;
}
DEBUG2("SimulatedSerialPort::writeDev : query \"%s\" found,\n",
convertToReadable((*theCurrentItem)->key));
DEBUG2(" answer will be: '%s'\n", convertToReadable((*theCurrentItem)->data));
theItemIndex = 0;
return true;
}
int SimulatedSerialPort::getOneByte(void)
{
if (theCurrentItem == theQueryList.end() || theItemIndex==-1)
{
return -1;
}
TQChar myByte = (*theCurrentItem)->data[theItemIndex];
theItemIndex++;
if (theItemIndex > static_cast<signed int>((*theCurrentItem)->data.length()))
{
theQueryList.erase(theCurrentItem);
theCurrentItem = theQueryList.end();
theItemIndex = -1;
}
return myByte;
}
//-----------------------------------------------------------------
LongSerialPort::~LongSerialPort()
{
DEBUG3("LongSerialPort::~LongSerialPort()\n");
closeDev();
Query::setSerial(NULL);
}
bool LongSerialPort::openDev(const TQString& aDeviceName, int aSpeed, long aSleepTime)
{
if (SerialPort::openDev(aDeviceName, aSpeed, aSleepTime))
{
Query::setSerial(this);
return true;
}
return false;
}
//-----------------------------------------------------------------
TempSerialPort::TempSerialPort()
{
DEBUG3("TempSerialPort::TempSerialPort()\n");
// save the current serial port of Query, so we can restore it later
theOldPtr = Query::setSerial(this);
}
TempSerialPort::~TempSerialPort()
{
DEBUG3("TempSerialPort::~TempSerialPort()\n");
closeDev();
// let's reset the serialport pointer in Query
// we should get a pointer to us back
assert(Query::setSerial(theOldPtr) == this);
}

@ -0,0 +1,163 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2006,2007,2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef SERIALPORT_CLASS
#define SERIALPORT_CLASS
// required for port speeds
#include <termio.h>
#include <ntqstring.h>
#include <list>
/** The SerialPort class sets up, maintains and reads/writes the serial port
* connection. Code derived in part from Paul Hardwick's 'comgt'
* application.
*
* NOTE: This SerialPort class cannot multiplex with PPP data streams
* It will thus work for any single serial port modems.
* The modem.cpp file in kppp details how to work around that.
*
* in general, the SerialPort class will be created and kept by Device
* and Device will use the static member of Query to install the SerialPort
* to Query.
*/
class SerialPort
{
public:
SerialPort() : theComFD(-1) {};
virtual ~SerialPort() {};
/** open a serial device for communication.
* If opening successful, it will also register itself for the Queryclass
* @param aDevName Device name to open, e.g. /dev/tts/0
* @param aPortSpeed Speed to operate the serial port (def=115200 baud)
* @returns true if successful, false if fails recoverably
*/
virtual bool openDev(const TQString& aDevName, int aPortSpeed = B115200, long aSleepTime = 20000);
/** closes the serial port device
* and unregisters itself in the Query class
*/
virtual bool closeDev();
/** resets the serial port device
* needed for single port serial devices after
* pppd has closed its connection
*/
virtual bool resetDev(void);
/** Write a string to the device
* @param aString string to send to device, nothing will be added.
* @returns true if successful
*/
virtual bool writeDev(const TQString& aString);
/** Gets a single byte from comm. device.
* Return -1 if none avail.
* Return 0 if should be available but there is none
*/
virtual int getOneByte(void);
private:
/// Communication file descriptor.
int theComFD;
/// perform a small sleep, in microseconds
void doSmallSleep(unsigned long aNumberOfMicroSecs);
/// time to wait before deciding no more characters are forthcoming
long theSleepTime;
int thePortSpeed;
protected:
/// contains the device name - once openDev() has been called
TQString theDevName;
private:
virtual void aDummy(void) = 0;
};
/** the SimulatedSerialPort class can be used to simulate the behavior of the
* regular SerialPort class - use it to test Queries and such
*
* you'll have to feed it first, though - through the ### member.
*/
class SimulatedSerialPort : public SerialPort
{
public:
SimulatedSerialPort() : theItemIndex(-1), isAllSatisfied(true) {};
virtual ~SimulatedSerialPort() {};
virtual bool openDev(const TQString& aDevName, int aPortSpeed = B115200, long aSleepTime = 20000);
virtual bool closeDev();
virtual bool writeDev(const TQString& aString);
virtual int getOneByte(void);
// specific for this class
void addSerialStatement(const TQString& aQueryString, const TQString& aResponse);
bool isAllUsed(void) const {return theQueryList.empty();};
bool wasAllSatisfied(void) const {return isAllSatisfied;};
private:
struct keydata {TQString key; TQString data;};
typedef std::list<keydata*> QueryList;
QueryList theQueryList;
QueryList::iterator theCurrentItem;
int theItemIndex;
bool isAllSatisfied;
virtual void aDummy(void) {};
};
/** This class is the regular long-term use of SerialPort.
*/
class LongSerialPort : public SerialPort
{
public:
LongSerialPort() {};
virtual ~LongSerialPort();
virtual bool openDev(const TQString& aDevName, int aPortSpeed = B115200, long aSleepTime = 20000);
private:
SerialPort* theOldPtr;
virtual void aDummy(void) {};
};
/** This class is for use by PPPConnection. This TempSerialPort will open another
* SerialPort class, store the current port set in Query and return that state upon
* destruction.
* Note that this modification of Query already is done on creation - not on opening the device!
*/
class TempSerialPort : public SerialPort
{
public:
TempSerialPort();
virtual ~TempSerialPort();
private:
SerialPort* theOldPtr;
virtual void aDummy(void) {};
};
#endif // defined SERIALPORT_CLASS

@ -0,0 +1,129 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "TheSettingsSingleton.h"
#include <assert.h>
#include <ntqdir.h>
// for atexit(3)
#include <cstdlib>
// the various strings related to general settings
// I'd prefer to keep them together - here
const char* theLanguageSetting = "/General/Language";
const char* theGeneralAutoConnectSettingName = "/General/Autoconnect";
const char* theWasRoamingSettingName = "/General/WasRoaming";
static TheSettingsSingleton* theSingletonInstancePtr = NULL;
static TQSettings* theTQSettingsInstancePtr = NULL;
TheSettingsSingleton::TheSettingsSingleton()
{
DEBUG5("TheSettingsSingleton::TheSettingsSingleton()\n");
assert(theTQSettingsInstancePtr == NULL);
theTQSettingsInstancePtr = new TQSettings();
// I want to store the settings on the usual place: $HOME/.umtsmon/umtsmonrc
TQString mySettingsLocation = TQDir::homeDirPath() + "/." + APPNAME;
DEBUG2("Settings will be saved in : '%s'\n", mySettingsLocation.ascii());
theTQSettingsInstancePtr->insertSearchPath (TQSettings::Unix, mySettingsLocation);
theTQSettingsInstancePtr->beginGroup(APPNAME);
// register the end member to destruct properly at
// the end of normal application operation
atexit(TheSettingsSingleton::end);
}
TheSettingsSingleton::~TheSettingsSingleton(void)
{
DEBUG5("DESTRUCTOR TheSettingsSingleton::~TheSettingsSingleton()\n");
if (theTQSettingsInstancePtr)
{
delete theTQSettingsInstancePtr;
theTQSettingsInstancePtr = NULL;
}
}
void TheSettingsSingleton::end(void)
{
delete theSingletonInstancePtr;
theSingletonInstancePtr = NULL;
}
// dear programmers, keep in mind that this member is static,
// i.e. you cannot use any of the other members in the class,
// nor any of the variables
TQSettings& TheSettingsSingleton::getTQSRef(void)
{
// do we exist? if not: create us
if (theSingletonInstancePtr == NULL)
theSingletonInstancePtr = new TheSettingsSingleton();
// once that is done, theTQSettingsInstancePtr should have a legal pointer
assert (theTQSettingsInstancePtr != NULL);
return *theTQSettingsInstancePtr;
}
void TheSettingsSingleton::makeChangesPersistent(void)
{
if (theSingletonInstancePtr != NULL)
theSingletonInstancePtr->end();
}
bool TheSettingsSingleton::removeSubTree(const TQString& aSubTreeName)
{
DEBUG3("deleteSubTree '%s' start\n", aSubTreeName.ascii());
TQStringList myList = getTQSRef().subkeyList(aSubTreeName);
TQStringList::Iterator it = myList.begin();
while( it != myList.end() )
{
// recursively scan through all "subdirectories" first
if (removeSubTree (aSubTreeName + "/" + (*it)) == false)
{
DEBUG1("deleteSubTree returned false\n");
return false;
}
++it;
}
// we've scanned through all "subdirectories" (and deleted their contents)
// now let's remove all regular entries in this directory
myList =getTQSRef().entryList(aSubTreeName);
it = myList.begin();
while( it != myList.end() )
{
DEBUG3(" remove Entry: %s\n", (*it).ascii());
TheSettingsSingleton::getTQSRef().removeEntry(aSubTreeName + "/" +(*it));
++it;
}
// we're cool!
DEBUG3("deleteSubTree '%s' end\n", aSubTreeName.ascii());
return true;
}

@ -0,0 +1,110 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef THESETTINGSSINGLETON_H_
#define THESETTINGSSINGLETON_H_
#include <ntqsettings.h>
#include <ntqstring.h>
// the settings keys used in the [General] Section
extern const char* theLanguageSetting;
extern const char* theGeneralAutoConnectSettingName;
extern const char* theWasRoamingSettingName;
/** the Settings Singleton class is a singleton as meant in the
* Design Pattern "Singleton" from the Erich Gamma book.
*
* It thus has global access - everyone can ask for a reference to the
* TQSettings class and it is always guaranteed to exist.
* Don't cache the pointer, always use it like this:
* TheSettingsSingleton::getTQSRef.something()
*
* Note that this Singleton is different from the official pattern in that it
* does not return a reference to itself, but to the TQSettings instance.
*
* The TQSettings class is configured to store/retrieve its settings from
* the file: $HOME/.umtsmon/umtsmonrc
* So, a beginGroup() is already set - don't use
*
*
* Klaas chose to implement this as a Singleton for several reasons:
* - not to have to pass pointers around
* - not to have to create a global pointer
* - not to have to care when exactly the TQSettings class is to be created
* - not to have to care if the TQSettings class is destroyed
* (as only on destruction it will save its settings)
*/
class TheSettingsSingleton
{
public:
/** the entry to the Singleton class
* return is always a valid reference to the TQSettings instance
*
* NOTE: do *not* call other members than readEntry() or writeEntry() of
* the TQSettings class!!!
*
* As a key, you can specify e.g. "profile_athome/APN" or "/profile_athome/APN"
* (which are equivalent and will be placed in the [PPP] section)
* or you can specify e.g "updateStats" or "/updateStats"
* (which will be placed in the [General] section)
*/
static TQSettings& getTQSRef(void);
static TheSettingsSingleton& me(void);
/** removes a tree of settings.
* you should use this e.g. if you want to remove a profile with settings
* @param aSubTreeName contains the name to remove, e.g. /profile_athome
* @return false if tree not found
*/
static bool removeSubTree(const TQString& aSubTreeName);
/** settings are normally only saved on system exit.
* Calling this member will save the settings instantly.
*/
static void makeChangesPersistent(void);
private:
/** private constructor as demanded by the Singleton Design Pattern
* will be called by the getTQSRef() method if needed
*/
TheSettingsSingleton(void);
/** private destructor as demanded by the Singleton Design Pattern
* will be called by the end() method if needed
*/
~TheSettingsSingleton(void);
/** It is very important that this Singleton is destroyed on exit or the settings
* won't get written to disk. This static member will be setup by the constructor
* to be called atexit().
*/
static void end(void);
/// private, unimplemented copy constructor - don't use
TheSettingsSingleton(const TheSettingsSingleton& aPtr);
/// private, unimplemented assign operator - don't use
TheSettingsSingleton& operator=(TheSettingsSingleton& aPtr);
};
#endif /*THESETTINGSSINGLETON_H_*/

File diff suppressed because it is too large Load Diff

@ -0,0 +1,309 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2007, 2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef AUTODETECT_CLASS
#define AUTODETECT_CLASS
#include "Device.h"
/// thrown by AutoDetect_USB_ZeroCD if device was switched
class StopAutodetectionCycle
{
};
//////////////////////////////////////////////////////////////////////////////
/** abstract base class of the autodetection code
*/
class AutoDetectBase
{
public:
AutoDetectBase(void) : theDeviceID(DeviceCapabilities::UNKNOWN) {};
virtual ~AutoDetectBase() {};
enum AutoDetectResults
{
NOTHING_FOUND, // nothing was detected
DEVICE_DETECTED, // device was detected OK
DEVICE_ERROR // device was detected, but not usable
};
/// perform the autodetection and find corresponding ports
virtual AutoDetectResults go(void);
/** pure virtual function
* @returns the name of the Autodetection class
*/
virtual TQString getName(void) = 0;
/** creates the device that was autodetected
* @returns pointer to the Device or NULL if not possible/error
*/
virtual Device* createDevice(void);
protected:
/** pure virtual function
* traverse the internal trees (PCI lists, USB lists, etc) to find
* possible devices, then calls matchIDs to check if they match.
* @returns something from the enum AutoDetectResults
*/
virtual AutoDetectResults traverseTrees(void) = 0;
/** pure virtual function
* test to see if this vendor / (product/device) ID matches a known device
* @param aVendorID
* @param aProductID
* @returns true if match found, theDeviceID will be
* updated to match the detected combination (might be different
* values, though), false if no match.
*/
virtual AutoDetectResults matchIDs(unsigned long aVendorID, unsigned long aProductID) = 0;
/// pure virtual function - discover the AT/PPP port names
virtual bool findPortNames(void) = 0;
enum LogQuality
{
GOOD, // use GOOD if this is a positive ID of a certain card
BAD, // use BAD if an optional piece of detection failed, detection might not succeed but can continue
KILLING, // use KILLING if a REQUIRED piece of detection cannot be done
INFO // use INFO to state that something's present that can help detection
};
/// logs a message about autodetection
void sendLog(LogQuality isGood, const TQString& aMessage);
protected:
DeviceCapabilities::CardType theDeviceID;
TQStringList thePortsList;
};
//////////////////////////////////////////////////////////////////////////////
/** "not really" autodetection - attempts to build device from user or
* config file specified parameters.
*/
class NonAutoDetect : public AutoDetectBase
{
public:
NonAutoDetect()
: theSuggestedDeviceType(DeviceCapabilities::UNKNOWN),
theForceAutodetection(false) {};
/// augment go by checking for forced autodetection
virtual AutoDetectResults go(void);
//// empty implementation
virtual AutoDetectResults traverseTrees(void)
{return theForceAutodetection?NOTHING_FOUND:DEVICE_DETECTED;};
/// empty implementation
virtual AutoDetectResults matchIDs(unsigned long aVendorID, unsigned long aProductID);
/// empty
virtual bool findPortNames(void) {return true;};
/// @returns the name of the Autodetection class
virtual TQString getName(void)
{return "Device creation from supplied parameters";};
TQString theSuggestedATPortName;
TQString theSuggestedPPPPortName;
DeviceCapabilities::CardType theSuggestedDeviceType;
bool theForceAutodetection;
};
//////////////////////////////////////////////////////////////////////////////
/** USB autodetection
*/
class AutoDetect_USB : public AutoDetectBase
{
public:
//// implementation - opens libusb and uses that to find usb devices
virtual AutoDetectResults traverseTrees(void);
/// implementation - match vendor/product with known IDs for USB
virtual AutoDetectResults matchIDs(unsigned long aVendorID, unsigned long aProductID);
/// implementation - discover the AT/PPP port names
virtual bool findPortNames(void);
/// @returns the name of the Autodetection class
virtual TQString getName(void)
{return "USB Autodetection";}
protected:
/** suggests the user to insmod the usbserial module with parameters and
* checks if it helps
* @returns false if not
*/
bool suggestModprobe(void);
/** HSO devices have an entry in either /proc or /sys that tells the type
* of port it is. This member reads and parses that entry - the results will
* be printed and (if ok) the port will be added to the port list on the correct place.
* @param myHSx the port name
* @param myHSOTypeFileName the file containing the entry
*/
void detectHSOType(const TQString& myHSx, const TQString& myHSOTypeFileName);
/// (filled by traverseTrees) contains the USB vendor ID
unsigned long theUSBVendorID;
/// (filled by traverseTrees) contains the USB device ID
unsigned long theUSBDeviceID;
};
//////////////////////////////////////////////////////////////////////////////
/** USB autodetection - specific for the ZeroCD devices that need switching
* once it finds a device, it will prompt the user and then claim that
* no device was found - allowing the regular USB autodetector to find the switched device
*/
class AutoDetect_USB_ZeroCD : public AutoDetect_USB
{
public:
/// implementation - match vendor/product with known IDs for USB
virtual AutoDetectResults matchIDs(unsigned long aVendorID, unsigned long aProductID);
/// @returns the name of the Autodetection class
virtual TQString getName(void)
{return "USB ZeroCD Autodetection";};
/// implementation - discover the AT/PPP port names
virtual bool findPortNames(void);
private:
/** this member is specific to the ZeroCD autodetector and contains the code
* to actually switch the device and verify that switch
* @returns true if successful
*/
bool switchDevice(void);
};
//////////////////////////////////////////////////////////////////////////////
/** PCMCIA autodetection
* for now only works for BroadCom and Nozomi based chipsets, as they have a PCMCIA serial controller inside
* this class does not detect any of the pcmcia->usb2serial devices
*/
class AutoDetect_PCMCIA : public AutoDetectBase
{
public:
//// implementation - traverses the /sys/class/pcmcia_socket tree for PCMCIA cards
virtual AutoDetectResults traverseTrees(void);
/// implementation - match vendor/product with known IDs for PCMCIA
virtual AutoDetectResults matchIDs(unsigned long aVendorID, unsigned long aProductID);
/// implementation - discover the AT/PPP port names
virtual bool findPortNames(void);
/// implementation - returns the name of the Autodetection class
virtual TQString getName(void)
{return "PCMCIA (PCCard) Autodetection";};
private:
/// returns true if PCMCIA browsing in /sys is available
bool isPCMCIABrowsingPossible(void);
/// discover the AT/PPP port names for the Broadcom 4306 series
bool find4306PortNames(void);
/// discover the AT/PPP port names for the Nozomi-based series
bool findNozomiPortNames(void);
};
//////////////////////////////////////////////////////////////////////////////
/** Raw port autodetection - this includes ttyS* ttyUSB* ttyACM* rfcomm*
*/
class AutoDetect_Rawport : public AutoDetectBase
{
public:
//// implementation - creates a list of all serial ports on the system
virtual AutoDetectResults traverseTrees(void);
/// implementation - not used for Rawport
virtual AutoDetectResults matchIDs(unsigned long aVendorID, unsigned long aProductID);
/** implementation - discover the AT/PPP port names
* (working from the first one detected by traverseTrees)
*/
virtual bool findPortNames(void);
/// @returns the name of the Autodetection class
virtual TQString getName(void) = 0;
protected:
TQString theDevName;
private:
TQStringList theValidSerialPortsList;
};
//////////////////////////////////////////////////////////////////////////////
/** Raw USB Serial port autodetection - ttyUSB*
*/
class AutoDetect_RawUSBports : public AutoDetect_Rawport
{
public:
AutoDetect_RawUSBports() {theDevName = "ttyUSB*";};
/// @returns the name of the Autodetection class
virtual TQString getName(void)
{return "Raw USB Serial Probing";};
};
/** CSSerial port autodetection - ttyS*, but only if CSSerial is detected anyway
*/
class AutoDetect_CSSerialPorts : public AutoDetect_Rawport
{
public:
AutoDetect_CSSerialPorts() {theDevName = "ttyS*";};
/// @returns the name of the Autodetection class
virtual TQString getName(void)
{return "PCMCIA Serial Modem Probing";};
};
/** Phone modems - test the ttyACM* and rfcomm* ports
*/
class AutoDetect_PhoneModems : public AutoDetect_Rawport
{
public:
virtual AutoDetectResults go(void);
/// @returns the name of the Autodetection class
virtual TQString getName(void)
{return "Phone Modem Probing";};
};
#endif // AUTODETECT_CLASS

@ -0,0 +1,235 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2006, 2007, 2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "NetworkChanger.h"
#include "Query.h"
#include "OperatorList.h"
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
NetworkChanger::~NetworkChanger()
{
// to make sure that no Query exists anymore
// otherwise will have locking issues elsewhere
if (theQueryPtr != NULL)
{
delete theQueryPtr;
theQueryPtr = NULL;
}
};
bool NetworkChanger::setCardToAutomatic(void) const
{
// set new registration mode,
// see "3GPP 27007-700 chapter 7.3, PLMN selection"
Query myQuery("AT+COPS=0");
if (myQuery.runUntilDone() != Query::OK)
{
// no big deal, it happens, fail silently
DEBUG4("Query AT+COPS=0 failed...\n");
return false;
}
return true;
}
NetworkChanger::RegistrationMode
NetworkChanger::getRegistrationState(void) const
{
// see "3GPP 27007-700 chapter 7.3, PLMN selection"
Query myQuery("AT+COPS?");
if (myQuery.runUntilDone() != Query::OK)
return MODE_ERROR;
if (myQuery.hasAnswer()==false)
return MODE_ERROR;
// The usual answer should look like: '+COPS: 4,0,"vodafone NL",2'
TQString myAnswer = myQuery.getAnswer().first().section(":",1,1);
TQString myFirstChar = myAnswer.stripWhiteSpace().left(1);
int myDecimal = myFirstChar.toShort();
assert(myDecimal <= 4);
return static_cast<RegistrationMode>(myDecimal);
}
bool
NetworkChanger::startSearching(void)
{
assert(theQueryPtr == NULL);
// see "3GPP 27007-700 chapter 7.3, PLMN selection"
theQueryPtr = new Query("AT+COPS=?");
Query::ReturnCode myResult = theQueryPtr->run();
if (myResult == Query::ERROR)
{
stopSearch();
return false;
}
return true;
}
bool
NetworkChanger::isSearchCompleted(void)
{
assert(theQueryPtr != NULL);
Query::ReturnCode myCode = theQueryPtr->receiveMore();
if (myCode != Query::OK)
{
return false;
}
// if there is more than one answer, we will have to iterate through them...
if (theQueryPtr->hasAnswer())
for (TQStringList::Iterator myIterator = theQueryPtr->getAnswer().begin();
myIterator != theQueryPtr->getAnswer().end(); myIterator++)
{
TQString myAnswer = *myIterator;
theOperatorList.fill(myAnswer);
}
stopSearch();
return true;
}
void
NetworkChanger::stopSearch(void)
{
if (theQueryPtr)
{
delete theQueryPtr;
theQueryPtr = NULL;
}
}
/****************************************************************************
* BASICALLY THERE IS A HARD LINE BETWEEN THE ABOVE AND THE BELOW
* - Above is ask for a list of networks
* - Below is switching to one of the network IDs
*/
NetworkChanger::SwitchResults
NetworkChanger::startSwitchToNetworkID(unsigned long aNetworkID)
{
DEBUG5("NetworkChanger::startSwitchToNetworkID\n");
Operator* myID = theOperatorList.findNetworkID(aNetworkID);
if(myID == NULL)
{
// something's really wrong here
assert(false);
return ERROR;
}
switch(myID->getIconType())
{
case Operator::NOT_VALID:
case Operator::FORBIDDEN:
return ERROR;
case Operator::CURRENT:
return IS_CURRENT;
case Operator::AVAILABLE:
{
TQString myAT = "AT+COPS=1,2,\"" + TQString::number(aNetworkID) + "\"";
assert(theQueryPtr == NULL);
theQueryPtr = new Query(myAT);
// because the user has already waited 40 seconds to get this far,
// I want to try very hard to make this proceed - so, if there's something
// blocking the Query, we retry...
for (int i=0; i<3; i++)
{
Query::ReturnCode myResult = theQueryPtr->run();
if (myResult == Query::ERROR)
return ERROR;
if (myResult == Query::OK)
return OK;
if (myResult != Query::NO_LOCK)
return NOT_READY_YET;
// if we get here, we couldn't get a lock
// so sleep for a second and retry
sleep(1);
} // end-of-while
// if we get here, starting the Query timed out 3 times...
break;
} // end-of-case
} // end-of-switch
stopSearch();
return ERROR;
}
NetworkChanger::SwitchResults
NetworkChanger::isSwitchCompleted(void)
{
assert(theQueryPtr != NULL);
SwitchResults myResult = NOT_READY_YET;
switch (theQueryPtr->receiveMore())
{
case Query::OK:
// we're done!!!
myResult = OK;
break;
case Query::ERROR:
case Query::NO_CARRIER:
case Query::NO_DEVICE:
case Query::NO_LOCK:
// I/O troubles or real errors
// note that stopSearch() is not called, the QueryPtr remains
return ERROR;
case Query::UNKNOWN_ERROR:
// NOT FINISHED YET
return NOT_READY_YET;
}
stopSearch();
return myResult;
}
TQString
NetworkChanger::getErrorMessage(void)
{
DEBUG5("NetworkChanger::getErrorMessage(void)\n");
// some basic sanity tests
if (theQueryPtr == NULL)
return "";
if (theQueryPtr->hasAnswer()==false)
return "";
DEBUG5("NetworkChanger::getErrorMessage(void) iterate\n");
// let's hunt for ERROR and return that line
for (TQStringList::Iterator myIterator = theQueryPtr->getAnswer().begin();
myIterator != theQueryPtr->getAnswer().end(); myIterator++)
{
TQString myAnswer = *myIterator;
// search without case sensitivity
printf("myAnswer ='%s'\n",myAnswer.ascii());
if (myAnswer.contains("error", false))
return myAnswer;
}
return "";
}

@ -0,0 +1,101 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2006, 2007, 2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef NETWORKCHANGER_CLASS
#define NETWORKCHANGER_CLASS
#include "OperatorList.h"
#include "ConnectionInfo.h"
#include <ntqstring.h>
class Query;
/// created to find all networks and change over to a new one
class NetworkChanger
{
public:
NetworkChanger(void) : theQueryPtr(NULL) {};
virtual ~NetworkChanger();
public:
/** Sets the device to search for the best operator itself
* (i.e. the AT+COPS=0 command)
*/
bool setCardToAutomatic(void) const;
/// the possible answers to AT+COPS?
enum RegistrationMode {AUTOMATIC, MANUAL, DEREGISTER, SETONLY, MAN_AUTO, MODE_ERROR};
/** retrieves the network registration mode from the device
* @returns the registration mode
*/
RegistrationMode getRegistrationState(void) const;
/** sends the AT commands to start searching for networks.
@returns true if successful in sending, false if an error occurred
*/
bool startSearching(void);
/** returns true if the search is completed.
If so, it will call parseAnswer()
*/
bool isSearchCompleted(void);
/// closes up anything related to the search
void stopSearch(void);
enum SwitchResults{ NOT_READY_YET, OK, IS_CURRENT, ERROR};
/** asks the card to switch over to the specified network
* @param theNetworkID theNetworkID from a CurrentNetworkItem
* @returns false if the network is forbidden
*/
SwitchResults startSwitchToNetworkID(unsigned long aNetworkID);
/** returns true if the switching is completed.
*/
SwitchResults isSwitchCompleted(void);
/** if and only if there is an error, this member can
* take all the output and return it for display
* @returns a TQString with the error message, empty if none
*/
TQString getErrorMessage(void);
public:
OperatorList theOperatorList;
private:
Query* theQueryPtr;
/** if an instance of the ConnectionInfoInhibitor exists,
* ConnectionInfo is prohibited from sending out AT commands.
* That's convenient as extra AT commands during network selection
* might f*ck up the network selection.
* As this object will exist always if a NetworkChanger exists, we're
* done quickly :-)
*/
ConnectionInfoInhibitor myConnectionInfoInhibitor;
};
#endif // NETWORKCHANGER

@ -0,0 +1,374 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2006 Klaas van Gend
* copyright (C) 2007 Christofer Wesseling
* copyright (C) 2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "enterpindialog.h"
#include "enterpukdialog.h"
#include "SIMHandler.h"
#include "ProgressDialog.h"
#include "Query.h"
#include "TheDeviceManagerSingleton.h"
#include "Popup.h"
#include <assert.h>
#include <ntqstring.h>
#include <ntqtranslator.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
/** this string list contains all possible answers on the AT+CPIN question
* table is taken from Chapter 8.3 in 3GPP TS 27.007 V7.0.0 (2006-03)
*
*/
static const char* theCPIN_Answers[] =
{
// Translators notice: NEVER translate these texts!!!
"READY",
"SIM PIN",
"SIM PUK",
"PH-SIM PIN",
"PH-SIM PUK",
"PH-FSIM PIN",
"PH-FSIM PUK",
"SIM PIN2",
"SIM PUK2",
"PH-NET PIN",
"PH-NET PUK",
"PH-NETSUB PIN",
"PH-NETSUB PUK",
"PH-SP PIN",
"PH-SP PUK",
"PH-CORP PIN",
"PH-CORP PUK"
};
/** TRANSLATOR
* this string list contains descriptions for the possible answers
* on the AT+CPIN question
* Klaas took this list from the gsmlib/gsmctl man page
* and modified it to contain user understandable text...
* (If he understood the message himself)
*
* Several of these messages should not appear in the wild (including the phone-to-* messages)
*/
static const char* theCPIN_Descriptions[] =
{
QT_TR_NOOP("not pending for any password."), // READY
QT_TR_NOOP("waiting for the PIN code for the SIM card."), // SIM PIN
QT_TR_NOOP("waiting for the PUK code to unblock the SIM card again."), //SIM PUK
QT_TR_NOOP("waiting phone-to-SIM card password to be given."), //PH-SIM PIN
QT_TR_NOOP("waiting phone-to-very SIM card password to be given."), // PH-SIM PUK
QT_TR_NOOP("waiting phone-to-very first SIM card password to be given."), // PH-FSIM Pin
QT_TR_NOOP("waiting phone-to-very first SIM card unblocking password to be given."), // PH-FSIM PUK
QT_TR_NOOP("waiting SIM PIN2 to be given."), // SIM PIN2
QT_TR_NOOP("waiting SIM PUK2 to be given."), // SIM PUK2
QT_TR_NOOP("waiting network personalisation password to be given."),
QT_TR_NOOP("waiting network personalisation unblocking password to be given."), // PH-NET PUK
QT_TR_NOOP("waiting network subset personalisation password to be given."),
QT_TR_NOOP("waiting network subset personalisation unblock code to be given."), // PH-NETSUB PUK
QT_TR_NOOP("unknown (PH-SP PIN) - please contact author"),
QT_TR_NOOP("unknown (PH-SP PUK) - please contact author"),
QT_TR_NOOP("unknown (PH-CORP PIN) - please contact author"),
QT_TR_NOOP("unknown (PH-CORP PUK) - please contact author")
};
SIMHandler::SIMHandler()
{
// empty now
;
}
void SIMHandler::askForPIN(void)
{
DEBUG4("SIMHandler::askForPIN() has been called\n");
SIMHandler::PIN_ReturnCode myPINReturn;
// dont't let him out before the card signal: everything fine!
while( (myPINReturn=isPinCodeRequired()) != SIMHandler::PIN_READY)
{
DEBUG4("is Pin required: %s\n", getCPINDescription(myPINReturn).ascii());
switch(myPINReturn)
{
case SIMHandler::PIN_READY:
DEBUG5("No PIN required\n");
break; // everythink fine!
case SIMHandler::PIN_SIM:
{
DEBUG5("We need a PIN!\n");
EnterPIN myPIN;
myPIN.enableValidator();
myPIN.setSIMHandlerPtr(this);
// shows the dialog, blocking all other..
myPIN.exec();
if (myPIN.result() == TQDialog::Accepted)
{
// het think's he's reads? ok.. lets give him a try?
if( setPIN(myPIN.getPIN(), &myPIN) == true )
break;
}
else
{
// dialog rejected
exit(35); // ok, he wants to get out
}
break;
}
case SIMHandler::PIN_PUK:
{
EnterPUK myPUK;
myPUK.enableValidator();
myPUK.setSIMHandlerPtr(this);
myPUK.exec();
if (myPUK.result() == TQDialog::Rejected)
exit(35); // ok, he wants to get out
break;
}
default:
Popup::Critical( TQObject::tr("SIM card is moaning about something I don't know about:\n"
"\"%1\"\n"
"Please insert the SIM into a regular phone and check it...").arg(getCPINDescription(myPINReturn)));
assert(false);
}
} // end of while status != ok...
}
const TQString
SIMHandler::getCPINDescription(PIN_ReturnCode aCode)
{
assert(aCode > 0);
TQString myString;
if(aCode > ERROR_BEYOND_LAST)
myString = TQObject::tr("Unknown error - please review logs");
else
myString = TQObject::tr(theCPIN_Descriptions[aCode]);
return myString;
}
SIMHandler::PIN_ReturnCode SIMHandler::isPinCodeRequired(TQWidget* aWPtr)
{
DEBUG5("SIMHandler::isPinCodeRequired\n");
TQString myPINAnswer;
// create a Status Dialog....
ProgressDialog myPD(aWPtr, TQObject::tr("Waiting for SIM-Interface..."));
myPD.start(500);
// wait up to 10 seconds for a positive result...
// note: we can have three cases here
// 1) AT+CPIN fails because the interface is still being initialised
// we retry in that case (that's what the loop is for)
// 2) AT+CPIN fails for errors
// throw an error dialog and fail
// 3) AT+CPIN takes considerable time to finish...
// this is solved by using runUntilDone
myPD.setMaxTime(10);
while (myPD.runOneSecond())
{
Query myQuery("AT+CPIN?");
Query::ReturnCode myResult = myQuery.runUntilDone();
if (myResult == Query::OK)
{
if (!myQuery.hasAnswer())
{
DEBUG1("work around for cards not returning SIM_READY but only OK.\n")
return PIN_READY;
}
myPINAnswer = myQuery.getAnswer().first();
myPD.finish();
break; // faster than 10 seconds.. great!
}
if (myResult == Query::ERROR)
{
// regular error without explanation
if (!myQuery.hasAnswer())
{
myPD.finish();
return ERROR_ERROR;
}
TQString myLastAnswer = myQuery.getAnswer().last();
// at least the Option cards really give
// "+CME ERROR: SIM interface not started yet" error...
if( !myLastAnswer.contains("not started yet") &&
!myLastAnswer.contains("SIM busy") )
Popup::Critical(TQObject::tr("SIM card handling resulted in this error:\n"
" \"%1\", sorry.\numtsmon will now close.").arg(myLastAnswer.replace("+CME ERROR: ","",false)));
}
DEBUG2("no SIM interface yet - sleeping \n");
sleep(1); // wait 1 second...
}
// if you get here after the progress max TIME, the following will return an ERROR_UNKOWN...
// clean up the PIN answer, as it might contain all kinds of "rubbish"
myPINAnswer.replace("\"","");
myPINAnswer.replace("\'","");
myPINAnswer.replace("\r","");
myPINAnswer.replace("\n","");
int myCode;
for (myCode = 0; myCode < ERROR_BEYOND_LAST; myCode++)
{
TQString myCPINString = "+CPIN: ";
myCPINString += theCPIN_Answers[myCode];
if (myPINAnswer == myCPINString)
break;
}
// Fixup for "original Vodafone 3G" and "Solomon SCMi250u" cards
// as this means SIM READY !!
if ((myCode == PIN_PIN2 || myCode == PIN_PUK2) &&
TheDeviceManagerSingleton::getDeviceCapsRef().needsPIN2workaround()==true)
{
DEBUG2("Vodafone3G/SolomonSCMi250u workaround: PIN_PIN2/PIN_PUK2 means PIN_READY.\n");
myCode = PIN_READY;
}
// "magically", ERROR_UNKNOWN is equal to ERROR_BEYOND_LAST :-)
return static_cast<PIN_ReturnCode>(myCode);
}
bool SIMHandler::setPIN(const TQString& aPIN, TQWidget* aWPtr)
{
return getQueryReturnOK( "AT+CPIN=\"" + aPIN + "\"", aWPtr);
}
bool SIMHandler::setPUK(const TQString& aPUK, const TQString& aNewPIN, TQWidget* aWPtr)
{
//lets ensure that the sim reallay wants a puk...
for (int i=3; i>0; i--)
{
DEBUG5("SimHandler::setPUK invalid pin\n");
Query myQuery("AT+CLCK=\"SC\",0,\"" APPNAME "\"");
myQuery.run();
}
return getQueryReturnOK( "AT+CPIN=\"" + aPUK + "\",\""+aNewPIN+"\"", aWPtr );
}
bool SIMHandler::getQueryReturnOK(const TQString& aQueryString, TQWidget* aWPtr)
{
bool myReturn = false;
int myOriginalVerbosity = theVerbosity;
// we need some secrecy here: let's suspend logging until later
if (theVerbosity>2)
{
DEBUG2("suspending detailed logging until PIN/PUK is set\n");
theVerbosity=2;
}
Query myQuery(aQueryString);
Query::ReturnCode myResult = myQuery.run();
if (myResult == Query::OK)
{
myReturn = true;
goto the_end;
}
if (myResult == Query::ERROR)
goto the_end;
// create a Status Dialog....
{
ProgressDialog myPD(aWPtr, TQObject::tr("Trying to set PIN/PUK"));
myPD.start(500);
// wait up to 12 seconds for a positive result...
myPD.setMaxTime(12);
while (myPD.runOneSecond())
{
myResult = myQuery.receiveMore();
if ( myResult == Query::OK)
{
myReturn = true;
myPD.finish();
break;
}
DEBUG2("sleeping ..\n");
}
}
the_end:
if (theVerbosity != myOriginalVerbosity)
{
DEBUG2("PIN/PUK finished: Resuming log at verbosity %d\n", myOriginalVerbosity);
theVerbosity = myOriginalVerbosity;
}
return myReturn;
}
bool SIMHandler::isPINProtectionEnabled(void)
{
DEBUG4("SIMHandler::isPINProtectionEnabled\n");
// +CLCK: 0 -> PIN is off
// +CLCK: 1 -> PIN is on
Query myQuery("AT+CLCK=\"SC\",2");
// lets wait for an answer..
Query::ReturnCode myResult = myQuery.runUntilDone();
if (myResult == Query::OK)
{
if (myQuery.hasAnswer())
return( myQuery.getAnswer().last().contains("+CLCK: 1") );
else
return false;
}
if (myResult == Query::ERROR)
{
// e.g. the LG KU380 Cellphone does this
// it probably means nothing serious - let's assume it means
// the phone doesn't expect a PIN code.
DEBUG3("Phone probably didn't expect a PIN question - assuming no PIN needed\n");
return false;
}
// anything else?
// probably no PIN required...
return false;
}
bool SIMHandler::setPINActive(bool aPINActiceStatus, const TQString &aCurrentPIN, TQWidget* aWPtr)
{
DEBUG5("SIMHandler::setPINActive\n");
TQString myStatus = "1";
if(aPINActiceStatus == false)
myStatus = "0";
return getQueryReturnOK("AT+CLCK=\"SC\"," + myStatus + ",\"" + aCurrentPIN + "\"", aWPtr);
}
bool SIMHandler::setNewPIN(const TQString &aCurrentPIN, const TQString &aNewPIN, TQWidget* aWPtr)
{
DEBUG5("SIMHandler::setNewPIN \n");
return getQueryReturnOK("AT+CPWD=\"SC\","+aCurrentPIN+","+aNewPIN, aWPtr);
}

@ -0,0 +1,142 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2006 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef SIMHANDLER_CLASS
#define SIMHANDLER_CLASS
#include <ntqstring.h>
// forward declarations
class Query;
class Device;
class TQWidget;
/** the SIMHandler class contains everything related to the SIM card,
* including PIN and PUK code handling
*
* At this moment, there is no persistant data in this class, it is more
* a "class utility" than a real class.
*/
class SIMHandler
{
public:
/** this enum contains numerical IDs for all possible answers
* on a AT+CPIN question
* FIXME: Add pointer to where this list was taken from
*
* (the corresponding const text strings are in SIMHandler.cpp:
* static const char* theCPIN_Answers[] )
*/
enum PIN_ReturnCode
{
PIN_READY = 0,
PIN_SIM,
PIN_PUK,
PIN_PH_SIM,
PIN_PH_SIM_PUK,
PIN_PH_FSIM,
PIN_PH_FSIM_PUK,
PIN_PIN2,
PIN_PUK2,
PIN_PH_NET,
PIN_PH_NET_PUK,
PIN_PH_NETSUB,
PIN_PH_NETSUB_PUK,
PIN_PH_SP,
PIN_PH_SP_PUK,
PIN_CORP,
PIN_CORP_PUK,
// from here the codes are *not* ETSI/3GPP defined, but added by Klaas:
ERROR_BEYOND_LAST,
ERROR_SIMINTERFACE_NOT_STARTED_YET = 200,
ERROR_ERROR,
ERROR_UNKNOWN = ERROR_BEYOND_LAST
};
/// constructor
SIMHandler(void);
/// destructor
virtual ~SIMHandler(void) {};
/// checks wheter PIN/PUK is needed and starts the needed dialogs
void askForPIN(void);
/** checks if a PIN code must be entered before the SIM can be accessed
* @param aWPtr pointer to the Widget in front of which to put a Progress Dialog
* @return returns wheter a PIN or PUK or something else is needed
*/
PIN_ReturnCode isPinCodeRequired(TQWidget* aWPtr=NULL);
/** tries to set the puk and a new PIN - and control if it was succsessfully
* @param aPuk the PUK
* @param newPIN the new PIN
* @param aWPtr pointer to the Widget in front of which to put a Progress Dialog
* @returns true: new PIN has been set.. false: cant't set new PIN (wrong PUK, incompatible PIN or AT error)
*/
bool setPUK(const TQString& aPUK, const TQString& newPIN, TQWidget* aWPtr=NULL);
/** tries to set the pin and check if it was succsessfully
* @param aPIN the new PIN
* @param aWPtr pointer to the Widget in front of which to put a Progress Dialog
* @return true: setting the pin was successfully, false: PIN incorrect, or AT error
*/
bool setPIN(const TQString& aPIN, TQWidget* aWPtr=NULL);
/** checks if a PIN is needed to access the sim-card
* @return true: ask-for.PIN is active, user have to enter a pin to access the sim-card false: no pin will be asked
*/
bool isPINProtectionEnabled(void);
/** trys to set the ask-for-pin status
* @param wished pin-active-status
* @param current pin
* @param aWPtr pointer to the Widget in front of which to put a Progress Dialog
* @return true: change pinstatus succesfully, false: change PIN status failed
*/
bool setPINActive(bool aPINActiceStatus, const TQString &aCurrentPIN, TQWidget* aWPtr);
/** changes the actial pin to a new one
* @param current pin
* @param new pin
* @param aWPtr pointer to the Widget in front of which to put a Progress Dialog
* @return true: pin changed, false: change pin failed
*/
bool setNewPIN(const TQString &aCurrentPIN, const TQString &aNewPIN, TQWidget* aWPtr);
private:
/** Return a description for PIN RETURN Codes
* @param PIN_ReturnCode aCode
* @return TQString
*/
const TQString getCPINDescription(PIN_ReturnCode aCode);
/** Returns if the Result of the Query was "OK" or not...
* @param aQueryString the Query, for which you want to check the result...
* @param aWPtr pointer to the Widget in front of which to put a Progress Dialog
* @return true: when te last query had returned an "OK", false if not...
*/
bool getQueryReturnOK(const TQString& aQueryString, TQWidget* aWPtr=NULL);
};
#endif // SIMHANDLER_CLASS

@ -0,0 +1,313 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2007, 2009 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "TheDeviceManagerSingleton.h"
#include "Device.h"
#include "TheSettingsSingleton.h"
#include "Popup.h"
#include "Runner.h"
#include "FileStuff.h"
#include "HelperList.h"
#include <typeinfo>
#include <assert.h>
static TheDeviceManagerSingleton* theDeviceMgrSingletonInstancePtr = NULL;
static Device* theStaticDevicePtr = NULL;
static const char* thePPPKeyStr = "/device/PPPPortName";
static const char* theATKeyStr = "/device/ATPortName";
static const char* theDeviceTypeKeyStr = "/device/DeviceType";
TheDeviceManagerSingleton::TheDeviceManagerSingleton()
{
DEBUG5("TheDeviceManagerSingleton::TheDeviceManagerSingleton()\n");
// before doing anything else, let's make sure there's not a pppd running already
Runner myRunner;
if (myRunner.doesPPPDexist()!=-1)
{
// FIXME: remove this Popup...
Popup::Critical(TQObject::tr("Apparently there is already a pppd process running.\n"
"This prevents umtsmon from detecting your card,\numtsmon will now close."), NULL);
}
theStaticDevicePtr = Device::createDeviceInstance(DeviceCapabilities::NULLDEVICE);
atexit(destroy);
}
void TheDeviceManagerSingleton::destroy(void)
{
// this delete will trigger the destructor
delete theDeviceMgrSingletonInstancePtr;
theDeviceMgrSingletonInstancePtr = NULL;
}
TheDeviceManagerSingleton::~TheDeviceManagerSingleton(void)
{
DEBUG5("DESTRUCTOR TheDeviceManagerSingleton::~TheDeviceManagerSingleton()\n");
emptyAutoDetectList();
if (theStaticDevicePtr)
delete theStaticDevicePtr;
}
// dear programmers, keep in mind that this member is static,
// i.e. you cannot use any of the other members in the class,
// nor any of the variables
TheDeviceManagerSingleton& TheDeviceManagerSingleton::me(void)
{
// do we exist? if not: create us
if (theDeviceMgrSingletonInstancePtr == NULL)
theDeviceMgrSingletonInstancePtr = new TheDeviceManagerSingleton();
return *theDeviceMgrSingletonInstancePtr;
}
// dear programmers, keep in mind that this member is static,
// i.e. you cannot use any of the other members in the class,
// nor any of the variables
Device& TheDeviceManagerSingleton::getDeviceRef(void)
{
// do we exist? if not: create us
if (theStaticDevicePtr == NULL)
{
me();
}
// at this moment, we are very sure that a DevicePtr exists,
// even though it might be a null device...
assert(theStaticDevicePtr != NULL);
return *theStaticDevicePtr;
}
bool
TheDeviceManagerSingleton::setupDevice(void)
{
DEBUG3("TheDeviceManagerSingleton::setupDevice(void)\n");
// did the user config on the command line?
// did he force us not to look at the config file?
if (theNonAutoDetectClass.theSuggestedATPortName.isEmpty()
&& theNonAutoDetectClass.theForceAutodetection==false)
{
readFromConfigFile();
}
// no? then let's run the autodetectors
// note that the first autodetector is the NonAutoDetect,
// that - if we have specified settings on command line or in
// the config file - will instantiate the Device immediately
// without going through the autodetectors
DEBUG3("Start iterating through all AutoDetectors\n\n");
DEBUG4("Kernel: '%s'\n", FileStuff::getFileFirstLine("/proc/version").ascii());
AutoDetectList::iterator myDetector = theAutoDetectList.begin();
while (myDetector != theAutoDetectList.end())
{
try
{
if ((*myDetector)->go() == AutoDetectBase::DEVICE_DETECTED)
{
if (doDeviceCreation(**myDetector))
{
DEBUG3("Everything done - device created\n\n");
// at this point, we know where to expect the serial port(s)
// let's do some checks on read/write access now - for the ports
// and also suid checks on the helper applications we have
HelperList myList1;
if (myList1.testAndRun() == HelperList::QUIT)
exit(0);
return true;
}
}
}
catch (StopAutodetectionCycle)
{
// break this while - apparently it makes no sense to continue
DEBUG3("Autodetection cycle is halted for now...\n");
break;
}
++myDetector;
DEBUG3(" Let's continue with the next AutoDetector\n\n");
}
DEBUG3(" No device detected...\n");
return false;
}
bool
TheDeviceManagerSingleton::doDeviceCreation(AutoDetectBase& aSuggestedAutoDetector)
{
Device* myDevicePtr = aSuggestedAutoDetector.createDevice();
if (myDevicePtr==NULL)
return false;
theStaticDevicePtr = myDevicePtr;
// OK, so we got a real Device now. Let's store its settings for future use
// but only if we have not used the data from the config file...
if (typeid(aSuggestedAutoDetector) != typeid(NonAutoDetect))
{
DEBUG1("Found hardware configuration stored to disk\n");
writeToConfigFile();
}
else
{
DEBUG2("Using existing hardware config, not written to disk\n");
}
return true;
}
void
TheDeviceManagerSingleton::emptyAutoDetectList(void)
{
// the list is a list of pointers
// just delete the pointers and pop them should be enough
// keep in mind that the first one should be the non-autodetect
theAutoDetectList.pop_front();
while (!theAutoDetectList.isEmpty())
{
delete theAutoDetectList.last();
theAutoDetectList.pop_back();
}
}
void TheDeviceManagerSingleton::readFromConfigFile(void)
{
DEBUG3("TheDeviceManagerSingleton::readFromConfigFile()\n");
TQString myPPPString;
TQString myATString;
TQString myDeviceTypeString;
unsigned long myDeviceTypeLong;
// PPP
myPPPString = TheSettingsSingleton::getTQSRef().readEntry(thePPPKeyStr, "");
DEBUG4("read PPP port from config: '%s'.\n", myPPPString.ascii());
if (myPPPString.isEmpty())
goto nogood;
// AT
myATString = TheSettingsSingleton::getTQSRef().readEntry(theATKeyStr, "");
DEBUG4("read AT port from config: '%s'.\n", myATString.ascii());
if (myATString.isEmpty())
goto nogood;
// read hexadecimal type string
myDeviceTypeString = TheSettingsSingleton::getTQSRef().readEntry(theDeviceTypeKeyStr,
TQString::number(DeviceCapabilities::UNKNOWN));
myDeviceTypeLong = myDeviceTypeString.toULong(NULL, 0);
DEBUG4("read device type from config: 0x%08lX\n", myDeviceTypeLong);
if (myDeviceTypeLong == DeviceCapabilities::UNKNOWN)
goto nogood;
// good - we read a full set of parameters
theNonAutoDetectClass.theSuggestedDeviceType = static_cast<DeviceCapabilities::CardType>(myDeviceTypeLong);
theNonAutoDetectClass.theSuggestedPPPPortName = myPPPString;
theNonAutoDetectClass.theSuggestedATPortName = myATString;
DEBUG3("Complete config read from file - good :-)\n");
return;
nogood:
// bad - no full set
DEBUG1("Stored device configuration incomplete, reverting to autodetection\n");
theNonAutoDetectClass.theForceAutodetection = true;
}
void TheDeviceManagerSingleton::writeToConfigFile(void)
{
DEBUG3("TheDeviceManagerSingleton::writeToConfigFile()\n");
assert(theStaticDevicePtr != NULL);
assert(!theStaticDevicePtr->getPPPSerialPortName().isEmpty());
TheSettingsSingleton::getTQSRef().writeEntry(thePPPKeyStr,
theStaticDevicePtr->getPPPSerialPortName() );
assert(!theStaticDevicePtr->getATSerialPortName().isEmpty());
TheSettingsSingleton::getTQSRef().writeEntry(theATKeyStr,
theStaticDevicePtr->getATSerialPortName() );
// write type string in hex
assert(theStaticDevicePtr->getDeviceType()!=DeviceCapabilities::UNKNOWN);
TheSettingsSingleton::getTQSRef().writeEntry(theDeviceTypeKeyStr,
"0x" + TQString::number(theStaticDevicePtr->getDeviceType(),16) );
}
void
TheDeviceManagerSingleton::setSuggestedAT(const TQString& anATPortName)
{
theNonAutoDetectClass.theSuggestedATPortName = anATPortName;
DEBUG1("Set suggested AT port to '%s'\n", anATPortName.ascii());
}
void
TheDeviceManagerSingleton::setSuggestedPPP(const TQString& aPPPPortName)
{
theNonAutoDetectClass.theSuggestedPPPPortName = aPPPPortName;
DEBUG1("Set suggested PPP port to '%s'\n", aPPPPortName.ascii());
}
void
TheDeviceManagerSingleton::setSuggestedDeviceType(const DeviceCapabilities::CardType aDeviceType)
{
theNonAutoDetectClass.theSuggestedDeviceType = aDeviceType;
}
void
TheDeviceManagerSingleton::setupAutoDetectList(void)
{
if (!theAutoDetectList.isEmpty())
{
emptyAutoDetectList();
}
// the non-autodetect is the first in the autodetect list
// if anything gets supplied to this autodetector, it will attempt to
// create the device
// if that fails, the other autodetects will take over
theAutoDetectList.push_back(&theNonAutoDetectClass);
// warning: make sure these remain in this order, because otherwise
// you might get errors (e.g. the PCMCIA will error if it finds a USB2serial-based card)
// and one definitely wants to use the USB autodetect over the RawUSBports autodetect
theAutoDetectList.push_back(new AutoDetect_USB_ZeroCD());
theAutoDetectList.push_back(new AutoDetect_USB());
theAutoDetectList.push_back(new AutoDetect_PCMCIA());
theAutoDetectList.push_back(new AutoDetect_CSSerialPorts());
theAutoDetectList.push_back(new AutoDetect_PhoneModems());
theAutoDetectList.push_back(new AutoDetect_RawUSBports());
// theAutoDetectList.push_back(new AutoDetect_RawSerialPorts());
}
void
TheDeviceManagerSingleton::setForceAutodetection(void)
{
theNonAutoDetectClass.theForceAutodetection = true;
DEBUG1("Set force autodetection to true\n");
}
bool
TheDeviceManagerSingleton::tryDeviceDetection(void)
{
setupAutoDetectList();
return setupDevice();
}

@ -0,0 +1,120 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2007, 2009 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef THEDEVICEMANAGERSINGLETON_CLASS
#define THEDEVICEMANAGERSINGLETON_CLASS
#include "AutoDetect.h"
#include "DeviceCapabilities.h"
#include <ntqvaluelist.h>
//////////////////////////////////////////////////////////////////////////////
/** TheDeviceManagerSingleton abstracts, checks and protects the active instance
* of the Device class
*/
class TheDeviceManagerSingleton
{
private:
/** private constructor as demanded by the Singleton Design Pattern
* will be called by the get###() method if needed
*/
TheDeviceManagerSingleton(void);
/** private destructor as demanded by the Singleton Design Pattern
*/
~TheDeviceManagerSingleton(void);
// installed into atexit to destruct singeton on exit.
static void destroy(void);
/// private, unimplemented copy constructor - don't use
TheDeviceManagerSingleton(const TheDeviceManagerSingleton& aPtr);
/// private, unimplemented assign operator - don't use
TheDeviceManagerSingleton& operator=(TheDeviceManagerSingleton& aPtr);
/** the STATIC base for all get...Ref members
* if not Device exists yet, it will try to create one
*/
static Device& getDeviceRef(void);
public:
/// always use this member to get access to the DeviceCapabilities - never cache
static DeviceCapabilities& getDeviceCapsRef(void)
{ return dynamic_cast<DeviceCapabilities&>(getDeviceRef()); };
/// always use this member to get access to the DeviceRadioCapabilities - never cache
static DeviceRadioCapabilities& getDeviceRadioCapsRef(void)
{ return dynamic_cast<DeviceRadioCapabilities&>(getDeviceRef()); };
/// always use this member to get access to the ConnectionInfo - never cache
static ConnectionInfo* getConnectionInfoPtr(void)
{ return getDeviceRef().getConnectionInfoPtr(); };
/** resets (i.e. close+reopen) the Device's AT Serial Port.
* one better ensures that no Queries will be during this...
* @returns true if successful
*/
static bool resetDevice()
{
ConnectionInfoInhibitor myStartingInhibitor;
return getDeviceRef().resetATSerial();
};
/// the main entry member to the Singleton
static TheDeviceManagerSingleton& me(void);
/// used by main() to set a command-line specified AT port name
void setSuggestedAT(const TQString& anATPortName);
/// used by main() to set a command-line specified PPP port name
void setSuggestedPPP(const TQString& aPPPPortName);
/// used by main() to set the device type
void setSuggestedDeviceType(DeviceCapabilities::CardType aDeviceType);
/// used by main() to force autodetection, instead of relying on config file
void setForceAutodetection(void);
/// actually try to detect a device
bool tryDeviceDetection(void);
private:
bool setupDevice(void);
void readFromConfigFile(void);
void writeToConfigFile(void);
bool doDeviceCreation(AutoDetectBase& aSuggestedAutoDetector);
/// empties theAutoDetectList and deletes all autodetectors in it
void emptyAutoDetectList(void);
/// initialises theAutoDetectList with all autodetectors
void setupAutoDetectList(void);
// typedef to simplify usage of the AutoDetect list
typedef TQValueList<AutoDetectBase*> AutoDetectList;
/// list of all various AutoDetect subclass instances
AutoDetectList theAutoDetectList;
/** specialised autodetect pointer, to the autodetect class that can
* actually build a Device from supplied parameters.
* it's also the first entry of the AutoDetectList.
*/
NonAutoDetect theNonAutoDetectClass;
};
#endif // THEDEVICEMANAGERSINGLETON_CLASS

@ -0,0 +1,60 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006 Christofer Wesseling
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef VALIDATEPIN_CLASS
#define VALIDATEPIN_CLASS
#include "umtsmon_global.h"
#include <ntqvalidator.h>
#include <ntqstring.h>
/// validates the PIN
class ValidatePIN : public TQValidator
{
public:
ValidatePIN(TQObject* aParent, const char* aName = 0);
/// validate returns Acceptable if ... guess what...
virtual State validate(TQString& anInputString, __attribute__ ((unused)) int& aPos) const
{
/* ALLOWED is:
* ints: 0-9
* 4 to 8 digits....
*/
unsigned int myPosition=0;
while(myPosition < anInputString.length())
{
TQChar myChar = anInputString[myPosition];
myPosition++;
if (!myChar.isNumber())
return Invalid;
}
return Acceptable;
};
};
inline ValidatePIN::ValidatePIN( TQObject* aParent, const char* aName) : TQValidator(aParent, aName)
{
DEBUG5("Validate PIN\n");
}
#endif // defined VALIDATEPIN_CLASS

@ -0,0 +1,149 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef VALIDATEPHONENUMBER_CLASS
#define VALIDATEPHONENUMBER_CLASS
#include "umtsmon_global.h"
#include <ntqvalidator.h>
#include <ntqstring.h>
/// validates a phone number
class ValidatePhoneNumber : public TQValidator
{
public:
ValidatePhoneNumber(TQObject* aParent, const char* aName = 0);
/// validate returns Acceptable if ... guess what...
virtual State validate(TQString& anInputString, __attribute__ ((unused)) int& aPos) const
{
/* ALLOWED is:
* - any number of whitespace at the beginning
* - 0,1 or 2 times '+' at the beginning
* (FIXME: only 0 or 1 is actually allowed by the card)
* - any number of (0-9 '-' '.' ' ' or tab)
* but no starting 0 when a '+' is there...
*/
TQValidator::State myReturn = Acceptable;
unsigned int myPosition=0;
int myPlusCount = 0;
int myNumberCount = 0;
WhereAreWe myState = COUNTINGPLUSES;
while(myPosition < anInputString.length())
{
TQChar myChar = anInputString[myPosition];
myPosition++;
if (myChar.isSpace())
continue;
switch(myState)
{
case COUNTINGPLUSES:
if (myChar == '+')
myPlusCount++;
else
{
// re-check this one again
myPosition--;
myState=CHECKINGNUMBERS;
}
break;
case CHECKINGNUMBERS:
if (myChar == '0' && myPlusCount > 0 && myNumberCount == 0)
myReturn = Invalid;
if (myChar.isDigit())
myNumberCount++;
else
myReturn = Invalid;
break;
}
}
if(myPlusCount > 2)
{
myReturn = Invalid;
}
if (myReturn == Acceptable)
{
if (myNumberCount < 8)
myReturn = Intermediate;
}
return myReturn;
};
/// fixup... fixes the phone number...
virtual void fixup(TQString& anInputString) const
{
TQString myGoodString;
int myPlusCount=0;
for (unsigned int i=0; i<anInputString.length(); i++)
{
TQChar myChar = anInputString[i];
if (myChar.isSpace())
continue;
if (myChar == '+')
{
if (myPlusCount < 1)
{
myPlusCount++;
myGoodString += '+';
}
}
else
myGoodString += myChar;
}
anInputString = myGoodString;
};
private:
enum WhereAreWe
{
COUNTINGPLUSES,
CHECKINGNUMBERS
};
bool isWhiteSpace(int aChar)
{
switch (aChar)
{
case ' ':
case '-':
case '.':
return true;
default:
return false;
}
};
};
ValidatePhoneNumber::ValidatePhoneNumber(
TQObject* aParent, const char* aName)
: TQValidator(aParent, aName)
{
DEBUG5("ValidatePhoneNumber\n");
}
#endif // defined VALIDATEPHONENUMBER_CLASS

@ -0,0 +1,525 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2006,2007,2008,2009 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "ConnectionInfo.h"
#include "Query.h"
#include "OperatorList.h"
#include <ntqfile.h>
#include <ntqregexp.h>
#include <ntqtranslator.h>
#include <assert.h>
int ConnectionInfo::theInhibitionCount = 0;
bool ConnectionInfo::isInhibited(void) const
{
if (theInhibitionCount>0)
{
DEBUG3("ConnectionInfo probe inhibited\n");
return true;
}
return false;
}
ConnectionInfo::~ConnectionInfo()
{
if (theOperatorPtr!=NULL)
{
delete theOperatorPtr;
theOperatorPtr = NULL;
}
}
void ConnectionInfo::refresh(void)
{
refreshRegistration();
refreshSignalQuality();
if (isDeviceRegistered())
{
refreshOperator();
}
else
{
if (isSearching())
theOperatorName = TQObject::tr("Searching...");
else
theOperatorName = TQObject::tr("n/a");
}
// keep this one last - it might throw some exceptions
refreshTrafficStats();
}
void ConnectionInfo::refreshRegistration(void)
{
if (!isInhibited())
{
theRegistrationValue = refreshCGREG();
// if not successful, retry with AT+CREG
if (theRegistrationValue == REGISTRATION_UNKNOWN)
theRegistrationValue = refreshCREG();
}
}
void ConnectionInfo::refreshSignalQuality(void)
{
DEBUG4("ConnectionInfo::refreshSignalQuality(void)\n");
// only send Query if allowed
if (isInhibited())
{
theSignalQuality=99;
return;
}
// only do this when registered
// - data won't make sense otherwise
if (!isDeviceRegistered() && theRegistrationValue!=TRYING_TO_REGISTER)
theSignalQuality=99;
else
{
Query myQuery("AT+CSQ");
if (myQuery.runUntilDone() != Query::OK)
{
// no big deal, it happens, fail silently
DEBUG3("Query.run() failed\n");
return;
}
// result: '+CQS: 19,0' -> '19,0'
TQString myResult = myQuery.getAnswer().first().section(" ",1,1);
// result: '19,0' -> int 19 and display it...
theSignalQuality = myResult.section(",",0,0).toInt();
}
}
void ConnectionInfo::refreshOperator(void)
{
// only send Query if allowed
if (isInhibited())
return;
DEBUG4("ConnectionInfo::refreshOperator(void)\n");
// query for current operator
Query myQuery("AT+COPS?");
if (myQuery.runUntilDone() != Query::OK)
{
// no big deal, it happens, fail silently
DEBUG4("Query.run() failed...\n");
return;
}
TQString myAnswer = myQuery.getAnswer().first();
TQString myNewOperatorName;
if (myAnswer == "+COPS: 0")
{
myNewOperatorName = TQObject::tr("n/a");
theRadioType = -1;
}
else
{
// result: '+COPS: 0,0,"vodafone SE",0' -> 'vodafone SE'
myNewOperatorName = myAnswer.section("\"",1,1);
// filter after the second quote+comma -> ,2
theRadioType = myAnswer.section("\",",1,1).toInt();
}
// some operator names start with a number (e.g. '3' in the UK).
// all network ID's we've seen, are above 30000.
// so we can hopefully safely assume that any number above 1000
// is a network ID
// we leave it to resolveNetworkIDtoName to cache the lookup
if (theOperatorName != myNewOperatorName)
{
if (myNewOperatorName.toULong()>1000)
theOperatorName = resolveNetworkIDtoName(myNewOperatorName);
else
theOperatorName = myNewOperatorName;
}
}
TQString
ConnectionInfo::getRadiotypeString(int aRadioType)
{
TQString theType;
switch (aRadioType)
{
case -1:
theType = "n/a";
break;
case 0:
// officially: GSM
theType = "GPRS";
break;
case 1:
// officially: GSM compact
theType = "GSM compact";
break;
case 2:
// officially: UTRAN
theType = "UMTS";
break;
default:
theType = "???";
break;
}
return theType;
}
TQString ConnectionInfo::getRadiotype(void) const
{
if ( theRegistrationValue==REGISTERED_HOME ||
theRegistrationValue==REGISTERED_ROAMING)
return ConnectionInfo::getRadiotypeString(theRadioType);
else
{
if (theRegistrationValue==TRYING_TO_REGISTER)
return TQObject::tr("Searching...");
else
return TQObject::tr("n/a");
}
}
// this member contains the implementation of the official specification
// 3GPP TS 27.007 V7.0.0 (2006-03) - chapter 10.1.19
// unfortunately, this command is only 'Optional'.
ConnectionInfo::Registration ConnectionInfo::refreshCGREG(void)
{
if (isInhibited())
{
// we shouldn't really get here, but better safe then sorry
return REGISTRATION_UNKNOWN;
}
DEBUG4("ConnectionInfo::refreshCGREG(void)\n");
Query myQuery( "AT+CGREG?" );
Query::ReturnCode myResult = myQuery.runUntilDone();
if (myResult != Query::OK)
{
DEBUG2("unfortunately REGISTRATION_UNKNOWN as answer to AT+CGREG?\n");
return REGISTRATION_UNKNOWN;
}
// answer should be something like: +CGREG: <n>,<stat>[,<lac>,<ci>]
// where we don't care about <n>
// and <stat> can be 0,1,2,3,4,5
// For now, we don't care about <lac> or <ci> either
//
// in some cases, we will just receive "OK" - thanks Sierra!
if (!myQuery.hasAnswer())
return REGISTRATION_UNKNOWN;
TQString myAnswer = myQuery.getAnswer().first();
if (!myAnswer.contains("CGREG"))
{
DEBUG2("unfortunately unparsible answer '%s' to AT+CGREG.\n", myAnswer.ascii());
return REGISTRATION_UNKNOWN;
}
bool isOK;
int myCGREG = myAnswer.section(",",1,1).toInt(&isOK);
if (isOK)
return static_cast<Registration>(myCGREG);
else
return REGISTRATION_UNKNOWN;
}
// this member contains the implementation of the official specification
// 3GPP TS 27.007 V7.0.0 (2006-03) - chapter 7.2
// unfortunately, this command is only 'Optional'.
ConnectionInfo::Registration ConnectionInfo::refreshCREG(void)
{
if (isInhibited())
{
// we shouldn't really get here, but better safe then sorry
return REGISTRATION_UNKNOWN;
}
DEBUG4("ConnectionInfo::refreshCREG(void)\n");
Query myQuery( "AT+CREG?" );
Query::ReturnCode myResult = myQuery.runUntilDone();
if (myResult != Query::OK)
{
DEBUG2("unfortunately REGISTRATION_UNKNOWN as answer to AT+CREG?\n");
return REGISTRATION_UNKNOWN;
}
// answer should be something like: +CREG: <n>,<stat>[,<lac>,<ci>]
// where we don't care about <n>
// and <stat> can be 0,1,2,3,4,5
// For now, we don't care about <lac> or <ci> either
if (!myQuery.hasAnswer())
{
DEBUG2("Unfortunately only replied \"OK\" to CREG\n");
return REGISTRATION_UNKNOWN;
}
TQString myAnswer = myQuery.getAnswer().first();
if (!myAnswer.contains("CREG"))
{
DEBUG2("unfortunately unparsible answer '%s' to AT+CREG.\n", myAnswer.ascii());
return REGISTRATION_UNKNOWN;
}
bool isOK;
int myCGREG = myAnswer.section(",",1,1).toInt(&isOK);
if (isOK)
return static_cast<Registration>(myCGREG);
else
return REGISTRATION_UNKNOWN;
}
void ConnectionInfo::refreshTrafficStats(void)
{
DEBUG3("ConnectionInfo::refreshPPPStats\n");
unsigned long myCounterBytesSent = 0;
unsigned long myCounterBytesReceived = 0;
// update the rx and tx byte values
bool myIsProcNetDevStatPresent = false;
TQFile myFile("/proc/net/dev");
if (myFile.open(IO_ReadOnly) == true)
{
TQString myLine;
// FIXME: This is hardcoded for ppp0!!!
TQRegExp myPPP("ppp0");
while(myFile.readLine(myLine, 255)> 0)
{
// perform substring searching
if (myPPP.search(myLine,0) != -1)
{
myIsProcNetDevStatPresent = true;
TQStringList myList = TQStringList::split(TQRegExp("[ :]"), myLine);
myCounterBytesSent = myList[9].toLong();
myCounterBytesReceived = myList[1].toLong();
break; // breaks while loop
}
}
myFile.close();
}
// or did we change state?
if (myIsProcNetDevStatPresent != isProcNetDevStatisticPresent)
{
DEBUG2("PPP State changed to %s\n", myIsProcNetDevStatPresent?"present":"gone");
isProcNetDevStatisticPresent = myIsProcNetDevStatPresent;
// did we start the connection?
if (myIsProcNetDevStatPresent == true)
{
theMonthlyTraffic.start(isRoaming());
}
}
if (myCounterBytesSent > theCounterBytesSent)
theUpDelta = myCounterBytesSent - theCounterBytesSent;
else
theUpDelta = 0;
theCounterBytesSent = myCounterBytesSent;
if (myCounterBytesReceived > theCounterBytesReceived)
theDownDelta = myCounterBytesReceived - theCounterBytesReceived;
else
theDownDelta = 0;
theCounterBytesReceived = myCounterBytesReceived;
// whatever the outcome is, let's update the monthly traffic stats
theMonthlyTraffic.update(theCounterBytesSent, theCounterBytesReceived);
}
const TQString&
ConnectionInfo::resolveNetworkIDtoName(const TQString& aNetworkID)
{
// aNetworkID should contain a string containing just a number, in the
// range between 20,201 (Belgacom, Belgium) and 732,111 (Colombia Movil, Colombia)
// (of course, these are observed numbers - numbers outside this range may exist)
unsigned long myID = aNetworkID.toULong();
assert(myID > 9999 && myID < 999999);
if (thePreviousNetworkID==myID && theOperatorPtr!=NULL)
return theOperatorPtr->getNetworkName();
// if we get here, we definitely need to do a lookup
thePreviousNetworkID = myID;
if (theOperatorPtr != NULL)
{
delete theOperatorPtr;
theOperatorPtr = NULL;
}
// the lookup will always return a valid class,
// if necessary containing bogus info
theOperatorPtr = Operator::lookup(aNetworkID);
assert(theOperatorPtr != NULL);
return theOperatorPtr->getNetworkName();
}
void ConnectionInfo_ACM::refreshRegistration(void)
{
DEBUG5("ConnectionInfo_ACM::refreshRegistration(void)\n");
// if we're allowed to use CGREG/CREG, let's immediately do that
if (isCGREGUsed==false)
{
if (theSignalQuality>0 && theSignalQuality<99)
{
// we have a signal quality - we must be registered!
// unfortunately no way to figure out if roaming :-(
theRegistrationValue = REGISTERED_HOME;
}
else
{
// oh. we don't have a means to figure out registration info.
theRegistrationValue = TRYING_TO_REGISTER;
}
}
else
{
refreshRegistration();
}
}
void
ConnectionInfo_HSO::refreshTrafficStats(void)
{
DEBUG3("ConnectionInfo_HSO::refreshPPPStats\n");
unsigned long myCounterBytesSent = 0;
unsigned long myCounterBytesReceived = 0;
// for HSO devices, if the hso0 line is present in /proc/net/dev, it
// will remain there for as long as the device is inserted.
// that makes it easier compared to the PPP case:
// (no need to check if the line goes away)
// And harder at the same time:
// (if umtsmon is quit and restarted, we need to adjust for the in hs0)
// update the rx and tx byte values
bool myIsProcNetDevPresent = false;
TQFile myFile("/proc/net/dev");
if (myFile.open(IO_ReadOnly) == true)
{
TQString myLine;
// FIXME: This is hardcoded for hso0!!!
TQRegExp myHSORegExp("hso0");
while(myFile.readLine(myLine, 255)> 0)
{
// perform substring searching
if (myHSORegExp.search(myLine,0) != -1)
{
myIsProcNetDevPresent = true;
TQStringList myList = TQStringList::split(TQRegExp("[ :]"), myLine);
myCounterBytesSent = myList[9].toLong();
myCounterBytesReceived = myList[1].toLong();
break; // breaks while loop
}
}
myFile.close();
}
// or did we change state?
if (isProcNetDevStatisticPresent==false && myIsProcNetDevPresent==true)
{
DEBUG2("HSO State appeared in /proc/net/dev\n");
isProcNetDevStatisticPresent = true;
theBaseSent = myCounterBytesSent;
theBaseReceived = myCounterBytesReceived;
theMonthlyTraffic.start(isRoaming());
}
// adjust for the start value
myCounterBytesSent -= theBaseSent;
myCounterBytesReceived -= theBaseReceived;
if (myCounterBytesSent > theCounterBytesSent)
theUpDelta = myCounterBytesSent - theCounterBytesSent;
else
theUpDelta = 0;
theCounterBytesSent = myCounterBytesSent;
if (myCounterBytesReceived > theCounterBytesReceived)
theDownDelta = myCounterBytesReceived - theCounterBytesReceived;
else
theDownDelta = 0;
theCounterBytesReceived = myCounterBytesReceived;
// whatever the outcome is, let's update the monthly traffic stats
theMonthlyTraffic.update(theCounterBytesSent, theCounterBytesReceived);
}
void ConnectionInfo_ACM_Ericsson::refreshSignalQuality(void)
{
DEBUG4("ConnectionInfo_ACM_Ericsson::refreshSignalQuality(void)\n");
// only send Query if allowed
if (isInhibited())
{
theSignalQuality=99;
return;
}
// only do this when registered
// - data won't make sense otherwise
if (!isDeviceRegistered())
theSignalQuality=99;
else
{
// CIND returns follwing values:
// +CIND: ("battchg",(0-5)),("signal",(0-5)),("batterywarning",(0-1)),("chargerconnected",(0-1)),("service",(0-1)),("sounder",(0-1)),("message",(0-1)),("call",(0-1)),("roam",(0-1)),("smsfull",(0-1)),("callsetup",(0-3)),("callheld",(0-1))
Query myQuery("AT+CIND?");
if (myQuery.runUntilDone() != Query::OK)
{
// no big deal, it happens, fail silently
DEBUG3("Query.run() failed\n");
return;
}
// signalquality is second parameter ranging from 0 .. 5
// result: '+CIND: 3,5,0,0,...' -> '3,5,0,0,...'
TQString myResult = myQuery.getAnswer().first().section(" ",1,1);
// result: '3,5,0,0,...' -> int 5 and convert it it...
switch (myResult.section(",",1,1).toInt()) {
case 0: theSignalQuality = 0; break;
case 1: theSignalQuality = 5; break;
case 2: theSignalQuality = 10; break;
case 3: theSignalQuality = 15; break;
case 4: theSignalQuality = 20; break;
case 5: theSignalQuality = 25; break;
default: theSignalQuality = 99; break;
}
}
DEBUG4("ConnectionInfo_ACM_Ericsson::theSignalQuality is %i\n",theSignalQuality);
}

@ -0,0 +1,297 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2006,2007,2008,2009 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef CONNECTIONINFO_CLASS
#define CONNECTIONINFO_CLASS
#include "umtsmon_global.h"
#include "MonthlyTraffic.h"
#include <ntqobject.h>
#include <ntqstring.h>
// forward declaration: real declaration after ConnectionInfo class
class ConnectionInfoInhibitor;
// forward declaration: real include is in CPP file
class Operator;
/** The ConnectionInfo class creates and keeps metrics on the radio
* connection.
*/
class ConnectionInfo
{
public:
ConnectionInfo() :
theRegistrationValue(REGISTRATION_UNKNOWN),
theSignalQuality(0),
theOperatorName(""),
isProcNetDevStatisticPresent(false),
theCounterBytesSent(0),
theCounterBytesReceived(0),
theOperatorPtr(NULL),
thePreviousNetworkID(0)
{};
virtual ~ConnectionInfo();
/// refreshes the connection information
void refresh(void);
/** returns the signal quality.
* the value should (according to 3GPP TS 27.007 V7.0.0 (2006-03) - chapter 8.5)
* be interpreted as follows:
* 0 113 dBm or less
* 1 111 dBm
* 2...30 109... 53 dBm
* 31 51 dBm or greater
* 99 not known or not detectable
*/
unsigned int getSignalQuality(void) const
{ return theSignalQuality; };
/** returns the signal quality as a string - a number or "n/a" if not available
* See getSignalQuality() for more details
*/
TQString getSignalQualityString(void) const
{ return (theSignalQuality==99)?TQObject::tr("n/a"):TQString::number(theSignalQuality);};
const TQString& getOperatorName(void) const
{ return theOperatorName; };
/** static member: returns a string defining the Radiotype
* follows 3GPP TS 27.007 V7.0.0 (2006-03) - chapter 7.3
*/
static TQString getRadiotypeString(int aRadioType);
/** this member returns the radio type, but also takes registration into account
* i.e. if disconnected but searching, will return 'Searching...'.
*/
TQString getRadiotype(void) const;
/** info on whether the device is registered in *an* allowed operator network
* (either roaming or home)
*/
bool isDeviceRegistered(void) const
{ return (theRegistrationValue==REGISTERED_HOME || theRegistrationValue==REGISTERED_ROAMING); };
/// @returns true if we are currently connected to a roaming network
bool isRoaming(void) const
{ return (theRegistrationValue==REGISTERED_ROAMING); };
/// @returns true if the card is currently searching for a network
bool isSearching(void) const
{ return (theRegistrationValue==TRYING_TO_REGISTER); };
/// @returns the number of bytes sent in the current ppp session
unsigned long getCounterBytesSent(void) const
{ return theCounterBytesSent; };
/// @returns the number of bytes received in the current ppp session
unsigned long getCounterBytesReceived(void) const
{ return theCounterBytesReceived; };
/// @returns the delta between current and last upload observation in bytes
unsigned long getUploadDelta(void) const
{ return theUpDelta; };
/// @returns the delta between current and last download observation in bytes
unsigned long getDownloadDelta(void) const
{ return theDownDelta; };
// the following 5 members just wrap MonthlyTraffic
/// @returns the number of seconds connected
unsigned long getSecondsConnected(void) const
{ return theMonthlyTraffic.getSecondsConnected(); };
/** @returns the status of the current amount of time connected
* below, inbetween or over the limits
*/
MonthlyTraffic::ThresholdStatus getTimeThresholdStatus(void) const
{ return theMonthlyTraffic.getTimeThresholdStatus(); };
/// @returns the total number of seconds connected this month for this roaming and profile
unsigned long getTotalSecondsConnected(void) const
{ return theMonthlyTraffic.getTotalSecondsConnected(); };
/// @returns the total amount of traffic for this month for the current network type
unsigned long getTotalTraffic(void) const
{ return theMonthlyTraffic.getTotalTraffic(); };
/** @returns the status of the current amount of traffic
* below, inbetween or over the limits
*/
MonthlyTraffic::ThresholdStatus getTrafficThresholdStatus(void) const
{ return theMonthlyTraffic.getTrafficThresholdStatus(); };
protected:
/// asks the signal quality from the device
virtual void refreshSignalQuality(void);
/// retrieves the Regstration state from the device
virtual void refreshRegistration(void);
/** this function checks if ppp0 exists and
* refreshes the bytes read / bytes sent statics
*/
virtual void refreshTrafficStats(void);
/** returns true if ConnectionInfo should be prevented from
* from sending AT commands
*/
bool isInhibited(void) const;
/** the following are the return values of AT+CGREG
* 3GPP TS 27.007 V7.0.0 (2006-03) - chapter 10.1.19
*/
enum Registration
{
NOT_REGISTERED=0, // not registered, MT is not currently searching an operator to register to
REGISTERED_HOME=1, // registered, home network
TRYING_TO_REGISTER=2, // not registered, but MT is currently trying to
// attach or searching an operator to register to
// (also used by ConnectionInfo_ACM as internal state
// for "no CSQ yet")
REGISTRATION_DENIED=3, // registration denied
REGISTRATION_UNKNOWN=4, // unknown
REGISTERED_ROAMING=5 // registered, roaming
};
Registration theRegistrationValue;
unsigned int theSignalQuality;
int theRadioType;
TQString theOperatorName;
/// true if we have a ppp0 entry in /proc/net/dev
bool isProcNetDevStatisticPresent;
/// the bytes sent in the current session
unsigned long theCounterBytesSent;
/// the bytes received in the current session
unsigned long theCounterBytesReceived;
/// the delta between current and last upload observation in bytes
unsigned long theUpDelta;
/// the delta between current and last download observation in bytes
unsigned long theDownDelta;
MonthlyTraffic theMonthlyTraffic;
/** pointer to operator - used for resolving number-to-name issues
* in case AT+COPS only returns the network ID, not the operator name
*/
const Operator* theOperatorPtr;
unsigned long thePreviousNetworkID;
/** if AT+COPS only returns a number, this member can attempt to resolve
* the number to a name, using the [KnownOperators] section in the config file
* @param aNetworkID network ID to look up
* @returns TQString containing network name or "star + NetworkID"
* if not found
*/
const TQString& resolveNetworkIDtoName(const TQString& aNetworkID);
private:
void refreshOperator(void);
Registration refreshCGREG(void);
Registration refreshCREG(void);
/** this variable acts like a counting semaphore,
* increased and decreased by friend class ConnectionInfoInhibitor
*/
static int theInhibitionCount;
/** the above variable 'theInhibitionCount' must be accessible by
* ConnectionInfoInhibitor. But we don't want to expose it to anyone
* else. The solution is to declare the Inhibitor as a friend class
*/
friend class ConnectionInfoInhibitor;
};
//###########################################################################
/** specialised ConnectionInfo class for the HSO type of devices
*/
class ConnectionInfo_HSO : public ConnectionInfo
{
public:
ConnectionInfo_HSO()
: ConnectionInfo()
{DEBUG5("ConnectionInfo_HSO::ConnectionInfo_HSO()")};
virtual ~ConnectionInfo_HSO() {};
/// overridden from base class - statistics for HSO device, no ppp
virtual void refreshTrafficStats(void);
private:
unsigned long theBaseSent;
unsigned long theBaseReceived;
};
//###########################################################################
/** specialised ConnectionInfo class to work around AT limitations in most
* USB Modem implementations (mostly USB connected mobile phones)
*
* The limitations are:
* - no CGREG or CREG
* - or issueing it will cause the phone to start reconnecting :-(
* - FIXME: wasn't there a AT+COPS limitation???
*/
class ConnectionInfo_ACM : public ConnectionInfo
{
public:
ConnectionInfo_ACM() : ConnectionInfo(),isCGREGUsed(false) {};
virtual ~ConnectionInfo_ACM() {};
virtual void refreshRegistration();
void setUseOfCGREG(bool aBool)
{ isCGREGUsed = aBool; };
private:
bool isCGREGUsed;
};
/** specialised ConnectionInfo class for ericcson F3507g,
which uses AT+CIND for getting the signal quality
*/
class ConnectionInfo_ACM_Ericsson : public ConnectionInfo
{
public:
ConnectionInfo_ACM_Ericsson() : ConnectionInfo() {};
virtual ~ConnectionInfo_ACM_Ericsson() {};
protected:
void refreshSignalQuality(void);
};
//###########################################################################
/** This is a helper class to ConnectionInfo.
* Creating an instance of this class will prevent ConnectionInfo from
* actually sending out AT commands to retrieve connection metrics.
* just make this class a local variable - if it goes out of scope,
* the inhibition will automatically end.
*/
class ConnectionInfoInhibitor
{
public:
ConnectionInfoInhibitor() {ConnectionInfo::theInhibitionCount++; DEBUG4("ConnectionInfo:InhibitionCount ++, now is %d\n",ConnectionInfo::theInhibitionCount); };
~ConnectionInfoInhibitor() {ConnectionInfo::theInhibitionCount--; DEBUG4("ConnectionInfo:InhibitionCount --, now is %d\n",ConnectionInfo::theInhibitionCount); };
};
#endif // defined CONNECTIONINFO_CLASS

@ -0,0 +1,521 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2006,2007,2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "Device.h"
#include "Query.h"
#include "SerialPort.h"
#include "Popup.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
Device::~Device()
{
closeATSerial();
}
void
Device::closeATSerial(void)
{
if (theATSerialPortPtr)
{
delete theATSerialPortPtr;
theATSerialPortPtr = NULL;
Query::setSerial(NULL);
}
}
bool
Device::resetATSerial()
{
assert(theATSerialPortPtr != NULL);
if (theATSerialPortPtr == NULL)
return false;
return theATSerialPortPtr->resetDev();
}
Device*
Device::createDeviceInstance(CardType aCardType)
{
Device* myDevicePtr = NULL;
DEBUG3("Device creation for type 0x%08x requested\n", aCardType);
switch (aCardType)
{
case UNKNOWN:
// boo, bad, don't get here!!!
// - will be handled outside the switch()
DEBUG1("Attempt on creating device UNKNOWN - not good\n");
break;
case OPTION_3PORT: // is also for OPTION_4PORT
case OPTION_NOZOMI:
myDevicePtr = new Device_Option;
break;
case OPTION_HSO:
myDevicePtr = new Device_OptionHSO;
break;
case OPTION_VODAFONE_3G:
myDevicePtr = new Device_Vodafone3G;
break;
case BROADCOM_GPRS_EDGE:
myDevicePtr = new Device_BroadCom_GPRS_EDGE;
break;
case BROADCOM_57K6:
myDevicePtr = new Device_BroadCom57k6;
break;
case HUAWEI_MULTI:
myDevicePtr = new Device_Huawei;
break;
case NULLDEVICE:
myDevicePtr = new Device_NULL;
break;
case SIERRA_2PORT:
myDevicePtr = new Device_Sierra;
break;
case GENERIC_USER_SERIAL:
myDevicePtr = new Device_User_Serial;
break;
case GENERIC_CS_SERIAL:
myDevicePtr = new Device_CS_Serial;
break;
case MODEM_ACM:
myDevicePtr = new Device_ACM;
break;
case MODEM_RFCOMM:
myDevicePtr = new Device_RFComm;
break;
case MODEM_ACM_ERICSSON:
myDevicePtr = new Device_ACM_Ericsson;
break;
}
if (myDevicePtr != NULL)
myDevicePtr->theDeviceType = aCardType;
else
Popup::Critical("Critical error in device setup\nPlease rerun with -v5\ne-mail results to author");
return myDevicePtr;
}
bool
Device::probePortForAT( const TQString& aPortName ) const
{
DEBUG3("Device: probing port '%s' for AT commands\n", aPortName.ascii() );
Query::ReturnCode myResult = Query::ERROR;
TempSerialPort mySerialPort;
// the SerialPort class will automatically setup the Query class
if (mySerialPort.openDev(aPortName) == false)
{
goto not_good;
}
for (int i=0; i<3; i++)
{
Query myQueryAT("AT");
myResult = myQueryAT.run();
if (myResult == Query::OK)
{
DEBUG3("Got Query::OK from port\n");
break;
}
if (myResult != Query::ERROR)
{
DEBUG2("Device port '%s': no response to \"AT\", return code %d\n",
aPortName.ascii(), myResult);
goto not_good;
}
// in case of ERROR: retry...
DEBUG2("Device on port '%s' responded with ERROR, sleep & retry\n",
aPortName.ascii());
sleep(1);
}
not_good:
// and exit with returncode true or false
DEBUG3("Device: probing port '%s' %s\n", aPortName.ascii(),
(myResult == Query::OK)?"successful":"failed");
return (myResult == Query::OK);
}
bool
Device::setupPorts(const TQStringList& aListOfPorts, int aPortSpeed)
{
if (theATSerialPortName.isEmpty())
{
TQString myATName = aListOfPorts.last();
if (myATName.contains("/dev") > 0)
theATSerialPortName = myATName;
else
theATSerialPortName = "/dev/" + myATName;
}
if (thePPPSerialPortName.isEmpty())
{
TQString myName = aListOfPorts.first();
if (myName.contains("/dev") > 0)
thePPPSerialPortName = myName;
else
thePPPSerialPortName = "/dev/" + myName;
}
// check if the ports respond and adjust if necessary
if (probePortForAT(thePPPSerialPortName) == false)
thePPPSerialPortName = theATSerialPortName;
if (probePortForAT(theATSerialPortName) == false)
{
if (theATSerialPortName != thePPPSerialPortName)
{
// if the ports are different, we know the PPP port works
theATSerialPortName = thePPPSerialPortName;
}
else
return false;
}
DEBUG3("set AT serial to '%s'\n", theATSerialPortName.ascii());
DEBUG3("set PPP serial to '%s'\n", thePPPSerialPortName.ascii());
theATSerialPortPtr = new LongSerialPort;
// the SerialPort class will automatically setup the Query class
if (theATSerialPortPtr->openDev(theATSerialPortName, aPortSpeed, getPortSleepTime()) == false)
{
closeATSerial();
return false;
}
return true;
}
// ###########################################################################
// ###########################################################################
Device_Option::Device_Option()
{
theRadioPreferences = TQStringList::split("#",
"Only connect to GSM networks#"
"Only connect to UMTS networks#"
"If you have a choice - GPRS first#"
"If you have a choice - UMTS first#"
"Stick to the network the card connects to#"
"Automatic - let the card decide", false);
// This list is taken from Paul Hardwick's "Option Fusion Howto" page.
theConnectionInfoPtr = new ConnectionInfo;
}
Device_Option::~Device_Option ()
{
DEBUG5("Device_Option::~Device_Option\n");
if (theConnectionInfoPtr)
{
delete theConnectionInfoPtr;
theConnectionInfoPtr = NULL;
}
}
bool
Device_Option::setRadioPreferences(int aPref)
{
if (aPref<0 || aPref>5)
return false;
// FIXME: I have no clue what the second ,2 means...
Query myQuery( "AT_OPSYS=" + TQString::number(aPref) + ",2" );
Query::ReturnCode myResult = myQuery.runUntilDone();
if (myResult == Query::OK)
return true;
if (myResult == Query::NO_LOCK)
return false;
return false;
}
// ###########################################################################
// ###########################################################################
bool
Device_ACM::setupPorts(const TQStringList& aListOfPorts)
{
if (Device::setupPorts(aListOfPorts, getPortSpeed()) == false)
return false;
// use local scoping to ensure that this Query dies in time
{
// we need echo on, but for Moto phones, it's off by default.
Query myQuery("ATE1");
// don't use runUntilDone because the answer might not be complete... Sigh!!!
DEBUG2("ACM: Result from ATE1 query: %d\n", myQuery.run());
}
return true;
}
// ###########################################################################
// ###########################################################################
bool
Device_BroadCom_GPRS_EDGE::setupPorts(const TQStringList& aListOfPorts)
{
if (Device_Single_Serial::setupPorts(aListOfPorts) == false)
return false;
return doCFUN();
}
bool
Device_BroadCom_GPRS_EDGE::doCFUN(void)
{
Query myQueryAT("AT+CFUN=1,1");
Query::ReturnCode myResult = myQueryAT.runUntilDone();
if (myResult != Query::OK)
return false;
return true;
}
// ###########################################################################
// ###########################################################################
Device_Huawei::Device_Huawei() : Device_Option()
{
theRadioPrefsList.push_back( HuaweiRadioPrefs( 2,1, "GPRS/EDGE Preferred") );
theRadioPrefsList.push_back( HuaweiRadioPrefs( 2,2, "3G Preferred") );
theRadioPrefsList.push_back( HuaweiRadioPrefs(13,1, "GPRS/EDGE Only") );
theRadioPrefsList.push_back( HuaweiRadioPrefs(14,2, "3G only") );
// the Option constructor fills theRadioPreferences list wrongly.
// let's make it right.
theRadioPreferences.clear();
RadioPrefsList::iterator myI = theRadioPrefsList.begin();
while (myI != theRadioPrefsList.end())
{
theRadioPreferences.push_back( (*myI).theDescription);
myI++;
}
// Device_Option::Device_Option already created a CI instance
delete theConnectionInfoPtr;
// in an attempt to make the Huawei E226 work, we use the
// ACM version here - no CGREG/CREG queries for Huawei
theConnectionInfoPtr = new ConnectionInfo_ACM;
}
bool
Device_Huawei::setupPorts(const TQStringList& aListOfPorts)
{
// duplicate list because we cannot change the original one
TQStringList myList = aListOfPorts;
// Many people reported that the last port of a Huawei device is not usable
// so, let's remove it from the list...
while (myList.count() > 2)
{
DEBUG3("Huawei workaround in place: drop last port\n");
myList.pop_back();
}
return Device::setupPorts(myList);
}
bool
Device_Huawei::setRadioPreferences(int aPref)
{
if (aPref<0 || aPref>3)
return false;
TQString myTempString = "AT^SYSCFG="
+ TQString::number(theRadioPrefsList[aPref].theFirst)
+ ","
+ TQString::number(theRadioPrefsList[aPref].theSecond)
+ ",3FFFFFFF,1,2";
Query myQuery( myTempString);
Query::ReturnCode myResult = myQuery.runUntilDone();
return (myResult == Query::OK);
}
// ###########################################################################
// ###########################################################################
Device_Sierra::Device_Sierra()
{
theRadioPreferences = TQStringList::split("#",
"Automatic - let the card decide#"
"Connect to UMTS 3G networks only#"
"Connect to GSM 2G networks only#"
"If you have a choice - UMTS 3G preferred#"
"If you have a choice - GSM 2G preferred#"
, false);
theConnectionInfoPtr = new ConnectionInfo;
}
bool
Device_Sierra::setupPorts(const TQStringList& aListOfPorts)
{
TQStringList myList = aListOfPorts;
assert (thePPPSerialPortName.isEmpty());
// let's assume we have a list of 10 ports ;-)
// find the first one that has APP1
TQStringList::Iterator myI;
for (myI = myList.begin(); myI != myList.end(); myI++)
{
if (checkATI_for_APP1(*myI))
{
thePPPSerialPortName = "/dev/" + *myI;
myList.erase(myI);
break;
}
}
// so we now assigned the PPP port and removed it from the list
// (or we didn't do either if none of the ports replies with APP1)
// the rest is standard:
return Device::setupPorts(myList);
}
bool
Device_Sierra::checkATI_for_APP1(const TQString& aSerialPort)
{
if (probePortForAT(aSerialPort)==false)
return false;
DEBUG3("Device: probing port '%s' for APP1 on ATI command\n", aSerialPort.latin1());
Query::ReturnCode myResult = Query::ERROR;
TempSerialPort mySerialPort;
// the SerialPort class will automatically setup the Query class
if (mySerialPort.openDev(aSerialPort) == false)
{
return false;
}
Query myQueryATI("ATI");
myResult = myQueryATI.run();
if (myResult == Query::OK)
{
DEBUG3(" Got Query::OK from port\n");
if (myQueryATI.hasAnswer())
{
for (TQStringList::Iterator myIterator = myQueryATI.getAnswer().begin();
myIterator != myQueryATI.getAnswer().end(); myIterator++)
{
TQString myAnswer = *myIterator;
if (myAnswer.contains("APP1\n"))
{
DEBUG3(" Port answered with APP1 on ATI command\n");
return true;
}
}
}
}
else
{
DEBUG3(" Got not Query::OK from port\n");
}
return false;
}
bool
Device_Sierra::setRadioPreferences(int aPref)
{
if (aPref<0 || aPref>4)
return false;
TQString myTempString;
Query myQuery( "AT!SELRAT=" + myTempString.setNum(aPref));
Query::ReturnCode myResult = myQuery.runUntilDone();
if (myResult == Query::OK)
return true;
if (myResult == Query::ERROR)
return false;
return false;
}
int
Device_Sierra::getDefaultRadioPreference()
{
Query myQuery("AT!SELRAT?");
/* should return for example:
* at!selrat?
* !SELRAT: 03, UMTS 3G Preferred
*
* OK
*
* Possible answers:
* !SELRAT: 00, Automatic
* !SELRAT: 01, UMTS 3G Only
* !SELRAT: 02, GSM 2G Only
* !SELRAT: 03, UMTS 3G Preferred
* !SELRAT: 04, GSM 2G Preferred
*/
Query::ReturnCode myResult = myQuery.runUntilDone();
if(myResult == Query::OK)
{
TQString myAnswer = myQuery.getAnswer().first();
if(myAnswer.contains("00"))
return 0;
if(myAnswer.contains("01"))
return 1;
if(myAnswer.contains("02"))
return 2;
if(myAnswer.contains("03"))
return 3;
if(myAnswer.contains("04"))
return 4;
}
//if we get here, log error return the default answer
DEBUG2("Could not getDefaultRadioPreference() from Device\n");
return 0;
}
bool
Device_ACM_Ericsson::setupPorts(const TQStringList& aListOfPorts, int aPortSpeed)
{
if (Device::setupPorts(aListOfPorts, aPortSpeed) == false)
return false;
Query myQueryAT("AT+CFUN=1,0");
Query::ReturnCode myResult = myQueryAT.runUntilDone();
return myResult == Query::OK;
}

@ -0,0 +1,522 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2006,2007,2008,2009 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DEVICE_CLASS
#define DEVICE_CLASS
// forward declarations:
class SerialPort;
#include <assert.h>
#include <ntqstring.h>
#include <ntqstringlist.h>
#include <termios.h>
#include <vector>
#include "ConnectionInfo.h"
#include "DeviceCapabilities.h"
/// Device is an abstract base class that contains everything specific to a device
class Device : public DeviceCapabilities, public DeviceRadioCapabilities
{
public:
// NOTICE THE MISSING CONSTRUCTOR HERE - IT'S IN THE PROTECTED SECTION
/// destructor is public: anyone can delete this class (as opposed to constructing one)
virtual ~Device();
/** Factory method (see Design Patterns book) to create the Device class instance
* The only way to create a Device instance is to use this method
* @param aCardType - enum defines what Device class to construct
*/
static Device* createDeviceInstance(enum CardType aCardType);
/// closes and deletes theATSerialPortName
void closeATSerial(void);
/** resets (i.e. close+open) the Device's AT Serial Port.
* one better ensures that no Queries will be run after this...
* typically only called by TheDeviceManagerSingleton
* @returns true if successful
*/
bool resetATSerial();
/** setupPorts will initialise the Device class' serial ports.
* Most Device types will take the first entry to be the PPP port
* and the last entry to be the AT port, but implementation details
* exist - the Sierra Wireless devices will probe to tell which port
* should be AT and which should be PPP. In the case of only one port,
* AT and PPP will go through this one
* @param aListOfPorts list with PARTIAL device names (e.g. ttyUSB1 or ttyS7)
* Must contain at least one entry.
* @param aPortSpeed baud rate of the port to use.
* Note that for many devices, this number is irrelevant.
* @returns true if all setup went ok
*/
virtual bool setupPorts(const TQStringList& aListOfPorts,int aPortSpeed = B115200);
/// @returns PPP port device name
const TQString& getPPPSerialPortName(void) const
{ return thePPPSerialPortName; };
/// @returns AT port device name
const TQString& getATSerialPortName(void) const
{ return theATSerialPortName; };
/// @returns pointer to the device-specific ConnectionInfo class, do not cache
ConnectionInfo* getConnectionInfoPtr(void) const
{return theConnectionInfoPtr;};
/** answers if the modem has a method to set radio preferences (UMTS only, GPRS only, etc)
* @returns true if the Device class has an implementation for this
*/
virtual bool hasRadioPreferences(void) const {return false;};
/// returns a list of all Radio Preferences the card supports, default setting is first
virtual const TQStringList getRadioPreferences(void) {return NULL;};
/// returns true if setting the Radio Preference was OK
virtual bool setRadioPreferences( __attribute__ ((unused)) int aPref) {return false;};
/// returns the default radio preference for the card
virtual int getDefaultRadioPreference(void) {return 0;};
/// probes a port for answer with APP1 on ATI command
virtual bool checkATI_for_APP1(__attribute__ ((unused)) const TQString& aSerialPort) {return false;};
/// returns a string describing the Device C++ class - not the device itself
virtual TQString getDeviceClassName(void) = 0;
/// returns the type of the Device
virtual DeviceCapabilities::CardType getDeviceType(void) const
{ return theDeviceType; };
/// "normal" Devices do not need this workaround
virtual bool needsPIN2workaround(void) {return false;}
protected:
/** test if a port name is actually hosting a responding modem
* @param aPortName the name of the port to probe
* @returns true if responsive
*/
virtual bool probePortForAT( const TQString& aPortName ) const;
TQString theATSerialPortName;
TQString thePPPSerialPortName;
ConnectionInfo* theConnectionInfoPtr;
SerialPort* theATSerialPortPtr;
CardType theDeviceType;
/// for any Device type except the Bluetooth one, this is 20000
virtual int getPortSleepTime(void)
{ return 20000; };
protected:
/** Protected constructor: this class cannot be constructed by 3rdParties.
* call the *static* createDeviceInstance method for that
*/
Device() : theConnectionInfoPtr(NULL),
theATSerialPortPtr(NULL) {};
private:
/// private, unimplemented copy constructor - don't use
Device(const Device&);
/// private, unimplemented assign operator - don't use
Device& operator=(Device& aPtr);
};
//############################################################################
//############################################################################
//############################################################################
/** empty implementation of the Device class - not usable for anything real
* this class is used when there is no device:
* * device detection hasn't run yet
* * device detection has not yielded results
* * device was removed
*/
class Device_NULL : public Device
{
public:
Device_NULL() { theConnectionInfoPtr = NULL; };
virtual ~Device_NULL () {};
virtual int getNumberOfPorts(void) const {return 0;};
virtual TQString getDeviceClassName(void) {return "No Device present\n"; };
};
//############################################################################
//############################################################################
//############################################################################
/// implementation of Device class for Option cards (both GT and Fusion+ cards)
class Device_Option : public Device
{
public:
Device_Option();
virtual ~Device_Option ();
/// The Option cards have AT_OPSYS to set radio preferences
virtual bool hasRadioPreferences(void) const {return true;};
/// returns a list of all Radio Preferences the card supports, default setting is first
virtual const TQStringList getRadioPreferences(void) {return theRadioPreferences;};
/// returns true if setting the Radio Preference was OK
virtual bool setRadioPreferences(int aPref);
/// the default radio preference for Option Cards is "prefer UMTS"
virtual int getDefaultRadioPreference(void) {return 3;};
virtual int getNumberOfPorts(void) const {return 3;};
virtual TQString getDeviceClassName(void) {return "Qualcomm-based chipset\n"; };
protected:
TQStringList theRadioPreferences;
};
//############################################################################
//############################################################################
//############################################################################
/** implementation of Device class for Huawei cards with multiple ports
* (as far as Klaas knows, all cards by Huawei qualify - at least:
* E169/E170/E220/E270/E612/E620/E660
* still unknown: E510)
*/
class Device_Huawei : public Device_Option
{
public:
Device_Huawei();
virtual ~Device_Huawei () {};
virtual bool hasRadioPreferences(void) const {return true;};
virtual bool setRadioPreferences(int aPref);
virtual int getDefaultRadioPreference(void) {return 1;}; /// 3G preferred
virtual int getNumberOfPorts(void) const {return 2;};
virtual TQString getDeviceClassName(void) {return "Generic Huawei card\n"; };
/// overridden because we might need to drop the last port for Huawei devices
virtual bool setupPorts(const TQStringList& aListOfPorts);
private:
struct HuaweiRadioPrefs
{
int theFirst;
int theSecond;
TQString theDescription;
HuaweiRadioPrefs(int a, int b, const TQString& c)
: theFirst(a), theSecond(b), theDescription(c) {};
};
typedef std::vector<HuaweiRadioPrefs> RadioPrefsList;
RadioPrefsList theRadioPrefsList;
/// returns the port speed (as a termios number, e.g. B115200) of the single serial port
int getPortSpeed(void) {return (B115200);};
};
//############################################################################
//############################################################################
//############################################################################
/** implementation of Device class for the original Vodafone 3G card
* different in usb hub IDs, has a known bug in PIN handling
*/
class Device_Vodafone3G : public Device_Option
{
public:
Device_Vodafone3G() { theConnectionInfoPtr = new ConnectionInfo; };
virtual ~Device_Vodafone3G () {};
virtual int getNumberOfPorts(void) const {return 3;};
virtual TQString getDeviceClassName(void) {return "Original Vodafone 3G card\n"; };
virtual bool needsPIN2workaround(void) {return true;};
};
//############################################################################
//############################################################################
//############################################################################
/** implementation of Device class for the Option HSO cards
* These Option devices use a different driver /dev/HSO*** (or /dev/tty/HS*)
* It's also possible to use them as a networking interface, but that is
* not supported by umtsmon.
*/
class Device_OptionHSO : public Device_Option
{
public:
Device_OptionHSO() { theConnectionInfoPtr = new ConnectionInfo_HSO; }
virtual ~Device_OptionHSO () {};
virtual int getNumberOfPorts(void) const {return 2;};
virtual TQString getDeviceClassName(void) {return "Option HSO-type device\n"; };
protected:
/** on HSO devices, if they show up in sysfs, they're bound to work :-P
* actually, probing the ports may not work...
* @returns always true
*/
virtual bool probePortForAT( __attribute__ ((unused)) const TQString& aPortName ) const
{ return true; }
};
//############################################################################
//############################################################################
//############################################################################
/** the Single Serial Device abstracts the notion of everything that provides
* only one Serial Port - this in contrast to e.g. the Open 4 port usb2serial and the Nozomi
* devices which are 3 or 4 ports.
*
* A Single Serial device has concurrency issues - whilst a PPP connection is open,
* it is not possible (for now) to do e.g. signal quality requests
*/
class Device_Single_Serial : public Device
{
public:
Device_Single_Serial() { theConnectionInfoPtr = new ConnectionInfo; };
virtual ~Device_Single_Serial() {};
virtual int getNumberOfPorts(void) const {return 1;};
virtual bool setupPorts(const TQStringList& aListOfPorts)
{ return Device::setupPorts(aListOfPorts, getPortSpeed()); };
protected:
/// returns the port speed (as a termios number, e.g. B115200) of the single serial port
virtual int getPortSpeed(void) = 0;
};
//############################################################################
//############################################################################
//############################################################################
/// implemention of Device class for Broadcom 4306-based cards (Sony Ericsson GC79, Option GT EDGE and GT Combo EDGE)
class Device_BroadCom_GPRS_EDGE : public Device_Single_Serial
{
public:
virtual ~Device_BroadCom_GPRS_EDGE() {};
virtual TQString getDeviceClassName(void) {return "Broadcom based 2G card\n"; };
// overloaded member, also need to do AT+CFUN
virtual bool setupPorts(const TQStringList& aListOfPorts);
protected:
/** this function needs to be called on start of the device to power on
* the radio.
*/
bool doCFUN(void);
/// returns the port speed (as a termios number, e.g. B115200) of the single serial port
virtual int getPortSpeed(void) {return (B115200);};
};
//############################################################################
class Device_BroadCom57k6 : public Device_BroadCom_GPRS_EDGE
{
public:
virtual TQString getDeviceClassName(void) {return "Broadcom based 2.5G card\n"; };
protected:
/// returns the port speed (as a termios number, e.g. B115200) of the single serial port
virtual int getPortSpeed(void) {return (B57600);};
};
//############################################################################
//############################################################################
//############################################################################
/** implemention of Device class that handles a user-configured serial port.
* don't expect this Device class to contain much functionality
*/
class Device_User_Serial : public Device_Single_Serial
{
public:
virtual ~Device_User_Serial() {};
virtual TQString getDeviceClassName(void) {return "User provided serial port\n"; };
protected:
/// returns the port speed (as a termios number, e.g. B115200) of the single serial port
int getPortSpeed(void) {return (B115200);};
};
//############################################################################
//############################################################################
//############################################################################
/** implemention of Device class that handles a PCNCIA cs_serial devices
* this cs_serial device does not show up in the pcmcia devices list.
*/
class Device_CS_Serial : public Device_Single_Serial
{
public:
virtual ~Device_CS_Serial() {};
virtual TQString getDeviceClassName(void) {return "Generic PCMCIA serial modem\n"; };
protected:
/// returns the port speed (as a termios number, e.g. B115200) of the single serial port
int getPortSpeed(void) {return (B115200);};
};
//############################################################################
//############################################################################
//############################################################################
/// USB-connected mobile phone modem - e.g. connected over /dev/ttyACM0
class Device_ACM : public Device_Single_Serial
{
public:
virtual ~Device_ACM() {};
virtual TQString getDeviceClassName(void) {return "USB-connected mobile phone modem\n"; };
Device_ACM() : Device_Single_Serial()
{
theConnectionInfoPtr = new ConnectionInfo_ACM();
};
/// overloaded member, also needs to do ATE1
virtual bool setupPorts(const TQStringList& aListOfPorts);
/** FIXME: Let's just set it to true for all ACM devices
* even if we only know that the Solomon SCMi250u needs this
*/
virtual bool needsPIN2workaround(void) {return true;};
protected:
/// returns the port speed (as a termios number, e.g. B115200) of the single serial port
int getPortSpeed(void) {return (B115200);};
};
//############################################################################
//############################################################################
//############################################################################
/** Bluetooth connected mobile phone modem - e.g. connected over /dev/rfcomm0
*
* This type of modem is special because it requires modifications for the
* roundtrip latencies in the serial connection.
*/
class Device_RFComm : public Device_Single_Serial
{
public:
virtual ~Device_RFComm() {};
virtual TQString getDeviceClassName(void) {return "Bluetooth connected mobile phone modem\n"; };
protected:
/// returns the port speed (as a termios number, e.g. B115200) of the single serial port
virtual int getPortSpeed(void) {return (B57600);};
/// overriden for this Bluetooth device - longer sleeps are required
int getPortSleepTime(void)
{ return 200000;};
};
//############################################################################
//############################################################################
//############################################################################
/// implementation of Device class for Sierra Wireless cards
class Device_Sierra : public Device
{
public:
Device_Sierra();
virtual ~Device_Sierra () {};
virtual bool setupPorts(const TQStringList& aListOfPorts);
/// The Sierra cards have AT!SELRAT to set radio preferences
virtual bool hasRadioPreferences(void) const {return true;};
/// returns a list of all Radio Preferences the card supports, default setting is first
virtual const TQStringList getRadioPreferences(void) {return theRadioPreferences;};
/// returns true if setting the Radio Preference was OK
virtual bool setRadioPreferences(int aPref);
// interogates the card for the current radio preference
virtual int getDefaultRadioPreference(void);
virtual int getNumberOfPorts(void) const {return 2;};
virtual TQString getDeviceClassName(void) {return "Generic Sierra Wireless Card\n"; };
protected:
TQStringList theRadioPreferences;
/** For Sierra Wireless cards, issuing ATI will result in several lines of answers
* including a line stating "APP1" which indicates that this port is of PPP type.
* Sierra Wireless devices are sensitive to this - don't mix the ports!
* As we've observed devices which have their AT port as first and others (same brand,
* same revision) which have their AT port as second :-(
* @param aSerialPort device to run ATI Query on
* @returns true if APP1 was amongst the answers
*/
bool checkATI_for_APP1(const TQString& aSerialPort);
};
class Device_ACM_Ericsson : public Device_ACM
{
public:
virtual ~Device_ACM_Ericsson() {};
virtual TQString getDeviceClassName(void) {return "Ericsson umtsm device\n"; };
Device_ACM_Ericsson()
{
ConnectionInfo_ACM_Ericsson *a = new ConnectionInfo_ACM_Ericsson();
theConnectionInfoPtr = a;
};
// overloaded member, also need to do AT+CFUN
virtual bool setupPorts(const TQStringList& aListOfPorts,int aPortSpeed );
};
#endif // defined DEVICE_CLASS

@ -0,0 +1,110 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2007 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef DEVICECAPABILITIES_INTERFACE
#define DEVICECAPABILITIES_INTERFACE
#include <ntqstring.h>
/// Interface for higher-level classes to retrieve info of the Device
class DeviceCapabilities
{
public:
virtual ~DeviceCapabilities() {};
/** the number of ports a device has.
* @returns 0 (in case of a NoDevice) up to 4 (max we've encountered)
*/
virtual int getNumberOfPorts(void) const = 0;
virtual const TQString& getPPPSerialPortName(void) const = 0;
virtual const TQString& getATSerialPortName(void) const = 0;
/** @returns the name of the C++ class of the Device
* this probably only has value to programmers and support
*/
virtual TQString getDeviceClassName(void) = 0;
/** returns true if the SIM_PIN2 workaround is needed
* (Original Vodafone3G and Solomon SCM250i only)
* @return true if workaround is needed
*/
virtual bool needsPIN2workaround(void) = 0;
/** enum defining all known card types
* note: IDs are in a derivative of leetspeek (see 'leet' in Wikipedia)
* to fit "recognizable IDs" into 8 hex nibbles
*
* - this need to be recognizable, fixed IDs
* because they will appear in the config files
*/
enum CardType
{
UNKNOWN = 0,
NULLDEVICE = 1, // EMPTY DEVICE
GENERIC_USER_SERIAL = 0x5e21a700, // SERIAL00
MODEM_ACM = 0x1770D0AC, // MOD_AC
MODEM_ACM_ERICSSON = 0x1770D0E2, // MOD_ER
MODEM_RFCOMM = 0x1770D02F, // MOD_RF
GENERIC_CS_SERIAL = 0x5e21a7c5, // SERIALCS
OPTION_4PORT = 0xcaa1c004, // TQAALCO_4 (qualcomm chipset)
OPTION_3PORT = OPTION_4PORT,
OPTION_VODAFONE_3G = 0xcaa1c001, // TQAALCO_1 (qualcomm chipset)
OPTION_NOZOMI = 0x17020177, // NOZOM
OPTION_HSO = 0x06710450, // OPTI_HS0
HUAWEI_MULTI = 0x600A1000, // GOOAI
BROADCOM_GPRS_EDGE = 0xB20AD079, // BROAD_79 (79 as in 'SE GC79')
BROADCOM_57K6 = 0xB20AD057, // BROAD_57 (57k6 port speed limitation)
SIERRA_2PORT = 0x51322402, // SIERRA_2
NOVATEL_2PORT = GENERIC_USER_SERIAL,
SONYERICSSON_GC79 = BROADCOM_GPRS_EDGE,
};
/// returns the type of the Device
virtual CardType getDeviceType(void) const = 0;
bool isSinglePort(void)
{
return getPPPSerialPortName() == getATSerialPortName();
};
};
/// Interface for higher-level classes to retrieve info of the Device on the radio topic
class DeviceRadioCapabilities
{
public:
virtual ~DeviceRadioCapabilities() {};
/** answers if the modem has a method to set radio preferences (UMTS only, GPRS only, etc)
* @returns true if the Device class has an implementation for this
*/
virtual bool hasRadioPreferences(void) const = 0;
/// returns a list of all Radio Preferences the card supports, default setting is first
virtual const TQStringList getRadioPreferences(void) =0;
/// returns true if setting the Radio Preference was OK
virtual bool setRadioPreferences(int aPref) = 0;
/// returns the default radio preference for the card
virtual int getDefaultRadioPreference(void) = 0;
};
#endif // DEVICECAPABILITIES_INTERFACE

@ -0,0 +1,488 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2006,2007,2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "HelperList.h"
#include "FileStuff.h"
#include "Popup.h"
#include "TheDeviceManagerSingleton.h"
#include "helperlistgui.h"
#include <ntqfile.h>
#include <ntqpixmap.h>
#include <sys/types.h>
#include <grp.h>
#include <unistd.h>
#include <assert.h>
/////////////////////////////////////////////////////////////////////////////
bool HelperData::fixup(void)
{
DEBUG3("HelperApp::fixup()\n");
return false;
}
/////////////////////////////////////////////////////////////////////////////
HelperApp::HelperApp(int aNumber, Runner::BinariesToRun aHelper,
const TQString& aVersion, TQString aRemark)
: HelperData(aNumber), theHelper(aHelper), isBinaryMissing(false)
{
Runner myRunner;
theFullPath = myRunner.getPath(aHelper);
isSUID = myRunner.isSUID(aHelper)?(HelperData::YES):(HelperData::NO);
theRemarks = aRemark;
theVersion = aVersion;
// It's debatable whether this code belongs here or in Runner...
// For now it's here because this is the location where it concerns us
switch(aHelper)
{
case Runner::RUNNERTESTER:
theName = "INTERNAL ERROR";
isSUID = HelperData::NOTAPPLICABLE;
break;
case Runner::SOMESU:
theName = "*su";
isSUID = HelperData::NOTAPPLICABLE;
break;
case Runner::PPPD:
theName = "pppd";
break;
case Runner::CHAT:
theName = "chat";
break;
case Runner::PCCARDCTL:
theName = "(pc)cardctl";
break;
case Runner::USBMODESWITCH:
theName = "USB mode switcher";
break;
}
// do we see problems?
if (theFullPath.isEmpty() || (!FileStuff::doesFileExist(theFullPath)))
{
isBinaryMissing = true;
// binary isn't there :-(
// in case of SOMESU and PPPD, that's killing
// in case of PCCARDCTL or USBMODESWITCH, it may not even be relevant
theFullPath = TQObject::tr("!!! missing binary");
switch(aHelper)
{
case Runner::SOMESU:
case Runner::PPPD:
// problem
needsFix = true;
break;
case Runner::PCCARDCTL:
// not a problem, we still didn't implement 'eject'
break;
case Runner::USBMODESWITCH:
// let's put it this way: only if we find a binary
// but it's not suid, it's a problem
// if there's no binary, I don't care :-D
break;
case Runner::RUNNERTESTER:
case Runner::CHAT:
// *definitely* not a problem
break;
}
DEBUG3("Binary %s is missing and that's %s.\n", theName.ascii(), needsFix?"major":"minor");
}
else
{
if (isSUID == NO && aHelper!=Runner::PCCARDCTL)
{
DEBUG1("binary '%s' is not SUID -> needs fixing\n", theFullPath.ascii());
needsFix = true;
}
}
}
void HelperApp::add(TQListView* aListViewPtr)
{
DEBUG3("HelperApp::add\n");
TQListViewItem* myTQLVI = new TQListViewItem (aListViewPtr, TQString::number(theNumber,10), theName);
myTQLVI->setOpen(true);
TQListViewItem* mySubTQLVI= new TQListViewItem (myTQLVI, "",
theFullPath, theVersion, "", theRemarks);
switch(isSUID)
{
case HelperData::YES:
{
TQPixmap myPixmap( TQPixmap::fromMimeSource("ok.png") );
mySubTQLVI->setPixmap(3, myPixmap);
break;
}
case HelperData::NO:
{
TQPixmap myPixmap( TQPixmap::fromMimeSource("process-stop-16x16.png") );
mySubTQLVI->setPixmap(3, myPixmap);
break;
}
case HelperData::NOTAPPLICABLE:
mySubTQLVI->setText(3, "n/a");
break;
}
// in case the binary is missing, let's put up a sign
if (isBinaryMissing)
{
TQPixmap myPixmap( TQPixmap::fromMimeSource("process-stop-16x16.png") );
mySubTQLVI->setPixmap(1, myPixmap);
}
}
bool HelperApp::fixup(void)
{
DEBUG3("HelperApp::fixup()\n");
if (isBinaryMissing)
{
Popup::Warning(TQObject::tr("%1 couldn't find binary %2,"
" which is required for full operation.").arg(APPNAME).arg(theName));
return false;
}
TQString myCommand = "chown root:root " + theFullPath + " && chmod u+s " + theFullPath;
DEBUG2("The fixup is: '%s'\n", myCommand.ascii());
Runner myRunner;
myRunner.runCommand(Runner::SOMESU, myCommand);
needsFix = myRunner.isSUID(theHelper)==false;
isSUID = (!needsFix)?(HelperData::YES):(HelperData::NO);
// needsFix is true when there's something to be fixed
// we return here if everything was fixed - that's the opposite
return !needsFix;
}
/////////////////////////////////////////////////////////////////////////////
HelperDev::HelperDev(int aNumber, const TQString& anATPort, const TQString& aPPPPort) :
HelperData(aNumber), theATPort(anATPort), thePPPPort(aPPPPort)
{
needsFix=false;
if (FileStuff::isFileReadWrite(anATPort)!=FileStuff::READWRITE)
{
DEBUG1("Device %s is not read/write -> needs fix\n", anATPort.ascii());
needsFix = true;
}
if (FileStuff::isFileReadWrite(aPPPPort)!=FileStuff::READWRITE)
{
DEBUG1("Device %s is not read/write -> needs fix\n", aPPPPort.ascii());
needsFix = true;
}
}
TQListViewItem* HelperDev::newLVI(TQListViewItem* aTQLVI,
const TQString& aPortName)
{
TQString myRemarks;
bool isOK = false;
if (FileStuff::doesFileExist(aPortName))
{
switch(FileStuff::isFileReadWrite(aPortName))
{
case FileStuff::READ:
myRemarks = TQObject::tr("user does not have write access");
isOK = false;
break;
case FileStuff::WRITE:
myRemarks = TQObject::tr("user does not have read access");
isOK = false;
break;
case FileStuff::READWRITE:
myRemarks = TQObject::tr("read/write access is OK");
isOK = true;
break;
case FileStuff::NOTHING:
myRemarks = TQObject::tr("user does not have read nor write access "
"(or something else has a lock)");
isOK = false;
break;
}
}
else
{
isOK = false;
myRemarks = TQObject::tr("not found on file system");
}
TQListViewItem* mySubTQLVI = new TQListViewItem (aTQLVI, "",
aPortName, "n/a", "n/a", myRemarks);
if (isOK)
{
TQPixmap myPixmap( TQPixmap::fromMimeSource("ok.png") );
mySubTQLVI->setPixmap(4, myPixmap);
}
else
{
TQPixmap myPixmap( TQPixmap::fromMimeSource("process-stop-16x16.png") );
mySubTQLVI->setPixmap(4, myPixmap);
}
return mySubTQLVI;
}
void HelperDev::add(TQListView* aListViewPtr)
{
TQListViewItem* myTQLVI = new TQListViewItem (aListViewPtr,
TQString::number(theNumber, 10),
TQObject::tr("Modem Communication Ports"));
myTQLVI->setOpen(true);
//FIXME, here are probably two small, one-time-only memory leaks:
__attribute__ ((unused)) TQListViewItem* mySubTQLVI_AT = newLVI(myTQLVI, theATPort);
__attribute__ ((unused)) TQListViewItem* mySubTQLVI_PPP = newLVI(myTQLVI, thePPPPort);
}
bool HelperDev::fixDev(const TQString& aPort)
{
Runner myRunner;
if (aPort.isEmpty())
return false;
if (FileStuff::isFileReadWrite(aPort)!=FileStuff::READWRITE)
{
TQString myCommand = "chmod uog+rw " + aPort;
myRunner.runCommand(Runner::SOMESU, myCommand);
}
return FileStuff::isFileReadWrite(aPort)==FileStuff::READWRITE;
}
bool HelperDev::fixup(void)
{
DEBUG3("HelperDev::fixup()\n");
bool theResult = true;
if (fixDev(theATPort)==false)
theResult = false;
if (fixDev(thePPPPort)==false)
theResult = false;
needsFix = !theResult;
return theResult;
}
/////////////////////////////////////////////////////////////////////////////
HelperGroup::HelperGroup(int aNumber) :
HelperData(aNumber)
{
needsFix=false;
createGroupList();
}
void HelperGroup::createGroupList()
{
DEBUG5("HelperGroup::createGroupList()\n");
gid_t *myGroupArray;
unsigned int myNumberOfGroups;
unsigned long myMaxNumberGroups = sysconf(_SC_NGROUPS_MAX) + 1;
myGroupArray = (gid_t*)(malloc(myMaxNumberGroups * sizeof (gid_t)));
myNumberOfGroups = getgroups(myMaxNumberGroups, myGroupArray);
// according to the man page, the egid *might* be missing
if(myNumberOfGroups < myMaxNumberGroups)
{
myGroupArray[myNumberOfGroups] = getegid();
myNumberOfGroups++;
}
// and transform the array into a TQStringList
for(unsigned int i=0; i<myNumberOfGroups; i++)
{
struct group *myGroup = getgrgid(myGroupArray[i]);
DEBUG6("group: %d = %s\n", myGroupArray[i], myGroup->gr_name);
theGroupList.push_back(myGroup->gr_name);
}
}
void HelperGroup::add(TQListView* aListViewPtr)
{
bool isRoot = Runner::amIRoot();
TQString myGroupText;
TQString myGroupHelp;
if (isRoot)
myGroupText = TQObject::tr("You run as root - no need for groups");
else
{
myGroupText = TQObject::tr("Member of the following user groups");
myGroupHelp = TQObject::tr("usually one needed to access the device");
}
TQListViewItem *myTQLVI = new TQListViewItem(aListViewPtr, TQString::number(theNumber, 10), myGroupText, "", "", myGroupHelp);
myTQLVI->setOpen(true);
bool isOK = isRoot;
if (!isRoot)
{
TQListViewItem* mySubTQLVI_dialout = newLVI(myTQLVI, "dialout", &isOK);
TQListViewItem* mySubTQLVI_uucp = newLVI(myTQLVI, "uucp", &isOK);
if (isOK)
{
TQPixmap myPixmap( TQPixmap::fromMimeSource("ok.png") );
mySubTQLVI_dialout->setPixmap(4, myPixmap);
mySubTQLVI_uucp->setPixmap(4, myPixmap);
}
else
{
TQPixmap myPixmap( TQPixmap::fromMimeSource("process-stop-16x16.png") );
mySubTQLVI_dialout->setPixmap(4, myPixmap);
mySubTQLVI_uucp->setPixmap(4, myPixmap);
}
}
needsFix = !isOK;
}
bool HelperGroup::fixup(void)
{
DEBUG3("HelperGroup::fixup()\n");
// FIXME: to be implemented
return false;
}
TQListViewItem* HelperGroup::newLVI(TQListViewItem* aTQLVI,
const TQString& aGroupName, bool* isOKPtr)
{
TQString myMessage;
if (theGroupList.contains(aGroupName))
{
myMessage = TQObject::tr("is member");
*isOKPtr = true;
}
else
myMessage = TQObject::tr("not a member - not fixable by umtsmon");
TQListViewItem* mySubTQLVI = new TQListViewItem (aTQLVI, "",
aGroupName, "n/a", "n/a", myMessage);
return mySubTQLVI;
}
// ###########################################################################
// ###########################################################################
// ###########################################################################
// ###########################################################################
// ###########################################################################
HelperList::~HelperList()
{
DEBUG3("HelperList::~HelperList\n");
while(theHelperDataList.size()!=0)
{
delete (*(theHelperDataList.begin()));
theHelperDataList.pop_front();
}
}
HelperList::TestResults HelperList::testAndRun(void)
{
DEBUG3("HelperList::testAndRun(void)\n");
createHelperList();
// if nothing to fix - don't create window
if (needsFixing()==false)
return OK;
// create gui and handle everything
theGUIPtr = new helperlistgui();
theGUIPtr->show();
theGUIPtr->setHelperListPtr(this);
addListToWidget();
theGUIPtr->exec();
return OK;
}
bool HelperList::needsFixing(void)
{
DEBUG3("HelperList::needsFixing\n");
HelperDataList::iterator i = theHelperDataList.begin();
for (; i!=theHelperDataList.end(); i++)
{
if ( (*i)->isNeedingFix() )
return true;
}
return false;
}
bool HelperList::fixIt(void)
{
DEBUG3("HelperList::fixIt\n");
bool wasAllFixed = true;
HelperDataList::iterator i = theHelperDataList.begin();
for (; i!=theHelperDataList.end(); i++)
{
if ( (*i)->isNeedingFix() )
{
if ( ((*i)->fixup()) == false)
wasAllFixed = false;
}
}
return wasAllFixed;
}
void HelperList::createHelperList(void)
{
DEBUG3("HelperList::createHelperList()\n");
// create the appropriate HelperAdata-derived structs
theHelperDataList.push_back(new HelperApp(1, Runner::PPPD, "", TQObject::tr("required if you want to make connections")));
TQString thePccardctlStdOut = "";
if (!theRunner.getPath(Runner::PCCARDCTL).isEmpty())
{
theRunner.runCommand(Runner::PCCARDCTL, "--version");
thePccardctlStdOut = theRunner.getStdOutStringList()[0];
}
theHelperDataList.push_back(new HelperApp(2, Runner::PCCARDCTL,
thePccardctlStdOut,
TQObject::tr("only required for PCMCIA cards")));
theHelperDataList.push_back(new HelperApp(3, Runner::SOMESU));
theHelperDataList.push_back(new HelperApp(4, Runner::USBMODESWITCH,
"", TQObject::tr("if this app is present, you probably need it.")));
theHelperDataList.push_back(new HelperDev(5,
TheDeviceManagerSingleton::getDeviceCapsRef().getATSerialPortName(),
TheDeviceManagerSingleton::getDeviceCapsRef().getPPPSerialPortName()));
theHelperDataList.push_back(new HelperGroup(6));
}
void HelperList::addListToWidget(void)
{
theGUIPtr->clearList();
HelperDataList::iterator i = theHelperDataList.begin();
for (; i!=theHelperDataList.end();i++)
theGUIPtr->add(*i);
}

@ -0,0 +1,165 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2007 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef HELPERLIST_H_
#define HELPERLIST_H_
#include "Runner.h"
#include <ntqstring.h>
#include <ntqlistview.h>
// forward declarations
class helperlistgui;
class HelperData
{
public:
HelperData(int aNumber) : theNumber(aNumber), needsFix(false) {};
virtual ~HelperData() {};
/// @returns true if this item is incorrectly configured
bool isNeedingFix(void) {return needsFix;};
/** adds TQListViewItem(s) based on the data in the class to the widget
* @param aListViewPtr pointer to the widget to add the items to
*/
virtual void add(TQListView* aListViewPtr) = 0;
/** the code to actually fix the problem,
* @returns true if problem fixed
*/
virtual bool fixup(void) = 0;
protected:
/// this int is an ID to sort on in the dialog
int theNumber;
TQString theName;
TQString theFullPath;
TQString theVersion;
enum SUIDState {YES, NO, NOTAPPLICABLE};
SUIDState isSUID;
TQString theRemarks;
bool needsFix;
};
class HelperApp : public HelperData
{
public:
HelperApp(int aNumber, Runner::BinariesToRun aHelper,
const TQString& aVersion="version", TQString aRemark="");
virtual ~HelperApp() {};
virtual bool fixup(void);
virtual void add(TQListView* aListViewPtr);
private:
Runner::BinariesToRun theHelper;
bool isBinaryMissing;
};
class HelperDev : public HelperData
{
public:
HelperDev(int aNumber, const TQString& anATPort, const TQString& aPPPPort);
virtual ~HelperDev() {};
virtual bool fixup(void);
virtual void add(TQListView* aListViewPtr);
private:
/// (internal function) creates a new ListViewitem for port aPortName
TQListViewItem* newLVI(TQListViewItem* aTQLVI, const TQString& aPortName);
bool fixDev(const TQString& aPort);
TQString theATPort;
TQString thePPPPort;
};
class HelperGroup : public HelperData
{
public:
HelperGroup(int aNumber);
virtual ~HelperGroup() {};
virtual void add(TQListView* aListViewPtr);
virtual bool fixup(void);
private:
/** (internal function) creates a new "sub"TQListViewItem
* @param aTQLVI theTQListViewItem to create a sub item for
* @param aGroupName the group to create the item for
* @param isOKPtr (OUTPUT) becomes true if aGroupName found in theGroupList
* @return a pointer to the newly created TQLVI
*/
TQListViewItem *newLVI(TQListViewItem *aTQLVI,
const TQString & aGroupName,
bool* isOKPtr);
/// assembles everything for the group list
void createGroupList();
TQStringList theGroupList;
};
class HelperList
{
public:
HelperList() {};
virtual ~HelperList();
enum TestResults {OK, FIXED=OK, CONTINUE, QUIT};
TestResults testAndRun(void);
/// returns true if anything needs fixing
bool needsFixing(void);
/// fixup the problem that this instance found
bool fixIt(void);
/** adds all the HelperApps to the HelperDataList
* note that it does not create the entry for the device nodes (ports)
* to use - that's done in setSerialPorts()
*/
void createHelperList(void);
void addListToWidget(void);
private:
/// Runner class to do our stuff
Runner theRunner;
/// pointer to the QT Dialog associated to this class
helperlistgui* theGUIPtr;
typedef std::list<HelperData*> HelperDataList;
HelperDataList theHelperDataList;
};
#endif /*HELPERLIST_H_*/

@ -0,0 +1,314 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "MonthlyTraffic.h"
#include "Profile.h"
#include <assert.h>
static const char* theMonthlyTrafficStr = "/MonthlyTraffic";
static const char* theHomeTrafficStr = "HomeTrafficInBytes";
static const char* theRoamingTrafficStr = "RoamingTrafficInBytes";
static const char* theHomeSecondsStr = "HomeConnectedSeconds";
static const char* theRoamingSecondsStr = "RoamingConnectedSeconds";
/* constructors / destructors / operators first */
MonthlyTraffic::MonthlyTraffic(
unsigned int aYear,
unsigned int aMonth)
: isRoaming(TheSettingsSingleton::getTQSRef().readBoolEntry(theWasRoamingSettingName, false)),
theCounterBytesSent(0),
theCounterBytesReceived(0),
isMonthRollOverDetected(false)
{
// find out which date to create the instance for
if (aMonth==0 || aYear==0)
theDate = TQDate::currentDate();
else
theDate = TQDate(aYear, aMonth, 1);
refreshProfileData();
}
MonthlyTraffic::~MonthlyTraffic()
{
// let's assume the worst - nothing saved yet
save();
TheSettingsSingleton::getTQSRef().writeEntry(theWasRoamingSettingName, isRoaming);
}
/////////////////////////////////////////////////////////////////////////////
/////// implementation of the rest of the members in alphabetic order ///////
/////////////////////////////////////////////////////////////////////////////
TQString
MonthlyTraffic::createPathName(const TQString& aKey) const
{
return theMonthlyTrafficStr + TQString("/")
+ TQString::number(theDate.year()) + TQString("/")
+ TQString::number(theDate.month()) + TQString("/")
+ Profile::getActiveProfileName() + TQString("/")
+ aKey;
}
unsigned long
MonthlyTraffic::getSecondsConnected(void) const
{
if (theConnectionStartTime.isValid())
return theConnectionStartTime.secsTo(TQDateTime::currentDateTime());
else
return 0;
}
MonthlyTraffic::ThresholdStatus
MonthlyTraffic::getTimeThresholdStatus(void) const
{
unsigned long myPercentage = 0;
if (isRoaming && theRoamingTimeLimit!=0)
{
myPercentage = theRoamingSeconds / theRoamingTimeLimit;
}
if (!isRoaming && theHomeTimeLimit!=0)
{
myPercentage = theHomeSeconds / theHomeTimeLimit;
}
return percentageToStatus(myPercentage);
}
MonthlyTraffic::ThresholdStatus
MonthlyTraffic::getTrafficThresholdStatus(void) const
{
// I'm not entirely sure if it's cheaper to do 64-bit integer calculations
// or floating point calculations... I'm assuming 64-bit for now...
unsigned long long myTraffic = theCounterBytesReceived + theCounterBytesSent;
unsigned long long myPercentage = 0;
if (isRoaming)
{
myTraffic += theRoamingTraffic;
if (theRoamingDataLimit == 0)
myPercentage = 0;
else
myPercentage = (100*myTraffic) / theRoamingDataLimit;
}
else
{
myTraffic += theHomeTraffic;
if (theHomeDataLimit == 0)
myPercentage = 0;
else
myPercentage = (100*myTraffic) / theHomeDataLimit;
}
return percentageToStatus(myPercentage);
}
MonthlyTraffic::ThresholdStatus
MonthlyTraffic::percentageToStatus(unsigned long aPercentage) const
{
if (aPercentage == 0)
return LIMITS_DISABLED;
if (aPercentage < theThresholdPercentage)
return BELOW;
if (aPercentage >= 100)
return OVER_LIMIT;
return BETWEEN;
}
unsigned long
MonthlyTraffic::getTotalSecondsConnected(void) const
{
if (isRoaming)
return theRoamingSeconds+getSecondsConnected();
else
return theHomeSeconds+getSecondsConnected();
}
unsigned long
MonthlyTraffic::getTotalTraffic(void) const
{
// and return the total traffic for this month so far
if (isRoaming)
return theRoamingTraffic+theCounterBytesReceived+theCounterBytesSent;
else
return theHomeTraffic+theCounterBytesReceived+theCounterBytesSent;
}
void
MonthlyTraffic::refreshProfileData(void)
{
// and retrieve the traffic data for that specific month
theHomeTraffic = TheSettingsSingleton::getTQSRef().readEntry(
createPathName(theHomeTrafficStr), 0).toULong();
theRoamingTraffic = TheSettingsSingleton::getTQSRef().readEntry(
createPathName(theRoamingTrafficStr), 0).toULong();
theHomeSeconds = TheSettingsSingleton::getTQSRef().readEntry(
createPathName(theHomeSecondsStr), 0).toULong();
theRoamingSeconds = TheSettingsSingleton::getTQSRef().readEntry(
createPathName(theRoamingSecondsStr), 0).toULong();
// retrieve data from the active profile
Profile myCurProfile;
isWarnOnDataThreshold = myCurProfile.getWarnOnDataThreshold();
theThresholdPercentage = myCurProfile.getThresholdPercentage();
theHomeDataLimit = myCurProfile.getHomeDataLimit()*1024*1024;
theRoamingDataLimit = myCurProfile.getRoamingDataLimit()*1024*1024;
theHomeTimeLimit = myCurProfile.getHomeTimeLimit();
theRoamingTimeLimit = myCurProfile.getRoamingTimeLimit();
theProfileName = myCurProfile.getProfileName();
}
void
MonthlyTraffic::save(void)
{
DEBUG3("MonthlyTraffic::save()\n");
// we only need to save one (for now)
if (isRoaming)
{
theRoamingTraffic += theCounterBytesSent + theCounterBytesReceived;
theRoamingSeconds += getSecondsConnected();
}
else
{
theHomeTraffic += theCounterBytesSent + theCounterBytesReceived;
theHomeSeconds += getSecondsConnected();
}
theConnectionStartTime = TQDateTime(); // reset to null (invalid)
// because writeEntry doesn't exist in a unsigned long variety,
// we convert to TQString first
TheSettingsSingleton::getTQSRef().writeEntry(createPathName(theRoamingTrafficStr),
TQString::number(theRoamingTraffic));
TheSettingsSingleton::getTQSRef().writeEntry(createPathName(theHomeTrafficStr),
TQString::number(theHomeTraffic));
TheSettingsSingleton::getTQSRef().writeEntry(createPathName(theRoamingSecondsStr),
TQString::number(theRoamingSeconds));
TheSettingsSingleton::getTQSRef().writeEntry(createPathName(theHomeSecondsStr),
TQString::number(theHomeSeconds));
DEBUG5("MonthlyTraffic::save: totals for %d/%d are: home=%luB/%lus, roaming=%luB/%lus\n",
theDate.year(), theDate.month(),
theHomeTraffic, theHomeSeconds,
theRoamingTraffic, theRoamingSeconds);
// as these are now persistant on disk, we need to reset the values
theCounterBytesSent = 0;
theCounterBytesReceived = 0;
}
void
MonthlyTraffic::start(bool anIsRoaming)
{
DEBUG3("MonthlyTraffic::start(anIsRoaming=%d)\n", anIsRoaming);
theConnectionStartTime = TQDateTime::currentDateTime();
isRoaming = anIsRoaming;
assert(theCounterBytesSent == 0);
assert(theCounterBytesReceived == 0);
refreshProfileData();
}
unsigned long
MonthlyTraffic::update(unsigned long aCounterBytesSent, unsigned long aCounterBytesReceived)
{
DEBUG5("MonthlyTraffic::update(%lu, %lu)\n", aCounterBytesSent, aCounterBytesReceived);
// if either counter is below the existing counter, that's an indication of trouble.
// probably ppp has reset its counters. Let's save the current statistics and start
// allover with accounting
// note that we know fore sure that we lost track of some of the traffic :-(
if ( aCounterBytesSent < theCounterBytesSent ||
aCounterBytesReceived < theCounterBytesReceived )
{
DEBUG2("MonthlyTraffic::update detected non-monotonous traffic statistics. Some traffic bytes not accounted for!\n");
DEBUG3("previous Sent/Received numbers were: %lu, %lu\n", theCounterBytesSent, theCounterBytesReceived);
// if it happened to only one, make sure to adjust the other one
// because save() will set the theCounterBytes* to zero
if (aCounterBytesSent > theCounterBytesSent)
aCounterBytesSent -= theCounterBytesSent;
if (aCounterBytesReceived > theCounterBytesReceived)
aCounterBytesReceived -= theCounterBytesReceived;
save();
}
// and check for / replace the counters
assert( aCounterBytesSent >= theCounterBytesSent );
assert( aCounterBytesReceived >= theCounterBytesReceived );
theCounterBytesSent = aCounterBytesSent;
theCounterBytesReceived = aCounterBytesReceived;
// Check for date rollovers here
if (!isMonthRollOverDetected && TQDate::currentDate() > theDate)
{
DEBUG2("rollover to new date detected\n");
// is it a rollover to a new month?
TQDate myDate(theDate.year(), theDate.month(), 1);
if (TQDate::currentDate() >= myDate.addMonths(1))
{
DEBUG1("MonthlyTraffic::update detected rollover to new month!\n");
// the problem is that pppd doesn't care - it keeps counting
// we can't fix that, but we can tell the user to close the
// connection at his earliest convenience. Until then, we will
// keep counting in the old month.
isMonthRollOverDetected=true;
throw MonthRolloverException();
// note how we deliberately do NOT update the date here!!!
}
else
{
// update the internal date of our instance
theDate = TQDate::currentDate();
}
}
// is it time to send out a warning?
warnIfNeeded();
return getTotalTraffic();
}
void
MonthlyTraffic::warnIfNeeded()
{
if (isWarnOnDataThreshold)
{
if ((getTimeThresholdStatus()==OVER_LIMIT) ||
(getTimeThresholdStatus()==BETWEEN))
{
isWarnOnDataThreshold = false;
throw OverThresholdException(OverThresholdException::TIME);
}
else
if ((getTrafficThresholdStatus()==OVER_LIMIT) ||
(getTrafficThresholdStatus()==BETWEEN))
{
isWarnOnDataThreshold = false;
throw OverThresholdException(OverThresholdException::TRAFFIC);
}
}
}

@ -0,0 +1,185 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef MONTHLYTRAFFIC_H_
#define MONTHLYTRAFFIC_H_
#include <ntqstring.h>
#include <ntqdatetime.h>
/** thrown by MonthlyTraffic::update in case the date rolls over into a new month
* e.g. user starts connection at Jan 31, 2008 at 23:50.
* this should be catched by anyone calling update() and able to stop pppd
*/
class MonthRolloverException
{
};
/** thrown by MonthlyTraffic::warnIfNeeded and/or MonthlyTraffic::update if
* the data or time limit is reached
*/
class OverThresholdException
{
public:
enum ThresholdType { TIME, TRAFFIC };
OverThresholdException( ThresholdType aReachedThresh) :
theReachedThreshold(aReachedThresh) { };
ThresholdType getThreshReached(void) { return theReachedThreshold; };
private:
OverThresholdException(void);
ThresholdType theReachedThreshold;
};
/** this class keeps the traffic (data/time) limits for a certain month
*/
class MonthlyTraffic
{
public:
/** constructor, will load relevant settings into this class, based on current profile
* and current date (if no specific date set)
* @param aYear specify nonzero (e.g. 2008) if not current year
* @param aMonth specify nonzero (e.g. 1 for Jan) if not current month
*/
MonthlyTraffic(unsigned int aYear=0, unsigned int aMonth=0);
~MonthlyTraffic();
/** updates the transmit/receive/total statistics of this Month
* FIXME: what to do if switching from roaming to home and vice-versa???
* @param aCounterBytesSent total amount of bytes as reported by ppp,
* should be monotonously increasing
* @param aCounterBytesReceived total amount of bytes as reported by ppp
* should be monotonously increasing
* @throws MonthRolloverException if the date rolls over to a new month
* @throws OverThresholdException if the data/time limit is reached
* @returns the total amount of traffic for this month for the current network type
*/
unsigned long update(unsigned long aCounterBytesSent, unsigned long aCounterBytesReceived);
/// @returns the number of seconds connected
unsigned long getSecondsConnected(void) const;
/// @returns the total number of seconds connected this month for this roaming and profile
unsigned long getTotalSecondsConnected(void) const;
enum ThresholdStatus
{
BELOW, // total for month/network/profile is below threshold percentage
BETWEEN, // traffic inbetween threshold percentage and 100% of limit
OVER_LIMIT, // traffic exceeded 100% of data limit
LIMITS_DISABLED // user didn't specify any limits
};
/** @returns the status of the current amount of time
* below, inbetween or over the limits
*/
ThresholdStatus getTimeThresholdStatus(void) const;
/** @returns the status of the current amount of traffic
* below, inbetween or over the limits
*/
ThresholdStatus getTrafficThresholdStatus(void) const;
/// @returns the total amount of traffic for this month for the current network type
unsigned long getTotalTraffic(void) const;
/** resets everything (again) and starts counting the traffic
* (everything is: roaming state, profile data, counters)
* @param anIsRoaming true if currently roaming
*/
void start(bool anIsRoaming);
private:
/// the date for which the instance is initialised
TQDate theDate;
/// start date/time of the connection
TQDateTime theConnectionStartTime;
/// true if roaming, false if home network
bool isRoaming;
/// the number of bytes sent in the current PPP Session
unsigned long theCounterBytesSent;
/// the number of bytes received in the current PPP Session
unsigned long theCounterBytesReceived;
/// the total amount of traffic (RX+TX) *in bytes* for Home Network THIS MONTH
unsigned long theHomeTraffic;
/// the total amount of traffic (RX+TX) *in bytes* for Roaming THIS MONTH
unsigned long theRoamingTraffic;
/// the total amount of traffic (RX+TX) *in bytes* for Roaming Network THIS MONTH
unsigned long theRoamingSeconds;
/// the total amount of traffic (RX+TX) *in bytes* for Home Network THIS MONTH
unsigned long theHomeSeconds;
// *** the following are copies from the data in Profile ***
/** warn if a monthly data limit threshold should be reached
* (upon reaching that threshold, ONE popup is emitted and then this
* member is set to false to prevent duplicate warnings)
*/
bool isWarnOnDataThreshold;
/// the percentage above which to warn if traffic exceeds
unsigned int theThresholdPercentage;
/// the data limit (RX+TX) *in bytes* for Home Network
unsigned long theHomeDataLimit;
/// the data limit (RX+TX) *in bytes* for Roaming
unsigned long theRoamingDataLimit;
/// the time limit *in seconds* for Home Network
unsigned long theHomeTimeLimit;
/// the time limit *in seconds* for Roaming
unsigned long theRoamingTimeLimit;
/// the name of the profile we're currently using
TQString theProfileName;
/// true if an exception has been thrown for month rollover in update()
bool isMonthRollOverDetected;
private:
MonthlyTraffic::ThresholdStatus
percentageToStatus(unsigned long aPercentage) const;
/** returns the TQSettings PathName+Key for a certain key
* i.e. will return "Traffic/2008/01/HomeLimit" if aKey is "HomeLimit"
* and theMonth/theYear are set to 01 and 2008 respectively
* @param aKey key to create the full pathname for
* @returns TQString with full path name
*/
TQString createPathName(const TQString& aKey) const;
/// writes the current statistics to disk (might be an expensive operation!)
void save(void);
/** throw a warning if needed
* @throws OverThresholdException if the data limit is reached
*/
void warnIfNeeded();
/// updates the profile name and profile-related data
void refreshProfileData();
// for automated testing purposes
friend class MonthlyTrafficTester;
};
#endif // MONTHLYTRAFFIC_H_

@ -0,0 +1,157 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "OperatorList.h"
#include "Query.h"
#include "ConnectionInfo.h"
#include "TheSettingsSingleton.h"
#include <assert.h>
OperatorList::OperatorList()
{
}
OperatorList::~OperatorList()
{
while (!theOperatorList.empty())
{
delete theOperatorList.back();
theOperatorList.pop_back();
}
}
Operator*
OperatorList::add(Operator* aNewOperator)
{
Operator* myOp = findNetworkID(aNewOperator->getNetworkID());
if (myOp == NULL)
{
theOperatorList.push_back(aNewOperator);
return findNetworkID(aNewOperator->getNetworkID());
}
myOp->theRadioModes += "+" + aNewOperator->theRadioModes;
// FORBIDDEN or CURRENT are stronger than AVAILABLE
if (myOp->getIconType()!=Operator::CURRENT || myOp->getIconType()==Operator::FORBIDDEN)
myOp->theIconType = aNewOperator->theIconType;
return myOp;
}
void
OperatorList::fill(const TQString& anAnswer)
{
TQStringList myList = TQStringList::split("),", anAnswer);
// in case of multiple answers on one line (e.g. Option)
// we will iterate over all the answers here
int i=0;
for ( TQStringList::Iterator myIt = myList.begin();
myIt != myList.end(); ++myIt )
{
i=i+1;
// kill everything up to the first '('
TQString myFullTelcoString = (*myIt).section("(",1,1);
Operator* myNewOperatorPtr = new Operator(myFullTelcoString);
if (myNewOperatorPtr->getIconType() != Operator::NOT_VALID)
add(myNewOperatorPtr);
else
delete myNewOperatorPtr;
}
}
Operator*
OperatorList::findNetworkID(unsigned long aNetworkID)
{
TheOperatorListIterator i;
for (i=begin(); i!=end(); i++)
{
if ((*i)->getNetworkID() == aNetworkID)
{
return *i;
}
}
return NULL;
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
static const char* theKnownOperators = "/KnownOperators/";
Operator::Operator(const TQString& aFullTelcoString)
{
// DEBUG5("Operator::Operator(%s)\n", aFullTelcoString.ascii());
// DEBUG5(" allow: '%s'\n", aFullTelcoString.section(",",0,0).ascii());
// DEBUG5(" full: '%s'\n", aFullTelcoString.section(",",1,1).ascii());
// DEBUG5(" short: '%s'\n", aFullTelcoString.section(",",2,2).ascii());
// DEBUG5(" id: '%s'\n", aFullTelcoString.section(",",3,3).ascii());
// DEBUG5(" type: '%s'\n", aFullTelcoString.section(",",4,4).ascii());
switch (aFullTelcoString.section(",",0,0).toInt())
{
case 3: // forbidden
theIconType = FORBIDDEN;
break;
case 1: // available
theIconType = AVAILABLE;
break;
case 2: // current
theIconType = CURRENT;
break;
case 0: // unknown -> denotes the end of the list
theIconType = NOT_VALID;
return;
}
theNetworkName = aFullTelcoString.section(",",1,1).replace("\"","");
theNetworkID =
aFullTelcoString.section(",",3,3)
.section("\"",1,1).toLong();
theRadioModes =
ConnectionInfo::getRadiotypeString(
aFullTelcoString.section(",",4,4).toInt());
TheSettingsSingleton::getTQSRef().writeEntry( theKnownOperators + TQString::number(theNetworkID), theNetworkName);
}
const Operator*
Operator::lookup (const TQString& aNetworkID)
{
TQString myName = TheSettingsSingleton::getTQSRef().readEntry( theKnownOperators + aNetworkID, "");
IconType myType = AVAILABLE;
if (myName.isEmpty())
{
myType = NOT_VALID;
myName = "*" + aNetworkID + "*";
}
return new Operator(aNetworkID.toULong(), myName, myType);
}

@ -0,0 +1,128 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef OPERATORLIST_H_
#define OPERATORLIST_H_
#include <ntqstring.h>
#include <list>
// forward declaration
class Operator;
// some typedefs to ease this class' interface
typedef std::list<Operator*> TheOperatorList;
typedef TheOperatorList::iterator TheOperatorListIterator;
class OperatorList
{
public:
OperatorList(void);
virtual ~OperatorList(void);
TheOperatorListIterator begin(void)
{ return theOperatorList.begin(); };
TheOperatorListIterator end(void)
{ return theOperatorList.end(); };
size_t size(void)
{ return theOperatorList.size(); };
/** fill the operator list from the answer from a single line of an AT+COPS=? query
* depending on the card that generated the output, it can contain multiple operators
*
* if the operator already exists, its name string will
* be appended to contain the new radio type
*/
void fill(const TQString& anAnswer);
/** searches the current list for the network ID and returns a pointer to the Operator instance
* @returns pointer to the found instance or NULL if not found
*/
Operator* findNetworkID(unsigned long aNetworkID);
protected:
/// the real list of available networks
TheOperatorList theOperatorList;
/** adds the info of the Operator to the list
* if the operator already exists (checked through the ID),
* it will merge the info
* @param aNewOperator pointer to Operator instance containing the new data
* @returns pointer to the Operator class finally containing the data
*/
Operator* add(Operator* aNewOperator);
};
class Operator
{
public:
/** constructor - to be called with a single, full AT+COPS=? entry.
*/
Operator(const TQString& aFullTelcoString);
/** "kind of a" constructor - initialises an Operator class based on the
* networkid - by looking it up in the settings file.
* @param aNetworkID TQString containing numerical value of network ID
* (number to identify a mobile operator).
* @returns the resulting Operator instance - it is the responsibility of
* the caller to delete this instance
* If aNetworkID is unknown, the Icon type will be NOT_VALID and the
* NetworkName will be empty.
*/
static const Operator* lookup (const TQString& aNetworkID);
virtual ~Operator(void) {;};
enum IconType{ NOT_VALID=0, CURRENT, AVAILABLE, FORBIDDEN};
IconType getIconType(void)
{return theIconType;};
const TQString& getNetworkName(void) const
{ return theNetworkName;};
const TQString& getRadioModes(void) const
{ return theRadioModes;};
/** @returns the network ID.
* We've observed network IDs to be in the 10,000-400,000 range only
*/
unsigned long getNetworkID(void) const
{return theNetworkID;};
private:
IconType theIconType;
TQString theNetworkName;
TQString theRadioModes;
unsigned long theNetworkID;
friend class OperatorList;
/// private default constructor - not defined, not accessible
Operator(void);
/// private constructor - only accessible internally
Operator(unsigned long aNetworkID, const TQString& aName, IconType aType)
: theIconType(aType), theNetworkName(aName), theNetworkID(aNetworkID) {;};
};
#endif /*OPERATORLIST_H_*/

@ -0,0 +1,906 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2006,2007,2008,2009 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "PPPConnection.h"
#include "Query.h"
#include "Runner.h"
#include "Profile.h"
#include "TheDeviceManagerSingleton.h"
#include "TheSettingsSingleton.h"
#include "Popup.h"
#include "SerialPort.h"
#include "FileStuff.h"
#include <ntqregexp.h>
#include <ntqstring.h>
#include <signal.h>
#include <cstdlib>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
// the actual definition of thePPPDState
static ConnectionObserverInterface::ConnectionState thePPPDState = ConnectionObserverInterface::STOPPED;
static pid_t theRunningPPPDPID = -1;
// the function to be called by atexit
// to make sure the PPPD daemon is shut down
static void run_at_exit(void)
{
DEBUG5("PPPConnection run_at_exit() called\n");
Runner myRunner;
int myPID = myRunner.doesPPPDexist();
if (myPID!=-1)
{
if (thePPPDState != ConnectionObserverInterface::NOT_OURS_RUNNING)
{
// thePPPDState is either RUNNING or STARTING
DEBUG3("Killing PPPD - process %d\n", myPID);
kill(myPID, SIGTERM);
theRunningPPPDPID = -1;
}
}
}
static void run_at_signal(__attribute__ ((unused)) int aSignalNumber)
{
run_at_exit();
exit(1);
}
ConnectionBaseClass::ConnectionBaseClass(const ConnectionBaseClass& aRef)
: ObserverManager<ConnectionObserverInterface>(aRef)
{
atexit(run_at_exit);
signal(SIGINT, run_at_signal);
signal(SIGHUP, run_at_signal);
// let's assume the worst
setNewConnectionState(ConnectionObserverInterface::STOPPED);
}
ConnectionBaseClass::~ConnectionBaseClass(void)
{
DEBUG4("ConnectionBaseClass::~ConnectionBaseClass(void)\n");
// nothing else to do here
}
bool ConnectionBaseClass::chat(const Profile& aProfile) const
{
// have to declare all variables here because I want to use goto...
bool myResult = false;
unsigned int myCID;
TQString myConnectStr;
TQString myAPN;
DEBUG3("ConnectionBaseClass::chat() start\n");
// AT&F: reset modem to default profile
// FIXME: if this fails, we should do pccardctl eject and insert and retry
if (sendChatString("AT&F")==false)
goto bad_end;
// ATE1: enable echo
// FIXME: if this fails, we should do pccardctl eject and insert and retry
if (sendChatString("ATE1")==false)
goto bad_end;
// build up the connectionstring
// like "AT+CGDCONT=1,\"IP\",\"office.vodafone.nl\""
//
// security check: anAPN should not contain any quotes or spaces
myAPN = aProfile.getAPN();
if ( myAPN.contains("\"") || myAPN.contains("\"") ||
myAPN.contains("'") || myAPN.contains(" ") )
{
Popup::Warning(TQObject::tr("Your APN contains illegal characters.\nPlease go back to your Profile page and change the APN."));
DEBUG1("ERROR: APN contains illegal character\n");
goto bad_end;
}
if (myAPN.isEmpty())
{
Popup::WarningWithMemory("NoAPNMsg", TQObject::tr("Warning: You did not specify an 'APN' in your profile.\nThis may work ok, it may not - depending on your network operator."));
}
// myCID needs to be adjustable: different number for cell phones on USB or BT
myCID = aProfile.getCID();
myConnectStr = "AT+CGDCONT=";
myConnectStr += TQString::number(myCID);
myConnectStr += ",\"IP\",\"" + myAPN + "\"";
if (sendChatString(myConnectStr)==false)
goto bad_end;
// and call the actual dial
myResult = dial(aProfile, myConnectStr);
bad_end:
DEBUG3("ConnectionBaseClass::chat() end with result: %d\n", myResult);
return myResult;
}
bool ConnectionBaseClass::isConnectionStarting(void)
{
// if PPP is running, it is not starting anymore :-)
if (isConnectionActive())
return false;
return thePPPDState == ConnectionObserverInterface::STARTING;
}
void ConnectionBaseClass::notifyObserver(ConnectionObserverInterface* myObserverPtr) const
{
myObserverPtr->newConnectionState(thePPPDState);
}
bool
ConnectionBaseClass::sendChatString(const TQString& aChatString) const
{
Query myQuery(aChatString);
if (myQuery.runUntilDone() != Query::OK)
return false;
return true;
}
void ConnectionBaseClass::setNewConnectionState(ConnectionObserverInterface::ConnectionState aNewState)
{
// only go through the burden of notify if state really changed
if (aNewState != thePPPDState)
{
DEBUG3("ConnectionBaseClass::setNewPPPState state %d to %d\n", thePPPDState, aNewState);
thePPPDState = aNewState;
ConnectionObserverInterface* myObserverPtr = firstObserver();
while (myObserverPtr != NULL)
{
notifyObserver(myObserverPtr);
myObserverPtr = nextObserver();
}
if (aNewState == ConnectionObserverInterface::RUNNING)
{
// make sure to mark this profile successful for the future
Profile myProfile;
myProfile.setWasConnectionSuccess(true);
}
}
}
//############################################################################
static const TQString theStaticDummyVersion(TQObject::tr("No Connection Class defined yet"));
DummyConnection::DummyConnection(void)
: ConnectionBaseClass(*this)
{
DEBUG4("DummyConnection::DummyConnection(void)\n");
isConnectionActive();
}
DummyConnection::~DummyConnection(void)
{
DEBUG4("DummyConnection::~DummyConnection(void)\n");
stopConnection();
}
bool DummyConnection::dial(
__attribute__ ((unused)) const Profile& aProfile,
__attribute__ ((unused)) const TQString& myConnectStr) const
{
return false;
}
const TQString& DummyConnection::getPPPVersion(void)
{
return theStaticDummyVersion;
}
bool DummyConnection::isConnectionActive(void)
{
setNewConnectionState(ConnectionObserverInterface::STOPPED);
return false;
}
bool DummyConnection::startConnection(void)
{
return false;
}
void DummyConnection::stopConnection(void)
{
}
//############################################################################
PPPConnection::PPPConnection(const ConnectionBaseClass& aRef)
: ConnectionBaseClass(aRef),
theCIInhibitorPtr(NULL),
hasOnlyOnePort(false),
thePPPThreadPtr(NULL)
{
// for some compatibility stuff, we need the exact version number of pppd
Runner myRunner;
myRunner.runCommand(Runner::PPPD, "--version");
TQString myTotalVersionNr = myRunner.getStdErrStringList()[0];
int myFirst = myTotalVersionNr.find(TQRegExp("\\d"), 0);
int myLast = myTotalVersionNr.find(TQRegExp("\\d"), -1);
thePPPVersionNumber = myTotalVersionNr.mid(myFirst,myLast-myFirst+1);
DEBUG4("pppd version string '%s' results in '%s'.\n",
myTotalVersionNr.ascii(),
thePPPVersionNumber.ascii());
isConnectionActive();
}
PPPConnection::~PPPConnection(void)
{
DEBUG4("PPPConnection::~PPPConnection(void)\n");
stopConnection();
}
void
PPPConnection::stopConnection(void)
{
run_at_exit();
}
bool
PPPConnection::isConnectionActive(void)
{
// let's try to get a PID for a running pppd
// without reading through all of /proc every time
pid_t myPID = -1;
// if the running pppd process ID still exists,
// we do not need to check for a *new* pppd pid
if (theRunningPPPDPID>0
&& FileStuff::doesFileExist("/proc/"+TQString::number(theRunningPPPDPID)+"/stat"))
{
myPID = theRunningPPPDPID;
}
else
{
// if there is a routing table set up for pppX, a pppd is running
if (FileStuff::doesFileContainString("/proc/net/route", TQString("ppp"))
&& thePPPDState!=ConnectionObserverInterface::STOPPED)
{
myPID = Runner::doesPPPDexist();
}
}
switch (thePPPDState)
{
case ConnectionObserverInterface::ERROR:
setNewConnectionState(ConnectionObserverInterface::STOPPED);
break;
case ConnectionObserverInterface::STOPPED:
if (myPID!=-1)
{
DEBUG2("PPPConnection::isPPPConnected someone else started a pppd\n");
setNewConnectionState(ConnectionObserverInterface::NOT_OURS_RUNNING);
}
if (theRunningPPPDPID!=-1)
{
// shouldn't happen
DEBUG1("PPPConnection::isPPPConnected state changed to STOPPED "
"without updating theRunningPPPDPID\n");
assert(false);
theRunningPPPDPID=-1;
}
break;
case ConnectionObserverInterface::STARTING:
if (thePPPThreadPtr == NULL)
{
// something went wrong ?!?
setNewConnectionState(ConnectionObserverInterface::STOPPED);
thePPPDStdErr.push_back(APPNAME " internal Error: not thePPPThreadPtr");
break;
}
if (thePPPThreadPtr->isDone())
{
DEBUG2("isDone is true\n");
// so, was it successful or not?
if (myPID == theRunningPPPDPID)
{
// euh? finished *and* still running?
// that means we have a zombie
// - process is dead, we have to reap it...
myPID = -1;
}
if (myPID == -1)
{
theRunningPPPDPID=-1;
thePPPDStdOut = thePPPThreadPtr->getStdOut();
thePPPDStdErr = thePPPThreadPtr->getStdErr();
if(thePPPVerbosity > 1)
{
TQStringList::Iterator it;
DEBUG4("*****output of PPP to stdout\n");
for (it = thePPPDStdOut.begin(); it != thePPPDStdOut.end(); ++it )
{
DEBUG4("* %s\n", (*it).ascii());
}
DEBUG4("*****end-of-output\n");
DEBUG4("*****output of PPP to stderr\n");
for (it = thePPPDStdErr.begin(); it != thePPPDStdErr.end(); ++it )
{
DEBUG4("* %s\n", (*it).ascii());
}
DEBUG4("*****end-of-output\n");
}
setNewConnectionState(ConnectionObserverInterface::ERROR);
}
else
{
theRunningPPPDPID = myPID;
setNewConnectionState(ConnectionObserverInterface::RUNNING);
}
DEBUG3("thread end - wait and cleanup\n");
delete thePPPThreadPtr;
thePPPThreadPtr = NULL;
}
else
{
DEBUG3("PPPDThread still running\n");
}
break;
case ConnectionObserverInterface::RUNNING:
if (myPID==-1 || myPID!=theRunningPPPDPID)
{
DEBUG2("Our PPPD was killed by someone\n");
theRunningPPPDPID=-1;
setNewConnectionState(ConnectionObserverInterface::STOPPED);
}
break;
case ConnectionObserverInterface::NOT_OURS_RUNNING:
if (myPID==-1)
{
DEBUG2("Someone else's PPPD was killed\n");
setNewConnectionState(ConnectionObserverInterface::STOPPED);
}
break;
}
DEBUG5("The PPPDState is %d\n", thePPPDState);
// we need the ConnectionInfoInhibitor here if we have only one serial port
// and we're not in 'stopped'.
// note that PPPThread and startConnection also have CIIs to make sure that we
// don't run into simulatenous accessess.
if (hasOnlyOnePort)
{
if (thePPPDState==ConnectionObserverInterface::STOPPED)
{
if (theCIInhibitorPtr!=NULL)
{
TheDeviceManagerSingleton::resetDevice();
delete theCIInhibitorPtr;
theCIInhibitorPtr=NULL;
}
}
else
{
if (theCIInhibitorPtr==NULL)
{
theCIInhibitorPtr = new ConnectionInfoInhibitor;
}
}
}
if (thePPPDState==ConnectionObserverInterface::STOPPED
|| thePPPDState==ConnectionObserverInterface::STARTING)
return false;
else
return true;
}
bool
PPPConnection::startConnection()
{
// just for this startup, create a Profile - which should be the currently selected profile
Profile myProfile;
theSerialPortName = TheDeviceManagerSingleton::getDeviceCapsRef().getPPPSerialPortName();
assert(!theSerialPortName.isEmpty());
// check if AT and PPP are the same device
if (TheDeviceManagerSingleton::getDeviceCapsRef().getATSerialPortName() == theSerialPortName)
hasOnlyOnePort = true;
else
hasOnlyOnePort = false;
// just as a precaution, some sanity checks.
// we will be checking if a PPP connection is already running.
// This shouldn't be the case - that's why there is an assert(false).
// however, if this happens in a release build, just return false.
DEBUG3("PPPConnection::startPPP entry\n");
if (isConnectionActive())
{
// if happens in debug build: make a lot of noise
// if happens in release build: just error out of here
DEBUG2("PPPConnection::startPPP, PPP is already connected ?!?\n");
stopConnection();
sleep(1);
// this shouldn't happen - crash big time on debug builds
assert(isConnectionActive()==false);
// and a fall-through prevention for release builds
if (isConnectionActive())
return false;
}
// remove everything that might be left from previous connections
assert(thePPPThreadPtr==NULL);
thePPPDStdOut.clear();
thePPPDStdErr.clear();
// from now on until the exit of this member, prevent
// ConnectionInfo from interfering with the AT serial port
setNewConnectionState(ConnectionObserverInterface::STARTING);
assert(theCIInhibitorPtr == NULL);
if (hasOnlyOnePort)
theCIInhibitorPtr = new ConnectionInfoInhibitor();
// we cannot connect if this is not set
if ( theSerialPortName .isEmpty())
{
DEBUG2("PPPConnection::startPPP - no PPP device ?!?\n");
return false;
}
// let's create a new serial port, that will temporarily
// (as long as this temp class exists) replace the original serial
// port for queries. As this temp object will be deleted upon exit of this
// member, the original state will be returned automatically
TempSerialPort myTempPort;
if (myTempPort.openDev(theSerialPortName)==false)
{
DEBUG2("PPPConnection::startPPP - cannot open port '%s' ?!?\n", theSerialPortName.ascii());
return false;
}
// let's do the CHATting :-)
// (using the temp serial instance)
if (!chat(myProfile))
{
DEBUG2("PPPConnection::startPPP - chatting failed ?!?\n");
return false;
}
// let's assemble the command line for pppd and send it to the logs
TQStringList myPPPArguments = assembleArgumentList(myProfile);
TQStringList::const_iterator i = myPPPArguments.begin();
DEBUG4("Assembled PPP string is: '");
for (; i != myPPPArguments.end(); i++)
DEBUG4NT("%s ", (*i).ascii());
DEBUG4NT("'\n");
setNewConnectionState(ConnectionObserverInterface::STARTING);
thePPPThreadPtr = new PPPThread(myPPPArguments);
thePPPThreadPtr->start();
// if there is a PPP running now, it's ours.
// but it might take a while before all scheduling is done,
// so let's wait for it...
theRunningPPPDPID = -1;
for (int i=0; i<5 && theRunningPPPDPID==-1; i++)
{
DEBUG5("Waiting for ppp PID\n");
sleep(1);
theRunningPPPDPID = Runner::doesPPPDexist();
DEBUG5("Found PPP PID %d\n", theRunningPPPDPID);
};
return true;
}
bool PPPConnection::dial(const Profile& aProfile, const TQString& myConnectStr) const
{
TQString myDialStr = "";
unsigned int myCID = aProfile.getCID();
if ( aProfile.getCIDPrefix().stripWhiteSpace().isEmpty() )
myDialStr = "ATD*99***" + myConnectStr.number(myCID) + "#";
else
myDialStr = "ATD" + aProfile.getCIDPrefix() + TQString::number(myCID) + "#";
DEBUG3("Dial String is: %s \n", myDialStr.ascii() );
Query myQuery(myDialStr);
// don't expect an OK following this one...
// however, we must catch an "ERROR"
if (myQuery.run()== Query::ERROR)
{
DEBUG1("ATD returned ERROR - connection failed\n");
return false;
}
return true;
}
TQStringList PPPConnection::assembleArgumentList(const Profile& aProfile) const
{
TQStringList myPPPArguments;
myPPPArguments.push_back("idle"); myPPPArguments.push_back("7200");
if (aProfile.getNoAuth())
myPPPArguments.push_back("noauth");
myPPPArguments.push_back("asyncmap"); myPPPArguments.push_back("0");
// PPP related stuff
// we only ask PPP to detach if connection is successfully up
myPPPArguments.push_back("updetach");
if (thePPPVerbosity > 0)
{
myPPPArguments.push_back("dump");
myPPPArguments.push_back("debug");
myPPPArguments.push_back("debug");
myPPPArguments.push_back("debug");
}
// modem-related stuff
myPPPArguments.push_back("460800");
myPPPArguments.push_back("lock");
myPPPArguments.push_back("crtscts");
myPPPArguments.push_back("modem");
myPPPArguments.push_back(theSerialPortName);
// header compressions and such
myPPPArguments.push_back("noipx");
if (aProfile.getNoCompression())
{
myPPPArguments.push_back("novj");
myPPPArguments.push_back("nobsdcomp");
}
if (aProfile.getNoCCP())
myPPPArguments.push_back("noccp");
// routing related stuff
if (aProfile.getIsDefaultRoute())
myPPPArguments.push_back("defaultroute");
if (aProfile.getReplaceDefaultRoute())
myPPPArguments.push_back("replacedefaultroute");
if (aProfile.getUsePeerDns())
myPPPArguments.push_back("usepeerdns");
if (aProfile.getNoIpDefault())
myPPPArguments.push_back("noipdefault");
// login info
if (!aProfile.getUsername().isEmpty())
{
myPPPArguments.push_back("user");
myPPPArguments.push_back(aProfile.getUsername());
}
if (!aProfile.getPassword().isEmpty())
{
myPPPArguments.push_back("password");
myPPPArguments.push_back(aProfile.getPassword());
}
// users can specify a ppp peer to call which in turn
// will make pppd include /etc/ppp/peers/<name> .
// the good news is that this file allows for priviledged options
// without pppd having to run as root - that's convenient!
// (of course, this file can only be created by root)
if (!aProfile.getCallName().isEmpty())
{
myPPPArguments.push_back("call");
myPPPArguments.push_back(aProfile.getCallName());
}
return myPPPArguments;
}
//############################################################################
PPPConnection::PPPThread::PPPThread(const TQStringList& anArgumentList)
: TQThread(), theArgumentList(anArgumentList), theReturnValue(-1), isRunning(false)
{
DEBUG2("PPPConnection::PPPThread::PPPThread()\n");
}
void PPPConnection::PPPThread::run()
{
DEBUG2("PPPThread::run, before runCommand\n");
theReturnValue = theRunner.runCommand(Runner::PPPD, theArgumentList);
DEBUG2("PPPThread::run, after runCommand\n");
// end of the thread - we're done
isRunning = false;
}
//############################################################################
static const TQString theStaticHSOVersion(TQObject::tr("HSO device - no pppd required"));
static const TQString theEtcResolvLocation("/etc/resolv.conf");
static const TQString theEtcResolvBackupLocation("/etc/resolv.conf." APPNAME);
HSOConnection::HSOConnection(const ConnectionBaseClass& aRef)
: ConnectionBaseClass(aRef)
{
DEBUG4("HSOConnection::HSOConnection(void)\n");
isConnectionActive();
}
HSOConnection::~HSOConnection(void)
{
DEBUG4("HSOConnection::~HSOConnection(void)\n");
stopConnection();
}
bool HSOConnection::dial(
__attribute__ ((unused)) const Profile& aProfile,
__attribute__ ((unused)) const TQString& myConnectStr) const
{
// this will actually initiate the connection
sendChatString("AT_OWANCALL=1,1,0");
// now we are going to poll - there will be a lot of output to parse...
// FIXME: unfortunately, the current poll code will not rerender the UI
// we need to move this piece of code into isConnectionActive()
while(1)
{
switch (runOWANCALL())
{
case OWAN_FAILED:
case OWAN_DISCONNECTED:
DEBUG3("not good - HSOConnect::dial()ing failed...\n");
return false;
case OWAN_CONNECTED:
DEBUG4("yay, HSOConnect::dial()ing worked\n");
return true;
case OWAN_INSETUP:
// let's wait for a second and try again...
break;
}
sleep(1);
}
}
const TQString&
HSOConnection::getPPPVersion(void)
{
return theStaticHSOVersion;
}
bool
HSOConnection::isConnectionActive(void)
{
// we only use AT commands here.
// but these only are available once the SerialPort has been set up...
if (Query::hasSerial()==false)
{
DEBUG4("HSOConnection::isConnectionActive - no serial yet\n");
setNewConnectionState(ConnectionObserverInterface::STOPPED);
return false;
}
ResultsOWANCALL myCallStatus = runOWANCALL();
DEBUG4("HSOConnection::isConnectionActive - myCallStatus: %d, thePPPDState: %d\n", myCallStatus, thePPPDState);
switch(myCallStatus)
{
case OWAN_FAILED:
case OWAN_DISCONNECTED:
if (thePPPDState==ConnectionObserverInterface::RUNNING ||
thePPPDState==ConnectionObserverInterface::NOT_OURS_RUNNING)
{
// we just disconnected :-(
stopNetworking();
}
return false;
case OWAN_CONNECTED:
return true;
case OWAN_INSETUP:
// still in progress ... nothing to do ...
return true;
}
// there's no way we can get here... but ok... gcc thinks we can :-(
return false;
}
HSOConnection::ResultsOWANCALL HSOConnection::runOWANCALL(void) const
{
Query myQuery("AT_OWANCALL?");
if (myQuery.runUntilDone() != Query::OK)
return OWAN_FAILED;
if (myQuery.hasAnswer()==true)
{
// answer will have 10 lines, but we're only interested in the first line
// it should look like this: "_OWANCALL: 1, 2, 0" where the '2' is:
// 0 = Disconnected,
// 1 = Connected,
// 2 = In setup,
// 3 = Call setup failed
TQString myResult = myQuery.getAnswer().first().section(" ",2,2);
if (myResult.isEmpty())
return OWAN_FAILED;
char myFirstChar = myResult.ascii()[0];
switch (myFirstChar)
{
case '0':
return OWAN_DISCONNECTED;
case '1':
return OWAN_CONNECTED;
case '2':
return OWAN_INSETUP;
case '3':
return OWAN_FAILED;
default:
DEBUG4("HSOConnection::runOWANCALL unexpected response was '%c'\n", myFirstChar);
break;
}
}
DEBUG3("HSOConnection::runOWANCALL failed\n");
return OWAN_FAILED;
}
bool
HSOConnection::startConnection()
{
// just for this startup, create a Profile - which should be the currently selected profile
Profile myProfile;
// TODO: add check for DeviceType here...
// we will be checking if a connection is already running.
// This shouldn't be the case - that's why there is an assert(false).
// however, if this happens in a release build, just return false.
DEBUG3("HSOConnection::startConnection entry\n");
// from now on until the exit of this member, prevent
// ConnectionInfo from interfering with the AT serial port
ConnectionInfoInhibitor myCI;
setNewConnectionState(ConnectionObserverInterface::STARTING);
if (isConnectionActive())
{
return true;
}
// let's do the CHATting :-)
if (!chat(myProfile))
{
DEBUG2("PPPConnection::startPPP - chatting failed ?!?\n");
return false;
}
return startNetworking(myProfile);
// yay, everything worked!!!
return true;
}
bool
HSOConnection::startNetworking(const Profile& aProfile)
{
DEBUG2("HSOConnection::startNetworking(void)\n");
// yet another sanity check
if (runOWANCALL()!=OWAN_CONNECTED)
{
assert(false);
return false;
}
// If that went well, we can issue AT_OWANDATA?.
// This will return the IP settings you can use to configure the hso0 interface
Query myDataQuery("AT_OWANDATA?");
if (myDataQuery.runUntilDone() != Query::OK)
return false;
// The settings which will be returned are :
// _OWANDATA: 1, <gateway>, <IP>, <DNS 1>, <DNS 2>, <NBNS1>, <NBNS2>, <speed>
if (myDataQuery.hasAnswer()==false)
return false;
TQStringList myDATAargs = TQStringList::split(", ", myDataQuery.getAnswer().first(), true);
TQString myIP = myDATAargs[1];
TQString myDNS1 = myDATAargs[3];
TQString myDNS2 = myDATAargs[4];
// let's assemble the string that needs to be executed...
// ifconfig is always necessary
TQString myRootRun =
"/sbin/ifconfig hso0 " + myIP + " netmask 255.255.255.255 up; ";
// only add default route if specified in the profile
if (aProfile.getIsDefaultRoute())
myRootRun +=
"/sbin/route add default dev hso0; ";
// if /etc/resolv.conf's first line contains umtsmon, just overwrite it
if (FileStuff::getFileFirstLine(theEtcResolvLocation).contains(APPNAME)==false)
{
DEBUG5("%s file is not written by us, so let's save it...\n", theEtcResolvLocation.ascii());
myRootRun +=
"mv " + theEtcResolvLocation + " " + theEtcResolvBackupLocation + "; ";
}
else
DEBUG5("%s file is already touched by us - let's overwrite it...\n", theEtcResolvLocation.ascii());
// and create the new resolv.conf
myRootRun +=
"echo \"# umtsmon temporary resolv.conf\" > " + theEtcResolvLocation + "; "
"echo \"nameserver " + myDNS1 + "\" >> " + theEtcResolvLocation + "; "
"echo \"nameserver " + myDNS2 + "\" >> " + theEtcResolvLocation;
printf("\n***********STRING*************\n%s\n***********STRING*************\n\n", myRootRun.ascii());
Runner myRunner;
myRunner.runCommand(Runner::SOMESU, myRootRun);
setNewConnectionState(ConnectionObserverInterface::RUNNING);
return true;
}
void
HSOConnection::stopConnection(void)
{
DEBUG2("HSOConnection::stopConnection(void)\n");
stopNetworking();
// this will kill the actual radio connection
sendChatString("AT_OWANCALL=1,0,0");
}
void
HSOConnection::stopNetworking(void)
{
DEBUG1("************HSOConnection::stopNetworking(void)\n");
// let's assemble the string that needs to be executed...
// network definitely must go down
TQString myRootRun;
// do we need to rewrite the /etc/resolv.conf file???
if (FileStuff::doesFileExist(theEtcResolvBackupLocation))
{
DEBUG5("There is a backup resolv.conf\n");
if (FileStuff::getFileFirstLine(theEtcResolvLocation).contains(APPNAME))
{
DEBUG5("And the current resolv.conf was written by umtsmon\n")
myRootRun +=
"mv " + theEtcResolvBackupLocation + " " + theEtcResolvLocation + "; ";
}
}
// this ifconfig down will automatically kill the route
myRootRun +=
"/sbin/ifconfig hso0 down; ";
printf("\n***********STRING*************\n%s\n***********STRING*************\n\n", myRootRun.ascii());
Runner myRunner;
myRunner.runCommand(Runner::SOMESU, myRootRun);
setNewConnectionState(ConnectionObserverInterface::STOPPED);
}

@ -0,0 +1,325 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006,2007,2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef PPPCONNECTION_H_
#define PPPCONNECTION_H_
#include "Runner.h"
#include "ObserverManager.h"
#include "ConnectionInfo.h"
#include <ntqstring.h>
#include <ntqstringlist.h>
#include <ntqthread.h>
// forward declarations
class Profile;
class DeviceCapabilities;
/** implement this interface and attach yourself to the appropriate
* Connection if you want to hear when the ConnectionState changes
*/
class ConnectionObserverInterface
{
public:
enum ConnectionState
{
STOPPED,
STARTING,
RUNNING,
NOT_OURS_RUNNING,
ERROR
};
/** implement this and attach to the Connection to get info
* about state changes of the Connection
*/
virtual void newConnectionState(ConnectionState aNewState) = 0;
/// required but not used: virtual destructor
virtual ~ConnectionObserverInterface() {};
};
/** abstract base class for Connections
* two derived classes exist: PPPConnection and HSOConnection
*/
class ConnectionBaseClass :
public ObserverManager<ConnectionObserverInterface>
{
public:
/// constructor
ConnectionBaseClass(const ConnectionBaseClass& aRef);
/// destructor
virtual ~ConnectionBaseClass(void);
/** starts the Connection
* @returns true if succesful
*/
virtual bool startConnection(void) = 0;
/// stops the Connection, does nothing if there is none
virtual void stopConnection(void) = 0;
/// @returns a string containing the pppd version, e.g. "2.4.4"
virtual const TQString& getPPPVersion(void) = 0;
bool isConnectionStarting();
virtual bool hasErrors() {return thePPPDStdErr.count()!=0;};
/// stringlist with all the stdout of the most recent PPP run
TQStringList thePPPDStdOut;
/// stringlist with all the stderr of the most recent PPP run
TQStringList thePPPDStdErr;
/** returns true if a Connection exists
* in the case of ppp, it is not very sharp - it will return true if ANY
* pppd is running, not just if *our* pppd is running
*/
virtual bool isConnectionActive(void) = 0;
protected:
/** implementation of the pure virtual member in ObserverManager;
* the implementation should perform the notification of the observer pointed to.
*/
virtual void notifyObserver(ConnectionObserverInterface* anObserver) const;
/** cache the serial port to do the PPP connection on
* Note that we will still use the AT port for the dialling AT commands
*/
TQString theSerialPortName;
protected:
void setNewConnectionState(ConnectionObserverInterface::ConnectionState aNewState);
/** runs the 'chat', i.e. a series of queries to prepare the modem
* for the connection
* it will use the currently setup serialport - if that
* happens to be a TempSerial, that's not a problem :-)
* @param aProfile the profile to take data from
* @returns true if successful
*/
bool chat(const Profile& aProfile) const;
/** creates and runs the ATD (dial string)
*
* @param aProfile
* @param myConnectStr
* @return
*/
virtual bool dial(const Profile& aProfile, const TQString& myConnectStr) const = 0;
/** sends an actual line of the chat and waits for the answers
* @param aChatString the data to send
* @returns true if reply was "OK".
*/
bool sendChatString(const TQString& aChatString) const;
private:
/** assign operator is private and not implemented
* to prevent duplication of this class instance (EffC++ item27)
* DO NOT IMPLEMENT THIS MEMBER
*/
ConnectionBaseClass& operator=(const ConnectionBaseClass& aRef);
};
// ##########################################################################
/** The DummyConnection class is a dummy, empty connection class
*/
class DummyConnection :
public ConnectionBaseClass
{
public:
/// constructor
DummyConnection(void);
/// destructor
virtual ~DummyConnection(void);
/// inherited & overriden from ConnectionBaseClass
virtual bool startConnection(void);
/// inherited & overriden from ConnectionBaseClass
virtual void stopConnection(void);
/** @returns a string containing the pppd version...
* for HSOConnection, it is "HSO device - no pppd required"
*/
virtual const TQString& getPPPVersion(void);
/// inherited & overriden from ConnectionBaseClass
virtual bool isConnectionActive(void);
private:
/// inherited & overriden from ConnectionBaseClass
virtual bool dial(const Profile& aProfile, const TQString& myConnectStr) const;
};
// ##########################################################################
/** The PPPConnection class initiates, monitors and manages the PPP daemon and
* the connection it makes.
*/
class PPPConnection :
public ConnectionBaseClass
{
public:
/// constructor
PPPConnection(const ConnectionBaseClass& aRef);
/// destructor
virtual ~PPPConnection(void);
/// inherited & overriden from ConnectionBaseClass
virtual bool startConnection(void);
/// inherited & overriden from ConnectionBaseClass
virtual void stopConnection(void);
/// @returns a string containing the pppd version, e.g. "2.4.4"
virtual const TQString& getPPPVersion(void)
{ return thePPPVersionNumber; };
ConnectionInfoInhibitor* theCIInhibitorPtr;
/// inherited & overriden from ConnectionBaseClass
virtual bool isConnectionActive(void);
private:
/// true if AT and PPP serial ports are the same device
bool hasOnlyOnePort;
/// a string containing the PPP version
TQString thePPPVersionNumber;
/** assembles a TQStringList with all arguments to be given to PPPD
* taking input from various sources, including the profile.
* @param aProfile the profile to take data from
* @returns a TQStringList with arguments
*/
TQStringList assembleArgumentList(const Profile& aProfile) const;
protected:
/// inherited & overriden from ConnectionBaseClass
virtual bool dial(const Profile& aProfile, const TQString& myConnectStr) const;
private:
/** this nested class creates the separate execution thread that
* will fork/exec into ppp - to make sure that the main thread
* keeps running
* FIXME: This might move into Runner later...
*/
class PPPThread : public TQThread
{
public:
PPPThread(const TQStringList& anArgumentList);
virtual ~PPPThread() {DEBUG2("~PPPThread()\n"); TQThread::wait(); };
/** I re-implemented this one because I suspect the QT one
* (called finished()) to be misbehaving
* @returns true if the thread has ended or hasn't started yet
*/
virtual bool isDone() { return !isRunning;};
/// reimplemented from TQThread to ensure that isDone is working
virtual void start() {isRunning=true; TQThread::start();};
const TQStringList& getStdOut() const {return theRunner.getStdOutStringList();};
const TQStringList& getStdErr() const {return theRunner.getStdErrStringList();};
protected:
TQStringList theArgumentList;
/// this member contains the actual thread code
virtual void run();
int theReturnValue;
bool isRunning;
Runner theRunner;
/// as long as thePPPThread exists, no info updates
ConnectionInfoInhibitor theCII;
}; // end-of-PPPThread declaration
PPPThread* thePPPThreadPtr;
};
// ##########################################################################
/** The HSOConnection class initiates, monitors and manages connections
* made by HSO devices
*/
class HSOConnection :
public ConnectionBaseClass
{
public:
/// constructor
HSOConnection(const ConnectionBaseClass& aRef);
/// destructor
virtual ~HSOConnection(void);
/// inherited & overriden from ConnectionBaseClass
virtual bool startConnection(void);
/// inherited & overriden from ConnectionBaseClass
virtual void stopConnection(void);
/** @returns a string containing the pppd version...
* for HSOConnection, it is "HSO device - no pppd required"
*/
virtual const TQString& getPPPVersion(void);
/// inherited & overriden from ConnectionBaseClass
virtual bool isConnectionActive(void);
protected:
/// inherited & overriden from ConnectionBaseClass
virtual bool dial(const Profile& aProfile, const TQString& myConnectStr) const;
private:
enum ResultsOWANCALL
{
OWAN_DISCONNECTED = 0,
OWAN_CONNECTED = 1,
OWAN_INSETUP = 2,
OWAN_FAILED = 3
};
/** runs a AT_OWANCALL? query
*
* @return the result of the query, which is of the enum ResultsOWANCALL type
*/
ResultsOWANCALL runOWANCALL(void) const;
/** runs all networking cruft - ifconfig, resolv.conf, route
*
* @return true if successful
*/
bool startNetworking(const Profile& aProfile);
/// stops all networking cruft - ifconfig, resolv.conf
void stopNetworking(void);
};
#endif /*PPPCONNECTION_H_*/

@ -0,0 +1,406 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006,2007,2008 Christofer Wesseling, Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "Profile.h"
#include <assert.h>
#include <ntqregexp.h>
// to prevent keys from varying between setter and getter
// the below static const strings are defined.
static const char* theProfilesStr = "/ConnectionProfiles";
static const char* theActiveProfileStr = "ActiveProfile";
static const char* theDefaultNameStr = "Default";
static const char* theDefaultRouteStr = "DefaultRoute";
static const char* theApnStr = "apn";
static const char* theUsernameStr = "username";
static const char* thePasswordStr = "password";
static const char* theNoIpDefaultStr = "noIpDefault";
static const char* theReplaceDefaultRouteStr = "replaceDefaultRoute";
static const char* theUsePeerDnsStr = "usePeerDns";
static const char* theNoCompressionStr = "noCompression";
static const char* theNoCCPStr = "noCCP";
static const char* theNoAuthStr = "noAuth";
static const char* theWarnOnDataThresholdStr = "doWarnOnThreshold";
static const char* theThresholdPercentageStr = "thresholdPercentage";
static const char* theRoamingDataLimitStr = "roamingDataLimit";
static const char* theHomeDataLimitStr = "homeDataLimit";
static const char* theRoamingTimeLimitStr = "roamingTimeLimit";
static const char* theHomeTimeLimitStr = "homeTimeLimit";
static const char* theCIDPrefixStr = "CIDprefix";
static const char* theCIDStr = "CID";
static const char* theWasConnectionSuccess = "WasConnectionSuccess";
static const char* theCallName = "call";
const TQString Profile::getKeyPathName(const TQString aKey) const
{
assert(Profile::checkForValidProfileName(aKey));
TQString myProfileName;
if (Profile::checkForValidProfileName(theProfileName))
myProfileName = theProfileName;
else
myProfileName = theDefaultNameStr;
return theProfilesStr + TQString("/") + myProfileName + "/prof/" + aKey;
}
Profile::Profile(TQString aProfileName)
{
DEBUG2("Profile::Profile('%s')\n", aProfileName.ascii());
// if no profile name specified, let's load one from the settings
// if no active profile mentioned in settings, start a profile
// with the default name (i.e. 'Default'). That profile probably
// only contains the default settings :-)
if (aProfileName.isEmpty())
{
aProfileName = getActiveProfileName();
}
assert(checkForValidProfileName(aProfileName));
theProfileName = aProfileName;
DEBUG2(" finally created profile for '%s'\n", theProfileName.ascii());
assert(!theProfileName.isEmpty());
}
////////////////////////////////////////////////////////////
// GETTERS: return the .... setting of the current profile
TQString
Profile::getAPN(void) const
{
return TheSettingsSingleton::getTQSRef().readEntry(getKeyPathName(theApnStr), "");
}
TQString
Profile::getUsername(void) const
{
return TheSettingsSingleton::getTQSRef().readEntry(getKeyPathName(theUsernameStr), "");
}
TQString
Profile::getPassword(void) const
{
return TheSettingsSingleton::getTQSRef().readEntry(getKeyPathName(thePasswordStr), "");
}
bool
Profile::getNoIpDefault(void) const
{
return TheSettingsSingleton::getTQSRef().readBoolEntry(getKeyPathName(theNoIpDefaultStr), false);
}
bool
Profile::getIsDefaultRoute(void) const
{
return TheSettingsSingleton::getTQSRef().readBoolEntry(getKeyPathName(theDefaultRouteStr), true);
}
bool
Profile::getReplaceDefaultRoute(void) const
{
return TheSettingsSingleton::getTQSRef().readBoolEntry(getKeyPathName(theReplaceDefaultRouteStr), false);
}
bool
Profile::getUsePeerDns(void) const
{
return TheSettingsSingleton::getTQSRef().readBoolEntry(getKeyPathName(theUsePeerDnsStr), true);
}
bool
Profile::getNoCompression(void) const
{
return TheSettingsSingleton::getTQSRef().readBoolEntry(getKeyPathName(theNoCompressionStr), true);
}
bool
Profile::getNoCCP(void) const
{
return TheSettingsSingleton::getTQSRef().readBoolEntry(getKeyPathName(theNoCCPStr), false);
}
bool
Profile::getNoAuth(void) const
{
return TheSettingsSingleton::getTQSRef().readBoolEntry(getKeyPathName(theNoAuthStr), false);
}
bool
Profile::getWarnOnDataThreshold(void) const
{
return TheSettingsSingleton::getTQSRef().readBoolEntry(getKeyPathName(theWarnOnDataThresholdStr), false);
}
unsigned int
Profile::getThresholdPercentage(void) const
{
return TheSettingsSingleton::getTQSRef().readNumEntry(getKeyPathName(theThresholdPercentageStr), false);
}
unsigned long
Profile::getHomeDataLimit(void) const
{
return TheSettingsSingleton::getTQSRef().readNumEntry(getKeyPathName(theHomeDataLimitStr), 0);
}
unsigned long
Profile::getRoamingDataLimit(void) const
{
return TheSettingsSingleton::getTQSRef().readNumEntry(getKeyPathName(theRoamingDataLimitStr), 0);
}
unsigned long
Profile::getHomeTimeLimit(void) const
{
return TheSettingsSingleton::getTQSRef().readNumEntry(getKeyPathName(theHomeTimeLimitStr), 0);
}
unsigned long
Profile::getRoamingTimeLimit(void) const
{
return TheSettingsSingleton::getTQSRef().readNumEntry(getKeyPathName(theRoamingTimeLimitStr), 0);
}
TQString
Profile::getCIDPrefix(void) const
{
return TheSettingsSingleton::getTQSRef().readEntry(getKeyPathName(theCIDPrefixStr), "");
}
unsigned int
Profile::getCID(void) const
{
return TheSettingsSingleton::getTQSRef().readNumEntry(getKeyPathName(theCIDStr), 1);
}
bool
Profile::getWasConnectionSuccess(void) const
{
return TheSettingsSingleton::getTQSRef().readBoolEntry(
getKeyPathName(theWasConnectionSuccess), false);
}
TQString
Profile::getCallName(void) const
{
return TheSettingsSingleton::getTQSRef().readEntry(getKeyPathName(theCallName), "");
}
////////////////////////////////////////////////////////////
// SETTERS: change the .... setting of the current profile
bool
Profile::setAPN(TQString anApn)
{
assert(!theProfileName.isEmpty());
return TheSettingsSingleton::getTQSRef().writeEntry(getKeyPathName(theApnStr), anApn );
}
bool
Profile::setUsername(TQString anUsername)
{
assert(!theProfileName.isEmpty());
return TheSettingsSingleton::getTQSRef().writeEntry(getKeyPathName(theUsernameStr), anUsername );
}
bool Profile::setPassword(TQString aPassword)
{
assert(!theProfileName.isEmpty());
return TheSettingsSingleton::getTQSRef().writeEntry(getKeyPathName(thePasswordStr), aPassword );
}
bool
Profile::setNoIpDefault(bool aNoIpDefault)
{
assert(!theProfileName.isEmpty());
return TheSettingsSingleton::getTQSRef().writeEntry(getKeyPathName(theNoIpDefaultStr), aNoIpDefault);
}
bool
Profile::setIsDefaultRoute(bool aDefaultRoute)
{
assert(!theProfileName.isEmpty());
return TheSettingsSingleton::getTQSRef().writeEntry(getKeyPathName(theDefaultRouteStr), aDefaultRoute );
}
bool
Profile::setReplaceDefaultRoute(bool aReplaceDefaultRoute)
{
assert(!theProfileName.isEmpty());
return TheSettingsSingleton::getTQSRef().writeEntry(getKeyPathName(theReplaceDefaultRouteStr), aReplaceDefaultRoute );
}
bool
Profile::setUsePeerDns(bool anUsePeerDns)
{
assert(!theProfileName.isEmpty());
return TheSettingsSingleton::getTQSRef().writeEntry(getKeyPathName(theUsePeerDnsStr), anUsePeerDns );
}
bool
Profile::setNoCompression(bool aNoCompression)
{
assert(!theProfileName.isEmpty());
return TheSettingsSingleton::getTQSRef().writeEntry(getKeyPathName(theNoCompressionStr), aNoCompression );
}
bool
Profile::setNoCCP(bool aNoCCP)
{
assert(!theProfileName.isEmpty());
return TheSettingsSingleton::getTQSRef().writeEntry(getKeyPathName(theNoCCPStr), aNoCCP );
}
bool
Profile::setNoAuth(bool aNoAuth)
{
assert(!theProfileName.isEmpty());
return TheSettingsSingleton::getTQSRef().writeEntry(getKeyPathName(theNoAuthStr), aNoAuth );
}
bool
Profile::setWarnOnDataThreshold(bool aWarning)
{
assert(!theProfileName.isEmpty());
return TheSettingsSingleton::getTQSRef().writeEntry(getKeyPathName(theWarnOnDataThresholdStr), aWarning );
}
bool
Profile::setThresholdPercentage(unsigned int aPercentage)
{
assert(!theProfileName.isEmpty());
return TheSettingsSingleton::getTQSRef().writeEntry(getKeyPathName(theThresholdPercentageStr), static_cast<int>(aPercentage) );
}
bool
Profile::setHomeDataLimit(unsigned long aLimit)
{
assert(!theProfileName.isEmpty());
return TheSettingsSingleton::getTQSRef().writeEntry(getKeyPathName(theHomeDataLimitStr), static_cast<int>(aLimit) );
}
bool
Profile::setRoamingDataLimit(unsigned long aLimit)
{
assert(!theProfileName.isEmpty());
return TheSettingsSingleton::getTQSRef().writeEntry(getKeyPathName(theRoamingDataLimitStr), static_cast<int>(aLimit) );
}
bool
Profile::setHomeTimeLimit(unsigned long aLimit)
{
assert(!theProfileName.isEmpty());
return TheSettingsSingleton::getTQSRef().writeEntry(getKeyPathName(theHomeTimeLimitStr), static_cast<int>(aLimit) );
}
bool
Profile::setRoamingTimeLimit(unsigned long aLimit)
{
assert(!theProfileName.isEmpty());
return TheSettingsSingleton::getTQSRef().writeEntry(getKeyPathName(theRoamingTimeLimitStr), static_cast<int>(aLimit) );
}
bool
Profile::setWasConnectionSuccess(bool aWasConnectionSuccess)
{
assert(!theProfileName.isEmpty());
return TheSettingsSingleton::getTQSRef().writeEntry(getKeyPathName(
theWasConnectionSuccess), aWasConnectionSuccess );
}
////////////////////////////////////////////////////////////
// save the profile to the HDD - New APN Name = New Profile
void
Profile::save(void) const
{
TheSettingsSingleton::makeChangesPersistent();
}
////////////////////////////////////////////////////////////
bool
Profile::remove(void) const
{
DEBUG1("Request to remove profile '%s'\n", theProfileName.ascii());
assert(!theProfileName.isEmpty());
// if this was the active profile, we need to set another one current
if (Profile::getActiveProfileName() == theProfileName)
Profile::setActiveProfile(Profile::getProfileList().first());
return TheSettingsSingleton::removeSubTree(theProfilesStr+TQString("/")+ theProfileName);
}
////////////////////////////////////////////////////////////
bool
Profile::setActiveProfile(const TQString& aProfileName)
{
if (Profile::getProfileList().contains(aProfileName) > 0)
return TheSettingsSingleton::getTQSRef().writeEntry(theProfilesStr+TQString("/")+theActiveProfileStr, aProfileName);
return false;
}
TQStringList
Profile::getProfileList(void)
{
return TheSettingsSingleton::getTQSRef().subkeyList(theProfilesStr);
}
TQString
Profile::getActiveProfileName(void)
{
TQString myName = TheSettingsSingleton::getTQSRef().readEntry(
theProfilesStr+TQString("/")+theActiveProfileStr, "");
if (myName == "")
{
// nothing found?
// do we actually have one or more entries in the list?
if (getProfileList().count() > 0)
{
myName = getProfileList().first();
DEBUG1("No active profile found, selecting the first profile: '%s'\n", myName.ascii());
setActiveProfile(myName);
}
}
if (checkForValidProfileName(myName))
return myName;
else
return theDefaultNameStr;
}
bool
Profile::checkForValidProfileName(const TQString& aName)
{
// empty is not allowed
if (aName.isEmpty())
return false;
// no whitespace?
TQRegExp myRegExp("^\\w+$");
if (myRegExp.search(aName) < 0)
return false;
// dashes are not allowed
if (aName.contains("-"))
return false;
return true;
}

@ -0,0 +1,200 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2006,2007,2008 Christofer Wesseling, Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef PROFILE_H_
#define PROFILE_H_
#include "TheSettingsSingleton.h"
#include <ntqstring.h>
#include <ntqstringlist.h>
/** The Profile class manages a user profile
* * any Profile has a name
* * only one Profile at a time can be the "default profile"
* Note that the Profile class doesn't store settings itself, it immediately
* sends them through to TheSettingsSingleton.
*/
class Profile
{
public:
/** constructor
* @param aProfileName the profile to load settings for. If left empty, load the current active profile
*/
Profile(TQString aProfileName = "");
/// destructor
virtual ~Profile(void) {};
////////////////////////////////////////////////
// a list of getters & setters
TQString getAPN(void) const;
bool setAPN(TQString anAPN);
TQString getUsername(void) const;
bool setUsername(TQString anUsername);
TQString getPassword(void) const;
bool setPassword(TQString aPassword);
bool getNoIpDefault(void) const;
bool setNoIpDefault(bool aNoIpDefault);
// true: System uses the connection of this profile as default route
bool getIsDefaultRoute(void) const;
bool setIsDefaultRoute(bool aDefaultroute);
// true: if there is an existins default route, replace it!
bool getReplaceDefaultRoute(void) const;
bool setReplaceDefaultRoute(bool aReplaceDefaultRoute);
// true: use peer dns...
// if true, PPP will ask for ###
bool getUsePeerDns(void) const;
bool setUsePeerDns(bool anUserPeerDns);
// true: doesn't apply VJ compression to the packets of the ppp-connection
bool getNoCompression(void) const;
bool setNoCompression(bool aNoCompression);
/** config for "no CCP" (Control Compression Protocol)
* note that this should only be enabled if the peer (i.e. the operator)
* has buggy systems
*/
bool getNoCCP(void) const;
bool setNoCCP(bool aNoCCP);
/// true: enable the 'noauth' option
bool getNoAuth(void) const;
bool setNoAuth(bool aNoAuth);
/// true: warn if a monthly data limit threshold is reached
bool getWarnOnDataThreshold(void) const;
bool setWarnOnDataThreshold(bool aWarning);
/// the percentage above which to warn if traffic exceeds
unsigned int getThresholdPercentage(void) const;
bool setThresholdPercentage(unsigned int aPercentage);
/** the data limit in MiB (i.e. 2^20 bytes) for home networks
* use 0 for "unlimited"
*/
unsigned long getHomeDataLimit(void) const;
bool setHomeDataLimit(unsigned long aLimit);
/** the data limit in MiB (i.e. 2^20 bytes) for roaming
* use 0 for "unlimited"
*/
unsigned long getRoamingDataLimit(void) const;
bool setRoamingDataLimit(unsigned long aLimit);
/** the time limit in seconds for home networks
* use 0 for "unlimited"
*/
unsigned long getHomeTimeLimit(void) const;
bool setHomeTimeLimit(unsigned long aLimit);
/** the time limit in seconds for roaming
* use 0 for "unlimited"
*/
unsigned long getRoamingTimeLimit(void) const;
bool setRoamingTimeLimit(unsigned long aLimit);
/** returns the CID number - if modified
* this option is not in the Profile GUI
*
* (see man/advanced_umtsmon_tricks.txt)
*
* @returns CID number, default 1
*/
unsigned int getCID(void) const;
// bool setCID(unsigned int aCID);
/** if you want to use a custom CID Prefix, set it here
* not setting it, will imply a default CID prefix of *99***
*
* (see man/advanced_umtsmon_tricks.txt)
*
* @return CID Prefix - or empty string if none set (which means use default)
*/
TQString getCIDPrefix(void) const;
//bool setCIDPrefix(const TQString& aCIDPrefix);
// true: this profile has seen successful connections
bool getWasConnectionSuccess(void) const;
bool setWasConnectionSuccess(bool aWasConnectionSuccess);
/** in order to allow priviledged options to PPP or just
* other options that we don't provide in the UI, use "call namme"
* and create the /etc/ppp/peers/name file with the right parameters
*
* (see man/advanced_umtsmon_tricks.txt)
*
* @return the name to call - if any. The string will be empty if there is none
*/
TQString getCallName(void) const;
//bool setCallName(const TQString& aCallName);
/* ***************************************************************** */
/** forces saving of this Profile (and probably all other settings as well)
* note that saving the profile doesn't make it active - you need to do that separately
*/
void save(void) const;
/** removes the profile from the settings and resets the Active profile if needed
* FIXME: make this one static like the below members
* (note that this Profile *instance* remains)
*/
bool remove(void) const;
/** get the name of the profile currently marked as active,
* @returns an empty string if none
*/
static TQString getActiveProfileName(void);
/** set a certain profile to be the active one
* @param aProfileName the profile to make active. if name doesn't exists, return false
* @returns true if profile name was set to active
*/
static bool setActiveProfile(const TQString& aProfileName);
/// Returns a list of all known Profiles
static TQStringList getProfileList(void);
/// returns true if a name is valid - or false if not
static bool checkForValidProfileName(const TQString& aName);
/// returns the current profile name of this Profile instance
const TQString& getProfileName(void) const
{ return theProfileName; };
private:
TQString theProfileName;
/// returns the full path for keys of the current Profile
const TQString getKeyPathName(const TQString aKey) const;
};
#endif /*PROFILE_H_*/

@ -0,0 +1,317 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2006,2007,2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "Query.h"
#include "SerialPort.h"
#include "umtsmon_global.h"
#include <assert.h>
// make sure that upon initialisation, theSerialPortPtr is NULL
static SerialPort* theSerialPortPtr = NULL;
static TQMutex theQueryMutex;
SerialPort* Query::setSerial(SerialPort* aSerialPortPtr)
{
DEBUG5("%p = Query::setSerial(%p)\n", theSerialPortPtr, aSerialPortPtr);
SerialPort* myTempPtr = theSerialPortPtr;
theSerialPortPtr = aSerialPortPtr;
return myTempPtr;
}
bool Query::hasSerial(void)
{
return theSerialPortPtr != NULL;
}
TQString escapeString(const TQString& anIString)
{
TQString myOString;
for (unsigned int i=0; i< anIString.length();i++)
{
TQChar myChar = anIString[i];
if (isprint(myChar))
myOString += myChar;
else
myOString += "\\x" + TQString::number(myChar.upper().latin1(), 16);
}
return myOString;
}
Query::~Query()
{
if (hasLock)
{
DEBUG5("Query instance %p abandoned MUTEX\n", this);
theQueryMutex.unlock();
hasLock=false;
}
}
Query::ReturnCode Query::receiveMore()
{
// as we know the Query has already run, let's clean out the string list first
theQueryString="";
isFirstRun = false;
theAnswer.clear();
return realRun();
}
Query::ReturnCode Query::runUntilDone()
{
ReturnCode myResult = run();
theQueryString="";
isFirstRun = false;
int i=0;
while (myResult == Query::UNKNOWN_ERROR)
{
DEBUG5("Query::runUntilDone needs more time...\n");
// sleep for 100 ms
struct timespec sleep_time;
sleep_time.tv_sec=0;
sleep_time.tv_nsec=100*1000*1000;
nanosleep(&sleep_time,NULL);
// and retry
myResult = realRun();
// and check for larger timeouts
if (i++ > 100)
{
DEBUG1("Query::runUntilDone needed more than 10 seconds. Bailing out.\n");
break;
}
}
return myResult;
}
Query::ReturnCode Query::run()
{
// safety net
assert(theSerialPortPtr != NULL);
if (theSerialPortPtr == NULL)
{
return NO_DEVICE;
}
// more safety net: lock the mutex
assert(hasLock == false);
if (theQueryMutex.tryLock()==FALSE)
{
hasLock = false;
DEBUG5("Query instance %p trylock FAILED\n", this);
return NO_LOCK;
}
hasLock=true;
DEBUG5("Query instance %p acquired MUTEX\n", this);
// ***** first make sure there's no residual info on the line
TQString myExcess = receiveStringOnce();
if (!myExcess.isEmpty())
{
DEBUG2("QUERY: excess bytes received: '%s'\n", escapeString(myExcess).ascii());
}
return realRun();
}
Query::ReturnCode Query::realRun()
{
// ***** send our message
if (isFirstRun == true)
{
DEBUG4("Query sends the following mesage: '%s'\n", theQueryString.ascii());
if (theSerialPortPtr->writeDev("\r"+theQueryString+"\r")
== false)
{
return NO_DEVICE;
}
}
// ***** receive the response and split it up
int i=0;
theAnswer = TQStringList::split("\r\n", receiveStringRetry());
for ( TQStringList::Iterator myIt = theAnswer.begin();
myIt != theAnswer.end(); ++myIt )
{
i=i+1;
if ((*myIt).stripWhiteSpace().isEmpty())
{
DEBUG4("answer %d removed - empty\n", i);
TQStringList::Iterator myDeleted = (myIt--);
theAnswer.erase(myDeleted);
continue;
}
DEBUG4("answer %d:'%s'\n", i, (*myIt).stripWhiteSpace().ascii());
}
// ***** interpret the response
if (isFirstRun == true)
{
// remove echos from answers
checkQuery();
}
// check to see if any OK/ERROR in output
return interpretResult();
}
// read out the data from the serial port
TQString Query::receiveStringRetry(void) const
{
assert(theSerialPortPtr != NULL);
TQString myCompleteAnswer("");
// some devices take a while before they answer,
// or the answer "takes a while". That's why we retry and
// wait for three subsequent "no more" before we think we have
// the complete message
int myRetries = 3;
while (myRetries > 0)
{
TQString myPartAnswer = receiveStringOnce();
if (myPartAnswer.isEmpty()==false)
{
// we received a valid character - reset the counter...
myRetries=3;
myCompleteAnswer += myPartAnswer;
}
else
myRetries--;
DEBUG6("Query::receiveStringRetry %d\n", myRetries);
}
DEBUG5("receiveStringRetry: '%s'\n", escapeString(myCompleteAnswer).ascii());
return myCompleteAnswer;
}
// read out the data from the serial port
TQString Query::receiveStringOnce(void) const
{
int ch;
TQString myCompleteAnswer("");
while( (ch=theSerialPortPtr->getOneByte()) >0)
{
myCompleteAnswer += ch;
}
DEBUG6("Query::receiveStringOnce %s\n", escapeString(myCompleteAnswer).ascii());
return myCompleteAnswer;
}
// attempt to interpret the last line (OK/ERROR/etc)
Query::ReturnCode Query::interpretResult(void)
{
ReturnCode myReturnCode = UNKNOWN_ERROR;
TQStringList::Iterator myIterator = theAnswer.begin();
for (myIterator = theAnswer.begin();myIterator != theAnswer.end(); ++myIterator)
{
TQString myAnswer = *myIterator;
// let's do the plain, simple answers first
if (myAnswer == "OK")
myReturnCode = OK;
if (myAnswer == "ERROR")
myReturnCode = ERROR;
if (myAnswer == "NO CARRIER")
myReturnCode = NO_CARRIER;
// filter Huawei-specifics
// FIXME: This needs work
if (myAnswer.left(1) == "^")
{
DEBUG5("found Huawei state info: '%s'\n", myAnswer.ascii());
myIterator = theAnswer.erase(myIterator);
--myIterator;
}
}
if (myReturnCode != UNKNOWN_ERROR)
{
DEBUG5("because known statement #%d was detected, removing obvious answer '%s'\n",
myReturnCode, theAnswer.last().ascii());
theAnswer.pop_back();
}
// if the answer however contained a specific error
// message like +CME ERROR: SIM PIN, let's return
// error as well - but don't pop the error
if (theAnswer.last().contains("ERROR",true))
{
DEBUG5("found error in message!\n");
myReturnCode = ERROR;
}
return myReturnCode;
}
// check if first line equals the Query, and remove it if so.
bool Query::checkQuery(void)
{
if ( theQueryString == (*(theAnswer.begin())).stripWhiteSpace() )
{
DEBUG5("checkQuery: removing echo up front\n");
theAnswer.pop_front();
return true;
}
// apparently this extra check is needed for Samsung Innov8 or i8510 mobile phone
// see bug # 2558652
if ( (theQueryString+"\xd"+theQueryString) == (*(theAnswer.begin())).stripWhiteSpace() )
{
DEBUG5("checkQuery: removing double echo up front\n");
theAnswer.pop_front();
return true;
}
return false;
}
bool Query::sendMore(const TQString& aString)
{
// safety net
assert(theSerialPortPtr != NULL);
if (theSerialPortPtr == NULL)
{
return false;
}
// ***** send our message
return theSerialPortPtr->writeDev(aString+"\r");
}
TQStringList& Query::getAnswer()
{
// if this assert kicks in, it probably means you ran getAnswer() before run()
// OR
// the Query hasn't completed yet - you might need to run receiveMore()
// a few times until the answer gets in...
DEBUG5("Query::getAnswer returns %zd answer(s)\n", theAnswer.count() );
assert (!theAnswer.isEmpty());
return theAnswer;
}

@ -0,0 +1,150 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006,2007,2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef QUERY_CLASS
#define QUERY_CLASS
#include <ntqstring.h>
#include <ntqstringlist.h>
#include <ntqmutex.h>
// forward declaration
class SerialPort;
/** Holds the modem query plus its result.
* It also parses parts of the results for common error conditions.
*/
class Query
{
public:
/** constructor for Query.
* @param aString - query, will be appended with terminator character
*/
Query(const TQString& aQueryString)
: theQueryString(aQueryString), hasLock(false), isFirstRun(true)
{};
virtual ~Query();
/// contains the return code from the modem on the query
enum ReturnCode
{
OK,
ERROR,
NO_CARRIER,
NO_DEVICE,
NO_LOCK,
UNKNOWN_ERROR
};
/** call this member to actually run the query
* @return NO_LOCK if failed to obtain the lock
* - in that case, the Query hasn't run yet, retry is possible.
*/
ReturnCode run();
/// returns the answer from the modem - split by line
TQStringList& getAnswer();
/// returns true if there is an answer
bool hasAnswer()
{ return !theAnswer.empty();};
/** send even more data.
* @param aString - string to send, will be appended with terminator character
* @return true if successful, false if not
*/
bool sendMore(const TQString& aString);
/** receive even more data
* this function will clear theAnswer first and also clear theQueryString first
*/
ReturnCode receiveMore(void);
/** sets the serial port to use
* (static member - valid for all Queries!)
* Should only be called by the SerialPort class
* @param aSerialPortPtr the new serial port pointer
* @returns the old serial port pointer - if there was one
*/
static SerialPort* setSerial(SerialPort* aSerialPortPtr);
/// returns true if a SerialPort has been set
static bool hasSerial(void);
/** call this member to actually run the query and keep waiting
* until "OK" "ERROR" or similar is received.
* DO NOT USE THIS FUNCTION IF YOU EXPECT THE ANSWER TO TAKE MORE THAN HALF A SECOND
* in that case: write a loop and use receiveMore()
* @return NO_LOCK if failed to obtain the lock
* - in that case, the Query hasn't run yet, retry is possible.
*/
ReturnCode runUntilDone();
private:
/** read a string from the device
* will retry 3 times
* @returns TQString with the info read - it can be multiple lines
*/
TQString receiveStringRetry(void) const;
/** read a string from the device
* will attempt only once
* @returns TQString with the info read - it can be multiple lines
*/
TQString receiveStringOnce(void) const;
/// interpret the last line from the response (OK/ERROR/etc)
ReturnCode interpretResult(void);
/** check if first line equals "QUERY+\r",
* and remove it if so.
*/
bool checkQuery(void);
/** internal call actually running the query
* @return NO_LOCK if failed to obtain the lock
* - in that case, the Query hasn't run yet, retry is possible.
*/
ReturnCode realRun(void);
private:
TQString theQueryString;
TQStringList theAnswer;
/** This Mutex is needed to prevent two queries from running in parallel.
* this can happen if e.g. you are searching for a network to connect to
* and in the mean time iconify the program.
*
* The basic assumption in this code is that the Mutex is locked on first
* action (i.e. run()) and unlocked on destroy.
*/
TQMutex theSerialPortMutex;
/** Unfortunately, it is possible that run() cannot lock the mutex.
* in that case, run will return NO_LOCK, but we need to know not to unlock
* the mutex in the destructor.
*/
bool hasLock;
bool isFirstRun;
};
#endif // defined QUERY_CLASS

@ -0,0 +1,2 @@
aboutdialog.ui
.cvsignore

@ -0,0 +1,274 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2007,2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "LCDDisplay.h"
#include <ntqpainter.h>
// unfortunately, there's quite a lot of initialising here :-(
// we cache a lot to speed up drawing
LCDDisplay::LCDDisplay( TQWidget* aParent, const char* aName, WFlags aFlags)
: TQLabel(aParent, aName, aFlags), theSignalWidth(0), isRoaming(false),
theRadioType(tr("n/a")), theProfile(""),
the14Font("Helvetica", 14), the10Font("Helvetica", 10), the8Font("Helvetica", 8),
theBlack(20,20,20), theShadow(0x98, 0x9c, 0x62)
{
// This creates a extra pixmap on the TQWidget
//TQLabel::setPixmap(TQPixmap::fromMimeSource("LCDBackground.png"));
// This set the pixmap to the background of the image, unfortunatly it produce black border/corner
//setPaletteBackgroundColor(parentWidget()->paletteBackgroundColor())
//setPaletteBackgroundPixmap(TQPixmap::fromMimeSource("LCDBackground.png"));
// This read the background color of the parent widget, fill a TQPixmap with it
// overlay the LCD background PNG and put it into the widget background
TQPixmap bg = TQPixmap (336, 88);
TQPixmap pix = TQPixmap::fromMimeSource("LCDBackground.png");
bg.fill (parentWidget()->paletteBackgroundColor());
TQPainter p( &bg );
p.drawPixmap( pix.rect(), pix );
setPaletteBackgroundPixmap(bg);
theGaugePixmap = TQPixmap::fromMimeSource("LCDSignal.png");
the14Font.setPixelSize(15);
the10Font.setPixelSize(11);
// and... let's draw the thing!
this->update();
}
void LCDDisplay::setDownload(
unsigned long aDownload,
unsigned long aDownloadSpeed,
bool needsUpdate)
{
if (aDownload!=0)
setStringAndUpdate(theDownload, number2HumanString(aDownload), false);
else
setStringAndUpdate(theDownload, "", needsUpdate);
if (aDownloadSpeed!=0)
setStringAndUpdate( theDownloadSpeed,
number2HumanString(aDownloadSpeed)+"/s",
needsUpdate);
else
setStringAndUpdate(theDownloadSpeed, "", needsUpdate);
}
void LCDDisplay::setStrength(unsigned int aNewStrength, bool needsUpdate)
{
const unsigned int SIGNAL_SATURATION=24;
if (aNewStrength == 99)
theSignalWidth = -1;
else
{
if (aNewStrength > SIGNAL_SATURATION)
aNewStrength = SIGNAL_SATURATION;
theSignalWidth = (theGaugePixmap.width() * aNewStrength) / SIGNAL_SATURATION;
}
if (needsUpdate)
this->update();
}
void LCDDisplay::setUpload(
unsigned long anUpload,
unsigned long anUploadSpeed,
bool needsUpdate)
{
if (anUpload!=0)
setStringAndUpdate(theUpload, number2HumanString(anUpload), false);
else
setStringAndUpdate(theUpload, "", needsUpdate);
if (anUploadSpeed!=0)
setStringAndUpdate( theUploadSpeed,
number2HumanString(anUploadSpeed)+"/s",
needsUpdate);
else
setStringAndUpdate(theUploadSpeed, "", needsUpdate);
}
void LCDDisplay::drawContents ( TQPainter * p )
{
// draws the background --> if you have the background in an extra TQPixmap
//TQLabel::drawContents(p);
// let's make sure the string fits in the screen,
// compensate font size for the string length
if (theOperatorName.length() > 12)
p->setFont(the10Font);
else
p->setFont(the14Font);
int myOperatorNameX = 170;
if (isRoaming)
{
myOperatorNameX += 10;
TQPointArray myPoints(4);
p->setPen(theShadow);
myPoints.putPoints(0, 4, 171,27, 174,17, 178,27, 171,27);
p->drawPolygon(myPoints);
p->setPen(theBlack);
myPoints.putPoints(0, 4, 170,26, 173,16, 177,26, 170,26);
p->drawPolygon(myPoints);
}
p->setPen(theShadow);
p->drawText(myOperatorNameX+1,28, theOperatorName);
p->setPen(theBlack);
p->drawText(myOperatorNameX,27, theOperatorName);
// draw the labels - allow for i18n
p->setPen(theShadow);
p->setFont(the8Font);
// and draw the 10-size shadows & blacks of the other data
p->drawText( 48,57, theUpload);
p->drawText(104,57, theUploadSpeed);
p->drawText( 48,75, theDownload);
p->drawText(104,75, theDownloadSpeed);
p->drawText(246,52, theRadioType);
p->drawText(197,76, theTotal);
p->drawText(285,76, theConnectedTime);
if (!theProfile.isEmpty())
p->drawText(172,52, theProfile);
p->setPen(theBlack);
p->drawText( 47,56, theUpload);
p->drawText(103,56, theUploadSpeed);
p->drawText( 47,74, theDownload);
p->drawText(103,74, theDownloadSpeed);
p->drawText(245,51, theRadioType);
p->drawText(284,75, theConnectedTime);
if (!theProfile.isEmpty())
p->drawText(171,51, theProfile);
if (theSignalWidth == -1)
{
p->drawText(52,24, tr("n/a"));
}
else
p->drawPixmap( 42,17, theGaugePixmap, 0,0, theSignalWidth, theGaugePixmap.height() );
// draw the total in either green, orange or red, depending on the status
switch (theTotalStatus)
{
case MonthlyTraffic::OVER_LIMIT:
p->setPen(TQColor(200,20,20)); // red
break;
case MonthlyTraffic::BETWEEN:
p->setPen(TQColor(150,100,20)); // orange
break;
case MonthlyTraffic::BELOW:
p->setPen(TQColor(0,170,0)); // green
break;
case MonthlyTraffic::LIMITS_DISABLED:
p->setPen(theBlack); // green
break;
};
p->drawText(196,76, theTotal);
}
TQString
LCDDisplay::number2HumanString(unsigned long aNumber) const
{
TQString theUnit = "B";
double myNumber = aNumber;
if (myNumber < 1024.)
{
return TQString::number(aNumber) + " " + theUnit;
}
// reduce the order of the number
while ((myNumber/999.9) >= 1.)
{
myNumber /= 1024;
switch(theUnit[0].latin1())
{
case 'B':
theUnit = "KiB";
break;
case 'K':
theUnit = "MiB";
break;
case 'M':
theUnit = "GiB";
break;
case 'G':
theUnit = "TiB";
break;
}
}
// let's differentiate between '3.14', '31.4' and '314.'
if (myNumber >= 100.)
{
return TQString::number(myNumber, 'f', 0) + " " + theUnit;
}
if (myNumber >= 10.)
{
return TQString::number(myNumber, 'f', 1) + " " + theUnit;
}
return TQString::number(myNumber, 'f', 2) + " " + theUnit;
}
TQString
LCDDisplay::number2TimeString(unsigned long aNumber) const
{
const int SECONDS_IN_HOUR = 3600;
const int SECONDS_IN_DAY = 24*SECONDS_IN_HOUR;
unsigned long theDays = aNumber / (SECONDS_IN_DAY);
aNumber %= SECONDS_IN_DAY;
unsigned long theHours = aNumber / SECONDS_IN_HOUR;
aNumber %= SECONDS_IN_HOUR;
unsigned long theMinutes = aNumber / 60;
unsigned long theSeconds = aNumber % 60;
if (theDays > 0)
{
return TQString(tr("%1d %2h")) // e.g. 12d 12h => 12 days 13 hours
.arg(TQString::number(theDays))
.arg(TQString::number(theHours));
}
if (theHours > 0)
{
return TQString(tr("%1h %2m")) // e.g. 12h 35m => 12 hours 35 minutes
.arg(TQString::number(theHours))
.arg(TQString::number(theMinutes));
}
return TQString(tr("%1m %2s")) // e.g. 13m 3s => 13 minutes 3 seconds
.arg(TQString::number(theMinutes))
.arg(TQString::number(theSeconds));
}

@ -0,0 +1,17 @@
<!DOCTYPE CW><CW>
<customwidgets>
<customwidget>
<class>LCDDisplay</class>
<header location="local">src/view/LCDDisplay.h</header>
<sizehint>
<width>336</width>
<height>88</height>
</sizehint>
<container>0</container>
<sizepolicy>
<hordata>1</hordata>
<verdata>1</verdata>
</sizepolicy>
</customwidget>
</customwidgets>
</CW>

@ -0,0 +1,162 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2007,2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef LCDDISPLAY_H_
#define LCDDISPLAY_H_
#include "MonthlyTraffic.h"
#include <ntqwidget.h>
#include <ntqlabel.h>
#include <ntqpixmap.h>
#include <ntqfont.h>
#include <ntqcolor.h>
#include <ntqobject.h>
/// This GUI class graphically displays various information for the user
class LCDDisplay : public TQLabel
{
TQ_OBJECT
public:
LCDDisplay( TQWidget * aParent, const char * aName = 0, WFlags aFlags = 0 );
/// sets the operatorname and updates the GUI
void setOperatorName(const TQString& aName, bool needsUpdate=true)
{setStringAndUpdate(theOperatorName, aName, needsUpdate);};
/// sets the radio type string (HSDPA, UMTS, GPRS, etc) and updates the GUI
void setRadioType(const TQString& aName, bool needsUpdate=true)
{setStringAndUpdate(theRadioType, aName, needsUpdate);};
/// sets the profile name and updates the GUI
void setProfile(const TQString& aName, bool needsUpdate=true)
{setStringAndUpdate(theProfile, aName, needsUpdate);};
/** sets the upload strings and updates the GUI
* @param anUpload upload in bytes
* @param anUploadSpeed upload speed in bytes/s
*/
void setUpload(unsigned long anUpload,
unsigned long anUploadSpeed,
bool needsUpdate=true);
/** sets the upload strings and updates the GUI
* @param anUpload upload in bytes
* @param anUploadSpeed upload speed in bytes/s
*/
void setDownload(unsigned long aDownload,
unsigned long aDownloadSpeed,
bool needsUpdate=true);
/// sets the monthly total data traffic and update the GUI
void setTotalTraffic(unsigned long aNumber, MonthlyTraffic::ThresholdStatus aStatus, bool needsUpdate=true)
{
theTotalStatus = aStatus;
setStringAndUpdate(theTotal, number2HumanString(aNumber), needsUpdate);
};
/// sets the monthly time traffic and update the GUI
void setTotalTime(unsigned long aNumber, MonthlyTraffic::ThresholdStatus aStatus, bool needsUpdate=true)
{
theTotalStatus = aStatus;
setStringAndUpdate(theTotal, number2TimeString(aNumber), needsUpdate);
};
/// sets the connected time and update the GUI
void setConnectedTime(unsigned long aNumber, bool needsUpdate=true)
{setStringAndUpdate(theConnectedTime, number2TimeString(aNumber), needsUpdate);};
/** sets the signal strength of the radio (result of AT+CSQ)
* @param aNewStrength values of 0-31 and 99 are allowed
*/
void setStrength(unsigned int aNewStrength, bool needsUpdate=true);
/** sets the boolean for roaming or not
* this will have two implications:
* 1) if roaming: draw triangle in front of operator name
* 2) either home or global icon visible on the right side
* this is not the most critical part of the UI, therefore no immediate update
* @param anIsRoaming true if roaming
*/
void setRoaming(bool anIsRoaming)
{isRoaming = anIsRoaming;};
protected:
virtual void drawContents ( TQPainter * p );
private:
/** internal function that will set a string to a name and make the widget
* update its looks if needed
* @param aString OUTPUT the qstring to put stuff in to
* @param aName INPUT the qstring with the name to set
* @param needsUpdate true if you want to redraw the widget, false if not (yet)
*/
void setStringAndUpdate(TQString& aString, const TQString& aName, bool needsUpdate)
{ aString = aName.left(17); if (needsUpdate) {this->update();}; };
/** converts an ulong into a human readable number string.
* i.e. 31 will become 31 B
* 3141 will become 3.07 KiB
* 314156 will become 307 KiB
* 31415654 will become 30.0 MiB
* @param aNumber the number to convert
* @returns the converted and human readable string
*/
TQString number2HumanString(unsigned long aNumber) const;
/** converts an ulong into a human readable number string.
* i.e. 31 will become 0m 31s
* 3141 will become 52m 21s
* 314156 will become 87h 15m
* @param aNumber the number to convert
* @returns the converted and human readable string
*/
TQString number2TimeString(unsigned long aNumber) const;
TQPixmap theGaugePixmap;
/** this is the width of theGaugePixmap to draw (max 104, min 0 in 20 steps)
* -1 means "draw n/a"
*/
int theSignalWidth;
/// true if roaming
bool isRoaming;
TQString theOperatorName;
TQString theRadioType;
TQString theProfile;
TQString theConnectedTime;
TQString theUpload;
TQString theUploadSpeed;
TQString theDownload;
TQString theDownloadSpeed;
TQString theTotal;
MonthlyTraffic::ThresholdStatus theTotalStatus;
// three font sizes to cache
TQFont the14Font;
TQFont the10Font;
TQFont the8Font;
// two colors to cache
TQColor theBlack;
TQColor theShadow;
};
#endif // LCDDISPLAY_H_

@ -0,0 +1,238 @@
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
<class>PPPErrorLogsDialog</class>
<widget class="TQDialog">
<property name="name">
<cstring>PPPErrorLogsDialog</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>466</width>
<height>276</height>
</rect>
</property>
<property name="caption">
<string>PPP Error Logs</string>
</property>
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<property name="modal">
<bool>true</bool>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<property name="margin">
<number>11</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<widget class="TQTabWidget">
<property name="name">
<cstring>qtab684</cstring>
</property>
<widget class="TQWidget">
<property name="name">
<cstring>Widget8</cstring>
</property>
<attribute name="title">
<string>Problem</string>
</attribute>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLayoutWidget">
<property name="name">
<cstring>layout6</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<spacer>
<property name="name">
<cstring>spacer3_2</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>80</width>
<height>20</height>
</size>
</property>
</spacer>
<widget class="TQLabel">
<property name="name">
<cstring>textLabel1</cstring>
</property>
<property name="text">
<string>&lt;b&gt;Connection failed&lt;/b&gt;&lt;br&gt;&lt;br&gt;
Unfortunately, PPP could not make a connection.&lt;br&gt;&lt;br&gt;
On the next two tabs, you'll find the information PPP returned. Please check if you have the right PPP options enabled. If you need more information, please re-run this program from the command line with the -v4 argument.</string>
</property>
</widget>
<spacer>
<property name="name">
<cstring>spacer3</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>50</width>
<height>20</height>
</size>
</property>
</spacer>
</hbox>
</widget>
</vbox>
</widget>
<widget class="TQWidget">
<property name="name">
<cstring>Widget9</cstring>
</property>
<attribute name="title">
<string>PPP stdout</string>
</attribute>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQTextEdit">
<property name="name">
<cstring>StdOutTextBox</cstring>
</property>
<property name="wordWrap">
<enum>NoWrap</enum>
</property>
<property name="wrapPolicy">
<enum>AtWordBoundary</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="TextFormat">
<enum>PlainText</enum>
</property>
<property name="undoRedoEnabled">
<bool>false</bool>
</property>
<property name="toolTip" stdset="0">
<string>Copy this information into e.g. an e-mail.</string>
</property>
</widget>
</vbox>
</widget>
<widget class="TQWidget">
<property name="name">
<cstring>TabPage</cstring>
</property>
<attribute name="title">
<string>PPP stderr</string>
</attribute>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQTextEdit">
<property name="name">
<cstring>StdErrTextBox</cstring>
</property>
<property name="wordWrap">
<enum>NoWrap</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="TextFormat">
<enum>PlainText</enum>
</property>
<property name="undoRedoEnabled">
<bool>false</bool>
</property>
<property name="toolTip" stdset="0">
<string>Copy this information into e.g. an e-mail.</string>
</property>
</widget>
</vbox>
</widget>
</widget>
<widget class="TQLayoutWidget">
<property name="name">
<cstring>Layout1</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<spacer>
<property name="name">
<cstring>Horizontal Spacing2</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
<widget class="TQPushButton">
<property name="name">
<cstring>buttonOk</cstring>
</property>
<property name="text">
<string>&amp;OK</string>
</property>
<property name="accel">
<string></string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</hbox>
</widget>
</vbox>
</widget>
<connections>
<connection>
<sender>buttonOk</sender>
<signal>clicked()</signal>
<receiver>PPPErrorLogsDialog</receiver>
<slot>accept()</slot>
</connection>
</connections>
<pixmapinproject/>
<layoutdefaults spacing="6" margin="11"/>
</UI>

@ -0,0 +1,75 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "Popup.h"
#include "popupwithmemory.h"
#include "yesnowithmemory.h"
#include <ntqstring.h>
#include <ntqlabel.h>
void
Popup::WarningWithMemory(
const TQString& aName,
const TQString& aMessage,
TQWidget* currentWidget)
{
DEBUG2("Warning with Memory Name: %s, Message: %s\n", aName.ascii(), aMessage.ascii());
PopupWithMemory myDialog (currentWidget);
// do we need to show?
if (myDialog.setMemoryName(aName)==false)
{
DEBUG3(" Message not shown due to user preference\n");
return;
}
// if yes: display the message
myDialog.textLabel->setText(aMessage);
myDialog.setCaption(APPNAME + TQObject::tr(" message"));
myDialog.exec();
};
bool
Popup::YesNoQuestionWithMemory(
const TQString& aName,
const TQString& aMessage,
TQWidget* currentWidget)
{
DEBUG2("YesNo with Memory Name: %s, Message: %s\n", aName.ascii(), aMessage.ascii());
YesNoWithMemory myDialog (currentWidget);
// do we need to show?
if (myDialog.setMemoryName(aName)==false)
{
DEBUG3(" Message not shown due to user preference\n");
}
else
{
// if yes: display the message
myDialog.textLabel->setText(aMessage);
myDialog.setCaption(APPNAME + TQObject::tr(" message"));
myDialog.exec();
}
return myDialog.theResult;
};

@ -0,0 +1,139 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2006 Klaas van Gend
* (C) 2007 Christofer Wesseling, Klaas van Gend
* (C) 2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef POPUP_H_
#define POPUP_H_
#include <ntqstring.h>
#include <ntqmessagebox.h>
// for exit(3)
#include <cstdlib>
/// DON'T use this function in your code!!!
extern void printAbortMessage(int aSignalNumber);
/** This is a class utility - it encapsulates three member functions to do
* quick popup dialogs
*/
class Popup
{
public:
/** pops up a message box with a critical message
* PROGRAM EXECUTION WILL STOP AND THE APPLICATION WILL HALT
* @param aMessage: the Message
* @param currentWidget: the Widget below the Message - if Popup should appear in front of another form than the mainWindow
*/
static inline void Critical(const TQString& anErrorMessage, TQWidget* currentWidget = NULL)
{
DEBUG1("*** CRITICAL ERROR: %s\n",anErrorMessage.ascii());
TQMessageBox::critical (currentWidget,
APPNAME " critical error",
anErrorMessage,
TQMessageBox::Abort | TQMessageBox::Default,
TQMessageBox::NoButton,
TQMessageBox::NoButton);
// critical errors? we might want to explain the user on
// how to help solve this!
printAbortMessage(0);
// printAbortMessage doesn't exit - good!
// leaves us room to explain why we actually stop
DEBUG1("Critical Popup - application will halt\n");
exit(10);
};
/** pops up a message box with a informational message
* program execution will continue afterwards
* @param aMessage: the Message
* @param currentWidget: the Widget below the Message - if Popup should appear in front of another form than the mainWindow
*/
static inline void Info(const TQString& aMessage, TQWidget* currentWidget = NULL)
{
DEBUG2("Info Message: %s\n",aMessage.ascii());
TQMessageBox::information (currentWidget,
APPNAME " informational message",
aMessage,
TQMessageBox::Ok | TQMessageBox::Default,
TQMessageBox::NoButton,
TQMessageBox::NoButton);
};
/** pops up a message box with a warning message
* program execution will continue afterwards
* @param aMessage: the Message
* @param currentWidget: the Widget below the Message - if Popup should appear in front of another form than the mainWindow
*/
static inline void Warning(const TQString& aMessage, TQWidget* currentWidget = NULL)
{
DEBUG2("Warning Message: %s\n",aMessage.ascii());
TQMessageBox::warning (currentWidget,
APPNAME " warning",
aMessage,
TQMessageBox::Ok | TQMessageBox::Default,
TQMessageBox::NoButton,
TQMessageBox::NoButton);
};
/** pops up a message box with a question message
* if question answered YES, will return true, otherwise false
* @param aMessage: the Message
* @param currentWidget: the Widget below the Message - if Popup should appear in front of another form than the mainWindow
* @returns true if clicked Yes, false if no or 'escape'
*/
static inline bool YesNoQuestion(const TQString& aMessage, TQWidget* currentWidget = NULL)
{
DEBUG2("Yes/No Question: %s\n", aMessage.ascii());
if (TQMessageBox::question(currentWidget,
APPNAME " question",
aMessage,
TQMessageBox::Yes | TQMessageBox::Default,
TQMessageBox::No,
TQMessageBox::NoButton) == TQMessageBox::Yes)
return true;
else
return false;
};
/** pops up a message box with a warning message
* program execution will continue afterwards
* the message box will contain a checkbox "do not show again", which can be
* checked - and works as advertised :-)
* @param aName: unique name of the message which will be used to save the user's preference
* @param aMessage: the Message
* @param currentWidget: the Widget below the Message - if Popup should appear in front of another form than the mainWindow
*/
static void WarningWithMemory(const TQString& aName, const TQString& aMessage, TQWidget* currentWidget = NULL);
/** pops up a message box with a question message
* if question answered YES, will return true, otherwise false
* the message box will contain a checkbox "do not show again", which can be
* checked - and works as advertised :-)
* @param aName: unique name of the message which will be used to save the user's preference
* @param aMessage: the Message
* @param currentWidget: the Widget below the Message - if Popup should appear in front of another form than the mainWindow
* @returns true if clicked Yes, false if no or 'escape'
*/
static bool YesNoQuestionWithMemory(const TQString& aName, const TQString& aMessage, TQWidget* currentWidget = NULL);
};
#endif /*POPUP_H_*/

@ -0,0 +1,80 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006 Christofer Wesseling
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "ProgressDialog.h"
#include <ntqstring.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
ProgressDialog::ProgressDialog(TQWidget* aParent, const TQString& aTitle)
: TQProgressDialog(aTitle, TQObject::tr("Abort"), 1, aParent, "ProgressDialog-text2", TRUE)
{
setProgress( 0 );
setCaption(aTitle);
}
void
ProgressDialog::start(int aNumberOfMiliSecondsToWait)
{
setMinimumDuration(aNumberOfMiliSecondsToWait);
tqApp->processEvents();
}
bool
ProgressDialog::runOneSecond(void)
{
setProgress( progress()+1 );
DEBUG5("ProgressDialog::runOneSecond of % 3d, % 3d has passed\n", progress(), totalSteps()-1 );
if ( progress() >= totalSteps()-1 )
return false;
tqApp->processEvents();
sleep(1);
return (wasCanceled()==false);
}
void
ProgressDialog::finish(void)
{
// we will show a visible finish of the progress dialog here
// but we should only do such thing if the dialog was visible
// in the first place
if (progress() <= minimumDuration()*1000)
return;
struct timespec sleep_time;
sleep_time.tv_sec=0;
sleep_time.tv_nsec=30*1000000; // show each status 30ms
int myStepSize = (totalSteps()-progress())/10+1;
while( (totalSteps()-progress()) >1 )
{
int myProgress = progress()+myStepSize;
if (myProgress > totalSteps()-1)
myProgress = totalSteps()-1;
setProgress( myProgress );
tqApp->processEvents();
nanosleep(&sleep_time,NULL); // so the user is able to see it...
}
tqApp->processEvents();
}

@ -0,0 +1,77 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006 Christofer Wesseling
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef PROGRESSDIALOG_H_
#define PROGRESSDIALOG_H_
#include <ntqprogressdialog.h>
#include <ntqapplication.h>
//forward declaration of TQString
class TQString;
/**
* This ProgressDialog class hides some of the querks of the QT class
* it also provides us with a convenient "once per second" polling mechanism
*
* Depending on your wishes:
* * show from the start and kill it when success
* * show from start and rapid progress to 100% once success
* * show delayed and don't show at all if it finishes before a certain time span
* See the start(), setMaxTime() and finish() members for more explanation.
*/
class ProgressDialog : protected TQProgressDialog
{
public:
/// constructor
ProgressDialog(TQWidget* aParent, const TQString& aTitle);
/// destructor
virtual ~ProgressDialog() {};
/**Sets the Max Time in seconds so reach 100%
* (in reality it sets te amount of total steps, we wait 1 second per step....)
* @param aValue amount of seconds to wait
*/
void setMaxTime( int aValue ) {setTotalSteps(aValue+1);};
/** start the dialog,
* @param aNumberOfMiliSecondsToWait wait for this time before actually showing,
* 0 means show immediately.
*/
void start(int aNumberOfMiliSecondsToWait);
/** Makes one step, and waits after that one second..
* @return true if still OK, false if user cancelled OR if the Max Time (see above) is reached.
*/
bool runOneSecond(void);
/** GUI fixup: If there is not other visible indication to the user that a
* task finished correctly, run this member to have the progress bar go to
* 100% (and wait a little while) first.
* Note that if the time hasn't progressed beyond the aNumberOfMiliSecondsToWait
* as set by the start() member, this member will not show anything.
*/
void finish(void);
private:
};
#endif // defined ProgressDialog CLASS

@ -0,0 +1,146 @@
/* umtsmon - a program to cotrol/monitor your UMTS card
* This file copyright (C) 2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "SetLanguageDialog.h"
#include "Internationalisation.h"
#include "Popup.h"
#include <ntqpushbutton.h>
#include <ntqlabel.h>
#include <ntqbuttongroup.h>
#include <ntqradiobutton.h>
#include <ntqlayout.h>
#include <ntqtooltip.h>
#include <ntqwhatsthis.h>
#include <ntqimage.h>
#include <ntqpixmap.h>
#include <ntqstringlist.h>
SetLanguageDialog::SetLanguageDialog( TQWidget* parent, const char* name, bool modal, WFlags fl )
: TQDialog( parent, name, modal, fl )
{
setSizeGripEnabled(true);
theDialogLayout = new TQVBoxLayout( this, 11, 6, "DialogLayout");
textLabel1 = new TQLabel( this, "textLabel1" );
theDialogLayout->addWidget( textLabel1 );
theRadioButtonGroup = new TQButtonGroup( this, "RadioButtonGroup" );
theRadioButtonGroup->setColumnLayout(0, TQt::Vertical );
theRadioButtonGroup->layout()->setSpacing( 6 );
theRadioButtonGroup->layout()->setMargin( 11 );
theRadioButtonGroupLayout = new TQVBoxLayout( theRadioButtonGroup->layout() );
theRadioButtonGroupLayout->setAlignment( TQt::AlignTop );
theDialogLayout->addWidget( theRadioButtonGroup );
thePushButtonLayout = new TQHBoxLayout( 0, 0, 6, "PushButtonLayout");
Horizontal_Spacing2 = new TQSpacerItem( 20, 20, TQSizePolicy::Expanding, TQSizePolicy::Minimum );
thePushButtonLayout->addItem( Horizontal_Spacing2 );
buttonOk = new TQPushButton( this, "buttonOk" );
buttonOk->setAutoDefault(true);
buttonOk->setDefault(true);
buttonOk->setEnabled(false);
thePushButtonLayout->addWidget( buttonOk );
buttonCancel = new TQPushButton( this, "buttonCancel" );
buttonCancel->setAutoDefault(true);
thePushButtonLayout->addWidget( buttonCancel );
theDialogLayout->addLayout( thePushButtonLayout );
languageChange();
resize( TQSize(100, 209).expandedTo(minimumSizeHint()) );
clearWState( WState_Polished );
// signals and slots connections
connect( buttonOk, SIGNAL( clicked() ), this, SLOT( buttonOk_clicked() ) );
connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( reject() ) );
}
void SetLanguageDialog::languageChange()
{
// the strings in the radio buttons are missing here -
// don't translate them
setCaption( tr( "Set Language" ) );
textLabel1->setText( tr( "Please select your language. \n"
"This setting will be active after a restart." ) );
theRadioButtonGroup->setTitle( tr( "Available languages" ) );
buttonOk->setText( tr( "&OK" ) );
buttonOk->setAccel( TQKeySequence( TQString::null ) );
buttonCancel->setText( tr( "&Cancel" ) );
buttonCancel->setAccel( TQKeySequence( TQString::null ) );
}
void SetLanguageDialog::buttonOk_clicked()
{
// figure out which radio button is selected
// and find it's name
TQString myLocale = theRadioButtonGroup->selected()->text();
DEBUG3("We will use locale '%s'\n", myLocale.ascii());
if (theInternationalisationPtr->tryLocale(myLocale))
{
// yay!
DEBUG3("Setting new locale succeeded\n");
accept();
}
else
{
DEBUG3("Setting new locale failed\n");
Popup::Warning(tr("Selecting the language failed ?!?"), this);
// do not run accept()...
}
}
void SetLanguageDialog::radioButton_clicked()
{
DEBUG3("user clicked a radio button\n");
buttonOk->setEnabled(true);
buttonOk->setFocus();
}
void SetLanguageDialog::setI18nPtr(Internationalisation* aI18nPtr)
{
theInternationalisationPtr = aI18nPtr;
// make a copy of the list and sort it
TQStringList myLangList = aI18nPtr->getAllSupportedLocales();
qHeapSort(myLangList);
TQString myCurrentLang = aI18nPtr->getLocale();
DEBUG5("My current language = '%s'\n", myCurrentLang.ascii());
TQStringList::Iterator it;
for (it = myLangList.begin(); it != myLangList.end(); ++it )
{
// I'm not sure what this kludge is good for, but const char* is the
// only acceptable parameter for a button name.
// We could of course have named all buttons "button", but...
TQString myButtonName = "button_" + (*it);
TQRadioButton* myRadioButtonPtr = new TQRadioButton( theRadioButtonGroup, myButtonName.ascii() );
// don't attempt to translate the language names - no tr() here!
myRadioButtonPtr->setText(*it);
if ((*it) == myCurrentLang)
myRadioButtonPtr->setChecked(true);
// hook up the button to the signal handler to enable the OK button
connect( myRadioButtonPtr, SIGNAL( clicked() ), this, SLOT( radioButton_clicked() ) );
theRadioButtonGroupLayout->addWidget( myRadioButtonPtr );
}
}

@ -0,0 +1,71 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef SETLANGUAGEDIALOG_H_
#define SETLANGUAGEDIALOG_H_
#include <ntqvariant.h>
#include <ntqdialog.h>
#include <ntqobject.h>
class TQVBoxLayout;
class TQHBoxLayout;
class TQSpacerItem;
class TQLabel;
class TQButtonGroup;
class TQRadioButton;
class TQPushButton;
class Internationalisation;
/// this dialog allows a user to change the language for the UI
class SetLanguageDialog : public TQDialog
{
TQ_OBJECT
public:
SetLanguageDialog( TQWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 );
virtual ~SetLanguageDialog()
{// no need to delete child widgets, TQt does it all for us
};
/** pass the Internationalisation instance
* loads the dialog with all languages and allows for setting it later
*/
void setI18nPtr(Internationalisation* aI18nPtr);
private:
TQLabel* textLabel1;
TQButtonGroup* theRadioButtonGroup;
TQPushButton* buttonOk;
TQPushButton* buttonCancel;
TQVBoxLayout* theDialogLayout;
TQVBoxLayout* theRadioButtonGroupLayout;
TQHBoxLayout* thePushButtonLayout;
TQSpacerItem* Horizontal_Spacing2;
Internationalisation* theInternationalisationPtr;
private slots:
/// Sets the strings of the subwidgets using the current language.
void languageChange();
/// when OK button is clicked, make sure the new setting is used and saved
void buttonOk_clicked();
/// when a radio button is clicked, enable OK button
void radioButton_clicked();
};
#endif /*SETLANGUAGEDIALOG_H_*/

@ -0,0 +1,282 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2008, 2009 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "UIState.h"
#include "TheDeviceManagerSingleton.h"
#include "ConnectionInfo.h"
// FIXME: this include should vanish - setting LCD should go through mainwindow
#include "LCDDisplay.h"
#include <ntqtimer.h>
#include <assert.h>
// member order in this file:
// * constructors
// * destructor
// * all other members in alphabetical order
UIState::UIState(mainwindow* aMainWindowPtr)
: TQObject(aMainWindowPtr, "UIState instance"),
theMainWindowPtr(aMainWindowPtr),
theState(NO_DEVICE),
theUpdateTimer(NULL)
{
startUpdateTimer();
// only when both the user has requested autoconnect *and*
// we know that in history there has been successful connetions,
// enable autoconnect
Profile myProfile;
if (TheSettingsSingleton::getTQSRef().readBoolEntry(theGeneralAutoConnectSettingName, false)
&& myProfile.getWasConnectionSuccess())
theAutoConnectState = AUTOCONNECT_ENABLED;
else
theAutoConnectState = AUTOCONNECT_DISABLED;
}
UIState::~UIState()
{
stopUpdateTimer();
}
void UIState::handleSIMCHECK(void)
{
// lets check the PIN-Status... so we can make the menu user friendly... :)
SIMHandler mySIMHandler;
mySIMHandler.askForPIN();
if(!mySIMHandler.isPINProtectionEnabled())
{
DEBUG5(" PIN protection on SIM is disabled \n");
//let the user see whats active and not...
theMainWindowPtr->setPINmenu(mainwindow::PIN_DISABLED);
}
else
{
DEBUG5(" PIN protection on SIM is enabled \n");
//let the user see whats active and not...
theMainWindowPtr->setPINmenu(mainwindow::PIN_ENABLED);
}
}
void
UIState::newConnectionState(ConnectionState aNewState)
{
DEBUG2("UIState::newConnectionState(%d) callback called\n", aNewState);
switch (aNewState)
{
case STOPPED:
// this callback also gets called when we register our callback
// with PPPConnection - so only act on it when we know it makes sense
// in real life, this entry gets called when we disconnect OR when pppd is terminated
// either through a crash or a signal
if (getState() >= REGISTERED)
setState(REGISTERED);
break;
case STARTING:
assert (getState() >= REGISTERED);
setState(PPPCONNECTING);
break;
case RUNNING:
case NOT_OURS_RUNNING:
assert (getState() >= REGISTERED);
setState(PPPCONNECTED);
break;
case ERROR:
assert (getState() >= REGISTERED);
setState(PPPDISCONNECTING);
emit theMainWindowPtr->showPPPErrorLogsDialog();
break;
}
}
void UIState::setState(UIState::UmtsmonState aNewState)
{
DEBUG2("\n\nUIState::setState(%d -> %d)\n", theState, aNewState);
switch(aNewState)
{
case DEVICE_UNUSABLE:
case NO_DEVICE:
theState = NO_DEVICE;
break;
case DETECTING_DEVICE:
theState = aNewState;
if (TheDeviceManagerSingleton::me().tryDeviceDetection() == true)
{
theMainWindowPtr->setNewConnectionBasePtr();
setState(SIM_CHECK);
}
else
setState(NO_DEVICE);
break;
case SIM_CHECK:
theState = aNewState;
handleSIMCHECK();
setState(REGISTERING);
break;
case REGISTERING:
theState = aNewState;
// NOTHING TO DO
break;
case REGISTERED:
theState = aNewState;
if (Profile::getProfileList().size() == 0)
{
Popup::WarningWithMemory("PleaseCreateProfile", tr("Before you connect, please create a \"profile\"."), theMainWindowPtr);
}
if (theAutoConnectState == AUTOCONNECT_ENABLED)
{
// FIXME: move to UIState
theMainWindowPtr->ConnectPPP();
}
break;
case PPPDISCONNECTING:
// disable autoconnect for this session
theAutoConnectState = AUTOCONNECT_CANCELLED;
// deliberately no break; here
case PPPCONNECTING:
case PPPCONNECTED:
// nothing to do - it's all still in mainwindow.ui.h
theState = aNewState;
break;
}
}
TQChar UIState::spinner(void) const
{
// this member is not really an exemplary C++ member,
// but it works :-)
static int myState = 0;
myState++;
switch(myState)
{
case 1:
return '/';
case 2:
return '-';
case 3:
return '\\';
default:
myState = 0;
return '|';
}
}
void UIState::startUpdateTimer(void)
{
DEBUG5("***startUpdateTimer\n");
if (theUpdateTimer == NULL)
{
// setup the refreshtimer for network statistics and signal quality
theUpdateTimer = new TQTimer(this, "refreshtimer");
connect(theUpdateTimer, SIGNAL(timeout()), SLOT(update()));
theMainWindowPtr->updateNetworkData();
theUpdateTimer->start(SEC_REFRESH * 1000, FALSE);
}
else
{
DEBUG1("refreshtimer not null?!?");
}
// whether we set a timer or just killed it - let's refresh now
theMainWindowPtr->updateNetworkData();
}
void UIState::stopUpdateTimer()
{
DEBUG5("stopUpdateTimer\n");
if (theUpdateTimer != NULL)
{
theUpdateTimer->stop();
delete theUpdateTimer;
theUpdateTimer = NULL;
}
}
void UIState::update(void)
{
DEBUG2("***UIState::update(void), state=%d\n", theState);
switch(theState)
{
case NO_DEVICE:
theMainWindowPtr->setConnectButtons();
// only run autodetect every DEVICE_DETECT_REFRESH_COUNTxSEC_REFRESH
// (except the first time)
static int myCounter = 1;
myCounter--;
if (myCounter>0)
{
// in these case, it doesn't make sense to update network data
theMainWindowPtr->theLCDDisplay->setOperatorName(tr("No device (yet)... (%1)").arg(myCounter), true);
break;
}
myCounter = DEVICE_DETECT_REFRESH_COUNT;
setState(DETECTING_DEVICE);
// deliberately no break here...
case DETECTING_DEVICE:
// in these case, it doesn't make sense to update network data
theMainWindowPtr->theLCDDisplay->setOperatorName(tr("Detecting device %1").arg(spinner()), true);
break;
case SIM_CHECK:
// in these case, it doesn't make sense to update network data
theMainWindowPtr->theLCDDisplay->setOperatorName(tr("SIM check %1").arg(spinner()), true);
break;
case DEVICE_UNUSABLE:
// in these case, it doesn't make sense to update network data
theMainWindowPtr->theLCDDisplay->setOperatorName(tr("No device"), true);
break;
case REGISTERING:
{
// ask a ConnectionInfo if we are operator connected already
ConnectionInfo* myCIPtr = TheDeviceManagerSingleton::getConnectionInfoPtr();
assert(myCIPtr != NULL);
// none of the exceptions can be thrown here as we're not connected
myCIPtr->refresh();
if (myCIPtr->isDeviceRegistered())
setState(REGISTERED);
theMainWindowPtr->theLCDDisplay->setOperatorName(tr("Registering %1").arg(spinner()), true);
break;
}
case REGISTERED:
theMainWindowPtr->setConnectButtons();
theMainWindowPtr->updateNetworkData();
break;
case PPPCONNECTING:
theMainWindowPtr->setConnectButtons();
theMainWindowPtr->updateNetworkData();
theMainWindowPtr->theLCDDisplay->setOperatorName(tr("Connecting %1").arg(spinner()), true);
break;
case PPPCONNECTED:
theMainWindowPtr->setConnectButtons();
theMainWindowPtr->updateNetworkData();
break;
case PPPDISCONNECTING:
theMainWindowPtr->setConnectButtons();
theMainWindowPtr->updateNetworkData();
theMainWindowPtr->theLCDDisplay->setOperatorName(tr("Disconnecting %1").arg(spinner()), true);
break;
}
}

@ -0,0 +1,108 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2008, 2009 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef UISTATE_H_
#define UISTATE_H_
#include "mainwindow.h"
#include <ntqobject.h>
/** this class maintains a state machine
* it observes changes in the connection and hardware and acts on those
*
* This class only has one instance: owned and contained by mainwindow
*
* Note that this class is a friend class of mainwindow!
*/
class UIState : public TQObject, public ConnectionObserverInterface
{
TQ_OBJECT
public:
enum UmtsmonState
{ // (all entries starting with * are implemented)
NO_DEVICE, /// * start
DETECTING_DEVICE, /// * working on finding a device
DEVICE_UNUSABLE, /// big errors...
SIM_CHECK, /// * device present, working on SIM password checks
REGISTERING, /// device operational, not registered in network yet
REGISTERED, /// device operational, network found - ready to start PPP
PPPCONNECTING, ///
PPPCONNECTED, /// fully operational - all connected & ppp running
PPPDISCONNECTING,
};
enum AutoConnectStates
{
AUTOCONNECT_DISABLED, /// the current setting for autoconnect is disabled
AUTOCONNECT_ENABLED, /// the current setting for autoconnect is enabled
AUTOCONNECT_CANCELLED /** autoconnect is enabled, but the user cancelled it
* therefore, for this session it is disabled */
};
AutoConnectStates theAutoConnectState;
public:
/// constructor
UIState(mainwindow* aMainWindowPtr);
/// destructor
virtual ~UIState();
/** this is a callback from PPPConnection
* the member will process the new state and switch states accordingly
*
* @param aNewState the new state of the PPP Process
*/
virtual void newConnectionState(ConnectionState aNewState);
/** set the state, which will be communicated to all required subsystems
* * @param aNewState the new state from enum UmtsmonState
*/
void setState(UmtsmonState aNewState);
/// returns the state of umtsmon
UmtsmonState getState(void)
{return theState;}
/// time between two refreshes in seconds
static const unsigned int SEC_REFRESH=3;
/// number of refreshes between two device detects
static const unsigned int DEVICE_DETECT_REFRESH_COUNT = 5;
public slots:
void update(void);
private:
mainwindow* theMainWindowPtr;
UmtsmonState theState;
void handleSIMCHECK(void);
void startUpdateTimer(void);
void stopUpdateTimer(void);
/// this timer is used to run the updates from
TQTimer* theUpdateTimer;
/// returns a spinner character in the order / - \ |
TQChar spinner(void) const;
};
#endif /* UISTATE_H_ */

@ -0,0 +1,138 @@
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
<class>AboutDialogUmtsmon</class>
<widget class="TQDialog">
<property name="name">
<cstring>AboutDialogUmtsmon</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>503</width>
<height>476</height>
</rect>
</property>
<property name="caption">
<string>About</string>
</property>
<property name="icon">
<pixmap>dialog-information-16x16.png</pixmap>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQTabWidget">
<property name="name">
<cstring>tabWidget3</cstring>
</property>
<widget class="TQWidget">
<property name="name">
<cstring>tab</cstring>
</property>
<attribute name="title">
<string>About</string>
</attribute>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel">
<property name="name">
<cstring>textLabel1_2</cstring>
</property>
<property name="text">
<string>&lt;b&gt;&lt;font size="+2"&gt;UMTSmon&lt;/font&gt; - Monitoring your UMTS PCMCIA card&lt;/b&gt;&lt;br&gt;&lt;br&gt;
(C) 2006,2007,2008 by Klaas van Gend and others.&lt;br&gt;&lt;br&gt;
&lt;b&gt;This application is licensed by the GPL v2 license.&lt;/b&gt;&lt;br&gt;
The COPYING tab explains the rights and constraints that are granted to you due to this software license.
&lt;br&gt;
Refer to the AUTHORS tab to find out what parts of this application were derived/taken from other sources.</string>
</property>
</widget>
<spacer>
<property name="name">
<cstring>spacer23</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>31</width>
<height>261</height>
</size>
</property>
</spacer>
<widget class="TQLabel">
<property name="name">
<cstring>versionlabel</cstring>
</property>
<property name="text">
<string>version updated at runtime</string>
</property>
</widget>
</vbox>
</widget>
<widget class="TQWidget">
<property name="name">
<cstring>tab</cstring>
</property>
<attribute name="title">
<string>COPYING</string>
</attribute>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQTextEdit">
<property name="name">
<cstring>textEdit2</cstring>
</property>
<property name="text">
<string>
@COPYING@
</string>
</property>
<property name="wordWrap">
<enum>WidgetWidth</enum>
</property>
</widget>
</vbox>
</widget>
<widget class="TQWidget">
<property name="name">
<cstring>AUTHORS</cstring>
</property>
<attribute name="title">
<string>AUTHORS</string>
</attribute>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQTextEdit">
<property name="name">
<cstring>textEdit3</cstring>
</property>
<property name="text">
<string>
@AUTHORS@
</string>
</property>
<property name="wordWrap">
<enum>WidgetWidth</enum>
</property>
</widget>
</vbox>
</widget>
</widget>
</vbox>
</widget>
<pixmapinproject/>
<layoutdefaults spacing="6" margin="11"/>
</UI>

@ -0,0 +1,537 @@
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
<class>AboutDialogUmtsmon</class>
<widget class="TQDialog">
<property name="name">
<cstring>AboutDialogUmtsmon</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>503</width>
<height>476</height>
</rect>
</property>
<property name="caption">
<string>About</string>
</property>
<property name="icon">
<pixmap>dialog-information-16x16.png</pixmap>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQTabWidget">
<property name="name">
<cstring>tabWidget3</cstring>
</property>
<widget class="TQWidget">
<property name="name">
<cstring>tab</cstring>
</property>
<attribute name="title">
<string>About</string>
</attribute>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel">
<property name="name">
<cstring>textLabel1_2</cstring>
</property>
<property name="text">
<string>&lt;b&gt;&lt;font size="+2"&gt;UMTSmon&lt;/font&gt; - Monitoring your UMTS PCMCIA card&lt;/b&gt;&lt;br&gt;&lt;br&gt;
(C) 2006,2007,2008 by Klaas van Gend and others.&lt;br&gt;&lt;br&gt;
&lt;b&gt;This application is licensed by the GPL v2 license.&lt;/b&gt;&lt;br&gt;
The COPYING tab explains the rights and constraints that are granted to you due to this software license.
&lt;br&gt;
Refer to the AUTHORS tab to find out what parts of this application were derived/taken from other sources.</string>
</property>
</widget>
<spacer>
<property name="name">
<cstring>spacer23</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>31</width>
<height>261</height>
</size>
</property>
</spacer>
<widget class="TQLabel">
<property name="name">
<cstring>versionlabel</cstring>
</property>
<property name="text">
<string>version updated at runtime</string>
</property>
</widget>
</vbox>
</widget>
<widget class="TQWidget">
<property name="name">
<cstring>tab</cstring>
</property>
<attribute name="title">
<string>COPYING</string>
</attribute>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQTextEdit">
<property name="name">
<cstring>textEdit2</cstring>
</property>
<property name="text">
<string>
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
</string>
</property>
<property name="wordWrap">
<enum>WidgetWidth</enum>
</property>
</widget>
</vbox>
</widget>
<widget class="TQWidget">
<property name="name">
<cstring>AUTHORS</cstring>
</property>
<attribute name="title">
<string>AUTHORS</string>
</attribute>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQTextEdit">
<property name="name">
<cstring>textEdit3</cstring>
</property>
<property name="text">
<string>
AUTHORS OF UMTSMON
==================
Over 90% of umtsmon was written by Klaas van Gend in 2006, 2007, 2008 and 2009.
It is licensed under the GPLv2 License, see the file COPYING
However, Klaas is not the only copyright holder as some parts were derived
from or based on other sources. Also: several people gave advise on some
implementation topics or did supply patches or translations.
This file tries to list those contributions:
0)
Christofer Wesseling contributed to several parts of umtsmon as part
of his internship work at T-Mobile.
1)
the SerialPort class was based on COMGT 0.3 by Paul Hardwick
COMGT itself was based a package called dcon by Daniel Chouinard
See http://www.pharscape.org/content/view/46/70/
COMGT v0.3 was licensed under the GPLv2 or later.
Paul Hardwick also contributed to the DetectCard and Device classes.
2)
Debugging some issues in the SerialPort class was done with suggestions made by:
* Roel van den Broeck
* Martijn Wijms
* Tom Geelen
* Wouter Moors
3)
The image ok.png is taken from the tdelibs3 RPM from SuSE9.3
It is from the CrystalSVG icon set. According to the RPM, all files are
licensed through the GPL or LGPL.
4)
The UMTSmon logo as used on the website was drawn by 'Tazz_tux'.
5)
Autodetection for the Nozomi 2.2+ drivers and multiple pcmcia socket enumeration
was contributed by Stefan Seyfried [seife@suse.de]
Stefan also worked on several other issues related to card detection.
6)
The 'Runner' code to run other programs from umtsmon, specifically the piece to communicate
through pipes with the program run, was inspired by code from the following web page:
http://www.cryptnet.net/fdp/gtk/exec.html
the code on that page is GPL and copyrighted by V. Alex Brennen [vab@metanet.org] .
7)
Icons in the images/{16|22|SVG} directories come from the Tango icon
set, available at: http://tango.freedesktop.org/Tango_Icon_Library
These icons are licensed under the "Creative Commons Attribution Share-Alike license"
We think that we comply with the requirements of the license, even though we ship
the icons inside the umtsmon binary.
8)
Several compile-related and user interface issues were fixed by Gerald Pfeifer.
9)
fixup old/original Vodafone 3G detection, patch by dj9pz (Arnd Gronenberg)
10)
Huawei E220 fixes by Norbert Preining (norbusan)
11)
Lubomir Schmidt started translation into German and did lots of testing.
12)
additional German translations by Philipp Kießler, Dietmar Maurer and Thorsten Hesemeyer.
13)
translation work into Portugese (pt_PT) by Pedro Algarvio.
14)
some fixes by Carsten Clasohm.
15)
several UI improvements by Danny Kukawka.
16)
Translation into Norwegian Bokmaal by Klaus Ade Johnstad.
17)
comprehensive Sierra Wireless device support added by Phil Gorsuch
18)
Translation into Spanish by Emilio Arrufat, enhancements by Manuel Tornos
19)
Translation into Italian by Alessandro Briosi
20)
Translation into Polish by Tomasz Dominikowski
21)
Translation into Indonesian by Andika Triwidada
22)
The CID is now configurable from the config file thanks to Tobias Stober
23)
Michael Gisbers helped getting the HSO devices to work
24)
Till Busch provided tricks to add a "make install" target to umtsmon.
25)
Robert Verspuy fixed an issue with the Samsung Innov8 or i8510 mobile phone
26)
Martin Dummer provided the manpage and several fixes to umtsmon to allow
adding umtsmon to Debian. He also made gksu work with umtsmon.
27)
Dietmar Hillbrich implemented support for the Ericsson F3507g device.
If you have found any ommissions, please contact the author through the Sourceforge website:
http://www.sourceforge.net/projects/umtsmon
</string>
</property>
<property name="wordWrap">
<enum>WidgetWidth</enum>
</property>
</widget>
</vbox>
</widget>
</widget>
</vbox>
</widget>
<pixmapinproject/>
<layoutdefaults spacing="6" margin="11"/>
</UI>

@ -0,0 +1,220 @@
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
<class>EnterPIN</class>
<widget class="TQDialog">
<property name="name">
<cstring>EnterPIN</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>257</width>
<height>155</height>
</rect>
</property>
<property name="font">
<font>
</font>
</property>
<property name="caption">
<string>Enter PIN</string>
</property>
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQGroupBox" row="0" column="0" rowspan="1" colspan="2">
<property name="name">
<cstring>InfoGroup</cstring>
</property>
<property name="title">
<string>Info</string>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel">
<property name="name">
<cstring>errorMessage</cstring>
</property>
<property name="paletteForegroundColor">
<color>
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</property>
<property name="text">
<string>Please enter the PIN of your
SIM card</string>
</property>
<property name="alignment">
<set>AlignCenter</set>
</property>
</widget>
</vbox>
</widget>
<widget class="TQLayoutWidget" row="1" column="0" rowspan="1" colspan="2">
<property name="name">
<cstring>layout6</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQGroupBox">
<property name="name">
<cstring>PINGroup</cstring>
</property>
<property name="enabled">
<bool>true</bool>
</property>
<property name="minimumSize">
<size>
<width>128</width>
<height>80</height>
</size>
</property>
<property name="title">
<string>PIN</string>
</property>
<property name="toolTip" stdset="0">
<string>Enter the PIN of your SIM-Card.</string>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLineEdit">
<property name="name">
<cstring>pinField</cstring>
</property>
<property name="font">
<font>
<pointsize>20</pointsize>
</font>
</property>
<property name="maxLength">
<number>8</number>
</property>
<property name="echoMode">
<enum>Password</enum>
</property>
</widget>
</hbox>
</widget>
<spacer>
<property name="name">
<cstring>spacer12</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>16</width>
<height>20</height>
</size>
</property>
</spacer>
<widget class="TQLayoutWidget">
<property name="name">
<cstring>layout99</cstring>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQPushButton">
<property name="name">
<cstring>buttonOk</cstring>
</property>
<property name="text">
<string>&amp;OK</string>
</property>
<property name="accel">
<string></string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
<property name="iconSet">
<iconset>ok.png</iconset>
</property>
</widget>
<widget class="TQPushButton">
<property name="name">
<cstring>buttonCancel</cstring>
</property>
<property name="text">
<string>&amp;Cancel</string>
</property>
<property name="accel">
<string></string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="iconSet">
<iconset>process-stop-16x16.png</iconset>
</property>
</widget>
</vbox>
</widget>
</hbox>
</widget>
</grid>
</widget>
<connections>
<connection>
<sender>buttonCancel</sender>
<signal>clicked()</signal>
<receiver>EnterPIN</receiver>
<slot>reject()</slot>
</connection>
<connection>
<sender>buttonOk</sender>
<signal>clicked()</signal>
<receiver>EnterPIN</receiver>
<slot>buttonOk_clicked()</slot>
</connection>
</connections>
<tabstops>
<tabstop>pinField</tabstop>
<tabstop>buttonOk</tabstop>
<tabstop>buttonCancel</tabstop>
</tabstops>
<includes>
<include location="local" impldecl="in declaration">SIMHandler.h</include>
<include location="local" impldecl="in declaration">ValidatePIN.h</include>
<include location="local" impldecl="in implementation">enterpindialog.ui.h</include>
</includes>
<forwards>
<forward>class ConnectionInfo;</forward>
</forwards>
<variables>
<variable access="private">TQString thePIN;</variable>
<variable access="private">SIMHandler *mySIMHandlerPtr;</variable>
</variables>
<slots>
<slot>init( void )</slot>
<slot>buttonOk_clicked()</slot>
</slots>
<functions>
<function>setSIMHandlerPtr( SIMHandler * anSIMHandlerPtr )</function>
<function>enableValidator()</function>
<function returnType="TQString">getPIN()</function>
</functions>
<pixmapinproject/>
<layoutdefaults spacing="6" margin="11"/>
</UI>

@ -0,0 +1,83 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006 Klaas van Gend
* Copyright (C) 2006 Christofer Wesseling
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/****************************************************************************
** ui.h extension file, included from the uic-generated form implementation.
**
** If you want to add, delete, or rename functions or slots, use
** TQt Designer to update this file, preserving your code.
**
** You should not define a constructor or destructor in this file.
** Instead, write your code in functions called init() and destroy().
** These will automatically be called by the form's constructor and
** destructor.
*****************************************************************************/
#include "umtsmon_global.h"
#include "SIMHandler.h"
#include <ntqstring.h>
void EnterPIN::init(void)
{
DEBUG5("EnterPIN::init called\n");
mySIMHandlerPtr = NULL;
}
void EnterPIN::buttonOk_clicked()
{
DEBUG5("validate\n");
//min 4 digits.
if ( pinField->text().length() >= 4 )
{
// let the caller know, that the users wants to give him the data.. accept :)
accept();
}
else
{
errorMessage->setText(tr("This is not a valid PIN code."));
thePIN = "";
}
// if we got here, something went wrong.
// Either was the PIN code wrong, or it was not a valid one
// (because the only true way out of here is the accept() above,
// not calling accept() means that the dialog will stay open)
}
void EnterPIN::setSIMHandlerPtr( SIMHandler *anSIMHandlerPtr )
{
mySIMHandlerPtr = anSIMHandlerPtr;
}
/// enables the validator. validator just works if init() is finished :(
void EnterPIN::enableValidator()
{
pinField->setValidator(new ValidatePIN(pinField));
}
TQString EnterPIN::getPIN()
{
return pinField->text();
}

@ -0,0 +1,272 @@
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
<class>EnterPUK</class>
<widget class="TQDialog">
<property name="name">
<cstring>EnterPUK</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>403</width>
<height>201</height>
</rect>
</property>
<property name="caption">
<string>Please enter your PUK code</string>
</property>
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQGroupBox" row="1" column="0">
<property name="name">
<cstring>PUKGroup</cstring>
</property>
<property name="title">
<string>PUK of your SIM card</string>
</property>
<property name="toolTip" stdset="0">
<string>Please enter the PUK-Code of your SIM card</string>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLineEdit">
<property name="name">
<cstring>pukField</cstring>
</property>
<property name="font">
<font>
<pointsize>20</pointsize>
</font>
</property>
<property name="maxLength">
<number>8</number>
</property>
<property name="echoMode">
<enum>Password</enum>
</property>
<property name="toolTip" stdset="0">
<string>Enter here the PUK of your SIM card</string>
</property>
</widget>
</hbox>
</widget>
<spacer row="1" column="1">
<property name="name">
<cstring>spacer78_2</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
<widget class="TQGroupBox" row="1" column="2">
<property name="name">
<cstring>PINGroup</cstring>
</property>
<property name="enabled">
<bool>true</bool>
</property>
<property name="title">
<string>The new PIN</string>
</property>
<property name="toolTip" stdset="0">
<string>Enter here the new PIN for your SIM card</string>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLineEdit">
<property name="name">
<cstring>pinField</cstring>
</property>
<property name="font">
<font>
<pointsize>20</pointsize>
</font>
</property>
<property name="maxLength">
<number>8</number>
</property>
<property name="echoMode">
<enum>Password</enum>
</property>
<property name="toolTip" stdset="0">
<string>Enter here the new PIN of your SIM card</string>
</property>
</widget>
</hbox>
</widget>
<widget class="TQGroupBox" row="0" column="0" rowspan="1" colspan="3">
<property name="name">
<cstring>InfoGroup</cstring>
</property>
<property name="title">
<string>Info</string>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel" row="0" column="0">
<property name="name">
<cstring>errorMessage</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>5</hsizetype>
<vsizetype>5</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="paletteForegroundColor">
<color>
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</property>
<property name="text">
<string>You have entered a wrong PIN 3 times
Please Enter the PUK-Code.</string>
</property>
<property name="textFormat">
<enum>AutoText</enum>
</property>
<property name="alignment">
<set>AlignCenter</set>
</property>
</widget>
</grid>
</widget>
<widget class="TQLayoutWidget" row="2" column="0" rowspan="1" colspan="3">
<property name="name">
<cstring>Layout_OK_Cancel</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<property name="margin">
<number>4</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<spacer>
<property name="name">
<cstring>Horizontal Spacing2</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
<widget class="TQPushButton">
<property name="name">
<cstring>buttonOk</cstring>
</property>
<property name="text">
<string>&amp;OK</string>
</property>
<property name="accel">
<string></string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
<property name="iconSet">
<iconset>ok.png</iconset>
</property>
</widget>
<widget class="TQPushButton">
<property name="name">
<cstring>buttonCancel</cstring>
</property>
<property name="text">
<string>&amp;Cancel</string>
</property>
<property name="accel">
<string></string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="iconSet">
<iconset>process-stop-16x16.png</iconset>
</property>
</widget>
</hbox>
</widget>
</grid>
</widget>
<connections>
<connection>
<sender>buttonOk</sender>
<signal>clicked()</signal>
<receiver>EnterPUK</receiver>
<slot>OK_Button_clicked()</slot>
</connection>
<connection>
<sender>buttonCancel</sender>
<signal>clicked()</signal>
<receiver>EnterPUK</receiver>
<slot>close()</slot>
</connection>
</connections>
<tabstops>
<tabstop>pukField</tabstop>
<tabstop>pinField</tabstop>
<tabstop>buttonOk</tabstop>
<tabstop>buttonCancel</tabstop>
</tabstops>
<includes>
<include location="local" impldecl="in declaration">SIMHandler.h</include>
<include location="local" impldecl="in declaration">ValidatePIN.h</include>
<include location="local" impldecl="in implementation">enterpukdialog.ui.h</include>
</includes>
<forwards>
<forward>class ConnectionInfo;</forward>
</forwards>
<variables>
<variable access="private">TQString thePUK;</variable>
<variable access="private">SIMHandler *mySIMHandlerPtr;</variable>
</variables>
<slots>
<slot>init( void )</slot>
<slot>OK_Button_clicked()</slot>
</slots>
<functions>
<function>setSIMHandlerPtr( SIMHandler * anSIMHandlerPtr )</function>
<function>enableValidator()</function>
</functions>
<pixmapinproject/>
<layoutdefaults spacing="6" margin="11"/>
</UI>

@ -0,0 +1,111 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006 Christofer Wesseling
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/****************************************************************************
** ui.h extension file, included from the uic-generated form implementation.
**
** If you want to add, delete, or rename functions or slots, use
** TQt Designer to update this file, preserving your code.
**
** You should not define a constructor or destructor in this file.
** Instead, write your code in functions called init() and destroy().
** These will automatically be called by the form's constructor and
** destructor.
*****************************************************************************/
#include "umtsmon_global.h"
#include "Popup.h"
#include <ntqstring.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
void EnterPUK::init(void)
{
DEBUG5("Enter PUK & new PIN::init called\n");
mySIMHandlerPtr = NULL;
}
void EnterPUK::OK_Button_clicked()
{
DEBUG5("validate PUK:\n");
bool isOK = false;
if ( pinField->text().length() >= 4 )
if ( pukField->text().length() >= 8 )
isOK = true;
if (isOK == false)
{
errorMessage->setText(tr("PIN or PUK was not valid!"));
}
else
{
// if everything is fine...
if (mySIMHandlerPtr->setPUK(pukField->text(),pinField->text(), this)==true)
{
accept();
}
else
{
switch(mySIMHandlerPtr->isPinCodeRequired(this))
{
case SIMHandler::PIN_SIM:
// now he seems to want the pin...
// no yet implemented...can this case happen? -> christofer: No!
Popup::Critical(tr("PIN needed after PUK?\nThat's unexpected!\nPlease mail info to: umtsmon-develop@sourceforge.net"));
exit(35);
break;
case SIMHandler::PIN_READY:
// after PUK was set, Option-cards gives us a "READY"
errorMessage->setText(tr("success :-)"));
sleep(1);
this->accept();
break;
case SIMHandler::PIN_PUK:
errorMessage->setText(tr("PUK was not correct."));
break;
default:
Popup::Critical(tr("Something went wrong in the PIN procedures\numtsmon cannot recover\nPlease try a restart and/or\ninsert the SIM card in a GSM phone"));
exit(35);
break;
}
}
}
// end everthing is fine...
}
void EnterPUK::setSIMHandlerPtr( SIMHandler *anSIMHandlerPtr )
{
mySIMHandlerPtr = anSIMHandlerPtr;
}
/// enables the validator. validator just works if init() is finished :(
void EnterPUK::enableValidator()
{
pukField->setValidator(new ValidatePIN(pukField));
pinField->setValidator(new ValidatePIN(pinField));
}

@ -0,0 +1,237 @@
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
<class>helperlistgui</class>
<widget class="TQDialog">
<property name="name">
<cstring>helperlistgui</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>604</width>
<height>322</height>
</rect>
</property>
<property name="caption">
<string>Setup external applications</string>
</property>
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel">
<property name="name">
<cstring>textLabel1</cstring>
</property>
<property name="text">
<string>Several helper applications and file permission settings are needed for proper function.
Below is a list of those which also specifies whether everything is ok. If is not, "Fix" will try to change the appropriate setting.</string>
</property>
</widget>
<widget class="TQListView">
<column>
<property name="text">
<string>#</string>
</property>
<property name="clickable">
<bool>true</bool>
</property>
<property name="resizable">
<bool>true</bool>
</property>
</column>
<column>
<property name="text">
<string>Path</string>
</property>
<property name="clickable">
<bool>true</bool>
</property>
<property name="resizable">
<bool>true</bool>
</property>
</column>
<column>
<property name="text">
<string>Version</string>
</property>
<property name="clickable">
<bool>true</bool>
</property>
<property name="resizable">
<bool>true</bool>
</property>
</column>
<column>
<property name="text">
<string>suid?</string>
</property>
<property name="clickable">
<bool>true</bool>
</property>
<property name="resizable">
<bool>true</bool>
</property>
</column>
<column>
<property name="text">
<string>Remarks</string>
</property>
<property name="clickable">
<bool>true</bool>
</property>
<property name="resizable">
<bool>true</bool>
</property>
</column>
<property name="name">
<cstring>helperListView</cstring>
</property>
</widget>
<widget class="TQLayoutWidget">
<property name="name">
<cstring>layout2</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQPushButton">
<property name="name">
<cstring>buttonHelp</cstring>
</property>
<property name="text">
<string>&amp;Help</string>
</property>
<property name="accel">
<string>F1</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
<spacer>
<property name="name">
<cstring>Horizontal Spacing2</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>280</width>
<height>20</height>
</size>
</property>
</spacer>
<widget class="TQPushButton">
<property name="name">
<cstring>buttonFix</cstring>
</property>
<property name="text">
<string>&amp;Fix</string>
</property>
<property name="accel">
<string>Alt+F</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
<widget class="TQPushButton">
<property name="name">
<cstring>buttonIgnore</cstring>
</property>
<property name="text">
<string>&amp;Ignore</string>
</property>
<property name="accel">
<string>Alt+I</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="toolTip" stdset="0">
<string>don't adjust anything and continue running</string>
</property>
</widget>
<widget class="TQPushButton">
<property name="name">
<cstring>buttonQuit</cstring>
</property>
<property name="text">
<string>&amp;Quit</string>
</property>
<property name="accel">
<string>Alt+Q</string>
</property>
<property name="toolTip" stdset="0">
<string>stop running the application immediately</string>
</property>
</widget>
</hbox>
</widget>
</vbox>
</widget>
<connections>
<connection>
<sender>buttonFix</sender>
<signal>clicked()</signal>
<receiver>helperlistgui</receiver>
<slot>pushButton_Fixit_clicked()</slot>
</connection>
<connection>
<sender>buttonIgnore</sender>
<signal>clicked()</signal>
<receiver>helperlistgui</receiver>
<slot>pushButton_Ignore_clicked()</slot>
</connection>
<connection>
<sender>buttonQuit</sender>
<signal>clicked()</signal>
<receiver>helperlistgui</receiver>
<slot>pushButton_Quit_clicked()</slot>
</connection>
</connections>
<tabstops>
<tabstop>buttonIgnore</tabstop>
<tabstop>buttonQuit</tabstop>
<tabstop>buttonFix</tabstop>
<tabstop>buttonHelp</tabstop>
<tabstop>helperListView</tabstop>
</tabstops>
<includes>
<include location="local" impldecl="in declaration">Runner.h</include>
<include location="local" impldecl="in implementation">helperlistgui.ui.h</include>
</includes>
<forwards>
<forward>class HelperList;</forward>
<forward>struct HelperData;</forward>
</forwards>
<variables>
<variable access="private">Runner theRunner;</variable>
<variable access="private">HelperList* theHelperListPtr;</variable>
</variables>
<slots>
<slot>init( void )</slot>
<slot>pushButton_Fixit_clicked()</slot>
<slot>pushButton_Quit_clicked()</slot>
<slot>pushButton_Ignore_clicked()</slot>
</slots>
<functions>
<function>setHelperListPtr(HelperList* aPtr)</function>
<function>clearList(void)</function>
<function>add(HelperData* aDataPtr)</function>
</functions>
<pixmapinproject/>
<layoutdefaults spacing="6" margin="11"/>
</UI>

@ -0,0 +1,62 @@
/****************************************************************************
** ui.h extension file, included from the uic-generated form implementation.
**
** If you want to add, delete, or rename functions or slots, use
** TQt Designer to update this file, preserving your code.
**
** You should not define a constructor or destructor in this file.
** Instead, write your code in functions called init() and destroy().
** These will automatically be called by the form's constructor and
** destructor.
*****************************************************************************/
#include "umtsmon_global.h"
#include "FileStuff.h"
#include "Runner.h"
#include "HelperList.h"
#include <ntqfile.h>
#include <stdlib.h>
void helperlistgui::init(void)
{
theHelperListPtr = NULL;
}
void helperlistgui::pushButton_Fixit_clicked()
{
if (theHelperListPtr->fixIt())
accept();
else
theHelperListPtr->addListToWidget();
}
void helperlistgui::pushButton_Quit_clicked()
{
DEBUG3("Quit button in helperlistgui clicked - app will exit\n");
exit(0);
}
void helperlistgui::pushButton_Ignore_clicked()
{
// we could have made this connection directly, but this is more clear
reject();
}
void helperlistgui::setHelperListPtr(HelperList* aPtr)
{
theHelperListPtr = aPtr;
}
void helperlistgui::clearList(void)
{
helperListView->clear();
}
void helperlistgui::add(HelperData* aDataPtr)
{
aDataPtr->add(helperListView);
}

@ -0,0 +1,589 @@
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
<class>InfoDialogUmtsmon</class>
<widget class="TQDialog">
<property name="name">
<cstring>InfoDialogUmtsmon</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>600</width>
<height>452</height>
</rect>
</property>
<property name="font">
<font>
</font>
</property>
<property name="caption">
<string>System Info</string>
</property>
<property name="icon">
<pixmap>dialog-information-16x16.png</pixmap>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQTabWidget">
<property name="name">
<cstring>tabWidget3</cstring>
</property>
<widget class="TQWidget">
<property name="name">
<cstring>TabPage</cstring>
</property>
<attribute name="title">
<string>SIM / Device</string>
</attribute>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLayoutWidget" row="0" column="0">
<property name="name">
<cstring>layout114</cstring>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel" row="0" column="0">
<property name="name">
<cstring>textLabel1_2_2_2_2</cstring>
</property>
<property name="text">
<string>IMSI</string>
</property>
</widget>
<widget class="TQLabel" row="3" column="1">
<property name="name">
<cstring>lbl_CardType</cstring>
</property>
<property name="text">
<string> - no Value -</string>
</property>
</widget>
<widget class="TQLabel" row="2" column="0">
<property name="name">
<cstring>textLabel1_2_2_4</cstring>
</property>
<property name="text">
<string>Manufacturer</string>
</property>
</widget>
<widget class="TQLabel" row="0" column="1">
<property name="name">
<cstring>lbl_IMSI</cstring>
</property>
<property name="text">
<string> - no Value -</string>
</property>
</widget>
<widget class="TQLabel" row="3" column="0">
<property name="name">
<cstring>textLabel1_2_2_2</cstring>
</property>
<property name="text">
<string>Card-Type</string>
</property>
</widget>
<widget class="TQLabel" row="1" column="0">
<property name="name">
<cstring>textLabel1_2_2</cstring>
</property>
<property name="text">
<string>IMEI</string>
</property>
</widget>
<widget class="TQLabel" row="1" column="1">
<property name="name">
<cstring>lbl_IMEI</cstring>
</property>
<property name="text">
<string> - no Value -</string>
</property>
</widget>
<widget class="TQLabel" row="2" column="1">
<property name="name">
<cstring>lbl_Manufacturer</cstring>
</property>
<property name="text">
<string> - no Value -</string>
</property>
</widget>
<widget class="TQLabel" row="4" column="0">
<property name="name">
<cstring>textLabel1_2_2_3</cstring>
</property>
<property name="text">
<string>Revision</string>
</property>
</widget>
<widget class="TQLabel" row="4" column="1">
<property name="name">
<cstring>lbl_Revision</cstring>
</property>
<property name="text">
<string> - no Value -</string>
</property>
</widget>
</grid>
</widget>
<spacer row="1" column="0">
<property name="name">
<cstring>spacer31</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
<spacer row="0" column="1">
<property name="name">
<cstring>spacer6</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>201</width>
<height>20</height>
</size>
</property>
</spacer>
</grid>
</widget>
<widget class="TQWidget">
<property name="name">
<cstring>TabPage</cstring>
</property>
<attribute name="title">
<string>Linux Kernel</string>
</attribute>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQGroupBox">
<property name="name">
<cstring>groupBox19</cstring>
</property>
<property name="title">
<string>Version</string>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel">
<property name="name">
<cstring>lbl_System_Version</cstring>
</property>
<property name="minimumSize">
<size>
<width>500</width>
<height>33</height>
</size>
</property>
<property name="text">
<string>no information available</string>
</property>
<property name="textFormat">
<enum>AutoText</enum>
</property>
<property name="alignment">
<set>WordBreak|AlignTop</set>
</property>
</widget>
</vbox>
</widget>
<widget class="TQLayoutWidget">
<property name="name">
<cstring>layout3</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQGroupBox">
<property name="name">
<cstring>groupBox20</cstring>
</property>
<property name="title">
<string>modules</string>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQTable">
<column>
<property name="text">
<string>module</string>
</property>
</column>
<column>
<property name="text">
<string>size</string>
</property>
</column>
<column>
<property name="text">
<string>use count</string>
</property>
</column>
<property name="name">
<cstring>module_table</cstring>
</property>
<property name="enabled">
<bool>true</bool>
</property>
<property name="minimumSize">
<size>
<width>300</width>
<height>0</height>
</size>
</property>
<property name="resizePolicy">
<enum>AutoOneFit</enum>
</property>
<property name="numRows">
<number>0</number>
</property>
<property name="numCols">
<number>3</number>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="sorting">
<bool>false</bool>
</property>
<property name="selectionMode">
<enum>NoSelection</enum>
</property>
<property name="focusStyle">
<enum>FollowStyle</enum>
</property>
</widget>
</vbox>
</widget>
<widget class="TQGroupBox">
<property name="name">
<cstring>groupBox21</cstring>
</property>
<property name="title">
<string>devices</string>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQTable">
<column>
<property name="text">
<string>major nr</string>
</property>
</column>
<column>
<property name="text">
<string>device</string>
</property>
</column>
<property name="name">
<cstring>device_table</cstring>
</property>
<property name="enabled">
<bool>true</bool>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="resizePolicy">
<enum>AutoOneFit</enum>
</property>
<property name="numRows">
<number>0</number>
</property>
<property name="numCols">
<number>2</number>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="sorting">
<bool>false</bool>
</property>
<property name="selectionMode">
<enum>NoSelection</enum>
</property>
<property name="focusStyle">
<enum>FollowStyle</enum>
</property>
</widget>
</vbox>
</widget>
</hbox>
</widget>
</vbox>
</widget>
<widget class="TQWidget">
<property name="name">
<cstring>TabPage</cstring>
</property>
<attribute name="title">
<string>System</string>
</attribute>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel" row="0" column="0">
<property name="name">
<cstring>textLabel1</cstring>
</property>
<property name="text">
<string>pppd version:</string>
</property>
</widget>
<widget class="TQLabel" row="1" column="0">
<property name="name">
<cstring>textLabel3</cstring>
</property>
<property name="text">
<string>distro release:</string>
</property>
</widget>
<widget class="TQLabel" row="0" column="1" rowspan="1" colspan="2">
<property name="name">
<cstring>lbl_pppd_version</cstring>
</property>
<property name="text">
<string>- no Value -</string>
</property>
</widget>
<widget class="TQLabel" row="1" column="1" rowspan="1" colspan="2">
<property name="name">
<cstring>lbl_distro_release</cstring>
</property>
<property name="text">
<string>- no Value -</string>
</property>
</widget>
<spacer row="1" column="3">
<property name="name">
<cstring>spacer7_2</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>290</width>
<height>20</height>
</size>
</property>
</spacer>
<widget class="TQLabel" row="4" column="1" rowspan="1" colspan="2">
<property name="name">
<cstring>lbl_AT_Port</cstring>
</property>
<property name="text">
<string> - no Value -</string>
</property>
</widget>
<widget class="TQLabel" row="4" column="0">
<property name="name">
<cstring>textLabel2</cstring>
</property>
<property name="text">
<string>AT port</string>
</property>
</widget>
<widget class="TQLabel" row="3" column="0">
<property name="name">
<cstring>textLabel1_2</cstring>
</property>
<property name="text">
<string>umtsmon driver name</string>
</property>
</widget>
<widget class="TQLabel" row="3" column="1" rowspan="1" colspan="2">
<property name="name">
<cstring>lbl_Driver_Name</cstring>
</property>
<property name="text">
<string> - no Value -</string>
</property>
</widget>
<widget class="TQLabel" row="5" column="1" rowspan="1" colspan="2">
<property name="name">
<cstring>lbl_PPP_Port</cstring>
</property>
<property name="text">
<string> - no Value -</string>
</property>
</widget>
<widget class="TQLabel" row="5" column="0">
<property name="name">
<cstring>textLabel3_2</cstring>
</property>
<property name="text">
<string>PPP port</string>
</property>
</widget>
<spacer row="6" column="0">
<property name="name">
<cstring>spacer5</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>140</height>
</size>
</property>
</spacer>
<spacer row="6" column="2">
<property name="name">
<cstring>spacer7_3</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>141</height>
</size>
</property>
</spacer>
<spacer row="2" column="0">
<property name="name">
<cstring>spacer8</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>21</height>
</size>
</property>
</spacer>
<spacer row="2" column="1">
<property name="name">
<cstring>spacer9</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>21</height>
</size>
</property>
</spacer>
</grid>
</widget>
</widget>
<widget class="TQLayoutWidget">
<property name="name">
<cstring>layout4</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<spacer>
<property name="name">
<cstring>spacer7</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>344</width>
<height>20</height>
</size>
</property>
</spacer>
<widget class="TQPushButton">
<property name="name">
<cstring>OK_Button</cstring>
</property>
<property name="text">
<string>Close</string>
</property>
<property name="iconSet">
<iconset>system-log-out-16x16.png</iconset>
</property>
</widget>
</hbox>
</widget>
</vbox>
</widget>
<connections>
<connection>
<sender>OK_Button</sender>
<signal>clicked()</signal>
<receiver>InfoDialogUmtsmon</receiver>
<slot>accept()</slot>
</connection>
</connections>
<includes>
<include location="local" impldecl="in implementation">infodialog.ui.h</include>
</includes>
<slots>
<slot specifier="non virtual">sort_module_table( int section )</slot>
<slot specifier="non virtual">sort_device_table( int section )</slot>
</slots>
<functions>
<function access="private" specifier="non virtual">init()</function>
<function access="private" specifier="non virtual" returnType="TQString">get_Info_using_AT_Query( TQString anAtCommand )</function>
<function access="private">readSystemInformations()</function>
<function specifier="non virtual">setPPPDversion(TQString aVersionString)</function>
</functions>
<pixmapinproject/>
<layoutdefaults spacing="6" margin="11"/>
</UI>

@ -0,0 +1,249 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2006 Christofer Wesseling
* (C) 2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/****************************************************************************
** ui.h extension file, included from the uic-generated form implementation.
**
** If you want to add, delete, or rename functions or slots, use
** TQt Designer to update this file, preserving your code.
**
** You should not define a constructor or destructor in this file.
** Instead, write your code in functions called init() and destroy().
** These will automatically be called by the form's constructor and
** destructor.
*****************************************************************************/
#include "umtsmon_global.h"
#include "FileStuff.h"
#include "ProgressDialog.h"
#include "Query.h"
#include "TheDeviceManagerSingleton.h"
#include <ntqfile.h>
void InfoDialogUmtsmon::init()
{
// FIXME: the tables of modules&devices can't be sorted on other colums by the user BUG: 1616485
// it musn't be implemented at this position, it's just a reminder...
DEBUG2("InfoDialogUmtsmon::init called\n");
// create a Status Dialog....
ProgressDialog myPD(this, tr("Fetching device information..."));
myPD.start(0);
myPD.setMaxTime(6);
lbl_IMEI->setText( get_Info_using_AT_Query("AT+CGSN") );
myPD.runOneSecond();
lbl_IMSI->setText(get_Info_using_AT_Query("AT+CIMI"));
myPD.runOneSecond();
lbl_Manufacturer->setText(get_Info_using_AT_Query("AT+CGMI"));
myPD.runOneSecond();
lbl_CardType->setText(get_Info_using_AT_Query("AT+CGMM"));
myPD.runOneSecond();
lbl_Revision->setText(get_Info_using_AT_Query("AT+CGMR"));
DeviceCapabilities& myDevCapsRef = TheDeviceManagerSingleton::getDeviceCapsRef();
lbl_AT_Port ->setText( myDevCapsRef.getATSerialPortName());
lbl_PPP_Port ->setText( myDevCapsRef.getPPPSerialPortName());
lbl_Driver_Name ->setText( myDevCapsRef.getDeviceClassName());
// finish the progress dialog.. we're ready..
myPD.finish();
// read the system informations...
lbl_System_Version->setText(FileStuff::getFileFirstLine("/proc/version"));
readSystemInformations();
connect(module_table->horizontalHeader(), SIGNAL(clicked(int)), this, SLOT(sort_module_table(int)));
connect(device_table->horizontalHeader(), SIGNAL(clicked(int)), this, SLOT(sort_device_table(int)));
}
/**
* SLOT to sort the rows of the module_table depending on the selected column
* @param the section/column to sort
**/
void InfoDialogUmtsmon::sort_module_table(int section) {
if (module_table->horizontalHeader()->sortIndicatorOrder() == TQt::Ascending) {
module_table->sortColumn(section,false,true);
} else {
module_table->sortColumn(section,true,true);
}
module_table->horizontalHeader()->adjustHeaderSize();
}
/**
* sLOT to sort the rows of the device_table depending on the selected column
* @param the section/column to sort
**/
void InfoDialogUmtsmon::sort_device_table(int section) {
if (device_table->horizontalHeader()->sortIndicatorOrder() == TQt::Ascending) {
device_table->sortColumn(section,false,true);
} else {
device_table->sortColumn(section,true,true);
}
device_table->horizontalHeader()->adjustHeaderSize();
}
/**
* returns the result of the query
* @param the Query String
* @return the result of the query, "error" if no result
**/
TQString InfoDialogUmtsmon::get_Info_using_AT_Query( TQString anAtCommand )
{
Query myQuery(anAtCommand);
if (myQuery.runUntilDone() != Query::OK)
{
// no big deal, it happens, fail silently
DEBUG2("Query.run() failed\n");
return "error";
}
if (!myQuery.hasAnswer())
return tr("No answer from device.");
TQString myAnswer = myQuery.getAnswer().first();
if (myAnswer.isEmpty() && myQuery.getAnswer().count()>1)
{
DEBUG5("FIRST ANSWER EMPTY - GET SECOND ONE\n");
myAnswer = myQuery.getAnswer()[1];
}
DEBUG5("myAnswer: '%s'\n", myAnswer.ascii());
// if the answer contains a ':' in the first 6 characters, that probably means
// a string like: +CGSN: IMEI359411001731435
// but also: 1.5.5 (Date: May 17 2005, Time: 14:55:44)
int myFirstColonPosition = myAnswer.find(":");
if (myFirstColonPosition > 0 && myFirstColonPosition < 6)
{
myAnswer = myAnswer.section(":",1,1);
}
// if there are quotes inside the string, let's removed them if 2
// e.g. Motorola SLVR L7 returns stuff like:
// +CGMI: "Motorola CE, Copyright 2000"\r\n
// and keep them if not 2:
// +CGMM: "GSM900","GSM1800","GSM1900","GSM850","MODEL=L7"\r\n
int myIndex = 0;
int myQuoteCounter = -1;
while (myIndex != -1)
{
myIndex = myAnswer.find("\"", myIndex+1);
myQuoteCounter++;
}
if (myQuoteCounter == 2)
{
myAnswer = myAnswer.section("\"", 1,1);
}
return myAnswer.stripWhiteSpace();
}
/// reads systeminformations into the info dialog
void InfoDialogUmtsmon::readSystemInformations()
{
DEBUG5("InfoDialogUmtsmon::readSystemInformations()\n");
// System modules
TQString myLine;
TQFile f;
f.setName( "/proc/modules" );
f.open( IO_ReadOnly);
while(!f.atEnd ())
{
f.readLine(myLine,900); // how long will an entry max be..?
myLine = myLine.stripWhiteSpace ();
// insert into table..
/// new row at line 0
module_table->insertRows(0);
//insert into row,col,value
module_table->setText(0,0, myLine.section(" ",0,0) );
module_table->setText(0,1, myLine.section(" ",1,1) );
module_table->setText(0,2, myLine.section(" ",2,2) );
}
f.close();
module_table->horizontalHeader()->setStretchEnabled(-1, true);
module_table->sortColumn(0,true,true); // sort on module_names, whole row
module_table->adjustColumn(0);
module_table->adjustColumn(1);
module_table->adjustColumn(2);
//System devices
f.setName( "/proc/devices" );
f.open( IO_ReadOnly);
f.readLine(myLine,50); // first line is just "Character devices:"
while(!f.atEnd ())
{
f.readLine(myLine,50); // how long will an entry max be..?
myLine = myLine.stripWhiteSpace ();
// insert into table..
/// new row at line 0
if( ( myLine.left(3).isEmpty() ) ) // we have reached the last device.. :)
break;
device_table->insertRows(0);
//insert into row,col,value
device_table->setText(0,0, myLine.section(" ",0,0) ); // up to digit 3
device_table->setText(0,1, myLine.section(" ",1) ); //from digit 4 to end..
}
f.close();
device_table->horizontalHeader()->setStretchEnabled(-1, true);
device_table->sortColumn(1,true,true); // sort on device-name, whole row
device_table->adjustColumn(0);
device_table->adjustColumn(1);
// Software dependency versions
// let's try to read /etc/Suse-release /etc/redhat-release, etc...
// unfortunately, also something called '/etc/lsb-release' exists :-(
FileStuff::FindInDir myDirReader("/etc","*-release", TQDir::Files);
TQString myReleaseFileName;
while ( (myReleaseFileName=myDirReader.getNextEntry()) != "")
{
DEBUG5("FILE: %s\n", myReleaseFileName.ascii());
if (myReleaseFileName != "/etc/lsb-release")
break;
}
DEBUG5(" myReleaseFileName: %s\n", myReleaseFileName.ascii());
if (myReleaseFileName!="")
{
lbl_distro_release->setText(FileStuff::getFileFirstLine(myReleaseFileName));
DEBUG5(" release contents: %s\n", lbl_distro_release->text().ascii());
}
// the pppd version is written in mainwindow.h through setPPPDversion
}
void InfoDialogUmtsmon::setPPPDversion(TQString aVersionString)
{
DEBUG5("InfoDialogUmtsmon::setPPPDversion(\"%s\")\n", aVersionString.ascii());
lbl_pppd_version->setText(aVersionString);
}

@ -0,0 +1,246 @@
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
<class>ManageProfiles</class>
<widget class="TQDialog">
<property name="name">
<cstring>ManageProfiles</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>254</width>
<height>223</height>
</rect>
</property>
<property name="caption">
<string>Manage Profiles</string>
</property>
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLayoutWidget" row="1" column="0" rowspan="1" colspan="2">
<property name="name">
<cstring>Layout1</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<spacer>
<property name="name">
<cstring>Horizontal Spacing2</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
<widget class="TQPushButton">
<property name="name">
<cstring>buttonOk</cstring>
</property>
<property name="text">
<string>&amp;OK</string>
</property>
<property name="accel">
<string></string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
<widget class="TQPushButton">
<property name="name">
<cstring>buttonCancel</cstring>
</property>
<property name="text">
<string>&amp;Cancel</string>
</property>
<property name="accel">
<string></string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
</hbox>
</widget>
<widget class="TQListBox" row="0" column="0">
<property name="name">
<cstring>listBox_profiles</cstring>
</property>
<property name="toolTip" stdset="0">
<string>This area shows the profiles that you can use to connect with</string>
</property>
</widget>
<widget class="TQLayoutWidget" row="0" column="1">
<property name="name">
<cstring>layout7</cstring>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQPushButton">
<property name="name">
<cstring>pushButton_add_profile</cstring>
</property>
<property name="text">
<string>&amp;Add profile...</string>
</property>
<property name="accel">
<string>Alt+A</string>
</property>
<property name="toolTip" stdset="0">
<string>Create another profile</string>
</property>
</widget>
<widget class="TQPushButton">
<property name="name">
<cstring>pushButton_edit_profile</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&amp;Edit profile...</string>
</property>
<property name="accel">
<string>Alt+E</string>
</property>
<property name="toolTip" stdset="0">
<string>change an existing profile</string>
</property>
</widget>
<widget class="TQPushButton">
<property name="name">
<cstring>pushButton_set_active</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&amp;Set as active</string>
</property>
<property name="accel">
<string>Alt+S</string>
</property>
<property name="toolTip" stdset="0">
<string>make the selected profile active</string>
</property>
</widget>
<widget class="TQPushButton">
<property name="name">
<cstring>pushButton_delete_profile</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&amp;Delete profile</string>
</property>
<property name="accel">
<string>Alt+D</string>
</property>
<property name="toolTip" stdset="0">
<string>delete the currently selected profile</string>
</property>
</widget>
<spacer>
<property name="name">
<cstring>spacer11</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>80</height>
</size>
</property>
</spacer>
</vbox>
</widget>
</grid>
</widget>
<connections>
<connection>
<sender>buttonOk</sender>
<signal>clicked()</signal>
<receiver>ManageProfiles</receiver>
<slot>accept()</slot>
</connection>
<connection>
<sender>buttonCancel</sender>
<signal>clicked()</signal>
<receiver>ManageProfiles</receiver>
<slot>reject()</slot>
</connection>
<connection>
<sender>pushButton_add_profile</sender>
<signal>clicked()</signal>
<receiver>ManageProfiles</receiver>
<slot>pushButton_add_profile_clicked()</slot>
</connection>
<connection>
<sender>pushButton_edit_profile</sender>
<signal>clicked()</signal>
<receiver>ManageProfiles</receiver>
<slot>pushButton_edit_profile_clicked()</slot>
</connection>
<connection>
<sender>pushButton_delete_profile</sender>
<signal>clicked()</signal>
<receiver>ManageProfiles</receiver>
<slot>pushButton_delete_profile_clicked()</slot>
</connection>
<connection>
<sender>pushButton_set_active</sender>
<signal>clicked()</signal>
<receiver>ManageProfiles</receiver>
<slot>pushButton_set_default_profile()</slot>
</connection>
</connections>
<includes>
<include location="local" impldecl="in declaration">Profile.h</include>
<include location="local" impldecl="in implementation">newprofiledialog.h</include>
<include location="local" impldecl="in implementation">manageprofiles.ui.h</include>
</includes>
<slots>
<slot>init()</slot>
<slot>pushButton_add_profile_clicked()</slot>
<slot>pushButton_delete_profile_clicked()</slot>
<slot>pushButton_edit_profile_clicked()</slot>
<slot>pushButton_set_default_profile()</slot>
</slots>
<functions>
<function>enableButtons(bool isEnabled)</function>
</functions>
<pixmapinproject/>
<layoutdefaults spacing="6" margin="11"/>
</UI>

@ -0,0 +1,148 @@
/* ManageProfiles
* Copyright (C) 2006 Christofer Wesseling
* Copyright (C) 2007 Christofer Wesseling, Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/****************************************************************************
** ui.h extension file, included from the uic-generated form implementation.
**
** If you want to add, delete, or rename functions or slots, use
** TQt Designer to update this file, preserving your code.
**
** You should not define a constructor or destructor in this file.
** Instead, write your code in functions called init() and destroy().
** These will automatically be called by the form's constructor and
** destructor.
*****************************************************************************/
#include "umtsmon_global.h"
#include "Popup.h"
#include "profiledialog.h"
#include <ntqlineedit.h>
// load the Data into the Dialog:
void ManageProfiles::init()
{
// add the profiles to the gui
listBox_profiles->clear();
listBox_profiles->insertStringList(Profile::getProfileList());
// select the default Profile in the combo
if (listBox_profiles->count() > 0)
{
unsigned int i=0;
Profile myDefaultProfile;
while(i < listBox_profiles->count())
{
if (listBox_profiles->text(i) == myDefaultProfile.getProfileName())
{
listBox_profiles->setCurrentItem(i);
listBox_profiles->changeItem(
TQPixmap::fromMimeSource("ok.png"),
listBox_profiles->text(i), i);
}
i++;
}
enableButtons(true);
}
else
enableButtons(false);
}
void ManageProfiles::enableButtons(bool isEnabled)
{
pushButton_edit_profile ->setEnabled(isEnabled);
pushButton_set_active ->setEnabled(isEnabled);
pushButton_delete_profile->setEnabled(isEnabled);
}
void ManageProfiles::pushButton_add_profile_clicked()
{
NewProfileDialog myNewPrfDialog(this); //"this" means, put it in front of "this"-dialog
myNewPrfDialog.exec();
if(myNewPrfDialog.result() == TQDialog::Rejected)
{
DEBUG4("NewProfile: User clicked cancel\n");
return;
}
TQString myNewProfileName = myNewPrfDialog.newProfileName->text();
DEBUG2("New profile name: '%s'\n", myNewProfileName.ascii());
// FIXME: check if profile name already exists
// create the new profile and fill it up with default values
Profile myNewProfile(myNewProfileName);
if (myNewProfile.getAPN().isEmpty())
myNewProfile.setAPN(tr("please_replace_me"));
myNewProfile.save();
// insert into listbox
init();
// enable our new item in the list box
listBox_profiles->setCurrentItem(listBox_profiles->findItem(myNewProfileName));
// and run to the edit profile dialog
emit pushButton_edit_profile_clicked();
}
void ManageProfiles::pushButton_delete_profile_clicked()
{
// figure out which profile to delete
int myItemNr = listBox_profiles->currentItem();
TQString myProfileToDelete = listBox_profiles->currentText();
DEBUG2("Request to delete profile %d: '%s'\n", myItemNr, myProfileToDelete.ascii());
Profile myProfile(myProfileToDelete);
myProfile.remove();
listBox_profiles->removeItem(myItemNr);
// and refresh the listBox
init();
}
void ManageProfiles::pushButton_edit_profile_clicked()
{
// figure out which profile to edit
TQString myProfileToEdit = listBox_profiles->currentText();
DEBUG2("Request to edit profile '%s'\n", myProfileToEdit.ascii());
profiledialog myDialog;
if (myDialog.setProfile(myProfileToEdit) == false)
return;
myDialog.exec();
// and refresh the listBox
init();
}
void ManageProfiles::pushButton_set_default_profile()
{
// // figure out which profile to set default
TQString myProfileToSet = listBox_profiles->currentText();
DEBUG2("Request to set profile as active '%s'\n", myProfileToSet.ascii());
Profile::setActiveProfile(myProfileToSet);
// refresh dialog contents
init();
}

@ -0,0 +1,620 @@
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
<class>NetworkOperatorWizard</class>
<widget class="TQWizard">
<property name="name">
<cstring>NetworkOperatorWizard</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>577</width>
<height>409</height>
</rect>
</property>
<property name="caption">
<string>Network Operator Wizard</string>
</property>
<widget class="TQWidget">
<property name="name">
<cstring>WizardPage1</cstring>
</property>
<attribute name="title">
<string>Page 1: Welcome</string>
</attribute>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel" row="0" column="0">
<property name="name">
<cstring>pixmapLabel1</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>0</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="pixmap">
<pixmap>NetworkOperatorWizard.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
<widget class="TQLabel" row="0" column="1">
<property name="name">
<cstring>textLabel1</cstring>
</property>
<property name="text">
<string>&lt;b&gt;&lt;p align="center"&gt;Welcome to the&lt;br&gt;
Network Operator Wizard&lt;/p&gt;&lt;/b&gt;
&lt;p&gt;This wizard will help you choose an operator.&lt;/p&gt;
&lt;p&gt;Please note: when abroad, usually all operators will accept
your connection and charge you "roaming fees" -
much more expensive.&lt;/P&gt;</string>
</property>
<property name="alignment">
<set>WordBreak|AlignTop</set>
</property>
</widget>
</grid>
</widget>
<widget class="TQWidget">
<property name="name">
<cstring>WizardPage</cstring>
</property>
<attribute name="title">
<string>Page 2: Who picks the operator?</string>
</attribute>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQButtonGroup" row="1" column="1">
<property name="name">
<cstring>buttonGroup3</cstring>
</property>
<property name="title">
<string>who picks?</string>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQRadioButton">
<property name="name">
<cstring>radioButton_card</cstring>
</property>
<property name="text">
<string>have the card decide</string>
</property>
</widget>
<widget class="TQRadioButton">
<property name="name">
<cstring>radioButton_user</cstring>
</property>
<property name="text">
<string>let me select an operator</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</vbox>
</widget>
<widget class="TQLabel" row="0" column="0" rowspan="2" colspan="1">
<property name="name">
<cstring>pixmapLabel1_2</cstring>
</property>
<property name="pixmap">
<pixmap>NetworkOperatorWizard.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
<widget class="TQLabel" row="0" column="1">
<property name="name">
<cstring>textLabel1_2</cstring>
</property>
<property name="text">
<string>&lt;p&gt;Your SIM card contains
a "preferred" set of abroad operators.
The device can select these automatically.
("Preferred" doesn't necessarily mean lowest cost)&lt;/p&gt;
&lt;p&gt;Please note: if that "preferred" operator
has bad coverage, you won't have
a connection unless you manually switch.&lt;/p&gt;
&lt;p&gt;However, on manual selection, the device won't
switch unless you tell it to - moving to another country
requires running this wizard again. &lt;/p&gt;</string>
</property>
<property name="alignment">
<set>WordBreak|AlignTop</set>
</property>
</widget>
</grid>
</widget>
<widget class="TQWidget">
<property name="name">
<cstring>WizardPage</cstring>
</property>
<attribute name="title">
<string>Page 3: Get network strengths?</string>
</attribute>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<spacer row="1" column="1">
<property name="name">
<cstring>spacer1_2</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>16</height>
</size>
</property>
</spacer>
<widget class="TQLabel" row="0" column="1">
<property name="name">
<cstring>textLabel1_2_2</cstring>
</property>
<property name="text">
<string>&lt;p&gt;After searching for operators, we will start getting signal strengths.&lt;/p&gt;
&lt;p&gt;This will however significantly increase the search time!
&lt;/p&gt;</string>
</property>
</widget>
<widget class="TQLabel" row="0" column="0" rowspan="5" colspan="1">
<property name="name">
<cstring>pixmapLabel1_3</cstring>
</property>
<property name="pixmap">
<pixmap>NetworkOperatorWizard.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
<widget class="TQCheckBox" row="2" column="1">
<property name="name">
<cstring>checkBox_no_signal_strengths</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Don't get signal strengths</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
<spacer row="4" column="1">
<property name="name">
<cstring>spacer2_2</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
<widget class="TQLabel" row="3" column="1">
<property name="name">
<cstring>textLabel1_4</cstring>
</property>
<property name="paletteForegroundColor">
<color>
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</property>
<property name="text">
<string>&lt;p align="center"&gt;retrieving signal strengths not implemented yet&lt;/p&gt;</string>
</property>
</widget>
</grid>
</widget>
<widget class="TQWidget">
<property name="name">
<cstring>WizardPage</cstring>
</property>
<attribute name="title">
<string>Page 4: Searching for networks...</string>
</attribute>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQProgressBar" row="2" column="1">
<property name="name">
<cstring>progressBar_searching</cstring>
</property>
<property name="progress">
<number>15</number>
</property>
</widget>
<spacer row="1" column="1">
<property name="name">
<cstring>spacer32</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>21</width>
<height>31</height>
</size>
</property>
</spacer>
<spacer row="3" column="1">
<property name="name">
<cstring>spacer27</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>41</width>
<height>90</height>
</size>
</property>
</spacer>
<widget class="TQLabel" row="0" column="0" rowspan="4" colspan="1">
<property name="name">
<cstring>pixmapLabel1_4</cstring>
</property>
<property name="pixmap">
<pixmap>NetworkOperatorWizard.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
<widget class="TQLabel" row="0" column="1">
<property name="name">
<cstring>textLabel2</cstring>
</property>
<property name="text">
<string>&lt;p align="center"&gt;Searching for networks...&lt;/p&gt;
&lt;p align="center"&gt;Please wait...&lt;/p&gt;</string>
</property>
</widget>
</grid>
</widget>
<widget class="TQWidget">
<property name="name">
<cstring>WizardPage</cstring>
</property>
<attribute name="title">
<string>Page 5: Select a Network Operator</string>
</attribute>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel" row="0" column="1">
<property name="name">
<cstring>textLabel3</cstring>
</property>
<property name="text">
<string>Please select your network:</string>
</property>
</widget>
<widget class="TQLayoutWidget" row="2" column="1">
<property name="name">
<cstring>layout2</cstring>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel" row="1" column="0" rowspan="1" colspan="2">
<property name="name">
<cstring>textLabel_signals</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Still getting network strengths...</string>
</property>
</widget>
<widget class="TQProgressBar" row="0" column="0">
<property name="name">
<cstring>progressBar_signals</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="progress">
<number>5</number>
</property>
</widget>
<widget class="TQPushButton" row="0" column="1">
<property name="name">
<cstring>pushButton_stop_signals</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="maximumSize">
<size>
<width>30</width>
<height>32767</height>
</size>
</property>
<property name="text">
<string></string>
</property>
<property name="pixmap">
<pixmap>process-stop-16x16.png</pixmap>
</property>
</widget>
</grid>
</widget>
<widget class="TQLabel" row="0" column="0" rowspan="3" colspan="1">
<property name="name">
<cstring>pixmapLabel1_5</cstring>
</property>
<property name="pixmap">
<pixmap>NetworkOperatorWizard.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
<widget class="TQTable" row="1" column="1">
<column>
<property name="text">
<string>Operator</string>
</property>
</column>
<column>
<property name="text">
<string>Type</string>
</property>
</column>
<column>
<property name="text">
<string>Signal</string>
</property>
</column>
<column>
<property name="text">
<string>ID</string>
</property>
</column>
<property name="name">
<cstring>table_operators</cstring>
</property>
<property name="numRows">
<number>0</number>
</property>
<property name="numCols">
<number>4</number>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="sorting">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>SingleRow</enum>
</property>
<property name="whatsThis" stdset="0">
<string>This table lists the operators to choose from.</string>
</property>
</widget>
</grid>
</widget>
<widget class="TQWidget">
<property name="name">
<cstring>WizardPage</cstring>
</property>
<attribute name="title">
<string>Page 6: Connecting to operator...</string>
</attribute>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel" row="0" column="1">
<property name="name">
<cstring>textLabel2_2</cstring>
</property>
<property name="text">
<string>&lt;p align="center"&gt;Connecting to your network...&lt;/p&gt;
&lt;p align="center"&gt;Please wait...&lt;/p&gt;</string>
</property>
</widget>
<spacer row="3" column="1">
<property name="name">
<cstring>spacer28</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>51</width>
<height>81</height>
</size>
</property>
</spacer>
<spacer row="1" column="1">
<property name="name">
<cstring>spacer31</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>41</height>
</size>
</property>
</spacer>
<widget class="TQProgressBar" row="2" column="1">
<property name="name">
<cstring>progressBar_connecting</cstring>
</property>
<property name="totalSteps">
<number>10</number>
</property>
<property name="progress">
<number>-1</number>
</property>
</widget>
<widget class="TQLabel" row="0" column="0" rowspan="4" colspan="1">
<property name="name">
<cstring>pixmapLabel1_6</cstring>
</property>
<property name="pixmap">
<pixmap>NetworkOperatorWizard.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</grid>
</widget>
<widget class="TQWidget">
<property name="name">
<cstring>WizardPage</cstring>
</property>
<attribute name="title">
<string>The End</string>
</attribute>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel" row="0" column="1">
<property name="name">
<cstring>textLabel1_3</cstring>
</property>
<property name="text">
<string>&lt;b&gt;&lt;p align="center"&gt;Network Operator
Wizard&lt;br&gt;completed&lt;/p&gt;&lt;/b&gt;
&lt;br&gt;&lt;br&gt;
&lt;p&gt;Have fun on the internet!&lt;/P&gt;</string>
</property>
</widget>
<spacer row="1" column="1">
<property name="name">
<cstring>spacer29</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>21</width>
<height>110</height>
</size>
</property>
</spacer>
<widget class="TQLabel" row="0" column="0" rowspan="2" colspan="1">
<property name="name">
<cstring>pixmapLabel1_7</cstring>
</property>
<property name="pixmap">
<pixmap>NetworkOperatorWizard.png</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</grid>
</widget>
</widget>
<connections>
<connection>
<sender>table_operators</sender>
<signal>clicked(int,int,int,const TQPoint&amp;)</signal>
<receiver>NetworkOperatorWizard</receiver>
<slot>operatorSelected()</slot>
</connection>
</connections>
<includes>
<include location="global" impldecl="in implementation">ntqtimer.h</include>
<include location="local" impldecl="in declaration">NetworkChanger.h</include>
<include location="local" impldecl="in declaration">Popup.h</include>
<include location="local" impldecl="in implementation">OperatorList.h</include>
<include location="local" impldecl="in implementation">networkoperatorwizard.ui.h</include>
</includes>
<forwards>
<forward>class TQTimer;</forward>
</forwards>
<variables>
<variable access="private">int myConnectCount;</variable>
<variable access="private">TQTimer* myConnectTimer;</variable>
<variable access="private">int mySearchCount;</variable>
<variable access="private">TQTimer* mySearchTimer;</variable>
<variable access="private">NetworkChanger myNetworkChanger</variable>
</variables>
<slots>
<slot access="protected">back()</slot>
<slot access="protected">next()</slot>
<slot access="protected">operatorSelected()</slot>
<slot access="protected">startConnect()</slot>
<slot access="protected">progressConnect()</slot>
<slot access="protected">startSearch()</slot>
<slot access="protected">progressSearch()</slot>
<slot access="protected">updateTable()</slot>
<slot access="protected">sort_table_operators(int aSection)</slot>
</slots>
<functions>
<function access="private" specifier="non virtual">init()</function>
<function>gotoPage( int aPageNumber )</function>
<function>stopTimer( TQTimer ** aTimerPtrPtr )</function>
</functions>
<pixmapinproject/>
<layoutdefaults spacing="6" margin="11"/>
</UI>

@ -0,0 +1,444 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/****************************************************************************
** ui.h extension file, included from the uic-generated form implementation.
**
** If you want to add, delete, or rename functions or slots, use
** TQt Designer to update this file, preserving your code.
**
** You should not define a constructor or destructor in this file.
** Instead, write your code in functions called init() and destroy().
** These will automatically be called by the form's constructor and
** destructor.
*****************************************************************************/
#include "umtsmon_global.h"
#include <assert.h>
#include <ntqlistview.h>
enum NetwOpWizardPages
{
WELCOME,
WHOPICKS,
GETNWSTRENGTHS,
SEARCHING,
SELECT,
CONNECTING,
FINISH
};
void NetworkOperatorWizard::init()
{
DEBUG5("NetworkOperatorWizard::init()\n");
myConnectTimer = NULL;
mySearchTimer = NULL;
connect(table_operators->horizontalHeader(), SIGNAL(clicked(int)), this, SLOT(sort_table_operators(int)));
}
void NetworkOperatorWizard::back()
{
DEBUG5("NetworkOperatorWizard::back()\n");
int myCurrentPageNumber = indexOf(currentPage());
assert (myCurrentPageNumber>=0 && myCurrentPageNumber<pageCount());
NetwOpWizardPages myNextPageNumber = WELCOME;
switch (static_cast<NetwOpWizardPages>(myCurrentPageNumber))
{
case WELCOME:
case WHOPICKS:
myNextPageNumber = WELCOME;
break;
case GETNWSTRENGTHS:
myNextPageNumber = WHOPICKS;
break;
case SEARCHING:
// this situation only happens when the startSearch() runs
// into trouble and emits "back".
// therefore:
myNextPageNumber = GETNWSTRENGTHS;
break;
case SELECT:
// skip SEARCHING
myNextPageNumber = GETNWSTRENGTHS;
break;
case CONNECTING:
// this situation only happens when the connect process runs into
// trouble (e.g. timeout)
// therefore:
myNextPageNumber = SELECT;
break;
// should never happen
assert(false);
case FINISH:
if (radioButton_card->isChecked())
// back to where we came from
myNextPageNumber = WHOPICKS;
else
// skip CONNECTING;
myNextPageNumber = SELECT;
break;
};
gotoPage(myNextPageNumber);
}
// under some circumstances, it is possible that calls to next()
// are nested. The code doesn't really know how to cope with it, but
// the side effects are fortunately rather limited :-)
void NetworkOperatorWizard::next()
{
DEBUG5("NetworkOperatorWizard::next()\n");
int myCurrentPageNumber = indexOf(currentPage());
assert (myCurrentPageNumber>=0 && myCurrentPageNumber<pageCount());
NetwOpWizardPages myNextPageNumber = FINISH;
switch (static_cast<NetwOpWizardPages>(myCurrentPageNumber))
{
case WELCOME:
myNextPageNumber = WHOPICKS;
break;
case WHOPICKS:
if (radioButton_card->isChecked())
{
// switch device and finish
if (myNetworkChanger.setCardToAutomatic() == false)
{
Popup::Warning("Switching the device to automatic operator selection failed. Please retry", this);
myNextPageNumber = WHOPICKS;
}
else
myNextPageNumber = FINISH;
break;
}
myNextPageNumber = GETNWSTRENGTHS;
break;
case GETNWSTRENGTHS:
myNextPageNumber = SEARCHING;
break;
case SEARCHING:
myNextPageNumber = SELECT;
break;
case SELECT:
myNextPageNumber = CONNECTING;
break;
case CONNECTING:
myNextPageNumber = FINISH;
break;
case FINISH:
// should never happen
assert(false);
myNextPageNumber = FINISH;
break;
};
gotoPage(myNextPageNumber);
}
void NetworkOperatorWizard::gotoPage(int aPageNumber)
{
assert (aPageNumber>=0 && aPageNumber<pageCount());
showPage(page(aPageNumber));
switch (static_cast<NetwOpWizardPages>(aPageNumber))
{
case WELCOME:
setBackEnabled(currentPage(),false);
break;
case WHOPICKS:
setBackEnabled(currentPage(),true);
switch(myNetworkChanger.getRegistrationState())
{
case NetworkChanger::MANUAL:
case NetworkChanger::MAN_AUTO:
emit radioButton_user->setChecked(true);
break;
case NetworkChanger::DEREGISTER:
case NetworkChanger::SETONLY:
case NetworkChanger::MODE_ERROR:
DEBUG1("Registration mode set to weird stuff\n");
// and walk gracefully into the next one:
case NetworkChanger::AUTOMATIC:
emit radioButton_card->setChecked(true);
break;
}
break;
case GETNWSTRENGTHS:
break;
case SEARCHING:
setBackEnabled(currentPage(),false);
setNextEnabled(currentPage(),false);
emit startSearch();
break;
case SELECT:
setBackEnabled(currentPage(),true);
// will be enabled when the user clicks on a table entry
setNextEnabled(currentPage(),false);
emit updateTable();
break;
case CONNECTING:
setBackEnabled(currentPage(),false);
setNextEnabled(currentPage(),false);
emit startConnect();
break;
case FINISH:
setBackEnabled(currentPage(),true);
setNextEnabled(currentPage(),false);
setFinishEnabled(page(FINISH), true);
break;
};
setHelpEnabled(currentPage(), false);
}
void NetworkOperatorWizard::operatorSelected()
{
DEBUG5("NetworkOperatorWizard::operatorSelected()\n");
// if an operator is FORBIDDEN, don't enable next>
long myID = table_operators->text(table_operators->currentRow(),3).toLong();
Operator* myOp = myNetworkChanger.theOperatorList.findNetworkID(myID);
assert(myOp != NULL);
if (myOp == NULL)
return;
DEBUG5("user picked operator %ld\n", myID);
if (myOp->getIconType()==Operator::FORBIDDEN)
{
Popup::Info("You are not allowed to connect to " + myOp->getNetworkName(), this);
setNextEnabled(currentPage(),false);
}
else
setNextEnabled(currentPage(),true);
}
// 20 seconds = 20/0.3 = 66 steps
static const int MAX_TIMEOUT_CONNECT = 66;
void NetworkOperatorWizard::startConnect()
{
DEBUG5("NetworkOperatorWizard::startConnect()\n");
// We can get the required info from the table - the fourth column
// after all, the user clicked on the line, right?
TQString myID = table_operators->text(table_operators->currentRow(),3);
NetworkChanger::SwitchResults myResults = myNetworkChanger.startSwitchToNetworkID(myID.toLong());
switch(myResults)
{
case NetworkChanger::IS_CURRENT:
case NetworkChanger::OK:
// instant switching, not really likely to happen...
// unless e.g. the user selected the network he's already in
DEBUG5("immediate is current / ok\n");
emit next();
return;
break;
case NetworkChanger::ERROR:
// uh-oh
DEBUG5("immediate error\n");
emit back();
return;
break;
case NetworkChanger::NOT_READY_YET:
// handled outside switch
break;
}
assert(myConnectTimer == NULL);
if (myConnectTimer != NULL)
return;
myConnectCount = 0;
myConnectTimer = new TQTimer(this, "connecttimer");
connect(myConnectTimer, SIGNAL(timeout()), SLOT(progressConnect()));
myConnectTimer->start(300, FALSE);
emit progressConnect();
}
void NetworkOperatorWizard::progressConnect()
{
DEBUG5("NetworkOperatorWizard::progressConnect()\n");
NetworkChanger::SwitchResults myResults = myNetworkChanger.isSwitchCompleted();
switch (myResults)
{
case NetworkChanger::IS_CURRENT:
case NetworkChanger::OK:
// success
stopTimer(&myConnectTimer);
DEBUG5("progress - iscurrent/ok\n");
emit next();
break;
case NetworkChanger::ERROR:
{
// uh-oh
DEBUG5("progress - error\n");
stopTimer(&myConnectTimer);
// one of the arguments of the query should be an ERROR.
TQString myError = myNetworkChanger.getErrorMessage();
myNetworkChanger.stopSearch();
Popup::Warning("The following error occured:\n" + myError, this);
emit back();
break;
}
case NetworkChanger::NOT_READY_YET:
// handled outside switch
break;
}
myConnectCount++;
progressBar_connecting->setProgress(myConnectCount, MAX_TIMEOUT_CONNECT);
if (myConnectCount > MAX_TIMEOUT_CONNECT)
{
stopTimer(&myConnectTimer);
emit next();
}
}
// 150 seconds = 150/0.3 = 500 steps
static const int MAX_TIMEOUT_SEARCH = 500;
void NetworkOperatorWizard::startSearch()
{
DEBUG5("NetworkOperatorWizard::startSearch()\n");
assert(mySearchTimer == NULL);
if (mySearchTimer != NULL)
return;
mySearchCount = 0;
mySearchTimer = new TQTimer(this, "connecttimer");
connect(mySearchTimer, SIGNAL(timeout()), SLOT(progressSearch()));
mySearchTimer->start(300, FALSE);
if (myNetworkChanger.startSearching() == false)
{
// we get here if the card immediately returned with an error,
// e.g. if the PIN code has not been entered or
// if the PIN has not propagated through all of the card's subsystems
// yet - see Bug # 1527401.
stopTimer(&mySearchTimer);
Popup::Warning("The card returned ERROR when asking to start searching. You might want to try again",this);
emit back();
return;
}
emit progressSearch();
}
void NetworkOperatorWizard::progressSearch()
{
DEBUG5("NetworkOperatorWizard::progressSearch()\n");
if (myNetworkChanger.isSearchCompleted())
{
stopTimer(&mySearchTimer);
emit next();
return;
}
mySearchCount++;
progressBar_searching->setProgress(mySearchCount, MAX_TIMEOUT_SEARCH);
if (mySearchCount > MAX_TIMEOUT_SEARCH)
{
stopTimer(&mySearchTimer);
Popup::Warning("The device didn't respond in time - selecting the operator probably failed...",this);
emit back();
}
}
//void NetworkOperatorWizard::startTimer(TQTimer* aTimerPtr, void* aSlot())
//{
// assert(aTimerPtr == NULL);
// if (aTimerPtr != NULL)
// return;
// myConnectCount = 0;
// aTimerPtr = new TQTimer(this, "connecttimer");
// connect(aTimerPtr, SIGNAL(timeout()), SLOT(aSlot));
// aTimerPtr->start(300, FALSE);
//}
void NetworkOperatorWizard::stopTimer(TQTimer** aTimerPtrPtr)
{
(*aTimerPtrPtr)->stop();
delete (*aTimerPtrPtr);
*aTimerPtrPtr = NULL;
}
void NetworkOperatorWizard::updateTable()
{
DEBUG5("NetworkOperatorWizard::updateTable()\n");
// empty the TQTable
while(table_operators->numRows() > 0)
table_operators->removeRow(0);
if (myNetworkChanger.theOperatorList.size()==0)
{
Popup::Info(tr("No network operators were found.\nYou might want to try again."), this);
emit back();
return;
}
// create the pixmaps (will be copied upon entry in the table)
TQPixmap myOK( TQPixmap::fromMimeSource("ok.png") );
TQPixmap myForbidden( TQPixmap::fromMimeSource("process-stop-16x16.png") );
// fill the table
for (TheOperatorListIterator myI=myNetworkChanger.theOperatorList.begin();
myI != myNetworkChanger.theOperatorList.end(); myI++)
{
table_operators->insertRows(0);
table_operators->setText(0,0, (*myI)->getNetworkName() );
table_operators->setText(0,1, (*myI)->getRadioModes() );
table_operators->setText(0,3, TQString::number((*myI)->getNetworkID()) );
switch((*myI)->getIconType())
{
case Operator::NOT_VALID:
case Operator::FORBIDDEN:
table_operators->setPixmap(0, 0, myForbidden);
break;
case Operator::AVAILABLE:
break;
case Operator::CURRENT:
table_operators->setPixmap(0, 0, myOK);
break;
}
}
emit sort_table_operators(0);
}
/**
* SLOT to sort the rows of the table depending on the selected column
* @param the section/column to sort
**/
void NetworkOperatorWizard::sort_table_operators(int aSection)
{
if (table_operators->horizontalHeader()->sortIndicatorOrder() == TQt::Ascending)
{
table_operators->sortColumn(aSection,false,true);
}
else
{
table_operators->sortColumn(aSection,true,true);
}
table_operators->horizontalHeader()->adjustHeaderSize();
}

@ -0,0 +1,169 @@
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
<class>NewProfileDialog</class>
<widget class="TQDialog">
<property name="name">
<cstring>NewProfileDialog</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>346</width>
<height>114</height>
</rect>
</property>
<property name="font">
<font>
</font>
</property>
<property name="caption">
<string>New Profile</string>
</property>
<property name="icon">
<pixmap>document-new-22x22.png</pixmap>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel" row="0" column="0">
<property name="name">
<cstring>textLabel1</cstring>
</property>
<property name="text">
<string>Profile name</string>
</property>
</widget>
<widget class="TQLineEdit" row="0" column="1" rowspan="1" colspan="2">
<property name="name">
<cstring>newProfileName</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>1</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>222</width>
<height>0</height>
</size>
</property>
</widget>
<spacer row="2" column="0">
<property name="name">
<cstring>spacer13</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>5</width>
<height>21</height>
</size>
</property>
</spacer>
<widget class="TQLabel" row="1" column="0" rowspan="1" colspan="3">
<property name="name">
<cstring>labelMessages</cstring>
</property>
<property name="paletteForegroundColor">
<color>
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</property>
<property name="text">
<string>please enter a new profile name</string>
</property>
<property name="alignment">
<set>AlignCenter</set>
</property>
</widget>
<widget class="TQPushButton" row="2" column="1">
<property name="name">
<cstring>pushButtonOK</cstring>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>32767</width>
<height>40</height>
</size>
</property>
<property name="text">
<string>Create</string>
</property>
<property name="default">
<bool>true</bool>
</property>
<property name="iconSet">
<iconset>document-save-22x22.png</iconset>
</property>
</widget>
<widget class="TQPushButton" row="2" column="2">
<property name="name">
<cstring>pushButtonCancel</cstring>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>32767</width>
<height>40</height>
</size>
</property>
<property name="text">
<string>Cancel</string>
</property>
<property name="iconSet">
<iconset>process-stop-16x16.png</iconset>
</property>
</widget>
</grid>
</widget>
<connections>
<connection>
<sender>pushButtonCancel</sender>
<signal>clicked()</signal>
<receiver>NewProfileDialog</receiver>
<slot>reject()</slot>
</connection>
<connection>
<sender>pushButtonOK</sender>
<signal>clicked()</signal>
<receiver>NewProfileDialog</receiver>
<slot>validateProfileName()</slot>
</connection>
</connections>
<tabstops>
<tabstop>newProfileName</tabstop>
<tabstop>pushButtonOK</tabstop>
<tabstop>pushButtonCancel</tabstop>
</tabstops>
<includes>
<include location="local" impldecl="in implementation">newprofiledialog.ui.h</include>
</includes>
<slots>
<slot>validateProfileName()</slot>
</slots>
<pixmapinproject/>
<layoutdefaults spacing="6" margin="11"/>
</UI>

@ -0,0 +1,39 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/****************************************************************************
** ui.h extension file, included from the uic-generated form implementation.
**
** If you want to add, delete, or rename functions or slots, use
** TQt Designer to update this file, preserving your code.
**
** You should not define a constructor or destructor in this file.
** Instead, write your code in functions called init() and destroy().
** These will automatically be called by the form's constructor and
** destructor.
*****************************************************************************/
#include "Profile.h"
void NewProfileDialog::validateProfileName()
{
if (Profile::checkForValidProfileName(newProfileName->text()))
accept();
else
labelMessages->setText(tr("This profile name is invalid, please change."));
}

@ -0,0 +1,136 @@
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
<class>PopupWithMemory</class>
<widget class="TQDialog">
<property name="name">
<cstring>PopupWithMemory</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>362</width>
<height>119</height>
</rect>
</property>
<property name="caption">
<string>MyDialog</string>
</property>
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel">
<property name="name">
<cstring>textLabel</cstring>
</property>
<property name="text">
<string></string>
</property>
<property name="alignment">
<set>AlignCenter</set>
</property>
</widget>
<spacer>
<property name="name">
<cstring>spacer11</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>16</height>
</size>
</property>
</spacer>
<widget class="TQLayoutWidget">
<property name="name">
<cstring>layout12</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQCheckBox">
<property name="name">
<cstring>checkBoxDoNotShowAgain</cstring>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>Do not show this message again</string>
</property>
</widget>
<spacer>
<property name="name">
<cstring>Horizontal Spacing2</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>50</width>
<height>20</height>
</size>
</property>
</spacer>
<widget class="TQPushButton">
<property name="name">
<cstring>buttonOk</cstring>
</property>
<property name="text">
<string>&amp;OK</string>
</property>
<property name="accel">
<string></string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</hbox>
</widget>
</vbox>
</widget>
<connections>
<connection>
<sender>buttonOk</sender>
<signal>clicked()</signal>
<receiver>PopupWithMemory</receiver>
<slot>buttonOk_clicked()</slot>
</connection>
</connections>
<includes>
<include location="local" impldecl="in implementation">TheSettingsSingleton.h</include>
<include location="global" impldecl="in implementation">assert.h</include>
<include location="local" impldecl="in implementation">popupwithmemory.ui.h</include>
</includes>
<variables>
<variable>TQString theUniqueName;</variable>
</variables>
<slots>
<slot>buttonOk_clicked()</slot>
</slots>
<functions>
<function returnType="bool">setMemoryName( const TQString aName )</function>
</functions>
<pixmapinproject/>
<layoutdefaults spacing="6" margin="11"/>
</UI>

@ -0,0 +1,50 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/****************************************************************************
** ui.h extension file, included from the uic-generated form implementation.
**
** If you want to add, delete, or rename functions or slots, use
** TQt Designer to update this file, preserving your code.
**
** You should not define a constructor or destructor in this file.
** Instead, write your code in functions called init() and destroy().
** These will automatically be called by the form's constructor and
** destructor.
*****************************************************************************/
bool PopupWithMemory::setMemoryName(const TQString aName)
{
assert( !aName.isEmpty() );
theUniqueName = "/ShowPopupWithMemory/" + aName + ".showagain";
// true means we are going to show the dialog
return TheSettingsSingleton::getTQSRef().readBoolEntry( theUniqueName, true);
}
void PopupWithMemory::buttonOk_clicked()
{
// if box is checked, that means the user doesn't want to see the box again
// i.e. we need to write false
assert( !theUniqueName.isEmpty() );
TheSettingsSingleton::getTQSRef().writeEntry( theUniqueName, checkBoxDoNotShowAgain->isChecked()==false);
accept();
}

@ -0,0 +1,934 @@
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
<class>profiledialog</class>
<widget class="TQDialog">
<property name="name">
<cstring>profiledialog</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>395</width>
<height>523</height>
</rect>
</property>
<property name="caption">
<string>Edit Profile</string>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<spacer row="2" column="0">
<property name="name">
<cstring>spacer72_2</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>16</width>
<height>21</height>
</size>
</property>
</spacer>
<spacer row="1" column="0">
<property name="name">
<cstring>spacer72</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>16</width>
<height>21</height>
</size>
</property>
</spacer>
<widget class="TQLayoutWidget" row="0" column="0" rowspan="1" colspan="2">
<property name="name">
<cstring>layout9</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel">
<property name="name">
<cstring>lbl_current_profile</cstring>
</property>
<property name="text">
<string>Profile Name:</string>
</property>
</widget>
<widget class="TQLineEdit">
<property name="name">
<cstring>lineEdit_profile_name</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="acceptDrops">
<bool>false</bool>
</property>
<property name="dragEnabled">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
<spacer>
<property name="name">
<cstring>spacer13</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>181</width>
<height>21</height>
</size>
</property>
</spacer>
</hbox>
</widget>
<widget class="TQGroupBox" row="1" column="1">
<property name="name">
<cstring>groupBox2</cstring>
</property>
<property name="title">
<string>login</string>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLayoutWidget">
<property name="name">
<cstring>layout20</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel">
<property name="name">
<cstring>textLabel2_5</cstring>
</property>
<property name="text">
<string>APN</string>
</property>
</widget>
<widget class="TQLineEdit">
<property name="name">
<cstring>connection_apn</cstring>
</property>
<property name="text">
<string></string>
</property>
</widget>
<widget class="TQPushButton">
<property name="name">
<cstring>pushButtonLoginHelp</cstring>
</property>
<property name="text">
<string></string>
</property>
<property name="pixmap">
<pixmap>help-browser-16x16.png</pixmap>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</hbox>
</widget>
<widget class="TQLayoutWidget">
<property name="name">
<cstring>layout21</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel">
<property name="name">
<cstring>textLabel2_3</cstring>
</property>
<property name="text">
<string>Username</string>
</property>
</widget>
<widget class="TQLineEdit">
<property name="name">
<cstring>connection_username</cstring>
</property>
<property name="toolTip" stdset="0">
<string>if your operator requires a username, fill it in here.&lt;br&gt;If not, you probably want to put something dummy in here.</string>
</property>
</widget>
<widget class="TQLabel">
<property name="name">
<cstring>textLabel2_4</cstring>
</property>
<property name="text">
<string>Password</string>
</property>
</widget>
<widget class="TQLineEdit">
<property name="name">
<cstring>connection_password</cstring>
</property>
<property name="frameShape">
<enum>LineEditPanel</enum>
</property>
<property name="frameShadow">
<enum>Sunken</enum>
</property>
<property name="echoMode">
<enum>Password</enum>
</property>
<property name="toolTip" stdset="0">
<string>if your operator requires a password, fill it in here.&lt;br&gt;If not, you probably want to put something dummy in here.</string>
</property>
</widget>
</hbox>
</widget>
</vbox>
</widget>
<spacer row="4" column="0">
<property name="name">
<cstring>spacer11</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>16</width>
<height>20</height>
</size>
</property>
</spacer>
<widget class="TQLayoutWidget" row="5" column="0" rowspan="1" colspan="2">
<property name="name">
<cstring>layout8</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<spacer>
<property name="name">
<cstring>spacer14</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>251</width>
<height>21</height>
</size>
</property>
</spacer>
<widget class="TQPushButton">
<property name="name">
<cstring>pushButtonSaveProfile</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&amp;Save</string>
</property>
<property name="accel">
<string>Alt+S</string>
</property>
<property name="toolTip" stdset="0">
<string>Save the changes to the profile.&lt;br&gt;Only enabled if there are changes &lt;b&gt;and&lt;/b&gt; you have entered a valid APN.</string>
</property>
</widget>
<widget class="TQPushButton">
<property name="name">
<cstring>buttonCancel</cstring>
</property>
<property name="text">
<string>&amp;Cancel</string>
</property>
<property name="accel">
<string></string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
</hbox>
</widget>
<widget class="TQGroupBox" row="2" column="1">
<property name="name">
<cstring>groupBox1</cstring>
</property>
<property name="title">
<string>advanced PPP Options</string>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<spacer row="3" column="0">
<property name="name">
<cstring>spacer20</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>16</height>
</size>
</property>
</spacer>
<widget class="TQCheckBox" row="0" column="0">
<property name="name">
<cstring>connection_noAuth</cstring>
</property>
<property name="text">
<string>noauth</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="toolTip" stdset="0">
<string>Do not require the remote server to authenticate itself. This option is privileged. Usually disabled.</string>
</property>
</widget>
<widget class="TQCheckBox" row="1" column="0">
<property name="name">
<cstring>connection_routing_noipdefault</cstring>
</property>
<property name="text">
<string>no ip default</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="toolTip" stdset="0">
<string>If enabled, the remote server must supply you an IP Address. Usually disabled.</string>
</property>
</widget>
<widget class="TQCheckBox" row="2" column="0">
<property name="name">
<cstring>connection_routing_replaceDefaultRoute</cstring>
</property>
<property name="text">
<string>replace default route</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
<property name="toolTip" stdset="0">
<string>Use the connection for all network traffic when connected. Usually enabled.</string>
</property>
</widget>
<widget class="TQCheckBox" row="2" column="1">
<property name="name">
<cstring>connection_routing_defaultroute</cstring>
</property>
<property name="text">
<string>set default route</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="toolTip" stdset="0">
<string>Add a default route to the remote server if connected. Usually enabled.</string>
</property>
</widget>
<widget class="TQCheckBox" row="0" column="1">
<property name="name">
<cstring>connection_noCompression</cstring>
</property>
<property name="text">
<string>no header compression</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="toolTip" stdset="0">
<string>Header Compression saves a few byte per data packet by skipping information that is already known by the peer. ALWAYS ENABLED.</string>
</property>
</widget>
<widget class="TQCheckBox" row="1" column="1">
<property name="name">
<cstring>connection_noCCP</cstring>
</property>
<property name="text">
<string>no CCP</string>
</property>
<property name="toolTip" stdset="0">
<string>Do not negotiate the Compression Control Protocol. Usually disabled - only needed for buggy operators.</string>
</property>
</widget>
<widget class="TQCheckBox" row="3" column="1">
<property name="name">
<cstring>connection_routing_usepeerdns</cstring>
</property>
<property name="text">
<string>use peer DNS</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="toolTip" stdset="0">
<string>Receive DNS-settings from your Provider. Usually enabled.</string>
</property>
</widget>
</grid>
</widget>
<widget class="TQGroupBox" row="4" column="1">
<property name="name">
<cstring>groupBox3</cstring>
</property>
<property name="title">
<string>monthly data or time limits</string>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLayoutWidget" row="0" column="0" rowspan="1" colspan="3">
<property name="name">
<cstring>layout5</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQCheckBox">
<property name="name">
<cstring>checkBox_warn_data_threshold</cstring>
</property>
<property name="text">
<string>warn when threshold is reached:</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
<widget class="TQSpinBox">
<property name="name">
<cstring>spinBox_data_treshold</cstring>
</property>
<property name="maxValue">
<number>100</number>
</property>
<property name="minValue">
<number>50</number>
</property>
<property name="value">
<number>90</number>
</property>
<property name="toolTip" stdset="0">
<string>min 50%, max 100%</string>
</property>
</widget>
<widget class="TQLabel">
<property name="name">
<cstring>textLabel5</cstring>
</property>
<property name="text">
<string>%</string>
</property>
</widget>
<spacer>
<property name="name">
<cstring>spacer7</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</hbox>
</widget>
<widget class="TQLayoutWidget" row="2" column="2">
<property name="name">
<cstring>layout9</cstring>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<spacer row="0" column="0">
<property name="name">
<cstring>spacer8_2</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>16</width>
<height>20</height>
</size>
</property>
</spacer>
<widget class="TQLabel" row="1" column="3">
<property name="name">
<cstring>textLabel4_2</cstring>
</property>
<property name="text">
<string>min/month</string>
</property>
</widget>
<widget class="TQSpinBox" row="1" column="2">
<property name="name">
<cstring>spinBox_roaming_time_limit</cstring>
</property>
<property name="maxValue">
<number>99999</number>
</property>
<property name="lineStep">
<number>1000</number>
</property>
<property name="toolTip" stdset="0">
<string>If your subscription is time based,&lt;br&gt;enter the number of minutes whilst roaming per month here.</string>
</property>
</widget>
<widget class="TQLabel" row="0" column="1">
<property name="name">
<cstring>textLabel1_2</cstring>
</property>
<property name="text">
<string>home network:</string>
</property>
<property name="toolTip" stdset="0">
<string>Please enter the megabytes per month that is part of your subscription. This field is for your home network.</string>
</property>
</widget>
<widget class="TQSpinBox" row="0" column="2">
<property name="name">
<cstring>spinBox_home_time_limit</cstring>
</property>
<property name="maxValue">
<number>99999</number>
</property>
<property name="lineStep">
<number>1000</number>
</property>
<property name="toolTip" stdset="0">
<string>If your subscription is time based,&lt;br&gt;enter the number of minutes for your home network per month here.</string>
</property>
</widget>
<spacer row="1" column="0">
<property name="name">
<cstring>spacer9_2</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>16</width>
<height>20</height>
</size>
</property>
</spacer>
<widget class="TQLabel" row="0" column="3">
<property name="name">
<cstring>textLabel3_2</cstring>
</property>
<property name="text">
<string>min/month</string>
</property>
</widget>
<widget class="TQLabel" row="1" column="1">
<property name="name">
<cstring>textLabel2_2</cstring>
</property>
<property name="text">
<string>roaming:</string>
</property>
</widget>
</grid>
</widget>
<widget class="TQLayoutWidget" row="1" column="2">
<property name="name">
<cstring>layout8</cstring>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQSpinBox" row="1" column="2">
<property name="name">
<cstring>spinBox_roaming_data_limit</cstring>
</property>
<property name="maxValue">
<number>99999</number>
</property>
<property name="lineStep">
<number>1000</number>
</property>
<property name="toolTip" stdset="0">
<string>Please enter the megabytes per month that is part of your subscription. This field is for when you are outside your home network - also called roaming.</string>
</property>
</widget>
<widget class="TQLabel" row="1" column="1">
<property name="name">
<cstring>textLabel2</cstring>
</property>
<property name="text">
<string>roaming:</string>
</property>
</widget>
<widget class="TQSpinBox" row="0" column="2">
<property name="name">
<cstring>spinBox_home_data_limit</cstring>
</property>
<property name="maxValue">
<number>99999</number>
</property>
<property name="lineStep">
<number>1000</number>
</property>
<property name="toolTip" stdset="0">
<string>Please enter the megabytes per month that is part of your subscription. This field is for your home network.</string>
</property>
</widget>
<widget class="TQLabel" row="1" column="3">
<property name="name">
<cstring>textLabel4</cstring>
</property>
<property name="text">
<string>MiB/month</string>
</property>
</widget>
<spacer row="0" column="0">
<property name="name">
<cstring>spacer8</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>16</width>
<height>20</height>
</size>
</property>
</spacer>
<widget class="TQLabel" row="0" column="1">
<property name="name">
<cstring>textLabel1</cstring>
</property>
<property name="text">
<string>home network:</string>
</property>
</widget>
<spacer row="1" column="0">
<property name="name">
<cstring>spacer9</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>16</width>
<height>20</height>
</size>
</property>
</spacer>
<widget class="TQLabel" row="0" column="3">
<property name="name">
<cstring>textLabel3</cstring>
</property>
<property name="text">
<string>MiB/month</string>
</property>
</widget>
</grid>
</widget>
<spacer row="2" column="0">
<property name="name">
<cstring>spacer10_2</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
<widget class="TQLabel" row="2" column="1">
<property name="name">
<cstring>textLabel2_6</cstring>
</property>
<property name="text">
<string>Time:</string>
</property>
</widget>
<widget class="TQLabel" row="1" column="1">
<property name="name">
<cstring>textLabel1_3</cstring>
</property>
<property name="text">
<string>Traffic:</string>
</property>
</widget>
<spacer row="1" column="0">
<property name="name">
<cstring>spacer10</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>32</width>
<height>20</height>
</size>
</property>
</spacer>
</grid>
</widget>
<spacer row="3" column="1">
<property name="name">
<cstring>spacer15</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>16</height>
</size>
</property>
</spacer>
</grid>
</widget>
<connections>
<connection>
<sender>pushButtonLoginHelp</sender>
<signal>clicked()</signal>
<receiver>profiledialog</receiver>
<slot>pushButtonLoginHelp_clicked()</slot>
</connection>
<connection>
<sender>connection_apn</sender>
<signal>textChanged(const TQString&amp;)</signal>
<receiver>profiledialog</receiver>
<slot>check_apn(const TQString&amp;)</slot>
</connection>
<connection>
<sender>connection_noAuth</sender>
<signal>stateChanged(int)</signal>
<receiver>profiledialog</receiver>
<slot>dataChanged()</slot>
</connection>
<connection>
<sender>connection_noCompression</sender>
<signal>stateChanged(int)</signal>
<receiver>profiledialog</receiver>
<slot>dataChanged()</slot>
</connection>
<connection>
<sender>connection_password</sender>
<signal>textChanged(const TQString&amp;)</signal>
<receiver>profiledialog</receiver>
<slot>dataChanged()</slot>
</connection>
<connection>
<sender>connection_routing_defaultroute</sender>
<signal>stateChanged(int)</signal>
<receiver>profiledialog</receiver>
<slot>dataChanged()</slot>
</connection>
<connection>
<sender>connection_routing_noipdefault</sender>
<signal>stateChanged(int)</signal>
<receiver>profiledialog</receiver>
<slot>dataChanged()</slot>
</connection>
<connection>
<sender>connection_routing_replaceDefaultRoute</sender>
<signal>stateChanged(int)</signal>
<receiver>profiledialog</receiver>
<slot>dataChanged()</slot>
</connection>
<connection>
<sender>connection_routing_usepeerdns</sender>
<signal>stateChanged(int)</signal>
<receiver>profiledialog</receiver>
<slot>dataChanged()</slot>
</connection>
<connection>
<sender>connection_username</sender>
<signal>textChanged(const TQString&amp;)</signal>
<receiver>profiledialog</receiver>
<slot>dataChanged()</slot>
</connection>
<connection>
<sender>buttonCancel</sender>
<signal>clicked()</signal>
<receiver>profiledialog</receiver>
<slot>pushButton_Cancel_clicked()</slot>
</connection>
<connection>
<sender>pushButtonSaveProfile</sender>
<signal>clicked()</signal>
<receiver>profiledialog</receiver>
<slot>pushButtonSaveProfile_clicked()</slot>
</connection>
<connection>
<sender>spinBox_data_treshold</sender>
<signal>valueChanged(int)</signal>
<receiver>profiledialog</receiver>
<slot>dataChanged()</slot>
</connection>
<connection>
<sender>checkBox_warn_data_threshold</sender>
<signal>stateChanged(int)</signal>
<receiver>profiledialog</receiver>
<slot>dataChanged()</slot>
</connection>
<connection>
<sender>connection_noCCP</sender>
<signal>stateChanged(int)</signal>
<receiver>profiledialog</receiver>
<slot>dataChanged()</slot>
</connection>
<connection>
<sender>spinBox_home_data_limit</sender>
<signal>valueChanged(int)</signal>
<receiver>profiledialog</receiver>
<slot>dataChanged()</slot>
</connection>
<connection>
<sender>spinBox_roaming_data_limit</sender>
<signal>valueChanged(int)</signal>
<receiver>profiledialog</receiver>
<slot>dataChanged()</slot>
</connection>
<connection>
<sender>spinBox_home_time_limit</sender>
<signal>valueChanged(int)</signal>
<receiver>profiledialog</receiver>
<slot>dataChanged()</slot>
</connection>
<connection>
<sender>spinBox_roaming_time_limit</sender>
<signal>valueChanged(int)</signal>
<receiver>profiledialog</receiver>
<slot>dataChanged()</slot>
</connection>
</connections>
<tabstops>
<tabstop>lineEdit_profile_name</tabstop>
<tabstop>connection_apn</tabstop>
<tabstop>pushButtonLoginHelp</tabstop>
<tabstop>connection_username</tabstop>
<tabstop>connection_password</tabstop>
<tabstop>connection_noAuth</tabstop>
<tabstop>connection_noCompression</tabstop>
<tabstop>connection_routing_noipdefault</tabstop>
<tabstop>connection_noCCP</tabstop>
<tabstop>connection_routing_replaceDefaultRoute</tabstop>
<tabstop>connection_routing_defaultroute</tabstop>
<tabstop>connection_routing_usepeerdns</tabstop>
<tabstop>checkBox_warn_data_threshold</tabstop>
<tabstop>spinBox_data_treshold</tabstop>
<tabstop>spinBox_home_data_limit</tabstop>
<tabstop>spinBox_roaming_data_limit</tabstop>
<tabstop>spinBox_home_time_limit</tabstop>
<tabstop>spinBox_roaming_time_limit</tabstop>
<tabstop>pushButtonSaveProfile</tabstop>
<tabstop>buttonCancel</tabstop>
</tabstops>
<includes>
<include location="local" impldecl="in declaration">Profile.h</include>
<include location="local" impldecl="in declaration">newprofiledialog.h</include>
<include location="local" impldecl="in implementation">profiledialog.ui.h</include>
</includes>
<forwards>
<forward>class Profile;</forward>
</forwards>
<variables>
<variable access="private">Profile theProfile;</variable>
</variables>
<slots>
<slot>pushButtonSaveProfile_clicked()</slot>
<slot>pushButton_Cancel_clicked()</slot>
<slot>pushButtonLoginHelp_clicked()</slot>
<slot>enableButtonSaveProfile()</slot>
<slot>disableButtonSaveProfile()</slot>
<slot>updateCurrentProfile()</slot>
<slot>dataChanged()</slot>
<slot>check_apn( const TQString &amp; )</slot>
</slots>
<functions>
<function specifier="non virtual" returnType="bool">setProfile( TQString aProfileName )</function>
<function access="private" specifier="non virtual" returnType="bool">checkForUnsavedData()</function>
<function access="private" returnType="bool">testAPN( const TQString &amp; )</function>
</functions>
<pixmapinproject/>
<layoutdefaults spacing="6" margin="11"/>
</UI>

@ -0,0 +1,198 @@
/* profiledialog
* Copyright (C) 2006 Christofer Wesseling
* Copyright (C) 2007,2008 Christofer Wesseling, Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/****************************************************************************
** ui.h extension file, included from the uic-generated form implementation.
**
** If you want to add, delete, or rename functions or slots, use
** TQt Designer to update this file, preserving your code.
**
** You should not define a constructor or destructor in this file.
** Instead, write your code in functions called init() and destroy().
** These will automatically be called by the form's constructor and
** destructor.
*****************************************************************************/
#include "umtsmon_global.h"
#include "Popup.h"
#include <assert.h>
// load the Data into the Dialog:
bool profiledialog::setProfile(TQString aProfileName)
{
assert(aProfileName.isEmpty()==false);
// FIXME: Add check if aProfileName actually exists
theProfile = Profile(aProfileName);
// set the fields/checkboxen using the getters defaults from Profile...
updateCurrentProfile();
return true;
}
void profiledialog::pushButtonSaveProfile_clicked()
{
// do we have a username/password set?
// if not: let's warn the user.
if (connection_username->text().stripWhiteSpace().isEmpty() ||
connection_password->text().stripWhiteSpace().isEmpty())
{
// FIXME: a yes-no question with memory would work better here...
Popup::WarningWithMemory(tr("empty user/pass"),
tr("Are you sure you want to leave username or password empty?<br>"
"If you do not specify a username and/or password, "
"connection with the operator may not work as expected.<br>"
"Most operators expect dummy (but non-empty) values here.") , this);
}
// is this the only profile? then set it as current profile
if (Profile::getProfileList().empty())
Profile::setActiveProfile(theProfile.getProfileName());
//lets send the settings to de Profile... :)
theProfile.setAPN(connection_apn->text().stripWhiteSpace());
theProfile.setUsername(connection_username->text().stripWhiteSpace());
theProfile.setPassword(connection_password->text().stripWhiteSpace());
theProfile.setNoIpDefault(connection_routing_noipdefault->isChecked());
theProfile.setIsDefaultRoute(connection_routing_defaultroute->isChecked());
theProfile.setReplaceDefaultRoute(connection_routing_replaceDefaultRoute->isChecked());
theProfile.setUsePeerDns(connection_routing_usepeerdns->isChecked());
theProfile.setNoCompression(connection_noCompression->isChecked());
theProfile.setNoCCP(connection_noCCP->isChecked());
theProfile.setNoAuth(connection_noAuth->isChecked());
theProfile.setWarnOnDataThreshold(checkBox_warn_data_threshold->isChecked());
theProfile.setThresholdPercentage(spinBox_data_treshold->value());
theProfile.setHomeDataLimit(spinBox_home_data_limit->value());
theProfile.setRoamingDataLimit(spinBox_roaming_data_limit->value());
theProfile.setHomeTimeLimit(spinBox_home_time_limit->value());
theProfile.setRoamingTimeLimit(spinBox_roaming_time_limit->value());
theProfile.save();
accept();
}
void profiledialog::pushButton_Cancel_clicked()
{
if (checkForUnsavedData())
reject();
}
void profiledialog::pushButtonLoginHelp_clicked()
{
Popup::Info(TQObject::tr("<p align=\"center\"><b>APN info</b></p> <p align=\"left\">For internet-connection, most providers accept an empty APN-Name.<br>So you'll <b>not</b> have to fill in APN, username,password.</p> <p align=\"center\">If your provider requires an APN, you can find a list of those here:<br> <b>http://www.pinstack.com/carrier_settings_apn_gateway.html</b></p> <p align=\"left\">For Private APNs, please ask your provider for support!</p>"),this);
}
void profiledialog::enableButtonSaveProfile()
{
if (testAPN(connection_apn->text()))
pushButtonSaveProfile->setEnabled(true);
}
void profiledialog::disableButtonSaveProfile()
{
pushButtonSaveProfile->setEnabled(false);
}
void profiledialog::updateCurrentProfile()
{
//set the fields, getting defaults from Profile...
lineEdit_profile_name->setText(theProfile.getProfileName());
connection_username->setText( theProfile.getUsername() );
connection_password->setText( theProfile.getPassword() );
connection_apn->setText( theProfile.getAPN() );
connection_routing_noipdefault->setChecked(theProfile.getNoIpDefault());
connection_routing_defaultroute->setChecked(theProfile.getIsDefaultRoute());
connection_noCompression->setChecked(theProfile.getNoCompression());
connection_noCCP->setChecked(theProfile.getNoCCP());
connection_noAuth->setChecked(theProfile.getNoAuth());
connection_routing_replaceDefaultRoute->setChecked(theProfile.getReplaceDefaultRoute());
connection_routing_usepeerdns->setChecked(theProfile.getUsePeerDns());
checkBox_warn_data_threshold->setChecked(theProfile.getWarnOnDataThreshold());
spinBox_data_treshold->setValue(theProfile.getThresholdPercentage());
spinBox_home_data_limit->setValue(theProfile.getHomeDataLimit());
spinBox_roaming_data_limit->setValue(theProfile.getRoamingDataLimit());
spinBox_home_time_limit->setValue(theProfile.getHomeTimeLimit());
spinBox_roaming_time_limit->setValue(theProfile.getRoamingTimeLimit());
disableButtonSaveProfile();
}
/** checks if there is unsaved data and pops up a warning if so
* @returns true if ok to continue (i.e. loose unsaved data)
* false if user asked to not continue
*/
bool profiledialog::checkForUnsavedData()
{
// only accept if no unsaved changes or the user says OK.
if (pushButtonSaveProfile->isEnabled())
{
if (TQMessageBox::warning (this,
tr(APPNAME " warning"),
tr("There are unsaved changes to your profile!"),
TQMessageBox::Ignore,
TQMessageBox::Cancel | TQMessageBox::Default,
TQMessageBox::NoButton) == TQMessageBox::Ignore)
{
return true;
}
}
else
return true;
return false;
}
void profiledialog::dataChanged()
{
DEBUG2("data of the profile has changed\n");
emit enableButtonSaveProfile();
}
/// slot: called by the line edit to verify if the value is ok
void profiledialog::check_apn( const TQString& aNewAPN)
{
if (testAPN(aNewAPN))
emit dataChanged();
else
emit disableButtonSaveProfile();
}
/// actual check whether the APN is correct
bool profiledialog::testAPN(const TQString& aNewAPN)
{
if ( aNewAPN.stripWhiteSpace().isEmpty())
return false;
if ( aNewAPN.contains("\"") || aNewAPN.contains("\"") ||
aNewAPN.contains("'") || aNewAPN.contains(" ") )
{
Popup::Warning(tr("Your APN contains illegal characters.\nYou cannot save your profile until you fix this."));
return false;
}
return true;
}

@ -0,0 +1,187 @@
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
<class>RadioPreferences</class>
<widget class="TQDialog">
<property name="name">
<cstring>RadioPreferences</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>397</width>
<height>111</height>
</rect>
</property>
<property name="caption">
<string>Radio Preferences</string>
</property>
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLayoutWidget">
<property name="name">
<cstring>layout19</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel">
<property name="name">
<cstring>textLabelRadioTypes</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Limit radio types:</string>
</property>
</widget>
<widget class="TQComboBox">
<property name="name">
<cstring>comboBoxRadioTypes</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip" stdset="0">
<string>if your card supports this feature, you can limit the card to a certain radio technology. This is useful if you have a fringe coverage, e.g. the card is jumping between UMTS and GPRS because neither is really strong.</string>
</property>
</widget>
</hbox>
</widget>
<widget class="TQLabel">
<property name="name">
<cstring>textLabelRadioExplanation</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>(changing radio types whilst a PPP connection exists will fail)</string>
</property>
</widget>
<spacer>
<property name="name">
<cstring>spacer4</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>16</height>
</size>
</property>
</spacer>
<widget class="TQLayoutWidget">
<property name="name">
<cstring>Layout1</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<property name="margin">
<number>0</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<spacer>
<property name="name">
<cstring>Horizontal Spacing2</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
<widget class="TQPushButton">
<property name="name">
<cstring>buttonOk</cstring>
</property>
<property name="text">
<string>&amp;OK</string>
</property>
<property name="accel">
<string></string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
<widget class="TQPushButton">
<property name="name">
<cstring>buttonCancel</cstring>
</property>
<property name="text">
<string>&amp;Cancel</string>
</property>
<property name="accel">
<string></string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
</hbox>
</widget>
</vbox>
</widget>
<connections>
<connection>
<sender>buttonOk</sender>
<signal>clicked()</signal>
<receiver>RadioPreferences</receiver>
<slot>accept()</slot>
</connection>
<connection>
<sender>buttonCancel</sender>
<signal>clicked()</signal>
<receiver>RadioPreferences</receiver>
<slot>reject()</slot>
</connection>
<connection>
<sender>comboBoxRadioTypes</sender>
<signal>activated(int)</signal>
<receiver>RadioPreferences</receiver>
<slot>comboBoxRadioType_activated(int)</slot>
</connection>
</connections>
<includes>
<include location="local" impldecl="in implementation">radiopreferences.ui.h</include>
</includes>
<signals>
<signal>autoUpdateChanged()</signal>
</signals>
<slots>
<slot>loadSettings()</slot>
<slot>saveSettings()</slot>
<slot>comboBoxRadioType_activated( int anEntry )</slot>
</slots>
<functions>
<function>init()</function>
</functions>
<pixmapinproject/>
<layoutdefaults spacing="6" margin="11"/>
</UI>

@ -0,0 +1,89 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2007, 2009 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/****************************************************************************
** ui.h extension file, included from the uic-generated form implementation.
**
** If you want to add, delete, or rename functions or slots, use
** TQt Designer to update this file, preserving your code.
**
** You should not define a constructor or destructor in this file.
** Instead, write your code in functions called init() and destroy().
** These will automatically be called by the form's constructor and
** destructor.
*****************************************************************************/
#include "umtsmon_global.h"
#include "radiopreferences_defines.h"
#include "TheDeviceManagerSingleton.h"
#include "TheSettingsSingleton.h"
#include "Popup.h"
void RadioPreferences::init()
{
loadSettings();
}
void RadioPreferences::loadSettings()
{
DEBUG5("RadioPreferences::loadSettings()\n");
// do we have radio type settings anyway?
DeviceRadioCapabilities& theDRCRef = TheDeviceManagerSingleton::getDeviceRadioCapsRef();
bool hasRadio = theDRCRef.hasRadioPreferences();
comboBoxRadioTypes->setEnabled(hasRadio);
textLabelRadioExplanation->setEnabled(hasRadio);
textLabelRadioTypes->setEnabled(hasRadio);
// and populate the combobox in that case...
if (hasRadio)
{
DEBUG4("***Has Radio Preferences\n");
comboBoxRadioTypes->clear();
comboBoxRadioTypes->insertStringList(theDRCRef.getRadioPreferences());
comboBoxRadioTypes->setCurrentItem(
TheSettingsSingleton::getTQSRef().readNumEntry(
THE_RADIO_PREF_ROOT_NAME THE_RADIOTYPE_SETTING,
theDRCRef.getDefaultRadioPreference()));
}
}
void RadioPreferences::saveSettings()
{
// writing the setting only makes sense when we have one...
if (TheDeviceManagerSingleton::getDeviceRadioCapsRef().hasRadioPreferences())
{
TheSettingsSingleton::getTQSRef().writeEntry(
THE_RADIO_PREF_ROOT_NAME THE_RADIOTYPE_SETTING,
comboBoxRadioTypes->currentItem());
}
}
void RadioPreferences::comboBoxRadioType_activated(int anEntry)
{
DEBUG5("RadioPrefs::comboBoxRadioType_activated: currently selected: '%s' is %d - %d\n\n",
comboBoxRadioTypes->currentText().ascii(),
comboBoxRadioTypes->currentItem(), anEntry);
if (!TheDeviceManagerSingleton::getDeviceRadioCapsRef().setRadioPreferences(anEntry))
{
Popup::Warning(tr("Failed to set your radio technology preference."), this);
}
}

@ -0,0 +1,26 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2007, 2009 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef RADIOPREFERENCES_DEFINES
#define RADIOPREFERENCES_DEFINES
#define THE_RADIO_PREF_ROOT_NAME "/RadioSettings"
#define THE_RADIOTYPE_SETTING "/Radiotype"
#endif // RADIOPREFERENCES_DEFINES

@ -0,0 +1,353 @@
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
<class>smsdialog</class>
<widget class="TQDialog">
<property name="name">
<cstring>smsdialog</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>423</width>
<height>284</height>
</rect>
</property>
<property name="caption">
<string>Send SMS</string>
</property>
<property name="icon">
<pixmap>mail-message-new-16x16.png</pixmap>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLayoutWidget" row="0" column="0" rowspan="1" colspan="2">
<property name="name">
<cstring>layout61</cstring>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel">
<property name="name">
<cstring>textLabel1</cstring>
</property>
<property name="text">
<string>Send SMS to number:</string>
</property>
</widget>
<widget class="TQLineEdit">
<property name="name">
<cstring>smsToNumber</cstring>
</property>
<property name="minimumSize">
<size>
<width>116</width>
<height>20</height>
</size>
</property>
<property name="text">
<string></string>
</property>
<property name="toolTip" stdset="0">
<string>enter the number to SMS to here</string>
</property>
</widget>
</vbox>
</widget>
<widget class="TQLayoutWidget" row="0" column="4" rowspan="1" colspan="3">
<property name="name">
<cstring>layout65</cstring>
</property>
<grid>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLayoutWidget" row="1" column="0">
<property name="name">
<cstring>layout63</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLineEdit">
<property name="name">
<cstring>smsCharInMessages</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>0</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>20</height>
</size>
</property>
<property name="focusPolicy">
<enum>NoFocus</enum>
</property>
<property name="acceptDrops">
<bool>false</bool>
</property>
<property name="frameShape">
<enum>LineEditPanel</enum>
</property>
<property name="frameShadow">
<enum>Sunken</enum>
</property>
<property name="text">
<string>0</string>
</property>
<property name="dragEnabled">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="toolTip" stdset="0">
<string>The number of characters in your message</string>
</property>
</widget>
<widget class="TQLabel">
<property name="name">
<cstring>textLabel3</cstring>
</property>
<property name="text">
<string>/</string>
</property>
</widget>
<widget class="TQLineEdit">
<property name="name">
<cstring>smsCharLeft</cstring>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>0</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>20</height>
</size>
</property>
<property name="focusPolicy">
<enum>NoFocus</enum>
</property>
<property name="acceptDrops">
<bool>false</bool>
</property>
<property name="text">
<string>162</string>
</property>
<property name="dragEnabled">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="toolTip" stdset="0">
<string>The number of characters left to send in this message</string>
</property>
</widget>
</hbox>
</widget>
<widget class="TQLabel" row="0" column="0">
<property name="name">
<cstring>textLabel2_2</cstring>
</property>
<property name="text">
<string>Characters typed / left:</string>
</property>
</widget>
</grid>
</widget>
<spacer row="0" column="2" rowspan="1" colspan="2">
<property name="name">
<cstring>spacer32</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>110</width>
<height>21</height>
</size>
</property>
</spacer>
<widget class="TQLabel" row="1" column="0">
<property name="name">
<cstring>textLabel2</cstring>
</property>
<property name="text">
<string>Message:</string>
</property>
</widget>
<spacer row="1" column="1" rowspan="1" colspan="6">
<property name="name">
<cstring>spacer82</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>321</width>
<height>20</height>
</size>
</property>
</spacer>
<widget class="TQTextEdit" row="2" column="0" rowspan="1" colspan="7">
<property name="name">
<cstring>smsMessage</cstring>
</property>
<property name="enabled">
<bool>true</bool>
</property>
<property name="acceptDrops">
<bool>true</bool>
</property>
<property name="hScrollBarMode">
<enum>AlwaysOff</enum>
</property>
<property name="textFormat">
<enum>PlainText</enum>
</property>
<property name="wordWrap">
<enum>WidgetWidth</enum>
</property>
<property name="toolTip" stdset="0">
<string>enter your SMS message here, max 162 characters</string>
</property>
</widget>
<widget class="TQPushButton" row="3" column="5">
<property name="name">
<cstring>pushButtonClear</cstring>
</property>
<property name="text">
<string>Clea&amp;r</string>
</property>
<property name="iconSet">
<iconset>user-trash-full-16x16.png</iconset>
</property>
</widget>
<widget class="TQPushButton" row="3" column="3" rowspan="1" colspan="2">
<property name="name">
<cstring>pushButtonSendSMS</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&amp;Send</string>
</property>
<property name="iconSet">
<iconset>mail-message-new-16x16.png</iconset>
</property>
</widget>
<spacer row="3" column="0" rowspan="1" colspan="3">
<property name="name">
<cstring>spacer31</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>150</width>
<height>21</height>
</size>
</property>
</spacer>
<widget class="TQPushButton" row="3" column="6">
<property name="name">
<cstring>pushButtonExit</cstring>
</property>
<property name="text">
<string>&amp;Cancel</string>
</property>
<property name="iconSet">
<iconset>process-stop-16x16.png</iconset>
</property>
</widget>
</grid>
</widget>
<connections>
<connection>
<sender>pushButtonClear</sender>
<signal>clicked()</signal>
<receiver>smsMessage</receiver>
<slot>clear()</slot>
</connection>
<connection>
<sender>smsMessage</sender>
<signal>textChanged()</signal>
<receiver>smsdialog</receiver>
<slot>smsTextChanged()</slot>
</connection>
<connection>
<sender>pushButtonSendSMS</sender>
<signal>clicked()</signal>
<receiver>smsdialog</receiver>
<slot>pushButton_sendSMS()</slot>
</connection>
<connection>
<sender>pushButtonExit</sender>
<signal>clicked()</signal>
<receiver>smsdialog</receiver>
<slot>close()</slot>
</connection>
<connection>
<sender>pushButtonClear</sender>
<signal>clicked()</signal>
<receiver>smsToNumber</receiver>
<slot>clear()</slot>
</connection>
<connection>
<sender>smsMessage</sender>
<signal>modificationChanged(bool)</signal>
<receiver>pushButtonSendSMS</receiver>
<slot>setEnabled(bool)</slot>
</connection>
</connections>
<tabstops>
<tabstop>smsToNumber</tabstop>
<tabstop>smsMessage</tabstop>
<tabstop>pushButtonSendSMS</tabstop>
<tabstop>pushButtonClear</tabstop>
<tabstop>pushButtonExit</tabstop>
</tabstops>
<includes>
<include location="local" impldecl="in implementation">smsdialog.ui.h</include>
</includes>
<slots>
<slot>smsTextChanged()</slot>
<slot>pushButton_sendSMS()</slot>
</slots>
<functions>
<function access="private" specifier="non virtual">init()</function>
</functions>
<pixmapinproject/>
<layoutdefaults spacing="6" margin="11"/>
</UI>

@ -0,0 +1,131 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2007 Klaas van Gend, Christofer Wesseling
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/****************************************************************************
** ui.h extension file, included from the uic-generated form implementation.
**
** If you want to add, delete, or rename functions or slots, use
** TQt Designer to update this file, preserving your code.
**
** You should not define a constructor or destructor in this file.s
** Instead, write your code in functions called init() and destroy().
** These will automatically be called by the form's constructor and
** destructor.
*****************************************************************************/
#include "umtsmon_global.h"
#include "Popup.h"
#include "Query.h"
#include "ValidatePhoneNumber.h"
#include "ConnectionInfo.h"
#include "ProgressDialog.h"
#include <assert.h>
void smsdialog::init()
{
smsToNumber->setValidator(new ValidatePhoneNumber(smsToNumber));
}
void smsdialog::smsTextChanged()
{
int myNumberOfChars = smsMessage->length();
if (myNumberOfChars < 0)
myNumberOfChars = 0;
smsCharInMessages->setText(TQString::number(myNumberOfChars));
// FIXME: there's a magic number here...
smsCharLeft->setText(TQString::number(162-myNumberOfChars));
}
void smsdialog::pushButton_sendSMS()
{
// prevent ConnectionInfo from interfering
// for as long as this class is in scope.
ConnectionInfoInhibitor myInhibitor;
{
Query myQuery("AT+CPMS=\"SM\"");
if (myQuery.runUntilDone() != Query::OK)
{
DEBUG1("THE RESULT WAS NOT GOOD!\n");
assert(false);
}
}
{
Query myQuery("AT+CMGF=1");
if (myQuery.runUntilDone() != Query::OK)
{
DEBUG1("THE RESULT WAS NOT GOOD!\n");
assert(false);
}
}
// thanks to the 'ValidatorPhoneNumber' class, the input is already OK
// apart from spaces and a surplus of starting pluses...
TQString mySMSNumber = smsToNumber->text();
ValidatePhoneNumber myValidator(NULL);
myValidator.fixup(mySMSNumber);
if (mySMSNumber.length() > 0)
{
bool isOK = false;
ProgressDialog myPD(this, tr("sending SMS..."));
myPD.setMaxTime(12);
myPD.start(0); // show immediately
Query myQuery("AT+CMGS=\"" + mySMSNumber +"\"");
// the card does not answer "OK" here, it prompts for a message
myQuery.run();
if (!myQuery.hasAnswer())
goto skipTheRest;
// pop off the "AT+CMGS=..." echo
myQuery.getAnswer();
if (myQuery.getAnswer().first() != "> ")
{
DEBUG1("THE RESULT WAS NOT GOOD!\n");
assert(false);
}
// send message and a closing Ctrl-Z
myQuery.sendMore(smsMessage->text()+ TQChar(26));
while ((isOK = myPD.runOneSecond()))
{
Query::ReturnCode myCode = myQuery.receiveMore();
if (myCode == Query::OK)
{
DEBUG5("sent sms: '%s'\n", myQuery.getAnswer().first().ascii());
break;
}
if (myCode == Query::ERROR)
{
DEBUG1("Received error from card on SMS:-(\n");
isOK = false;
break;
}
}
skipTheRest:
myPD.finish();
if (isOK)
{
Popup::Info(tr("SMS sent (according to the device)."));
}
else
{
Popup::Warning(tr("SMS was not sent!"));
}
}
}

@ -0,0 +1,223 @@
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
<class>YesNoWithMemory</class>
<widget class="TQDialog">
<property name="name">
<cstring>YesNoWithMemory</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>423</width>
<height>151</height>
</rect>
</property>
<property name="caption">
<string>MyDialog</string>
</property>
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQLabel">
<property name="name">
<cstring>textLabel</cstring>
</property>
<property name="text">
<string></string>
</property>
<property name="alignment">
<set>AlignCenter</set>
</property>
</widget>
<spacer>
<property name="name">
<cstring>spacer11_2</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
<widget class="TQLayoutWidget">
<property name="name">
<cstring>layout4</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<spacer>
<property name="name">
<cstring>spacer3</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>71</width>
<height>20</height>
</size>
</property>
</spacer>
<widget class="TQPushButton">
<property name="name">
<cstring>buttonYes</cstring>
</property>
<property name="text">
<string>&amp;Yes</string>
</property>
<property name="accel">
<string>Alt+Y</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
<widget class="TQPushButton">
<property name="name">
<cstring>buttonNo</cstring>
</property>
<property name="text">
<string>&amp;No</string>
</property>
<property name="accel">
<string>Alt+N</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
<property name="default">
<bool>false</bool>
</property>
</widget>
<spacer>
<property name="name">
<cstring>spacer3_2</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>71</width>
<height>20</height>
</size>
</property>
</spacer>
</hbox>
</widget>
<spacer>
<property name="name">
<cstring>spacer11</cstring>
</property>
<property name="orientation">
<enum>Vertical</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
<widget class="TQLayoutWidget">
<property name="name">
<cstring>layout2</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="TQCheckBox">
<property name="name">
<cstring>checkBoxDoNotShowAgain</cstring>
</property>
<property name="font">
<font>
<pointsize>9</pointsize>
</font>
</property>
<property name="text">
<string>Do not show this message again</string>
</property>
</widget>
<spacer>
<property name="name">
<cstring>Horizontal Spacing2</cstring>
</property>
<property name="orientation">
<enum>Horizontal</enum>
</property>
<property name="sizeType">
<enum>Expanding</enum>
</property>
<property name="sizeHint">
<size>
<width>158</width>
<height>20</height>
</size>
</property>
</spacer>
</hbox>
</widget>
</vbox>
</widget>
<connections>
<connection>
<sender>buttonNo</sender>
<signal>clicked()</signal>
<receiver>YesNoWithMemory</receiver>
<slot>buttonNO_clicked()</slot>
</connection>
<connection>
<sender>buttonYes</sender>
<signal>clicked()</signal>
<receiver>YesNoWithMemory</receiver>
<slot>buttonYES_clicked()</slot>
</connection>
</connections>
<includes>
<include location="local" impldecl="in implementation">TheSettingsSingleton.h</include>
<include location="global" impldecl="in implementation">assert.h</include>
<include location="local" impldecl="in implementation">yesnowithmemory.ui.h</include>
</includes>
<variables>
<variable>TQString theUniqueName;</variable>
<variable access="public">bool theResult;</variable>
</variables>
<slots>
<slot>buttonYES_clicked()</slot>
<slot>buttonNO_clicked()</slot>
</slots>
<functions>
<function returnType="bool">setMemoryName( const TQString aName )</function>
<function >button_clicked(void)</function>
</functions>
<pixmapinproject/>
<layoutdefaults spacing="6" margin="11"/>
</UI>

@ -0,0 +1,63 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2009 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/****************************************************************************
** ui.h extension file, included from the uic-generated form implementation.
**
** If you want to add, delete, or rename functions or slots, use
** TQt Designer to update this file, preserving your code.
**
** You should not define a constructor or destructor in this file.
** Instead, write your code in functions called init() and destroy().
** These will automatically be called by the form's constructor and
** destructor.
*****************************************************************************/
bool YesNoWithMemory::setMemoryName(const TQString aName)
{
assert( !aName.isEmpty() );
theUniqueName = "/ShowPopupWithMemory/" + aName;
theResult = TheSettingsSingleton::getTQSRef().readBoolEntry( theUniqueName+".answer", false);
// true means we are going to show the dialog
return TheSettingsSingleton::getTQSRef().readBoolEntry( theUniqueName+".showagain", true);
}
void YesNoWithMemory::buttonYES_clicked()
{
theResult = true;
button_clicked();
}
void YesNoWithMemory::buttonNO_clicked()
{
theResult = false;
button_clicked();
}
void YesNoWithMemory::button_clicked()
{
// if box is checked, that means the user doesn't want to see the box again
// i.e. we need to write false
assert( !theUniqueName.isEmpty() );
TheSettingsSingleton::getTQSRef().writeEntry( theUniqueName+".showagain", checkBoxDoNotShowAgain->isChecked()==false);
TheSettingsSingleton::getTQSRef().writeEntry( theUniqueName+".answer", theResult);
accept();
}

@ -0,0 +1,2 @@
AutoDetectTester
Makefile

@ -0,0 +1,29 @@
# include a file with all the common stuff
include(../GenericTestPro.inc)
LIBS += -lusb
HEADERS += \
../../umtsmon_global.h \
../../src/controller/AutoDetect.h \
../../src/base/FileStuff.h \
../../src/model/Device.h \
../../src/model/MonthlyTraffic.h \
../../src/model/Profile.h \
../../src/model/Query.h \
../../src/base/SerialPort.h \
../../src/base/TheSettingsSingleton.h \
../../src/view/Popup.h
SOURCES += AutoDetectTester_main.cpp \
../../src/controller/AutoDetect.cpp \
../../src/model/ConnectionInfo.cpp \
../../src/model/Device.cpp \
../../src/model/MonthlyTraffic.cpp \
../../src/model/Profile.cpp \
../../src/model/Query.cpp \
../../src/base/FileStuff.cpp \
../../src/base/Runner.cpp \
../../src/base/SerialPort.cpp \
../../src/base/TheSettingsSingleton.cpp

@ -0,0 +1,163 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file (C) 2007, 2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "AutoDetect.h"
#include <ntqstring.h>
#include <assert.h>
#include <errno.h>
#include "../TestFrame.cpp"
// conveniently set theVerbosity to a number of your liking
int theVerbosity = 5;
// we subclass the AutoDetect_PCMCIA to get access to some of
// the protected variables
class AutoDetectTesterP : public AutoDetect_PCMCIA
{
public:
Device::CardType getDeviceID(void) {return theDeviceID;};
void setDeviceID(Device::CardType myID) {theDeviceID = myID;};
const TQString& getAT (void) {return thePortsList.last();};
const TQString& getPPP(void) {return thePortsList.first();};
void setAT (TQString myAT) {thePortsList.push_front(myAT);};
void setPPP (TQString myPPP) {thePortsList.push_back(myPPP);};
};
class AutoDetectTesterU : public AutoDetect_USB
{
public:
Device::CardType getDeviceID(void) {return theDeviceID;};
void setDeviceID(Device::CardType myID) {theDeviceID = myID;};
const TQString& getAT (void) {return thePortsList.last();};
const TQString& getPPP(void) {return thePortsList.first();};
void setAT (TQString myAT) {thePortsList.push_front(myAT);};
void setPPP (TQString myPPP) {thePortsList.push_back(myPPP);};
};
class AutoDetectTesterR : public AutoDetect_Rawport
{
public:
Device::CardType getDeviceID(void) {return theDeviceID;};
void setDeviceID(Device::CardType myID) {theDeviceID = myID;};
const TQString& getAT (void) {return thePortsList.last();};
const TQString& getPPP(void) {return thePortsList.first();};
void setAT (TQString myAT) {thePortsList.push_front(myAT);};
void setPPP (TQString myPPP) {thePortsList.push_back(myPPP);};
virtual TQString getName() {return "tester";};
};
int main()
{
// I'm not entirely sure if this is allowed and/or works
errno = 0;
// welcome to user
printf("Test app is called '%s' version '%s'\n", APPNAME, APPRELEASE);
#if 0
AutoDetectTesterP myPCMCIA;
check(!myPCMCIA.getName().isEmpty(), "PCMCIA class does have a name\n");
check( myPCMCIA.getVendorID() == 0, "VendorID is 0\n");
check( myPCMCIA.getDeviceID() == 0, "DeviceID is 0\n");
// let's do some matching
check( myPCMCIA.matchIDs(0,0) == AutoDetectBase::NOTHING_FOUND, "no known vendor 0\n");
check( myPCMCIA.matchIDs(CardDetection::NEC,0) == AutoDetectBase::DEVICE_ERROR,
"should not detect NEC based cards here\n");
check( myPCMCIA.matchIDs(CardDetection::OPTION,0) == AutoDetectBase::DEVICE_DETECTED,
"supplying vendor OPTION already gives Nozomi\n");
check( myPCMCIA.getDeviceID() == Device::OPTION_NOZOMI, "DeviceID is now NOZOMI\n");
check( myPCMCIA.findPortNames() == false, "no Nozomi card inserted - ports are not available\n");
myPCMCIA.setVendorID(CardDetection::UNKNOWN);
myPCMCIA.setDeviceID(Device::UNKNOWN);
#endif
#if 0
printf("\n*** Let's do some real tests:\n"
"From here onwards, the test code expects a GC79 in the PCMCIA slot\n\n");
// at this moment, Klaas has the SonyEricsson GC79 inserted.
check( myPCMCIA.go() == AutoDetectBase::DEVICE_DETECTED, "Found the GC79 device\n");
check( myPCMCIA.getDeviceID() == Device::BROADCOM_GPRS_EDGE, "DeviceID is now BROADCOM_GPRS_EDGE\n");
check( myPCMCIA.getAT() == "/dev/ttyS1", "device name is now correct\n");
check( myPCMCIA.getPPP()== "/dev/ttyS1", "AT and PPP names are the same\n");
#endif
#if 0
AutoDetectTesterU myUSB;
check(!myUSB.getName().isEmpty(), "USB class does have a name\n");
printf("\n*** Let's do some real tests:\n"
"From here onwards, the test code expects a Option GT in the PCMCIA slot\n\n");
// at this moment, Klaas has the Option GT Max inserted.
check( myUSB.go() == AutoDetectBase::DEVICE_DETECTED, "Found the GT device\n");
check( myUSB.getDeviceID() == Device::OPTION_3PORT, "DeviceID is now OPTION_3PORT\n");
check( myUSB.getAT() == "/dev/ttyUSB0", "device name is now correct\n");
check( myUSB.getPPP()== "/dev/ttyUSB2", "AT and PPP names are different\n");
#endif
#if 1
AutoDetectTesterR myRaw;
check(!myRaw.getName().isEmpty(), "Raw class does have a name\n");
printf("\n*** Let's do some real tests:\n"
"From here onwards, the test code expects a Option GT in the PCMCIA slot\n\n");
// at this moment, Klaas has the Option GT Max inserted.
check( myRaw.go() == AutoDetectBase::DEVICE_DETECTED, "Found the GT device\n");
check( myRaw.getDeviceID() == Device::OPTION_3PORT, "DeviceID is now OPTION_3PORT\n");
check( myRaw.getAT() == "/dev/ttyUSB0", "device name is now correct\n");
check( myRaw.getPPP()== "/dev/ttyUSB2", "AT and PPP names are different\n");
#endif
// keep this last for summary:
finish();
return 0;
}
void printAbortMessage(__attribute__ ((unused)) int aSignalNumber)
{
printf("\n\n *** " APPNAME " version " APPRELEASE " closed due to an"
" unrecoverable program error.\n"
" *** Please e-mail all of the above output to"
" umtsmon-develop@lists.sourceforge.net,\n"
" *** Or go to the " APPNAME " website and file a bug.\n\n\n");
// do not call exit here - or the signal will not be handled correctly
}

@ -0,0 +1,20 @@
# This is an include file that defines generic parameters for all test programs.
# it is included in each *.pro file at the beginning.
TEMPLATE = app
LANGUAGE = C++
### uncomment these two lines for compiling with code coverage instrumentation
#QMAKE_CXXFLAGS_DEBUG += -fprofile-arcs -ftest-coverage
#QMAKE_LFLAGS_DEBUG += -fprofile-arcs -ftest-coverage
CONFIG += qt warn_on debug
INCLUDEPATH +=../.. ../../src/base ../../src/model ../../src/view ../../src/controller
unix {
UI_DIR = ../../.ui
MOC_DIR = ../../.moc
OBJECTS_DIR = .obj
}

@ -0,0 +1,4 @@
Makefile
HelperTester
helperlistgui.ui.h
helperlistgui.ui

@ -0,0 +1,49 @@
# include a file with all the common stuff
include(../GenericTestPro.inc)
!exists(helperlistgui.ui.h) {
system(ln -s ../../src/view/helperlistgui.ui.h .) {}
system(ln -s ../../src/view/helperlistgui.ui .) {}
}
LIBS += -lusb
HEADERS += \
../../umtsmon_global.h \
../../src/controller/AutoDetect.h \
../../src/model/ConnectionInfo.h \
../../src/model/Device.h \
../../src/base/FileStuff.h \
../../src/model/HelperList.h \
../../src/model/MonthlyTraffic.h \
../../src/model/OperatorList.h \
../../src/view/Popup.h \
../../src/model/Profile.h \
../../src/model/Query.h \
../../src/base/Runner.h \
../../src/base/SerialPort.h \
../../src/controller/TheDeviceManagerSingleton.h \
../../src/base/TheSettingsSingleton.h
SOURCES += \
HelperTester_main.cpp \
../../src/controller/AutoDetect.cpp \
../../src/model/ConnectionInfo.cpp \
../../src/model/Device.cpp \
../../src/base/FileStuff.cpp \
../../src/model/HelperList.cpp \
../../src/model/MonthlyTraffic.cpp \
../../src/model/OperatorList.cpp \
../../src/model/Query.cpp \
../../src/model/Profile.cpp \
../../src/base/Runner.cpp \
../../src/base/SerialPort.cpp \
../../src/controller/TheDeviceManagerSingleton.cpp \
../../src/base/TheSettingsSingleton.cpp
FORMS = \
./helperlistgui.ui
IMAGES = ../../images/Wizard/NetworkOperatorWizard.png \
../../images/ok.png \
../../images/16/process-stop-16x16.png

@ -0,0 +1,70 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "HelperList.h"
#include <ntqapplication.h>
#include <ntqstring.h>
#include <assert.h>
#include <errno.h>
#include "../TestFrame.cpp"
// conveniently set theVerbosity to a number of your liking
int theVerbosity = 5;
const char* theWasRoamingSettingName = "/General/WasRoaming";
int main( int aArgC, char* aArgV[] )
{
// I'm not entirely sure if this is allowed and/or works
errno = 0;
// welcome to user
printf("Test app is called '%s' version '%s'\n", APPNAME, APPRELEASE);
chapter("INIT\n");
TQApplication myApp( aArgC , aArgV );
chapter("TEST GUI - let device choose\n")
HelperList myList1;
check (myList1.testAndRun() != HelperList::QUIT, "user did not select exit");
// keep this last for summary:
finish();
return 0;
}
void printAbortMessage(__attribute__ ((unused)) int aSignalNumber)
{
printf("\n\n *** " APPNAME " version " APPRELEASE " closed due to an"
" unrecoverable program error.\n"
" *** Please e-mail all of the above output to"
" umtsmon-develop@lists.sourceforge.net,\n"
" *** Or go to the " APPNAME " website and file a bug.\n\n\n");
// do not call exit here - or the signal will not be handled correctly
}

@ -0,0 +1,4 @@
infodialog.ui.h
infodialog.ui
InfoDialogTester
Makefile

@ -0,0 +1,25 @@
# include a file with all the common stuff
include(../GenericTestPro.inc)
!exists(infodialog.ui.h) {
system(ln -s ../../src/view/infodialog.ui.h .) {}
system(ln -s ../../src/view/infodialog.ui .) {}
}
HEADERS += ../../src/model/Query.h \
../../umtsmon_global.h \
../../src/base/SerialPort.h \
../../src/view/ProgressDialog.h \
../../src/base/FileStuff.h \
infodialog.h
SOURCES += InfoDialogTester_main.cpp \
../../src/model/Query.cpp \
../../src/base/FileStuff.cpp \
../../src/base/SerialPort.cpp \
../../src/model/ConnectionInfo.cpp \
../../src/view/ProgressDialog.cpp
#FORMS = \
# ./infodialog.ui

@ -0,0 +1,126 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006, 2007 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "Query.h"
#include "SerialPort.h"
#include <ntqstring.h>
#include <assert.h>
#include <errno.h>
#include "../TestFrame.cpp"
// conveniently set theVerbosity to a number of your liking
int theVerbosity = 2;
#include "FileStuff.h"
#include "infodialog.h"
// and the implementation of the members
#include "infodialog.ui.h"
int main(int argc, char** argv)
{
// I'm not entirely sure if this is allowed and/or works
errno = 0;
// welcome to user
printf("Test app is called '%s' version '%s'\n", APPNAME, APPRELEASE);
printf("\n*** INIT\n");
TQApplication a( argc, argv );
SimulatedSerialPort mySP;
Query::setSerial(&mySP);
mySP.addSerialStatement("AT","OK");
mySP.addSerialStatement("AT","ERROR");
printf("\n*** Motorola Sliver 7\n");
// Moto SLVR L7 answer:
mySP.addSerialStatement("AT+CGSN", "+CGSN: IMEI359411001731435\r\nOK\r\n");
mySP.addSerialStatement("AT+CIMI", "204042920481060\r\n\r\nOK\r\n");
mySP.addSerialStatement("AT+CGMI", "\xFF\xFF\r\r\n+CGMI: \"Motorola CE, Copyright 2000\"\r\n\r\nOK\r\n");
mySP.addSerialStatement("AT+CGMM", "+CGMM: \"GSM900\",\"GSM1800\",\"GSM1900\",\"GSM850\",\"MODEL=L7\"\r\n\r\nOK\r\n");
mySP.addSerialStatement("AT+CGMR", "+CGMR: \"R4513_G_08.B7.DCR_RB\"\r\n\r\nOK\r\n");
InfoDialogUmtsmon mySL7;
mySL7.init();
check (mySL7.lbl_IMEI.text() == "IMEI359411001731435", "IMEI correct\n");
check (mySL7.lbl_IMSI.text() == "204042920481060", "IMSI correct\n");
check (mySL7.lbl_Manufacturer.text() == "Motorola CE, Copyright 2000", "Manufacturer correct\n");
#if 0
printf("\n*** Motorola 680E\n");
// Moto 680E answers:
mySP.addSerialStatement("AT+CGSN", "+CGSN: IMEI359411001731435\r\nOK\r\n");
mySP.addSerialStatement("AT+CIMI", "204042920481060\r\n\r\nOK\r\n");
mySP.addSerialStatement("AT+CGMI", "\xFF\xFF\r\r\n+CGMI: \"Motorola CE, Copyright 2000\"\r\n\r\nOK\r\n");
mySP.addSerialStatement("AT+CGMM", "+CGMM: \"GSM900\",\"GSM1800\",\"GSM1900\",\"GSM850\",\"MODEL=L7\"\r\n\r\nOK\r\n");
mySP.addSerialStatement("AT+CGMR", "+CGMR: \"R4513_G_08.B7.DCR_RB\"\r\n\r\nOK\r\n");
InfoDialogUmtsmon my680;
my680.init();
check (my680.lbl_IMEI.text() == "IMEI359411001731435", "IMEI correct\n");
check (my680.lbl_IMSI.text() == "204042920481060", "IMSI correct\n");
check (my680.lbl_Manufacturer.text() == "Motorola CE, Copyright 2000", "Manufacturer correct\n");
#endif
printf("\n*** Option GT \n");
// Option GT answers:
mySP.addSerialStatement("AT+CGSN", "355201021053686,QL4A5C73PR\r\n\r\nOK\r\n");
mySP.addSerialStatement("AT+CIMI", "204042920481060\r\n\r\nOK\r\n");
mySP.addSerialStatement("AT+CGMI", "Option N.V.\r\n\r\nOK\r\n");
mySP.addSerialStatement("AT+CGMM", "GlobeTrotter Fusion Quad Lite\r\n\r\nOK\r\n");
mySP.addSerialStatement("AT+CGMR", "1.5.5 (Date: May 17 2005, Time: 14:55:44)\r\n\r\nOK\r\n");
InfoDialogUmtsmon myGT;
myGT.init();
check (myGT.lbl_IMEI.text() == "355201021053686,QL4A5C73PR", "IMEI correct\n");
check (myGT.lbl_IMSI.text() == "204042920481060", "IMSI correct\n");
check (myGT.lbl_Manufacturer.text() == "Option N.V.", "Manufacturer correct\n");
// keep this last for summary:
finish();
return 0;
}
void printAbortMessage(__attribute__ ((unused)) int aSignalNumber)
{
printf("\n\n *** " APPNAME " version " APPRELEASE " closed due to an"
" unrecoverable program error.\n"
" *** Please e-mail all of the above output to"
" umtsmon-develop@lists.sourceforge.net,\n"
" *** Or go to the " APPNAME " website and file a bug.\n\n\n");
// do not call exit here - or the signal will not be handled correctly
}

@ -0,0 +1,97 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2007 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include <ntqvariant.h>
#include <ntqdialog.h>
#include <ntqtable.h>
class TQVBoxLayout;
class TQHBoxLayout;
class TQGridLayout;
class TQSpacerItem;
class TQTabWidget;
class TQWidget;
class TQLabel;
class TQGroupBox;
class TestLabel
{
public:
TestLabel* operator ->(void) {return this;}
void setText(TQString aString) {theString = aString; DEBUG2("setText(\"%s\")\n", aString.ascii());};
TQString text(void) {return theString;};
private:
TQString theString;
};
class TestTable
{
public:
TestTable* operator ->(void) {return this;}
void insertRows(__attribute__ ((unused)) int a1) {;};
void sortColumn(__attribute__ ((unused)) int a1,
__attribute__ ((unused)) bool a2,
__attribute__ ((unused)) bool a3) {;};
void adjustColumn(__attribute__ ((unused)) int a1) {;};
void setText(__attribute__ ((unused)) int a1,
__attribute__ ((unused)) int a2,
__attribute__ ((unused)) TQString aString) {;};
TQHeader * horizontalHeader () const {static TQHeader myHeader; return &myHeader;};
};
class InfoDialogUmtsmon : public TQDialog
{
Q_OBJECT
public:
InfoDialogUmtsmon() {};
virtual ~InfoDialogUmtsmon() {};
TQTabWidget* tabWidget3;
TQWidget* TabPage;
TestLabel lbl_CardType;
TestLabel lbl_IMSI;
TestLabel lbl_IMEI;
TestLabel lbl_Manufacturer;
TestLabel lbl_Revision;
TQWidget* TabPage_2;
TestLabel lbl_System_Version;
TestTable device_table;
TestTable module_table;
TestLabel lbl_pppd_version;
TestLabel lbl_distro_release;
public slots:
void sort_module_table(int section);
void sort_device_table(int section);
public:
void init();
TQString get_Info_using_AT_Query( TQString anAtCommand );
void readSystemInformations();
void setPPPDversion(TQString aVersionString);
};

@ -0,0 +1,9 @@
.ui
LCDDisplay.cpp
LCDDisplay.h
LCDDisplayTester
Makefile
LCDSignal.png
LCDBackground.png
i18n
.moc

File diff suppressed because one or more lines are too long

@ -0,0 +1,82 @@
/****************************************************************************
** ui.h extension file, included from the uic-generated form implementation.
**
** If you want to add, delete, or rename functions or slots, use
** TQt Designer to update this file, preserving your code.
**
** You should not define a constructor or destructor in this file.
** Instead, write your code in functions called init() and destroy().
** These will automatically be called by the form's constructor and
** destructor.
*****************************************************************************/
#include <stdio.h>
static const int theDownload = 1025;
void LCDDisplayTest::init(void)
{
printf("LCDDisplayTest::init(void)\n");
theLCDDisplayPtr->setRadioType("HSDPA");
theLCDDisplayPtr->setRoaming(checkBox_Roaming->isChecked());
checkBox_Roaming_update();
spinBox_upload_update();
emit spinBox1->setValue(13);
comboBox1->setCurrentItem(1);
combo_activated(comboBox1->currentText());
comboBox_Profile_activated(comboBox_Profile->currentText());
}
void LCDDisplayTest::combo_activated(const TQString& aNewString)
{
printf("Form1::combo_activated changed to '%s'\n", aNewString.ascii());
theLCDDisplayPtr->setOperatorName(aNewString);
}
void LCDDisplayTest::spin_changed( int aNewValue)
{
printf("Form1::spinbox_changed to %d\n", aNewValue);
theLCDDisplayPtr->setStrength(aNewValue);
}
void LCDDisplayTest::comboBox_Profile_activated(const TQString& aNewString)
{
printf("Form1::comboBox_Profile_activated changed to '%s'\n", aNewString.ascii());
if (aNewString.find("empty") > 0)
theLCDDisplayPtr->setProfile("");
else
theLCDDisplayPtr->setProfile(aNewString);
}
void LCDDisplayTest::spinBox_upload_update()
{
int myLimitID = comboBox_limits->currentItem();
printf("%s, %d\n", spinBox_upload->text().ascii(), myLimitID);
theLCDDisplayPtr->setUpload(spinBox_upload->value(),
spinBox_Speed->value());
theLCDDisplayPtr->setDownload(2*spinBox_upload->value(),
4*spinBox_Speed->value());
theLCDDisplayPtr->setTotalTraffic(
spinBox_upload->value()+theDownload,
static_cast<MonthlyTraffic::ThresholdStatus>(myLimitID));
}
void LCDDisplayTest::checkBox_Roaming_update()
{
theLCDDisplayPtr->setRoaming(checkBox_Roaming->isChecked());
// because this one doesn't update the display:
comboBox_Profile_activated(comboBox_Profile->currentText());
}
void LCDDisplayTest::spinBox_ConnectedTime_update()
{
theLCDDisplayPtr->setConnectedTime(spinBox_TimeConnected->value());
}

@ -0,0 +1,21 @@
# include a file with all the common stuff
include(../GenericTestPro.inc)
HEADERS += LCDDisplay.h \
../../umtsmon_global.h
SOURCES += main.cpp \
LCDDisplay.cpp
FORMS = LCDDisplayTest.ui
IMAGES = LCDBackground.png \
LCDSignal.png
!exists(LCDBackground.png) {
system(ln -s ../../images/LCDDisplay/LCDBackground.png .) {}
system(ln -s ../../images/LCDDisplay/LCDSignal.png .) {}
system(ln -s ../../src/view/LCDDisplay.h .) {}
system(ln -s ../../src/view/LCDDisplay.cpp .) {}
system(ln -s ../../i18n .) {}
}

@ -0,0 +1,31 @@
#include "LCDDisplayTest.h"
#include "umtsmon_global.h"
#include <ntqapplication.h>
#include <ntqtranslator.h>
#include <ntqtextcodec.h>
#include <stdio.h>
int main( int argc, char **argv )
{
TQApplication a( argc, argv );
puts( "LCDDisplayTest" );
// translation file for TQt
TQTranslator myTQTTranslator(0);
myTQTTranslator.load( TQString( "qt_" ) + TQTextCodec::locale(), "." );
a.installTranslator( &myTQTTranslator );
// translation file for application strings
TQTranslator myAppTranslator( 0 );
myAppTranslator.load( TQString( APPNAME "_" ) + TQTextCodec::locale(), "i18n" );
a.installTranslator( &myAppTranslator );
LCDDisplayTest w;
w.show();
return w.exec();
}

@ -0,0 +1,3 @@
Makefile
MonthlyTrafficTester
*.gcov

@ -0,0 +1,14 @@
# include a file with all the common stuff
include(../GenericTestPro.inc)
HEADERS += \
../../src/base/TheSettingsSingleton.h \
../../src/model/Profile.h \
../../src/model/MonthlyTraffic.h \
umtsmon_global.h
SOURCES += \
../../src/base/TheSettingsSingleton.cpp \
../../src/model/Profile.cpp \
MonthlyTrafficTester_main.cpp
# note that MonthlyTraffic.cpp is actually missing because it's #included by MonthlyTrafficTester_main.cpp

@ -0,0 +1,303 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2007 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include <assert.h>
#include <errno.h>
#include "MonthlyTraffic.cpp"
#include <ntqdir.h>
#include "../TestFrame.cpp"
// conveniently set theVerbosity to a number of your liking
int theVerbosity = 5;
/** this class is a friend of MonthlyTraffic and therefore
* can access the innards of MonthlyTraffic
*/
class MonthlyTrafficTester
{
public:
MonthlyTrafficTester(MonthlyTraffic& anMTRef)
: theMTRef(anMTRef)
{};
/** use to manipulate the date of a MonthlyTraffic instance
* note that we use 'whitebox' knowledge here
*/
void setDate(int aYear, int aMonth)
{
theMTRef.theDate.setYMD(aYear, aMonth, theMTRef.theDate.day());
};
bool getIsRoaming(void)
{ return theMTRef.isRoaming;};
unsigned long getCounterBytesSent(void)
{ return theMTRef.theCounterBytesSent;};
unsigned long getCounterBytesReceived(void)
{ return theMTRef.theCounterBytesReceived;};
unsigned long getHomeTraffic(void)
{ return theMTRef.theHomeTraffic;};
unsigned long getRoamingTraffic(void)
{ return theMTRef.theRoamingTraffic;};
void setHome(unsigned long aNumber)
{ theMTRef.theHomeTraffic = aNumber;};
void setRoaming(unsigned long aNumber)
{ theMTRef.theRoamingTraffic = aNumber;};
void setReceivedBytes(unsigned long aNumber)
{ theMTRef.theCounterBytesReceived = aNumber;};
void setSentBytes(unsigned long aNumber)
{ theMTRef.theCounterBytesSent = aNumber;};
void save(void)
{ theMTRef.save();};
MonthlyTraffic& theMTRef;
};
void removeSettings(void)
{
// a config file of this tester should be called $HOME/.umtsmontester/umtsmontesterrc
// Let's check if such directory exists, and kill it
TQString mySettingsLocation = TQDir::homeDirPath() + "/." + APPNAME;
TQString mySettingsFile = mySettingsLocation + "/" + APPNAME + "rc";
TQString mySettingsLockFile = mySettingsLocation + "/." + APPNAME + "rc.lock";
TQDir mySettingsDir(mySettingsLocation);
if (mySettingsDir.exists())
{
testmsg("** removing settingsdir %s\n", mySettingsLocation.ascii());
check (mySettingsDir.remove(mySettingsFile), "removal of exisiting file '"
+ mySettingsFile + "'\n");
check (mySettingsDir.remove(mySettingsLockFile), "removal of exisiting file '"
+ mySettingsLockFile + "'\n");
check (mySettingsDir.rmdir(mySettingsLocation), "removal of exisiting dir '"
+ mySettingsLocation + "'\n", true);
}
check(!mySettingsDir.exists(), "settings directory " + mySettingsLocation
+ " does not exist (anymore)\n");
}
int main()
{
// I'm not entirely sure if this is allowed and/or works
errno = 0;
// welcome to user
printf("Test app is called '%s' version '%s'\n", APPNAME, APPRELEASE);
// and check if the APPNAME is correct
check(TQString(APPNAME) != TQString("umtsmon"), "Tester is not called umtsmon\n", true);
removeSettings();
TQDate theCurrentDate = TQDate::currentDate();
unsigned long theTotalHomeTraffic = 0;
unsigned long theTotalRoamingTraffic = 0;
//
// FIXME: no attempt is made to check for the warning upon reaching the threshold
//
chapter("simple persistancy and update tests\n");
// let's create a MonthlyTester and update and save and kill it
{
MonthlyTraffic myMT(false);
MonthlyTrafficTester myMTT(myMT);
myMT.update(123, 256);
check(myMTT.getIsRoaming()==false, "not roaming - good\n");
check(myMTT.getCounterBytesSent()==123, "bytes sent is correct\n");
check(myMTT.getCounterBytesReceived()==256, "bytes received is correct\n");
theTotalHomeTraffic = 684+511;
check( myMT.update(684, 511) == theTotalHomeTraffic, "update returns the right numbers\n");
check(myMTT.getCounterBytesSent()==684, "bytes sent is correct\n");
check(myMTT.getCounterBytesReceived()==511, "bytes received is correct\n");
check(myMTT.getHomeTraffic()==0, "no home traffic yet - nothing saved\n");
check(myMTT.getRoamingTraffic()==0, "no roaming traffic yet\n");
}
// check for persistence of the above home RX+TX *and*
// check if roaming doesn't influence that
{
MonthlyTraffic myMT(true);
MonthlyTrafficTester myMTT(myMT);
check(myMTT.getIsRoaming()==true, "roaming - good\n");
check(myMTT.getCounterBytesSent()==0, "bytes sent is correct\n");
check(myMTT.getCounterBytesReceived()==0, "bytes received is correct\n");
check(myMTT.getHomeTraffic()==theTotalHomeTraffic, "home traffic is correct\n");
//
theTotalRoamingTraffic = 345+678;
check(myMT.update(345, 678) == theTotalRoamingTraffic, "update returns the right numbers\n");
check(myMTT.getCounterBytesSent()==345, "bytes sent is correct\n");
check(myMTT.getCounterBytesReceived()==678, "bytes received is correct\n");
check(myMTT.getHomeTraffic()==theTotalHomeTraffic, "home traffic is still correct\n");
check(myMTT.getRoamingTraffic()==0, "roaming traffic is still zero\n");
}
// check for persistence of the above home *and* roaming traffic numbers
{
MonthlyTraffic myMT(false);
MonthlyTrafficTester myMTT(myMT);
check(myMTT.getHomeTraffic()==684+511, "home traffic is correct\n");
check(myMTT.getRoamingTraffic()==345+678, "roaming traffic is correct\n");
}
// check for larger numbers
{
MonthlyTraffic myMT(false);
MonthlyTrafficTester myMTT(myMT);
theTotalHomeTraffic += 1234684L+123456789L;
check( myMT.update(1234684L, 123456789L) == theTotalHomeTraffic, "update works for larger numbers\n");
}
printf("theTotalHomeTraffic : %lu\n", theTotalHomeTraffic);
chapter("thresholds and limits");
// Within home network, let's test for 3 cases, that means adapting a Profile 3x
{
Profile myProfile;
myProfile.setHomeDataLimit(5);
myProfile.setThresholdPercentage(50);
myProfile.save();
MonthlyTraffic myMT(false);
MonthlyTrafficTester myMTT(myMT);
check( myMT.getThresholdStatus()==MonthlyTraffic::OVER_LIMIT, "over limit is correctly detected\n");
}
{
Profile myProfile;
// keep in mind that the Profile's data limits are in megabytes, not in bytes
myProfile.setHomeDataLimit(static_cast<unsigned long>((theTotalHomeTraffic>>20)*1.5));
myProfile.save();
MonthlyTraffic myMT(false);
MonthlyTrafficTester myMTT(myMT);
check( myMT.getThresholdStatus()==MonthlyTraffic::BETWEEN,
"inbetween threshold and limit is correctly detected\n");
}
{
Profile myProfile;
// keep in mind that the Profile's data limits are in megabytes, not in bytes
myProfile.setHomeDataLimit(theTotalHomeTraffic);
myProfile.save();
MonthlyTraffic myMT(false);
MonthlyTrafficTester myMTT(myMT);
check( myMT.getThresholdStatus()==MonthlyTraffic::BELOW,
"below threshold is correctly detected\n");
}
{
Profile myProfile;
// keep in mind that the Profile's data limits are in megabytes, not in bytes
myProfile.setHomeDataLimit(0);
myProfile.save();
MonthlyTraffic myMT(false);
MonthlyTrafficTester myMTT(myMT);
check( myMT.getThresholdStatus()==MonthlyTraffic::BELOW,
"no limit set, should result in BELOW\n");
}
// and do two tests for Roaming to cover all lines there
{
Profile myProfile;
// keep in mind that the Profile's data limits are in megabytes, not in bytes
myProfile.setRoamingDataLimit(theTotalRoamingTraffic);
myProfile.save();
MonthlyTraffic myMT(true);
MonthlyTrafficTester myMTT(myMT);
check( myMT.getThresholdStatus()==MonthlyTraffic::BELOW,
"below threshold for roaming is correctly detected\n");
}
{
Profile myProfile;
// keep in mind that the Profile's data limits are in megabytes, not in bytes
myProfile.setRoamingDataLimit(0);
myProfile.save();
MonthlyTraffic myMT(true);
MonthlyTrafficTester myMTT(myMT);
check( myMT.getThresholdStatus()==MonthlyTraffic::BELOW,
"no limit set for roaming, should result in BELOW\n");
}
chapter("more complex cases part 1: restart of ppp\n");
// ppp returns zero traffic for both - that should trigger a save
{
MonthlyTraffic myMT(false);
MonthlyTrafficTester myMTT(myMT);
check(myMTT.getHomeTraffic()==theTotalHomeTraffic, "home traffic is correct\n");
theTotalHomeTraffic += 100+102;
check(myMT.update(100,102)==theTotalHomeTraffic, "update 1 returns correct number\n");
check(myMT.update(0,0)==theTotalHomeTraffic, "update 2 returns correct number\n");
}
// ppp returns a lower TX - that should trigger a save
{
MonthlyTraffic myMT(true);
MonthlyTrafficTester myMTT(myMT);
check(myMTT.getRoamingTraffic()==theTotalRoamingTraffic, "roaming traffic is correct\n");
theTotalRoamingTraffic += 23221+36789;
check(myMT.update(23221,36789)==theTotalRoamingTraffic, "update 1 returns correct number\n");
theTotalRoamingTraffic += (23456-23221) + 12345;
check(myMT.update(23456,12345)==theTotalRoamingTraffic, "update 2 returns correct number\n");
}
chapter("more complex cases part 2: rollover of date\n\n");
{
TQDate myPreviousMonth = theCurrentDate.addMonths(-1);
MonthlyTraffic myMT(true, myPreviousMonth.year(), myPreviousMonth.month());
MonthlyTrafficTester myMTT(myMT);
// setup the old month
myMTT.setHome (3456789);
myMTT.setRoaming(2345678);
myMTT.save();
}
// check that a current month doesn't know
{
MonthlyTraffic myMT(true);
MonthlyTrafficTester myMTT(myMT);
check(myMTT.getRoamingTraffic()==theTotalRoamingTraffic, "roaming traffic for this month is correct\n");
check(myMTT.getHomeTraffic()==theTotalHomeTraffic, "home traffic for this month is correct\n");
}
// and check that a previous month does
{
TQDate myPreviousMonth = theCurrentDate.addMonths(-1);
MonthlyTraffic myMT(true, myPreviousMonth.year(), myPreviousMonth.month());
MonthlyTrafficTester myMTT(myMT);
check(myMTT.getRoamingTraffic()==2345678, "roaming traffic for last month is correct\n");
check(myMTT.getHomeTraffic()==3456789, "home traffic for last month is correct\n");
myMTT.setReceivedBytes(2345);
myMTT.setSentBytes (1234);
try
{
myMT.update(1244,2368);
}
catch (MonthRolloverException myException)
{
check(true, "update detected a new month and threw an exception\n");
};
// note that after the exception, the MonthlyTraffic still exists...
// data is not saved yet
check(myMTT.getHomeTraffic()==3456789, "home traffic for last month is untouched\n");
// and because the instance still exists, new updates will still work
check(myMT.update(1254,2368)==2345678+1254+2368, "new update()s still work as expected\n");
}
// keep this last for summary:
finish();
return 0;
}

@ -0,0 +1,26 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// just use the original umtsmon_global
#include "../../umtsmon_global.h"
// except for the app name
#undef APPNAME
#define APPNAME "umtsmontester"

@ -0,0 +1,4 @@
NetworkChangerTester
Makefile
*.gcno
*.gcda

@ -0,0 +1,22 @@
# include a file with all the common stuff
include(../GenericTestPro.inc)
HEADERS += \
../../src/model/Query.h \
../../src/model/Profile.h \
../../src/model/OperatorList.h \
../../src/model/MonthlyTraffic.h \
../../umtsmon_global.h \
../../src/base/TheSettingsSingleton.h \
../../src/base/SerialPort.h \
../../src/controller/NetworkChanger.h
SOURCES += NetworkChangerTester_main.cpp \
../../src/model/Query.cpp \
../../src/model/Profile.cpp \
../../src/model/OperatorList.cpp \
../../src/model/MonthlyTraffic.cpp \
../../src/controller/NetworkChanger.cpp \
../../src/base/TheSettingsSingleton.cpp \
../../src/base/SerialPort.cpp \
../../src/model/ConnectionInfo.cpp

@ -0,0 +1,232 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006, 2007 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "Query.h"
#include "SerialPort.h"
#include "NetworkChanger.h"
#include <ntqstring.h>
#include <assert.h>
#include <errno.h>
#include "../TestFrame.cpp"
// conveniently set theVerbosity to a number of your liking
int theVerbosity = 5;
int main()
{
// I'm not entirely sure if this is allowed and/or works
errno = 0;
// welcome to user
printf("Test app is called '%s' version '%s'\n", APPNAME, APPRELEASE);
chapter("INIT\n");
SimulatedSerialPort mySP;
Query::setSerial(&mySP);
mySP.addSerialStatement("AT","OK");
mySP.addSerialStatement("AT","ERROR");
chapter("Simple test\n");
{
// short answer (modified Netherlands output) to test basics first
mySP.addSerialStatement("AT+COPS=?", "\xFF\xFF+COPS: (2,\"vodafone NL\",\"vodafone"
"-NL\",\"20404\",0),,(0, 1, 3, 4),(0-2)\r\nOK");
NetworkChanger myNWC;
myNWC.startSearching();
check(myNWC.isSearchCompleted() == false, "Searching takes a while\n");
check(myNWC.isSearchCompleted() == true, "Searching is finished\n");
check(myNWC.theOperatorList.size() == 1, "one entry in the list\n");
// analyse the first (and only) entry
check((*myNWC.theOperatorList.begin())->getNetworkID() == 20404, "correct network ID\n");
check((*myNWC.theOperatorList.begin())->getIconType() == Operator::CURRENT, "correct icon type\n");
}
chapter("Huawei E220 with trailing info\n");
{
// this ent
mySP.addSerialStatement("AT+COPS=?", "\xFF\xFF+COPS: (1,\"vodafone NL\",\"voda NL\","
"\"20404\",0),(2,\"vodafone NL\",\"voda NL\",\"20404\",2),(3,\"T-Mobile NL\","
"\"TMO NL\",\"20416\",0),(3,\"NL KPN\",\"NL KPN\",\"20408\",0),(3,\"NL KPN\","
"\"NL KPN\",\"20408\",2),(3,\"Orange NL\",\"Orange\",\"20420\",2),"
"(3,\"T-Mobile NL\",\"TMO NL\",\"20416\",2),(3,\"Orange NL\",\"Orange\","
"\"20420\",0),,(0,1,3,4),(0,1,2)\r\n"
"OK\r\n\r\n"
"^RSSI:23\r\n");
NetworkChanger myNWC;
myNWC.startSearching();
check(myNWC.isSearchCompleted() == false, "Searching takes a while\n");
check(myNWC.isSearchCompleted() == true, "Searching is finished\n");
check(myNWC.theOperatorList.size() == 4, "four entries in the list\n");
// analyse the first entry
check((*myNWC.theOperatorList.begin())->getNetworkID() == 20404, "correct network ID\n");
check((*myNWC.theOperatorList.begin())->getIconType() == Operator::CURRENT, "correct icon type\n");
}
chapter("Complex test - Qualcomm style \n");
{
// the complete answer for The Netherlands - Qualcomm style
mySP.addSerialStatement("AT+COPS=?", "\xFF\xFF"
"+COPS: (2,\"vodafone NL\",\"vodafone-NL\",\"20404\",0),"
"(3,\"NL-KPN\",\"NL-KPN\",\"20408\",0),"
"(3,\"NL-KPN\",\"NL-KPN\",\"20408\",2),"
"(3,\"T-Mobile-NL\",\"TMO-NL\",\"20416\",0),"
"(3,\"Orange-NL\",\"Orange\",\"20420\",0),"
"(3,\"NL-Telfort\",\"NL-Tlfrt\",\"20412\",0),"
",(0, 1, 3, 4),(0-2)\r\n"
"OK");
NetworkChanger myNWC;
myNWC.startSearching();
check(myNWC.isSearchCompleted() == false, "Searching takes a while\n");
check(myNWC.isSearchCompleted() == true, "Searching is finished\n");
check(myNWC.theOperatorList.size() == 5, "Five entries in the list (one double)\n");
// analyse the second entry (NL-KPN with both UMTS and GRPS)
Operator* myKPN = *(++myNWC.theOperatorList.begin());
check(myKPN->getNetworkID() == 20408, "second entry has correct network ID\n");
check(myKPN->getIconType() == Operator::FORBIDDEN, "second entry has correct icon type\n");
check(myKPN->getNetworkName() == "NL-KPN", "Correct network name");
check(myKPN->getRadioModes() == "GPRS+UMTS", "UMTS and GPRS are integrated\n");
}
chapter("Complex test - Novatel XU870 style \n");
{
// the complete answer for Germany - Novatel XU870 style
mySP.addSerialStatement("AT+COPS=?", "\xFF\xFF"
"+COPS: (1,\"Vodafone.de\",\"voda DE\",\"26202\",0)\r\n"
"+COPS: (2,\"Vodafone.de\",\"voda DE\",\"26202\",2)\r\n"
"+COPS: (3,\"E-Plus\",\"E-Plus\",\"26203\",2)\r\n"
"+COPS: (3,\"T-Mobile D\",\"TMO D\",\"26201\",2)\r\n"
"+COPS: (3,\"T-Mobile D\",\"TMO D\",\"26201\",0)\r\n"
"+COPS: (3,\"E-Plus\",\"E-Plus\",\"26203\",0)\r\n"
"+COPS: (3,\"o2 - de\",\"o2 - de\",\"26207\",2)\r\n"
"+COPS: (3,\"o2 - de\",\"o2 - de\",\"26207\",0)\r\n"
"OK");
NetworkChanger myNWC;
myNWC.startSearching();
check(myNWC.isSearchCompleted() == false, "Searching takes a while\n");
check(myNWC.isSearchCompleted() == true, "Searching is finished\n");
check(myNWC.theOperatorList.size() == 4, "Four entries in the list (all entries double)\n");
// the first entry has both states CURRENT and AVAILABLE - that should become CURRENT
check((*myNWC.theOperatorList.begin())->getIconType() == Operator::CURRENT, "First entry has correct icon type\n");
check((*myNWC.theOperatorList.begin())->getNetworkID() == 26202, "First entry has correct network ID\n");
}
chapter("Complex test - GC79 style \n");
{
// the complete answer for The Netherlands (summer 2006) - Sony GC79 style
mySP.addSerialStatement("AT+COPS=?", "\xFF\xFF"
"+COPS: (2,\"Orange\",\"Orange NL\",\"20420\"),,(0,1,2,3,4),(0,1,2)\r\n"
"+COPS: (3,\"vodafone NL\",\"vodafone NL\",\"20404\"),,(0,1,2,3,4),(0,1,2)\r\n"
"+COPS: (3,\"T-Mobile NL\",\"T-Mobile NL\",\"20416\"),,(0,1,2,3,4),(0,1,2)\r\n"
"+COPS: (3,\"NL KPN\",\"KPN\",\"20408\"),,(0,1,2,3,4),(0,1,2)\r\n"
"+COPS: (3,\"NL Telfort\",\"Telfort\",\"20412\"),,(0,1,2,3,4),(0,1,2)\r\n"
"OK");
NetworkChanger myNWC;
myNWC.startSearching();
check(myNWC.isSearchCompleted() == false, "Searching takes a while\n");
check(myNWC.isSearchCompleted() == true, "Searching is finished\n");
check(myNWC.theOperatorList.size() == 5, "Five entries in the list\n");
check((*myNWC.theOperatorList.begin())->getNetworkID() == 20420, "First entry has correct network ID\n");
}
chapter("Complex test - Novatel U740 from 'gromeck' style \n");
{
// the complete answer for Germany from Gromeck
mySP.addSerialStatement("AT+COPS=?", "\xFF\xFF"
"\r\n"
"+COPS: (0,\"T-Mobile D\",\"TMO D\",\"26201\",2)\r\n"
"+COPS: (2,\"o2 - de\",\"o2 - de\",\"26207\",2)\r\n"
"+COPS: (1,\"T-Mobile D\",\"TMO D\",\"26201\",0)\r\n"
"+COPS: (1,\"E-Plus\",\"E-Plus\",\"26203\",0)\r\n"
"+COPS: (1,\"Vodafone.de\",\"voda DE\",\"26202\",0)\r\n"
"+COPS: (0,\"Vodafone.de\",\"voda DE\",\"26202\",2)\r\n"
"+COPS: (0,\"E-Plus\",\"E-Plus\",\"26203\",2)\r\n"
"\r\n"
"OK\r\n");
NetworkChanger myNWC;
myNWC.startSearching();
check(myNWC.isSearchCompleted() == false, "Searching takes a while\n");
check(myNWC.isSearchCompleted() == true, "Searching is finished\n");
check(myNWC.theOperatorList.size() == 4, "Four entries in the list\n");
check((*myNWC.theOperatorList.begin())->getNetworkID() == 26207, "First entry has correct network ID\n");
}
chapter("Complex test - Novatel U630\n");
{
// the complete answer for The Netherlands from Klaas
mySP.addSerialStatement("AT+COPS=?", "\xFF\xFF"
"\r\n"
"+COPS: (2,\"vodafone NL\",\"voda NL\",\"20404\")\r\n"
"+COPS: (3,\"NL KPN\",\"NL KPN\",\"20408\")\r\n"
"+COPS: (3,\"T-Mobile NL\",\"TMO NL\",\"20416\")\r\n"
"+COPS: (1,\"Orange NL\",\"Orange\",\"20420\")\r\n"
"\r\n"
"OK\r\n");
NetworkChanger myNWC;
myNWC.startSearching();
check(myNWC.isSearchCompleted() == false, "Searching takes a while\n");
check(myNWC.isSearchCompleted() == true, "Searching is finished\n");
check(myNWC.theOperatorList.size() == 4, "Four entries in the list\n");
check((*myNWC.theOperatorList.begin())->getNetworkID() == 20404, "First entry has correct network ID\n");
// note that this block doesn't end but continues in the next chapter...
chapter("Let's connect\n");
mySP.addSerialStatement("AT+COPS=1,2,\"20420\"","\xFF\xFF"
"\r\n"
"\xd\xa^MODE:3,3\xd\xa\xd\xa+CME ERROR: no network service\xd\xa");
NetworkChanger::SwitchResults myResult = myNWC.startSwitchToNetworkID(20420);
printf("result: %d\n", myResult);
check( myResult == NetworkChanger::NOT_READY_YET,
"connecting takes time\n");
check(myNWC.isSwitchCompleted() == NetworkChanger::NOT_READY_YET,
"connecting takes more time\n");
check(myNWC.isSwitchCompleted() == NetworkChanger::ERROR,
"connecting failed... (which was expected)\n");
printf("error: '%s'\n", myNWC.getErrorMessage().ascii());
check(myNWC.getErrorMessage().contains("CME"), "the correct piece of the answer was returned as error message\n");
}
// keep this last for summary:
finish();
return 0;
}
void printAbortMessage(__attribute__ ((unused)) int aSignalNumber)
{
printf("\n\n *** " APPNAME " version " APPRELEASE " closed due to an"
" unrecoverable program error.\n"
" *** Please e-mail all of the above output to"
" umtsmon-develop@lists.sourceforge.net,\n"
" *** Or go to the " APPNAME " website and file a bug.\n\n\n");
// do not call exit here - or the signal will not be handled correctly
}

@ -0,0 +1,7 @@
NetworkOperatorWizardTester
Makefile
networkoperatorwizard.ui.h
networkoperatorwizard.ui
NetworkChanger.gcda
*.gcno
*.gcda

@ -0,0 +1,37 @@
# include a file with all the common stuff
include(../GenericTestPro.inc)
!exists(networkoperatorwizard.ui.h) {
system(ln -s ../../src/view/networkoperatorwizard.ui.h .) {}
system(ln -s ../../src/view/networkoperatorwizard.ui .) {}
}
HEADERS += \
../../src/model/ConnectionInfo.h \
../../umtsmon_global.h \
../../src/model/MonthlyTraffic.h \
../../src/controller/NetworkChanger.h \
../../src/model/OperatorList.h \
../../src/view/Popup.h \
../../src/model/Profile.h \
../../src/model/Query.h \
../../src/base/SerialPort.h \
../../src/base/TheSettingsSingleton.h
SOURCES += \
NetworkOperatorWizardTester_main.cpp \
../../src/model/ConnectionInfo.cpp \
../../src/model/MonthlyTraffic.cpp \
../../src/controller/NetworkChanger.cpp \
../../src/model/OperatorList.cpp \
../../src/model/Profile.cpp \
../../src/model/Query.cpp \
../../src/base/SerialPort.cpp \
../../src/base/TheSettingsSingleton.cpp
FORMS = \
./networkoperatorwizard.ui
IMAGES = ../../images/Wizard/NetworkOperatorWizard.png \
../../images/ok.png \
../../images/16/process-stop-16x16.png

@ -0,0 +1,115 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2008 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "Query.h"
#include "SerialPort.h"
#include "Popup.h"
#include "networkoperatorwizard.h"
#include <ntqapplication.h>
#include <ntqstring.h>
#include <assert.h>
#include <errno.h>
#include "../TestFrame.cpp"
// conveniently set theVerbosity to a number of your liking
int theVerbosity = 5;
int main( int aArgC, char* aArgV[] )
{
// I'm not entirely sure if this is allowed and/or works
errno = 0;
// welcome to user
printf("Test app is called '%s' version '%s'\n", APPNAME, APPRELEASE);
chapter("INIT\n");
SimulatedSerialPort mySP;
Query::setSerial(&mySP);
LongSerialPort myRealSP;
myRealSP.openDev("/dev/ttyUSB1", 115200);
TQApplication myApp( aArgC , aArgV );
chapter("TEST GUI - let device choose\n")
if (true)
{
// Answer that it already is automatic mode and expect the user to confirm that again.
mySP.addSerialStatement("AT+COPS?", "+COPS: 0,0,\"vodafone NL\",2\r\nOK\r\n\r\n");
mySP.addSerialStatement("AT+COPS=0", "OK\r\n\r\n");
NetworkOperatorWizard myNOW;
Popup::Info("Contrary to most test binaries, this one requires the user to click a few buttons.\nPlease click Next> Next> Finish", NULL);
myNOW.show();
check(myNOW.exec() == TQDialog::Accepted, "the user clicked FINISH\n", true);
check(mySP.wasAllSatisfied(), "no unexpected Queries arose\n", true);
check(mySP.isAllUsed(), "all expected Queries have happened\n", true);
}
chapter("TEST GUI - let user choose\n")
{
// this is one of the test strings from NetworkChangerTester, enhanced with some more
// delays - to make the GUI look more realistic
// I also removed the Huawei test string as it doesn't matter right now
mySP.addSerialStatement("AT+COPS?", "+COPS: 1,0,\"vodafone NL\",2\r\nOK\r\n\r\n");
mySP.addSerialStatement("AT+COPS=?", "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
"+COPS: (1,\"vodafone NL\",\"voda NL\","
"\"20404\",0),(2,\"vodafone NL\",\"voda NL\",\"20404\",2),(1,\"T-Mobile NL\","
"\"TMO NL\",\"20416\",0),(3,\"NL KPN\",\"NL KPN\",\"20408\",0),(3,\"NL KPN\","
"\"NL KPN\",\"20408\",2),(3,\"Orange NL\",\"Orange\",\"20420\",2),"
"(1,\"T-Mobile NL\",\"TMO NL\",\"20416\",2),(3,\"Orange NL\",\"Orange\","
"\"20420\",0),,(0,1,3,4),(0,1,2)\r\n"
"OK\r\n\r\n");
mySP.addSerialStatement("AT+COPS=1,2,\"20416\"",
"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF+COPS: 2,0,\"T-Mobile NL\",2\r\n"
"OK\r\n\r\n");
NetworkOperatorWizard myNOW;
Popup::Info("Please click Next> Next> Next> Orange OK T-Mobile Next> Finish", NULL);
myNOW.show();
check(myNOW.exec() == TQDialog::Accepted, "the user clicked FINISH\n", true);
check(mySP.wasAllSatisfied(), "no unexpected Queries arose\n", true);
check(mySP.isAllUsed(), "all expected Queries have happened\n", true);
}
// keep this last for summary:
finish();
return 0;
}
void printAbortMessage(__attribute__ ((unused)) int aSignalNumber)
{
printf("\n\n *** " APPNAME " version " APPRELEASE " closed due to an"
" unrecoverable program error.\n"
" *** Please e-mail all of the above output to"
" umtsmon-develop@lists.sourceforge.net,\n"
" *** Or go to the " APPNAME " website and file a bug.\n\n\n");
// do not call exit here - or the signal will not be handled correctly
}

@ -0,0 +1,8 @@
# include a file with all the common stuff
include(../GenericTestPro.inc)
HEADERS += ../../src/base/ObserverManager.h \
../../umtsmon_global.h
SOURCES += ObserverManagerTester_main.cpp

@ -0,0 +1,211 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006, 2007 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "ObserverManager.h"
#include <ntqstring.h>
#include <assert.h>
#include <errno.h>
#include "../TestFrame.cpp"
// conveniently set theVerbosity to a number of your liking
int theVerbosity = 5;
/** this class is a pure interface class - used to call the Observer
* in case something happens in the state of the onderlying class
*/
class OBS
{
public:
virtual void notify(void) = 0;
virtual ~OBS() {;};
};
/** Observer1 is a class interested in observing the changes, so
* it derives from OBS.
*/
class Observer1 : public OBS
{
public:
Observer1(void) : count(0) {};
void notify(void)
{
count++;
};
int count;
};
/** OMTester is the actual class implementing ObserverManager
* and it is a friend - so it can look at the internals of that class as well
*/
class OMTester : public ObserverManager<OBS>
{
public:
OMTester() {DEBUG1("OMTester constructor\n");};
virtual ~OMTester() {DEBUG1("OMTester destructor\n");};
virtual void notifyObservers(void)
{
OBS* myObserverPtr = firstObserver();
while (myObserverPtr != NULL)
{
myObserverPtr->notify();
myObserverPtr = nextObserver();
}
};
virtual void notifyObserver(OBS* anObserver) const
{
anObserver->notify();
};
int getObserverCount(void)
{
return theObserverList.size();
};
// because it inherits from ObserverManager, it also has
// attach and detach :-)
};
int main()
{
// I'm not entirely sure if this is allowed and/or works
errno = 0;
// welcome to user
printf("Test app is called '%s' version '%s'\n", APPNAME, APPRELEASE);
chapter("INIT\n");
OMTester theOMTester;
check (theOMTester.getObserverCount() == 0, "no observers yet\n", true);
Observer1 theObserver1;
check (theObserver1.count == 0, "theObserver1 initialised correctly\n", true);
Observer1 theObserver2;
check (theObserver2.count == 0, "theObserver2 initialised correctly\n", true);
chapter("Attach & Detach first observer\n");
theOMTester.attach(&theObserver1);
check (theOMTester.getObserverCount() == 1, "one observer attached\n", true);
check (theObserver1.count == 1, "theObserver1 has been notified once\n", true);
theOMTester.notifyObservers();
check (theObserver1.count == 2, "theObserver1 has been notified\n", true);
check (theOMTester.getObserverCount() == 1, "one observer attached\n", true);
theOMTester.detach(&theObserver1);
check (theOMTester.getObserverCount() == 0, "no observer attached\n", true);
check (theObserver1.count == 2, "theObserver1 has not been notified again\n", true);
theOMTester.notifyObservers();
check (theObserver1.count == 2, "theObserver1 has not been notified again\n", true);
check (theOMTester.getObserverCount() == 0, "no observer attached\n", true);
theObserver1.count = 0;
theObserver2.count = 0;
chapter("Attach & Detach two observers\n");
theOMTester.attach(&theObserver1);
theOMTester.attach(&theObserver2);
check (theOMTester.getObserverCount() == 2, "two observers attached\n", true);
theOMTester.notifyObservers();
check (theObserver1.count == 2, "theObserver1 has been notified\n", true);
check (theObserver2.count == 2, "theObserver2 has been notified\n", true);
check (theOMTester.getObserverCount() == 2, "two observer attached\n", true);
theOMTester.detach(&theObserver1);
check (theOMTester.getObserverCount() == 1, "only one observer left attached\n", true);
check (theObserver1.count == 2, "theObserver1 has not been notified again\n", true);
check (theObserver2.count == 2, "theObserver1 has not been notified again\n", true);
theOMTester.notifyObservers();
check (theObserver1.count == 2, "theObserver1 has NOT been notified\n", true);
check (theObserver2.count == 3, "theObserver2 has been notified\n", true);
check (theOMTester.getObserverCount() == 1, "only one observer left attached\n", true);
chapter("Double entries check\n");
theObserver1.count = 0;
theObserver2.count = 0;
theOMTester.attach(&theObserver1);
theOMTester.attach(&theObserver2);
check (theOMTester.getObserverCount() == 3, "three observers attached\n", true);
// so we now have #2 #1 #2 attached...
theOMTester.notifyObservers();
// observer 1: once notified on attach, once on notify
check (theObserver1.count == 2, "theObserver1 has been notified twice\n", true);
// observer 1: once notified on attach, twice on notify - the first attach was before the count was set to 0!
check (theObserver2.count == 3, "theObserver2 has been notified three times\n", true);
theOMTester.notifyObserver(&theObserver2);
check (theObserver1.count == 2, "theObserver1 has NOT been notified again\n", true);
check (theObserver2.count == 4, "theObserver2 has been notified three times now\n", true);
theOMTester.detach(&theObserver2);
check (theOMTester.getObserverCount() == 1, "only one observer left attached\n", true);
theOMTester.notifyObservers();
check (theObserver1.count == 3, "theObserver1 has been notified again\n", true);
check (theObserver2.count == 4, "theObserver2 has not been notified again\n", true);
chapter("Test Copy Constructor\n");
OMTester theOMTester2(theOMTester);
// notifying the new copy should work
theOMTester2.notifyObservers();
check (theObserver1.count == 4, "theObserver1 has been notified again\n", true);
check (theObserver2.count == 4, "theObserver2 has not been notified again\n", true);
// but the old one should still work, too
// and anything happening to the old one doesn't happen to the new one!
theOMTester.detach(&theObserver1);
theOMTester.notifyObservers();
check (theObserver1.count == 4, "theObserver1 has not been notified again\n", true);
check (theObserver2.count == 4, "theObserver2 has not been notified again\n", true);
// the new one should be unaffected
theOMTester2.attach(&theObserver2);
check (theObserver2.count == 5, "theObserver2 has been notified due to attach\n", true);
theOMTester2.notifyObservers();
check (theObserver1.count == 5, "theObserver1 has been notified again\n", true);
check (theObserver2.count == 6, "theObserver2 has been notified again\n", true);
// keep this last for summary:
finish();
return 0;
}

@ -0,0 +1,2 @@
ProfileTester
Makefile

@ -0,0 +1,12 @@
# include a file with all the common stuff
include(../GenericTestPro.inc)
HEADERS += \
../../src/base/TheSettingsSingleton.h \
../../src/model/Profile.h \
umtsmon_global.h
SOURCES += \
../../src/base/TheSettingsSingleton.cpp \
ProfileTester_main.cpp
# note that Profile.cpp is actually missing because it's #included by ProfileTester_main.cpp

@ -0,0 +1,144 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2007 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "Profile.h"
#include <assert.h>
#include <errno.h>
#include "../TestFrame.cpp"
#include "../../src/model/Profile.cpp"
#include <ntqdir.h>
// conveniently set theVerbosity to a number of your liking
int theVerbosity = 5;
int main()
{
// I'm not entirely sure if this is allowed and/or works
errno = 0;
// welcome to user
printf("Test app is called '%s' version '%s'\n", APPNAME, APPRELEASE);
// and check if the APPNAME is correct
check(TQString(APPNAME) != TQString("umtsmon"), "Tester is not called umtsmon\n", true);
// a config file of this tester should be called $HOME/.umtsmontester/umtsmontesterrc
// Let's check if such directory exists, and kill it
TQString mySettingsLocation = TQDir::homeDirPath() + "/." + APPNAME;
TQString mySettingsFile = mySettingsLocation + "/" + APPNAME + "rc";
TQString mySettingsLockFile = mySettingsLocation + "/." + APPNAME + "rc.lock";
TQDir mySettingsDir(mySettingsLocation);
if (mySettingsDir.exists())
{
testmsg("** removing settingsdir %s\n", mySettingsLocation.ascii());
check (mySettingsDir.remove(mySettingsFile), "removal of exisiting file '"
+ mySettingsFile + "'\n");
check (mySettingsDir.remove(mySettingsLockFile), "removal of exisiting file '"
+ mySettingsLockFile + "'\n");
check (mySettingsDir.rmdir(mySettingsLocation), "removal of exisiting dir '"
+ mySettingsLocation + "'\n", true);
}
check(!mySettingsDir.exists(), "settings directory " + mySettingsLocation
+ " does not exist (anymore)\n");
// let's create a naive profile and save and kill it and see if it persists
{
Profile myFirst("First");
myFirst.setAPN("FirstOne");
myFirst.setUsername("Klaas");
myFirst.setPassword("Secret");
myFirst.save();
check(Profile::getProfileList().contains("First"), "Profile First exists\n", true);
}
{
Profile myFirst("First");
Profile mySecond("Second");
check(myFirst.getAPN() == "FirstOne", "APN was persistent - good\n", true);
check(myFirst.getUsername() == "Klaas", "Username was persistent - good\n", true);
check(myFirst.getPassword() == "Secret", "Password was persistent - good\n", true);
check(mySecond.getAPN() == "", "APN did not smear out to other profiles - good\n", true);
check(Profile::getProfileList().contains("First"), "Profile First exists\n", true);
check(Profile::getProfileList().contains("Second")==0, "Profile Second does not exist - good\n", true);
}
// let's test the active profile thingies
check(Profile::setActiveProfile("Second") == false, "Cannot set Second active as it doesn't exist\n");
check(Profile::setActiveProfile("First"), "set First active succeeds\n");
check(Profile::getActiveProfileName() == "First", "First is now the active profile\n");
check(Profile::setActiveProfile("Wrong")==false, "setting Wrong profile fails - good\n");
check(Profile::getActiveProfileName() == "First", "First is still the active profile\n");
{
Profile mySecond("Second");
mySecond.setAPN("SecondTwo");
mySecond.setIsDefaultRoute(false); // set it to opposite of default
mySecond.setNoIpDefault(true); // set it to opposite of default
mySecond.setReplaceDefaultRoute(false); // set it to opposite of default
mySecond.save();
}
check(Profile::getActiveProfileName() == "First", "First is again the active profile\n");
check(Profile::setActiveProfile("Second"), "set Second active succeeds\n");
check(Profile::getActiveProfileName() == "Second", "Second is now the active profile\n");
check(Profile::setActiveProfile("Wrong")==false, "setting Wrong profile fails - good\n");
check(Profile::getActiveProfileName() == "Second", "Second is still the active profile\n");
{
// method one to create a Default profile
Profile myActive;
check(myActive.getProfileName() == "Second", "An unspecified Profile will be of Second type\n");
check(myActive.getIsDefaultRoute() == false, "IsDefaultRoute is false - good\n");
check(myActive.getNoIpDefault() == true, "NoIpDefault is true - good\n");
check(myActive.getReplaceDefaultRoute() == false, "ReplaceDefaultRoute is false - good\n");
}
{
// method two to create a Default profile
Profile myActive2("");
check(myActive2.getProfileName() == "Second", "An unnamed Profile will be of Second type\n");
}
// Second is now active. If we remove it, First should be made active automatically
{
Profile mySecond("Second");
check(mySecond.remove(), "Removal was OK\n");
}
check(Profile::getProfileList().contains("Second")==0, "Profile Second does not exist anymore - good\n", true);
check(Profile::getActiveProfileName() == "First", "First is again the active profile\n", true);
{
// let's use method one to create a Default profile again
Profile myActive;
check(myActive.getProfileName() == "First", "An unspecified Profile will be of First type now\n");
check(myActive.getIsDefaultRoute() == true, "IsDefaultRoute is true - good\n");
check(myActive.getNoIpDefault() == false, "NoIpDefault is false - good\n");
check(myActive.getReplaceDefaultRoute() == true, "ReplaceDefaultRoute is true - good\n");
}
// keep this last for summary:
finish();
return 0;
}

@ -0,0 +1,26 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// just use the original umtsmon_global
#include "../../umtsmon_global.h"
// except for the app name
#undef APPNAME
#define APPNAME "umtsmontester"

@ -0,0 +1,11 @@
# include a file with all the common stuff
include(../GenericTestPro.inc)
HEADERS += \
../../src/model/Query.h \
../../umtsmon_global.h \
../../src/base/SerialPort.h
SOURCES += QueryTester_main.cpp \
../../src/model/Query.cpp \
../../src/base/SerialPort.cpp

@ -0,0 +1,79 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006, 2007 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "Query.h"
#include "SerialPort.h"
#include <ntqstring.h>
#include <assert.h>
#include <errno.h>
#include "../TestFrame.cpp"
// conveniently set theVerbosity to a number of your liking
int theVerbosity = 5;
int main()
{
// I'm not entirely sure if this is allowed and/or works
errno = 0;
// welcome to user
printf("Test app is called '%s' version '%s'\n", APPNAME, APPRELEASE);
printf("\n*** INIT\n");
SimulatedSerialPort mySP;
mySP.addSerialStatement("AT","OK");
mySP.addSerialStatement("AT","ERROR");
Query::setSerial(&mySP);
{
Query myQuery("AT");
check(myQuery.runUntilDone() == Query::OK, "Query was OK\n");
}
printf("\n*** PART2\n");
{
Query myQuery("AT");
check(myQuery.runUntilDone() == Query::ERROR, "Query was not OK - as expected\n");
}
// keep this last for summary:
finish();
return 0;
}
void printAbortMessage(__attribute__ ((unused)) int aSignalNumber)
{
printf("\n\n *** " APPNAME " version " APPRELEASE " closed due to an"
" unrecoverable program error.\n"
" *** Please e-mail all of the above output to"
" umtsmon-develop@lists.sourceforge.net,\n"
" *** Or go to the " APPNAME " website and file a bug.\n\n\n");
// do not call exit here - or the signal will not be handled correctly
}

@ -0,0 +1,14 @@
# include a file with all the common stuff
include(../GenericTestPro.inc)
# contrary to e.g. SettingsTester, I don't need to
# copy the Runner.* files here because they will work
# regardless of the location they're compiled in.
HEADERS += ../../src/base/Runner.h \
../../src/base/FileStuff.h \
umtsmon_global.h
SOURCES += ../../src/base/Runner.cpp \
../../src/base/FileStuff.cpp \
RunnerTester_main.cpp

@ -0,0 +1,126 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006, 2007 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "umtsmon_global.h"
#include "Runner.h"
#include <ntqstring.h>
#include <ntqstringlist.h>
#include <ntqfile.h>
#include <ntqfileinfo.h>
#include <ntqdatetime.h>
#include <assert.h>
#include <errno.h>
#include "../TestFrame.cpp"
// conveniently set theVerbosity to a number of your liking
int theVerbosity = 5;
int runChild(void)
{
fprintf(stdout, "hello on stdout 1\n");
fprintf(stderr, "hello on stderr 1\n");
sleep(1);
fprintf(stdout, "hello on stdout 2\n");
fprintf(stderr, "hello on stderr 2\n");
sleep(3);
return 0;
}
int main(int argc, __attribute__ ((unused)) char* argv[])
{
if (argc==2)
return runChild();
// I'm not entirely sure if this is allowed and/or works
errno = 0;
// welcome to user
printf("Test app is called '%s' version '%s'\n", APPNAME, APPRELEASE);
// and check if the APPNAME is correct
check(TQString(APPNAME) != TQString("umtsmon"), "Tester is not called umtsmon\n", true);
Runner myRunner;
check(myRunner.amIRoot()==false, "This app is not run as root - good\n", true);
printf("*** warning: the next test takes approx 6 seconds to complete\n");
check(myRunner.runCommand(Runner::RUNNERTESTER,"child") == 0, "the stdout/stderr test returned ok\n");
check(myRunner.getStdOutStringList().size()==2, "two strings on stdout\n");
check(myRunner.getStdErrStringList().size()==2, "two strings on stderr\n");
// let's try to create a file "hello" in /
check(myRunner.runCommand(Runner::SOMESU,"/usr/bin/touch /hello") == 0,
"(kde|gnome)su returned success\n", true);
check(TQFile::exists("/hello"), "/hello indeed exists\n");
TQFileInfo myFI("/hello");
check( myFI.lastModified() >= TQDateTime::currentDateTime().addSecs(-5),
"/hello was created/modified during the last 5 seconds\n");
//try to execute some commands in an shell
//first attempt - all commands in one string
check(myRunner.runCommand(Runner::SOMESU,"/bin/sh -c \"echo hello >> /hello; wc -l /hello >/hello2;\"") == 0,
"(kde|gnome)su returned success for shell exec, first attempt\n");
check(TQFile::exists("/hello2"), "/hello2 exists\n");
TQFileInfo myFI2("/hello2");
check( myFI2.lastModified() >= TQDateTime::currentDateTime().addSecs(-5),
"/hello2 was created/modified during the last 5 seconds\n This is known to work with \"tdesudo\"\n");
//second attempt
TQStringList myCommands = "/bin/sh";
myCommands += "-c";
myCommands += "echo hello >> /hello; wc -l /hello >/hello3";
check(myRunner.runCommand(Runner::SOMESU,myCommands)==0,
"(kde|gnome)su returned success for shell exec, second attempt\n");
check(TQFile::exists("/hello3"), "/hello3 exists\n");
TQFileInfo myFI3("/hello3");
check( myFI3.lastModified() >= TQDateTime::currentDateTime().addSecs(-5),
"/hello3 was created/modified during the last 5 seconds\n This is known to work with \"gksu\"\n");
// let's check if pccardctl actually is SUID,
// because otherwise the 'eject' won't work
if (!myRunner.isSUID(Runner::PCCARDCTL))
{
// uh-oh, we need to suid it...
check(myRunner.runCommand(Runner::SOMESU,
"/bin/chmod +s "+myRunner.getPath(Runner::PCCARDCTL) ) == 0,
"setting suid of pccardctl succeeded\n");
}
// let's try to eject a PCMCIA card
check (myRunner.runCommand(Runner::PCCARDCTL, "eject") == 0,
"pccardctl succeeded in eject\n");
myRunner.runCommand(Runner::PPPD, "--help");
printf(" --- first line output of `pppd --help`: '%s'\n",
myRunner.getStdErrStringList()[0].ascii());
check(myRunner.getStdErrStringList()[0].contains("version"), "pppd shows version\n");
// keep this last for summary:
finish();
return 0;
}

@ -0,0 +1,26 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// just use the original umtsmon_global
#include "../../umtsmon_global.h"
// except for the app name
#undef APPNAME
#define APPNAME "RunnerTester"

@ -0,0 +1,5 @@
SettingsTester
Makefile
TheSettingsSingleton.cpp
TheSettingsSingleton.h

@ -0,0 +1,14 @@
# include a file with all the common stuff
include(../GenericTestPro.inc)
!exists(TheSettingsSingleton.h) {
system(ln -s ../../src/base/TheSettingsSingleton.h .) {}
system(ln -s ../../src/base/TheSettingsSingleton.cpp .) {}
}
HEADERS += TheSettingsSingleton.h \
./umtsmon_global.h
SOURCES += TheSettingsSingleton.cpp \
SettingsTester_main.cpp

@ -0,0 +1,148 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// use the local header files!!!
#include "umtsmon_global.h"
#include "TheSettingsSingleton.h"
#include <ntqstring.h>
#include <ntqstringlist.h>
#include <ntqdir.h>
#include <assert.h>
#include <errno.h>
/* This is an automated test program to test various functionality of
* TheSettingsSingleton
*
* It should be run at least once before every release - any issues should be fixed.
*
* NOTE: THIS CODE HAS KNOWLEDGE ABOUT THE INTERNALS OF TheSettingsSingleton
* DON'T COPY CODE FROM THIS TESTER INTO YOUR CODE
* DON'T ASSUME THAT ANY CODE IN HERE STAYS THE SAME
*/
#include "../TestFrame.cpp"
// conveniently set theVerbosity to a number of your liking
int theVerbosity = 5;
int main( void )
{
// I'm not entirely sure if this is allowed and/or works
errno = 0;
// welcome to user
printf("Test app is called '%s' version '%s'\n", APPNAME, APPRELEASE);
// and check if the APPNAME is correct
check(TQString(APPNAME) != TQString("umtsmon"), "Tester is not called umtsmon\n", true);
// a config file of this tester should be called $HOME/.umtsmontester/umtsmontesterrc
// Let's check if such directory exists, and kill it
TQString mySettingsLocation = TQDir::homeDirPath() + "/." + APPNAME;
TQString mySettingsFile = mySettingsLocation + "/" + APPNAME + "rc";
TQString mySettingsLockFile = mySettingsLocation + "/." + APPNAME + "rc.lock";
TQDir mySettingsDir(mySettingsLocation);
if (mySettingsDir.exists())
{
testmsg("** removing settingsdir %s\n", mySettingsLocation.ascii());
check (mySettingsDir.remove(mySettingsFile), "removal of exisiting file '"
+ mySettingsFile + "'\n");
check (mySettingsDir.remove(mySettingsLockFile), "removal of exisiting file '"
+ mySettingsLockFile + "'\n");
check (mySettingsDir.rmdir(mySettingsLocation), "removal of exisiting dir '"
+ mySettingsLocation + "'\n", true);
}
check(!mySettingsDir.exists(), "settings directory " + mySettingsLocation
+ " does not exist (anymore)\n");
//////////////////////////////////////////////////////////////////
// add a settings and save settings
chapter("Reading/Writing of settings and persistancy checks\n");
TQString myTestString = "was here";
TheSettingsSingleton::getTQSRef().writeEntry(APPNAME, myTestString);
check (myTestString == TheSettingsSingleton::getTQSRef().readEntry(APPNAME, "nope"),
"setting is present\n");
TheSettingsSingleton::makeChangesPersistent();
// this should result in a file... let's check...
check(mySettingsDir.exists(), "settings directory " + mySettingsLocation
+ " now exists (again)\n", true);
// check for real persistancy - the setting should still be present
check (myTestString == TheSettingsSingleton::getTQSRef().readEntry(APPNAME, "nope"),
"setting is apparently persistent\n", true);
// check for changeing and persistance as well
myTestString = "was here, too";
TheSettingsSingleton::getTQSRef().writeEntry(APPNAME, myTestString);
TheSettingsSingleton::makeChangesPersistent();
check (myTestString == TheSettingsSingleton::getTQSRef().readEntry(APPNAME, "nope"),
"change is apparently present\n");
// check for changeing to bool
TheSettingsSingleton::getTQSRef().writeEntry(APPNAME, true);
TheSettingsSingleton::makeChangesPersistent();
check (TheSettingsSingleton::getTQSRef().readEntry(APPNAME, false),
"change string setting to bool is allowed\n");
//////////////////////////////////////////////////////////////////
// tests for removeSubTree()
chapter("reading/writing/traversing/deleting setting trees\n");
TQString myBase = "/profile";
TheSettingsSingleton::getTQSRef().writeEntry(myBase + "/1", "1");
TheSettingsSingleton::getTQSRef().writeEntry(myBase + "/2", "2");
TheSettingsSingleton::getTQSRef().writeEntry(myBase + "/2/a", "a");
TheSettingsSingleton::getTQSRef().writeEntry(myBase + "/2/b", "b");
TheSettingsSingleton::getTQSRef().writeEntry(myBase + "/2/z/c", "c");
TheSettingsSingleton::getTQSRef().writeEntry(myBase + "/2/z/d", "d");
TheSettingsSingleton::getTQSRef().writeEntry(myBase + "/2/y/e", "e");
TheSettingsSingleton::getTQSRef().writeEntry(myBase + "/2/x/f", "f");
TheSettingsSingleton::getTQSRef().writeEntry(myBase + "/3", "3");
check ("3" == TheSettingsSingleton::getTQSRef().readEntry(myBase + "/3", "1"),
"tree setting present\n", true);
// check if the entryList and subkeyList return expected info
check( TheSettingsSingleton::getTQSRef().entryList(myBase).count() == 3,
"there are 3 direct entries in "+ myBase + "\n");
check( TheSettingsSingleton::getTQSRef().subkeyList(myBase).count() == 1,
"there is 1 3 sub key in "+ myBase + "\n");
check( TheSettingsSingleton::getTQSRef().entryList(myBase+"/2/z").count() == 2,
"there are 2 direct entries in " + myBase + "/2/z\n");
check( TheSettingsSingleton::getTQSRef().subkeyList(myBase+"/2").count() == 3,
"there are 3 sub keys in " + myBase + "/2\n");
// let's delete the SubTree
check(TheSettingsSingleton::removeSubTree(myBase), "removeSubTree returned ok\n", true);
// let's check the results afterwards:
check( TheSettingsSingleton::getTQSRef().entryList(myBase).count() == 0,
"there are 0 direct entries in "+ myBase + "\n");
check( TheSettingsSingleton::getTQSRef().subkeyList(myBase).count() == 0,
"there are 0 sub keys in "+ myBase + "\n");
// keep this last for summary:
finish();
}

@ -0,0 +1,26 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// just use the original umtsmon_global
#include "../../umtsmon_global.h"
// except for the app name
#undef APPNAME
#define APPNAME "umtsmontester"

@ -0,0 +1,68 @@
/* umtsmon - a program to control/monitor your UMTS card
* Copyright (C) 2006 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <unistd.h>
#include <stdlib.h>
#include <ntqstring.h>
// conveniently set theVerbosity to a number of your liking
extern int theVerbosity;
int theNumberOfOKs = 0;
int theNumberOfFAILs = 0;
#define testmsg(format, ...) printf(" " format, ## __VA_ARGS__);
#define chapter(format, ...) printf("\n** " format, ## __VA_ARGS__);
void finish(int anExit=0)
{
int myTotal = theNumberOfOKs + theNumberOfFAILs;
assert(myTotal > 0);
printf("\nSummary:\n--------\n");
printf("Number of OKs : % 3d, (% 4d %%)\n",
theNumberOfOKs, (100*theNumberOfOKs)/myTotal);
printf("Number of FAILs: % 3d, (% 4d %%)\n\n",
theNumberOfFAILs, (100*theNumberOfFAILs)/myTotal);
exit(anExit);
}
bool check(bool aCondition, const TQString& aMessage, bool abortIfWrong=false)
{
if (aCondition)
{
TQString myTotalLine ="* \033[1m\033[32mOK\033[m : " + aMessage;
printf (myTotalLine.ascii());
theNumberOfOKs++;
}
else
{
printf(("* \033[1m\033[31mFAIL: " + aMessage + "\033[m").ascii());
testmsg("the strerror might help: '%s'\n", strerror(errno));
theNumberOfFAILs++;
if (abortIfWrong)
{
printf("*****************************\nFATAL FAIL\n");
finish(35);
}
}
return aCondition;
}

@ -0,0 +1,22 @@
[Desktop Entry]
Comment=control your 3G mobile devices
Comment[en_US]=control your 3G mobile devices
Comment[de]=Verwalte dein UMTS/GPRS-PCMCIA-Modem
Comment[nl]=Bestuur je mobiele netwerk apparaat
Encoding=UTF-8
Exec=umtsmon
GenericName=umtsmon - control your 3G mobile devices
GenericName[en_US]=umtsmon - control your 3G mobile devices
Icon=umtsmon-128x128.png
MimeType=
Name=umtsmon
Name[en_US]=umtsmon
Name[de]=umtsmon
Path=
StartupNotify=true
Terminal=false
Type=Application
X-TDE-SubstituteUID=false
X-TDE-StartupNotify=true
Categories=Qt;TDE;Network;Dialup;

@ -0,0 +1,186 @@
TEMPLATE = app
LANGUAGE = C++
# install prefix
# can be overridden with PREFIX environment variable
PREFIX=/usr/local
CONFIG += tqt warn_on release
LIBS += -lusb
DEFINES += QT_NO_ASCII_CAST
INCLUDEPATH += src/model src/view src/base src/controller /usr/include/tqt /usr/include/tqt3
#CXXFLAGS += -ggdb3 -O0
HEADERS += umtsmon_global.h \
src/base/FileStuff.h \
src/base/Internationalisation.h \
src/base/ObserverManager.h \
src/base/Runner.h \
src/base/SerialPort.h \
src/base/TheSettingsSingleton.h \
src/controller/AutoDetect.h \
src/controller/NetworkChanger.h \
src/controller/SIMHandler.h \
src/controller/TheDeviceManagerSingleton.h \
src/controller/ValidatePIN.h \
src/controller/ValidatePhoneNumber.h \
src/model/ConnectionInfo.h \
src/model/Device.h \
src/model/DeviceCapabilities.h \
src/model/HelperList.h \
src/model/MonthlyTraffic.h \
src/model/OperatorList.h \
src/model/PPPConnection.h \
src/model/Profile.h \
src/model/Query.h \
src/view/LCDDisplay.h \
src/view/Popup.h \
src/view/ProgressDialog.h \
src/view/radiopreferences_defines.h \
src/view/SetLanguageDialog.h \
src/view/UIState.h
SOURCES += main.cpp \
src/base/FileStuff.cpp \
src/base/Internationalisation.cpp \
src/base/Runner.cpp \
src/base/SerialPort.cpp \
src/base/TheSettingsSingleton.cpp \
src/controller/AutoDetect.cpp \
src/controller/NetworkChanger.cpp \
src/controller/SIMHandler.cpp \
src/controller/TheDeviceManagerSingleton.cpp \
src/model/ConnectionInfo.cpp \
src/model/Device.cpp \
src/model/HelperList.cpp \
src/model/MonthlyTraffic.cpp \
src/model/OperatorList.cpp \
src/model/PPPConnection.cpp \
src/model/Profile.cpp \
src/model/Query.cpp \
src/view/Popup.cpp \
src/view/ProgressDialog.cpp \
src/view/LCDDisplay.cpp \
src/view/SetLanguageDialog.cpp \
src/view/UIState.cpp
FORMS = src/view/newprofiledialog.ui \
src/view/enterpindialog.ui \
src/view/enterpukdialog.ui \
src/view/aboutdialog.ui \
src/view/infodialog.ui \
src/view/smsdialog.ui \
mainwindow.ui \
src/view/profiledialog.ui \
src/view/helperlistgui.ui \
src/view/PPPErrorLogsDialog.ui \
src/view/radiopreferences.ui \
src/view/manageprofiles.ui \
src/view/networkoperatorwizard.ui \
src/view/popupwithmemory.ui \
src/view/yesnowithmemory.ui
IMAGES = images/22/address-book-new-22x22.png \
images/22/document-new-22x22.png \
images/22/document-save-22x22.png \
images/22/network-transmit-receive-22x22.png \
images/22/network-offline-22x22.png \
images/22/network-wireless-22x22.png \
images/22/mail-message-new-22x22.png \
images/22/applications-system-22x22.png \
images/22/view-refresh-22x22.png \
images/22/umtsmon-22x22.png \
images/16/address-book-new-16x16.png \
images/16/applications-system-16x16.png \
images/16/dialog-information-16x16.png \
images/16/document-new-16x16.png \
images/16/document-save-16x16.png \
images/16/help-browser-16x16.png \
images/16/mail-message-new-16x16.png \
images/16/network-wireless-16x16.png \
images/16/process-stop-16x16.png \
images/16/system-log-out-16x16.png \
images/16/system-search-16x16.png \
images/16/umtsmon-16x16.png \
images/16/user-trash-full-16x16.png \
images/16/view-refresh-16x16.png \
images/ok.png \
images/LCDDisplay/LCDBackground.png \
images/LCDDisplay/LCDSignal.png \
images/Wizard/NetworkOperatorWizard.png
DISTFILES = \
README \
TODO \
AUTHORS \
COPYING
unix {
UI_DIR = .ui
MOC_DIR = .moc
OBJECTS_DIR = .obj
}
TRANSLATIONS = \
i18n/umtsmon_de.ts \
i18n/umtsmon_es.ts \
i18n/umtsmon_id.ts \
i18n/umtsmon_it.ts \
i18n/umtsmon_nb_NO.ts \
i18n/umtsmon_nl.ts \
i18n/umtsmon_pl.ts \
i18n/umtsmon_pt_BR.ts \
i18n/umtsmon_pt_PT.ts \
i18n/umtsmon_ru.ts \
i18n/umtsmon_sv.ts
# build translations
translations_qm = ${TRANSLATIONS}
translations_qm ~= s/\.ts/.qm/g
lupdate.target=$${TRANSLATIONS}
lupdate.commands=lupdate -verbose umtsmon.pro
lupdate.depends=$${HEADERS} $${SOURCES} $${FORMS} umtsmon.pro
lrelease.target=$${translations_qm}
lrelease.commands=lrelease -verbose umtsmon.pro
lrelease.depends=$${TRANSLATIONS}
aboutdialog.target=src/view/aboutdialog.ui
aboutdialog.commands=sed -e '/@AUTHORS@/rAUTHORS' -e '/@COPYING@/rCOPYING' src/view/aboutdialog.base.ui -e '/@COPYING@/d;/@AUTHORS@/d' > src/view/aboutdialog.ui
aboutdialog.depends=AUTHORS COPYING src/view/aboutdialog.base.ui
#
TQMAKE_EXTRA_UNIX_TARGETS += lupdate lrelease
TQMAKE_EXTRA_UNIX_TARGETS += aboutdialog
POST_TARGETDEPS = $${lupdate.target} $${lrelease.target}
# make install rules
env_prefix=$$(PREFIX)
!isEmpty(env_prefix) {
PREFIX=$${env_prefix}
}
target.path=$${PREFIX}/bin
trans.files=$${translations_qm}
trans.path=$${PREFIX}/share/umtsmon/translations
desktop.files=umtsmon.desktop
desktop.path=$${PREFIX}/share/applications
icon128.files=images/128/umtsmon-128x128.png
icon128.path=$${PREFIX}/share/icons/hicolor/128x128/apps
INSTALLS += target trans desktop icon128
TQMAKE_CLEAN += \
src/view/aboutdialog.ui \
$${translations_qm} \
umtsmon

@ -0,0 +1,52 @@
/* umtsmon - a program to control/monitor your UMTS card
* This file copyright (C) 2006,2007,2008,2009 Klaas van Gend
*
* 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
* applicable version is GPL version 2 only.
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef UMTSMON_GLOBAL
#define UMTSMON_GLOBAL
#define APPNAME "umtsmon"
#define APPRELEASE "0.9.72"
/* for your special versioning needs, normally empty */
#ifndef APPFLAVOUR
#define APPFLAVOUR ""
#endif
/* Debug verbosity
* level 1 = very little information, autodetect KILLING
* level 2 = level 1 + autodetect GOOD/BAD + some general messages on behaviour
* level 3 = level 2 + autodetect INFO
* level 4 = level 3 + AT commands and answers
* level 5 = all debugging, including entry of functions under scrutiny
* level 6 = timing info on serial port
*/
#include <stdio.h>
#include <time.h>
extern int theVerbosity; // actually defined in main.cpp
extern int thePPPVerbosity;
#define MAX_VERBOSITY 6
// note: the below is actually GCC-specific, see "info:/gcc/Variadic Macros"
#define DEBUG1(format, ...) {if (theVerbosity>=1) printf("##P1 t=%03ld: " format, time(NULL)%1000, ## __VA_ARGS__);}
#define DEBUG2(format, ...) {if (theVerbosity>=2) printf("##P2 t=%03ld: " format, time(NULL)%1000, ## __VA_ARGS__);}
#define DEBUG3(format, ...) {if (theVerbosity>=3) printf("##P3 t=%03ld: " format, time(NULL)%1000, ## __VA_ARGS__);}
#define DEBUG4(format, ...) {if (theVerbosity>=4) printf("##P4 t=%03ld: " format, time(NULL)%1000, ## __VA_ARGS__);}
#define DEBUG4NT(format, ...) {if (theVerbosity>=4) printf(format, ## __VA_ARGS__);}
#define DEBUG5(format, ...) {if (theVerbosity>=5) printf("##P5 t=%03ld: " format, time(NULL)%1000, ## __VA_ARGS__);}
#define DEBUG6(format, ...) {if (theVerbosity>=6) printf("##P6 t=%03ld: " format, time(NULL)%1000, ## __VA_ARGS__);}
#endif // UMTSMON_GLOBAL
Loading…
Cancel
Save