mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-03-13 20:50:41 +00:00
gsmopen: re-added gsmlib
This commit is contained in:
parent
61894c23ae
commit
3747375196
8
src/mod/endpoints/mod_gsmopen/gsmlib/README
Normal file
8
src/mod/endpoints/mod_gsmopen/gsmlib/README
Normal file
@ -0,0 +1,8 @@
|
||||
For Linux distros without gsmlib (eg: CentOS):
|
||||
|
||||
Here are the original (ancient) sources for gsmlib, and the patch made by Ubuntu for modern compilers.
|
||||
|
||||
In the directory gsmlib-1.10-patched-13ubuntu are the patched sources, ready for (no need to patch them again):
|
||||
./configure
|
||||
make
|
||||
make install
|
@ -0,0 +1,226 @@
|
||||
Notes on the Free Translation Project
|
||||
*************************************
|
||||
|
||||
Free software is going international! The Free Translation Project
|
||||
is a way to get maintainers of free software, translators, and users all
|
||||
together, so that will gradually become able to speak many languages.
|
||||
A few packages already provide translations for their messages.
|
||||
|
||||
If you found this `ABOUT-NLS' file inside a distribution, you may
|
||||
assume that the distributed package does use GNU `gettext' internally,
|
||||
itself available at your nearest GNU archive site. But you do *not*
|
||||
need to install GNU `gettext' prior to configuring, installing or using
|
||||
this package with messages translated.
|
||||
|
||||
Installers will find here some useful hints. These notes also
|
||||
explain how users should proceed for getting the programs to use the
|
||||
available translations. They tell how people wanting to contribute and
|
||||
work at translations should contact the appropriate team.
|
||||
|
||||
When reporting bugs in the `intl/' directory or bugs which may be
|
||||
related to internationalization, you should tell about the version of
|
||||
`gettext' which is used. The information can be found in the
|
||||
`intl/VERSION' file, in internationalized packages.
|
||||
|
||||
One advise in advance
|
||||
=====================
|
||||
|
||||
If you want to exploit the full power of internationalization, you
|
||||
should configure it using
|
||||
|
||||
./configure --with-included-gettext
|
||||
|
||||
to force usage of internationalizing routines provided within this
|
||||
package, despite the existence of internationalizing capabilities in the
|
||||
operating system where this package is being installed. So far, only
|
||||
the `gettext' implementation in the GNU C library version 2 provides as
|
||||
many features (such as locale alias or message inheritance) as the
|
||||
implementation here. It is also not possible to offer this additional
|
||||
functionality on top of a `catgets' implementation. Future versions of
|
||||
GNU `gettext' will very likely convey even more functionality. So it
|
||||
might be a good idea to change to GNU `gettext' as soon as possible.
|
||||
|
||||
So you need not provide this option if you are using GNU libc 2 or
|
||||
you have installed a recent copy of the GNU gettext package with the
|
||||
included `libintl'.
|
||||
|
||||
INSTALL Matters
|
||||
===============
|
||||
|
||||
Some packages are "localizable" when properly installed; the
|
||||
programs they contain can be made to speak your own native language.
|
||||
Most such packages use GNU `gettext'. Other packages have their own
|
||||
ways to internationalization, predating GNU `gettext'.
|
||||
|
||||
By default, this package will be installed to allow translation of
|
||||
messages. It will automatically detect whether the system provides
|
||||
usable `catgets' (if using this is selected by the installer) or
|
||||
`gettext' functions. If neither is available, the GNU `gettext' own
|
||||
library will be used. This library is wholly contained within this
|
||||
package, usually in the `intl/' subdirectory, so prior installation of
|
||||
the GNU `gettext' package is *not* required. Installers may use
|
||||
special options at configuration time for changing the default
|
||||
behaviour. The commands:
|
||||
|
||||
./configure --with-included-gettext
|
||||
./configure --with-catgets
|
||||
./configure --disable-nls
|
||||
|
||||
will respectively bypass any pre-existing `catgets' or `gettext' to use
|
||||
the internationalizing routines provided within this package, enable
|
||||
the use of the `catgets' functions (if found on the locale system), or
|
||||
else, *totally* disable translation of messages.
|
||||
|
||||
When you already have GNU `gettext' installed on your system and run
|
||||
configure without an option for your new package, `configure' will
|
||||
probably detect the previously built and installed `libintl.a' file and
|
||||
will decide to use this. This might be not what is desirable. You
|
||||
should use the more recent version of the GNU `gettext' library. I.e.
|
||||
if the file `intl/VERSION' shows that the library which comes with this
|
||||
package is more recent, you should use
|
||||
|
||||
./configure --with-included-gettext
|
||||
|
||||
to prevent auto-detection.
|
||||
|
||||
By default the configuration process will not test for the `catgets'
|
||||
function and therefore they will not be used. The reasons are already
|
||||
given above: the emulation on top of `catgets' cannot provide all the
|
||||
extensions provided by the GNU `gettext' library. If you nevertheless
|
||||
want to use the `catgets' functions use
|
||||
|
||||
./configure --with-catgets
|
||||
|
||||
to enable the test for `catgets' (this causes no harm if `catgets' is
|
||||
not available on your system). If you really select this option we
|
||||
would like to hear about the reasons because we cannot think of any
|
||||
good one ourself.
|
||||
|
||||
Internationalized packages have usually many `po/LL.po' files, where
|
||||
LL gives an ISO 639 two-letter code identifying the language. Unless
|
||||
translations have been forbidden at `configure' time by using the
|
||||
`--disable-nls' switch, all available translations are installed
|
||||
together with the package. However, the environment variable `LINGUAS'
|
||||
may be set, prior to configuration, to limit the installed set.
|
||||
`LINGUAS' should then contain a space separated list of two-letter
|
||||
codes, stating which languages are allowed.
|
||||
|
||||
Using This Package
|
||||
==================
|
||||
|
||||
As a user, if your language has been installed for this package, you
|
||||
only have to set the `LANG' environment variable to the appropriate
|
||||
ISO 639 `LL' two-letter code prior to using the programs in the
|
||||
package. For example, let's suppose that you speak German. At the
|
||||
shell prompt, merely execute `setenv LANG de' (in `csh'),
|
||||
`export LANG; LANG=de' (in `sh') or `export LANG=de' (in `bash'). This
|
||||
can be done from your `.login' or `.profile' file, once and for all.
|
||||
|
||||
An operating system might already offer message localization for
|
||||
many of its programs, while other programs have been installed locally
|
||||
with the full capabilities of GNU `gettext'. Just using `gettext'
|
||||
extended syntax for `LANG' would break proper localization of already
|
||||
available operating system programs. In this case, users should set
|
||||
both `LANGUAGE' and `LANG' variables in their environment, as programs
|
||||
using GNU `gettext' give preference to `LANGUAGE'. For example, some
|
||||
Swedish users would rather read translations in German than English for
|
||||
when Swedish is not available. This is easily accomplished by setting
|
||||
`LANGUAGE' to `sv:de' while leaving `LANG' to `sv'.
|
||||
|
||||
Translating Teams
|
||||
=================
|
||||
|
||||
For the Free Translation Project to be a success, we need interested
|
||||
people who like their own language and write it well, and who are also
|
||||
able to synergize with other translators speaking the same language.
|
||||
Each translation team has its own mailing list, courtesy of Linux
|
||||
International. You may reach your translation team at the address
|
||||
`LL@li.org', replacing LL by the two-letter ISO 639 code for your
|
||||
language. Language codes are *not* the same as the country codes given
|
||||
in ISO 3166. The following translation teams exist, as of December
|
||||
1997:
|
||||
|
||||
Chinese `zh', Czech `cs', Danish `da', Dutch `nl', English `en',
|
||||
Esperanto `eo', Finnish `fi', French `fr', German `de', Hungarian
|
||||
`hu', Irish `ga', Italian `it', Indonesian `id', Japanese `ja',
|
||||
Korean `ko', Latin `la', Norwegian `no', Persian `fa', Polish
|
||||
`pl', Portuguese `pt', Russian `ru', Slovenian `sl', Spanish `es',
|
||||
Swedish `sv', and Turkish `tr'.
|
||||
|
||||
For example, you may reach the Chinese translation team by writing to
|
||||
`zh@li.org'.
|
||||
|
||||
If you'd like to volunteer to *work* at translating messages, you
|
||||
should become a member of the translating team for your own language.
|
||||
The subscribing address is *not* the same as the list itself, it has
|
||||
`-request' appended. For example, speakers of Swedish can send a
|
||||
message to `sv-request@li.org', having this message body:
|
||||
|
||||
subscribe
|
||||
|
||||
Keep in mind that team members are expected to participate
|
||||
*actively* in translations, or at solving translational difficulties,
|
||||
rather than merely lurking around. If your team does not exist yet and
|
||||
you want to start one, or if you are unsure about what to do or how to
|
||||
get started, please write to `translation@iro.umontreal.ca' to reach the
|
||||
coordinator for all translator teams.
|
||||
|
||||
The English team is special. It works at improving and uniformizing
|
||||
the terminology in use. Proven linguistic skill are praised more than
|
||||
programming skill, here.
|
||||
|
||||
Available Packages
|
||||
==================
|
||||
|
||||
Languages are not equally supported in all packages. The following
|
||||
matrix shows the current state of internationalization, as of December
|
||||
1997. The matrix shows, in regard of each package, for which languages
|
||||
PO files have been submitted to translation coordination.
|
||||
|
||||
Ready PO files cs da de en es fi fr it ja ko nl no pl pt ru sl sv
|
||||
.----------------------------------------------------.
|
||||
bash | [] [] [] | 3
|
||||
bison | [] [] [] | 3
|
||||
clisp | [] [] [] [] | 4
|
||||
cpio | [] [] [] [] [] [] | 6
|
||||
diffutils | [] [] [] [] [] | 5
|
||||
enscript | [] [] [] [] [] [] | 6
|
||||
fileutils | [] [] [] [] [] [] [] [] [] [] | 10
|
||||
findutils | [] [] [] [] [] [] [] [] [] | 9
|
||||
flex | [] [] [] [] | 4
|
||||
gcal | [] [] [] [] [] | 5
|
||||
gettext | [] [] [] [] [] [] [] [] [] [] [] | 12
|
||||
grep | [] [] [] [] [] [] [] [] [] [] | 10
|
||||
hello | [] [] [] [] [] [] [] [] [] [] [] | 11
|
||||
id-utils | [] [] [] | 3
|
||||
indent | [] [] [] [] [] | 5
|
||||
libc | [] [] [] [] [] [] [] | 7
|
||||
m4 | [] [] [] [] [] [] | 6
|
||||
make | [] [] [] [] [] [] | 6
|
||||
music | [] [] | 2
|
||||
ptx | [] [] [] [] [] [] [] [] | 8
|
||||
recode | [] [] [] [] [] [] [] [] [] | 9
|
||||
sh-utils | [] [] [] [] [] [] [] [] | 8
|
||||
sharutils | [] [] [] [] [] [] | 6
|
||||
tar | [] [] [] [] [] [] [] [] [] [] [] | 11
|
||||
texinfo | [] [] [] | 3
|
||||
textutils | [] [] [] [] [] [] [] [] [] | 9
|
||||
wdiff | [] [] [] [] [] [] [] [] | 8
|
||||
`----------------------------------------------------'
|
||||
17 languages cs da de en es fi fr it ja ko nl no pl pt ru sl sv
|
||||
27 packages 6 4 25 1 18 1 26 2 1 12 20 9 19 7 4 7 17 179
|
||||
|
||||
Some counters in the preceding matrix are higher than the number of
|
||||
visible blocks let us expect. This is because a few extra PO files are
|
||||
used for implementing regional variants of languages, or language
|
||||
dialects.
|
||||
|
||||
For a PO file in the matrix above to be effective, the package to
|
||||
which it applies should also have been internationalized and
|
||||
distributed as such by its maintainer. There might be an observable
|
||||
lag between the mere existence a PO file and its wide availability in a
|
||||
distribution.
|
||||
|
||||
If December 1997 seems to be old, you may fetch a more recent copy
|
||||
of this `ABOUT-NLS' file on most GNU archive sites.
|
||||
|
@ -0,0 +1,482 @@
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the library GPL. It is
|
||||
numbered 2 because it goes with version 2 of the ordinary GPL.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Library General Public License, applies to some
|
||||
specially designated Free Software Foundation software, and to any
|
||||
other libraries whose authors decide to use it. You can use it for
|
||||
your libraries, 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 library, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link a program with the library, you must provide
|
||||
complete object files to the recipients so that they can relink them
|
||||
with the library, after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
Our method of protecting your rights has two steps: (1) copyright
|
||||
the library, and (2) offer you this license which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
Also, for each distributor's protection, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
library. If the library is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original
|
||||
version, 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 companies distributing free
|
||||
software will individually obtain patent licenses, thus in effect
|
||||
transforming the program into proprietary software. To prevent this,
|
||||
we have made it clear that any patent must be licensed for everyone's
|
||||
free use or not licensed at all.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the ordinary
|
||||
GNU General Public License, which was designed for utility programs. This
|
||||
license, the GNU Library General Public License, applies to certain
|
||||
designated libraries. This license is quite different from the ordinary
|
||||
one; be sure to read it in full, and don't assume that anything in it is
|
||||
the same as in the ordinary license.
|
||||
|
||||
The reason we have a separate public license for some libraries is that
|
||||
they blur the distinction we usually make between modifying or adding to a
|
||||
program and simply using it. Linking a program with a library, without
|
||||
changing the library, is in some sense simply using the library, and is
|
||||
analogous to running a utility program or application program. However, in
|
||||
a textual and legal sense, the linked executable is a combined work, a
|
||||
derivative of the original library, and the ordinary General Public License
|
||||
treats it as such.
|
||||
|
||||
Because of this blurred distinction, using the ordinary General
|
||||
Public License for libraries did not effectively promote software
|
||||
sharing, because most developers did not use the libraries. We
|
||||
concluded that weaker conditions might promote sharing better.
|
||||
|
||||
However, unrestricted linking of non-free programs would deprive the
|
||||
users of those programs of all benefit from the free status of the
|
||||
libraries themselves. This Library General Public License is intended to
|
||||
permit developers of non-free programs to use free libraries, while
|
||||
preserving your freedom as a user of such programs to change the free
|
||||
libraries that are incorporated in them. (We have not seen how to achieve
|
||||
this as regards changes in header files, but we have achieved it as regards
|
||||
changes in the actual functions of the Library.) The hope is that this
|
||||
will lead to faster development of free libraries.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, while the latter only
|
||||
works together with the library.
|
||||
|
||||
Note that it is possible for a library to be covered by the ordinary
|
||||
General Public License rather than by this special one.
|
||||
|
||||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library which
|
||||
contains a notice placed by the copyright holder or other authorized
|
||||
party saying it may be distributed under the terms of this Library
|
||||
General Public License (also called "this License"). Each licensee is
|
||||
addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, 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 library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete 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 distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
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 Library or any portion
|
||||
of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
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 Library, 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 Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you 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.
|
||||
|
||||
If distribution of 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 satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also compile or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
c) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
d) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. 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.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library 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.
|
||||
|
||||
9. 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 Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
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.
|
||||
|
||||
11. 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 Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library 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 Library.
|
||||
|
||||
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.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library 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.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Library 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 Library
|
||||
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 Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
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
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "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
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. 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 LIBRARY 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
|
||||
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
@ -0,0 +1,386 @@
|
||||
gsmlib-1.10
|
||||
- reactivated code in gsm_at to retry sending PDU after
|
||||
unsolicited result code
|
||||
|
||||
- added description of unicode handling to FAQ
|
||||
|
||||
- compilation fixes for gcc-3.0.4
|
||||
|
||||
- added quick exit for ATZ in UnixSerialPort constructor
|
||||
if phone gives ERROR
|
||||
|
||||
- added fix for phones that return +CLIP: "Number not available."
|
||||
instead of giving caller ID
|
||||
|
||||
- added get/setCLIRPresentation() functions to MeTa (contribution by
|
||||
ivan)
|
||||
|
||||
- added "NO CARRIER" event to the event mechanism (contribution by
|
||||
clock)
|
||||
|
||||
- added Win32 port of gsmsmsd (thanks to Konstantin Forostyan)
|
||||
|
||||
- further extented Win32 port of gsmsmsd to handle outgoing messages
|
||||
|
||||
- fixed problem with Ericsson T39m SMS sending (zero bytes in handshake)
|
||||
|
||||
- added capability to send concatenated SMSs in gsmsmsd and gsmsendsms
|
||||
|
||||
- fixed unsigned/signed char problems in Unix/Win32 serial port
|
||||
implementations
|
||||
|
||||
- added capability to send multiple SMSs to gsmsendsms/gsmsmsd
|
||||
|
||||
gsmlib-1.9
|
||||
- fixed decoding of alphanumeric addresses in gsm_sms_codec.
|
||||
|
||||
- fixed bug in gsm_event when checking whether to send an
|
||||
acknowledgment for a received SMS
|
||||
|
||||
- More Siemens-specific patches, some extensions to the AT
|
||||
command parser
|
||||
|
||||
- New code to print PIN status and set the PIN in gsmctl, setPIN
|
||||
function in MeTa class (Andreas Roedl <flood@flood-net.de>)
|
||||
|
||||
- Missing virtual destructor in Port class caused destructors of
|
||||
UnixSerialPort and Win32SerialPort not to be called - fixed
|
||||
|
||||
- Added new code to set functionality level on or off (thanks to
|
||||
David Woodhouse)
|
||||
|
||||
- found bug in SMS store implementation that caused the now
|
||||
obsolete _capacity member to be set to a too low value
|
||||
|
||||
- Added changes contributed by Frediano Ziglio to enable compilation
|
||||
on Windows
|
||||
|
||||
- Added call waiting functions contributed by Ivan
|
||||
|
||||
gsmlib-1.8
|
||||
- added workaround for Nokia Cellular Card Phone RPE-1 GSM900
|
||||
that reports a CDS event that actually is an CDSI and sends a spurious
|
||||
CR when waiting for a PDU
|
||||
|
||||
- SMS are stored without index in files now
|
||||
|
||||
- tested compilation with gcc-3.0.2
|
||||
|
||||
- added workaround for gsmlib getting confused when receiving SMS
|
||||
and echo cannot be switched off - echos of the AT command are
|
||||
filtered out in chat() now
|
||||
|
||||
- extended gsm_phonebook preload mechanism to batch-load phonebooks
|
||||
where the index does not start with 1
|
||||
|
||||
- Added workaround for Motorola Timeport 260 to write back
|
||||
deliver messages to the ME
|
||||
|
||||
- added workaround for compilation with libstdc++-v2
|
||||
|
||||
- private members of MeTa made protected
|
||||
|
||||
- new ext directory for phone-specific extensions
|
||||
|
||||
gsmlib-1.7
|
||||
- fixed bug with calculation of userData length if userDataHeader
|
||||
is present (octet count was subtracted, not septet count)
|
||||
|
||||
- fixed problem with string erase() at end of PDU for Falcom A2-1
|
||||
|
||||
- -t/--charset option of gsmpb did not work due to missing parameter
|
||||
of getopt_long, fixed
|
||||
|
||||
- The SMS decoder/encoder can now handle alphanumeric addresses
|
||||
in the GSM default alphabet
|
||||
|
||||
- set only those SMS stores that are actually needed to perform
|
||||
SMS store operation
|
||||
|
||||
- Fixed signalling error 321 (Invalid memory index) when trying to
|
||||
read from empty SMS store entry
|
||||
|
||||
- Fixed parsing error when reading current network operator if no
|
||||
network connection
|
||||
|
||||
- Added capability to parse cell broadcast messages to gsmlib and
|
||||
the gsmsmsd program
|
||||
|
||||
- Added workaround for Motorola Timeport 260 bug that doesn't correctly
|
||||
report the message status when retrieving SMS messages from the
|
||||
store
|
||||
|
||||
- Added workaround for Motorola Timeport 260 that allocates index
|
||||
numbers to SMS messages linearly so that index number can be
|
||||
be larger than capacity reported by AT command
|
||||
|
||||
gsmlib-1.6
|
||||
- more fixes for the COPS=? return format
|
||||
|
||||
- fixed putBack() behaviour in gsm_parser (don't put back if end-of-
|
||||
stream is reached)
|
||||
|
||||
- added toString() function to gsm_sms_codec's Address class
|
||||
|
||||
- SMS dates and times are now output in a locale-specific manner
|
||||
|
||||
- fixed bug in Parser::getEol() (_eos was accidentally set to true)
|
||||
|
||||
- added gsm_win32_serial module, Win32 project (VC++), and
|
||||
Option FirstFone changes contributed by Frediano Ziglio
|
||||
<freddy77@angelfire.com>
|
||||
|
||||
- fix in COM port recognition for Win32 (gsm_util)
|
||||
|
||||
- renamed library files libgsm.* to libgsmme.* (now starting with
|
||||
version 1.0) because of conflict with another Debian package
|
||||
|
||||
- in gsm_phonebook and gsm_store the caching of entries can now
|
||||
be disabled
|
||||
|
||||
- added facilities to use other character sets for phonebooks
|
||||
|
||||
- fixed workaround for Ericcson SH888 (missing service centre address)
|
||||
|
||||
- fixed bug in gsm_phonebook that prevented texts with the
|
||||
character '@' to be written to to the phonebook
|
||||
|
||||
- fixed nasty memory allocation bug in gsmpb/gsmsmsstore
|
||||
(automatic MeTa variable went out of scope even though used
|
||||
later)
|
||||
|
||||
- fixed Y2K problem in timestamp printing
|
||||
|
||||
- fixed "make dist" to include win32 files
|
||||
|
||||
- added workarounds for Falcom A2-1 (autodetection and enabling by
|
||||
"export GSMLIB_FALCOM_A2_1_FIX=1", zero after PDU)
|
||||
|
||||
- fixed bug that caused gsmlib to abort with an assert if a malformed
|
||||
PDU was read
|
||||
|
||||
gsmlib-1.5
|
||||
- adapted MeTa::getCurrentOPInfo() and MeTa::getAvailableOPInfo()
|
||||
to handle Nokia 8290 quirks
|
||||
|
||||
- code to set line speed in gsm_unix_serial reinserted (it was
|
||||
accidentally removed in previous version)
|
||||
|
||||
- minor changes to initialization sequence in gsm_unix_serial
|
||||
|
||||
- bugfix in gsm_unix_serial.cc: readByte() == 0 does not mean no
|
||||
more bytes, but is legal value
|
||||
|
||||
- additionally allowed characters "*#pwPW" and '+' at any
|
||||
position in telephone numbers
|
||||
|
||||
- added environment variable GSMLIB_SH888_FIX that (if set)
|
||||
enables the gsmlib workaround for Ericsson SH888's broken SMS TPDUs
|
||||
|
||||
- fixed command line parameter handling bug in gsmsmsstore
|
||||
|
||||
- fixed %files section .spec file to correctly include manual pages
|
||||
|
||||
- fixed some bugs in terminal line setup (gsm_unix_serial) regarding
|
||||
software/hardware handshake
|
||||
|
||||
- added new "--sca" option to SMS-related apps to set the SMS
|
||||
service centre address on the command line (useful if default is not
|
||||
set correctly in the phone)
|
||||
|
||||
- removed tcflush() call in UnixSerialPort::putLine that broke
|
||||
the event system needed for gsmsmsd
|
||||
|
||||
gsmlib-1.4
|
||||
- more attempts to fix UNIX serial port access
|
||||
|
||||
- allow custom backends for sorted phonebooks to be integrated
|
||||
into gsmlib (eg. for RDBMS or LDAP storage). Introduced a new
|
||||
module gsm_sorted_phonebook_base that contains the infrastructure for
|
||||
this.
|
||||
|
||||
- Now gsmlib needs at least gcc-2.95.2 to compile correctly.
|
||||
|
||||
- Implemented option to open device with software handshaking (XON/XOFF).
|
||||
The applications now have an -X option to turn this on.
|
||||
|
||||
- gsmlib now contains a facility to interrupt ongoing activity in a
|
||||
controlled way. gsm_unix_serial now blocks for one second
|
||||
maximum until it checks whether it was interrupted.
|
||||
|
||||
- various small bugfixes
|
||||
|
||||
- added workaround for phones that omit ':' in AT command responses
|
||||
|
||||
- all debugging output is now printed to stderr
|
||||
|
||||
- gsm_unix_serial: new attempt to initialize modem in a more
|
||||
robust way (contributed)
|
||||
|
||||
- gsm_sms: fixed handling of user data header (contributed)
|
||||
|
||||
gsmlib-1.3
|
||||
- fixed bug that caused gsmlib to hang if TAs don't respond
|
||||
to AT inquiries for serial number etc.
|
||||
|
||||
- fixed bug with handling of CB mode AT command construction in
|
||||
gsm_me_ta.cc, setSMSRoutingToTA()
|
||||
|
||||
- allow '+' as the first character of phonenumbers
|
||||
|
||||
- implemented reading and writing from/to stdin/stdout in
|
||||
gsm_sorted_[sms_store|phonebook] and gsmpb/gsmsmsstore
|
||||
|
||||
- fixed (hopefully) the intermittent hangup problem in
|
||||
gsm_unix_serial_port
|
||||
|
||||
- Some mobile phones cannot report the status of some facility
|
||||
locks. The gsmctl program now prints out "unknown" in the
|
||||
corresponding result line from the FLSTAT
|
||||
operation if this problem occurs (instead of terminating).
|
||||
|
||||
- switched off non-blocking access to serial device
|
||||
|
||||
gsmlib-1.2
|
||||
- gsmlib now also works with TAs that can not switch off echo
|
||||
|
||||
- fixed bug that prevented gsmlib from copying SMS_DELIVER and
|
||||
SMS_STATUS_REPORT back to the ME
|
||||
|
||||
- introduced -I (--init) parameter to all command line apps to
|
||||
allow for device-specific initialization
|
||||
|
||||
- made SMS decoding routines more robust against bad SMS (especially
|
||||
premature end of PDU)
|
||||
|
||||
- New debugging feature: If compiled without NDEBUG, the
|
||||
environment variable GSMLIB_DEBUG determines the verbosity of
|
||||
debugging messages (0 = none, 1 = many, 2 = extreme)
|
||||
|
||||
gsmlib-1.1
|
||||
|
||||
- Parse multiple COPS (operator info) lines returned by some phones
|
||||
|
||||
- accept string as numeric value when interpreting COPS=? response
|
||||
(Ericsson phone + GSM12 GSM module)
|
||||
|
||||
- accept string as numeric value when interpreting COPS? response
|
||||
(Ericsson phone + GSM12 GSM module)
|
||||
|
||||
- retry when initializing TA (ATZ/ATE0 sequences)
|
||||
|
||||
- Set SMS routing:
|
||||
allow mode 3 (special in-band technique) when setting routing
|
||||
to TA (gsmlib should not be active when phone is switched to data mode
|
||||
anyway)
|
||||
|
||||
- Set SMS routing:
|
||||
handle buffer mode but only if it was reported by the +CNMI=? command
|
||||
(the Ericsson GM12 GSM modem does not like it otherwise)
|
||||
|
||||
- Determine CPMS number of parameters for CPMS command (better
|
||||
compability with some mobile phones / GSM modems)
|
||||
|
||||
- handle missing service centre address in incoming SMS for Ericsson
|
||||
model 6050102
|
||||
|
||||
- add new RING event to gsm_event.h/.cc, gsmsmsd now handles RING
|
||||
indications properly
|
||||
|
||||
- defined default event handler mostly to handle unexpected RING
|
||||
indications that might otherwise confuse gsmlib
|
||||
|
||||
- gsmsmsd: can now be cleanly terminated using the SIGINT or SIGTERM
|
||||
signals
|
||||
|
||||
- gsmsmsd: now handles multiple incoming SMS messages cleanly, before
|
||||
there was a chance that some SMS messages coming in rapid succession
|
||||
might have been lost
|
||||
|
||||
- gsmsmsd: flush option implemented that dispatches and erases
|
||||
existing messages in SMS store
|
||||
|
||||
- gsmsmsd: added sending of SMS messages. gsmsmsd now accepts a
|
||||
spool directory options where it expects to find SMS message file in a
|
||||
simple format, these are dispatched every 5 seconds
|
||||
|
||||
gsmlib-1.0
|
||||
|
||||
- RPM support (spec file)
|
||||
|
||||
- the "+" is at least for the Siemens S10 and S25 a valid char in
|
||||
telephone numbers (inserts a pause of 3 seconds), therefore it is now
|
||||
allowed as part of telephone numbers
|
||||
|
||||
- fixed incorrect analysis of facility class parameters in gsmctl.cc
|
||||
|
||||
- restricted call forward time to 0..30 seconds in gsm_me_ta.cc
|
||||
|
||||
gsmlib-0.3
|
||||
|
||||
- implemented timeout for accessing the mobile phone in order
|
||||
to avoid hangs
|
||||
|
||||
- upgraded to BETA status
|
||||
|
||||
- written glossary for abbreviations (gsminfo(7))
|
||||
|
||||
- implemented NLS support, added German translations
|
||||
|
||||
- implemented preserving the index position of phonebook entries in
|
||||
gsmpb.cc and gsm_sorted_phonebook
|
||||
|
||||
- cleaned up manual pages (alphabetic ordering of options etc.)
|
||||
|
||||
- gsmsmstore program and gsm_sorted_sms_store./.cc completed and
|
||||
tested
|
||||
|
||||
- gsmpb and gsmsmsstore now have --verbose (-V) options for detailed
|
||||
progress reporting
|
||||
|
||||
- now check for getopt_long in configure (can be compiled on non-GNU
|
||||
systems)
|
||||
|
||||
- removed asserts regarding lengths of numeric data types, put them
|
||||
into configure script
|
||||
|
||||
- sorted options in apps/*.cc alphabetically (--help option)
|
||||
|
||||
- in gsm_sorted_sms_store compare telephone numbers more sensibly
|
||||
|
||||
- introduced -v option to gsmpb and gsmsmsstore to report execution
|
||||
statistics
|
||||
|
||||
- tested new synchronization function in gsmpb program
|
||||
|
||||
- implemented operations in the gsmctl program
|
||||
|
||||
- rewrote test cases (compare output)
|
||||
|
||||
- completed gsmsmsstore program
|
||||
|
||||
- first changes for compilation with VC++ 6.0 on WIN32
|
||||
|
||||
gsmlib-0.2
|
||||
|
||||
- gsmsmstore program and gsm_sorted_sms_store./.cc mostly
|
||||
completed but not yet much tested
|
||||
|
||||
- Fixed problem with some mobiles/TAs not giving prefixes after
|
||||
certain AT sequences (reported for SIEMENS S25/IrDA, Nokia
|
||||
8810/IrDA)
|
||||
|
||||
- Fixed problem with Xircom REM56G.100/Nokia 6150 that give
|
||||
"CABLE: GSM" instead of "OK" after ATZ
|
||||
|
||||
- Mobiles that return nothing when empty phonebook entries are
|
||||
requested are now handled correctly (reported for SIEMENS S25/IrDA)
|
||||
|
||||
- optimizations in gsm_*_phonebook modules (less AT commands necessary)
|
||||
|
||||
- new synchronization function in gsmpb program that is (hopefully)
|
||||
more sensible (see man page for details)
|
||||
|
||||
gsmlib-0.1
|
||||
|
||||
- Initial release
|
@ -0,0 +1,198 @@
|
||||
GSMLIB Installation
|
||||
===================
|
||||
|
||||
This distribution uses autoconf/automake/libtool. See below
|
||||
for generic installation instructions. The default commands would be:
|
||||
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
See also the section INSTALLATION in the README file in this
|
||||
directory. For questions regarding the internationalization of this
|
||||
package refer to doc/README.NLS and ./ABOUT-NLS.
|
||||
|
||||
Developers: See also the file doc/README.developers.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, a file
|
||||
`config.cache' that saves the results of its tests to speed up
|
||||
reconfiguring, and a file `config.log' containing compiler output
|
||||
(useful mainly for debugging `configure').
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If at some point `config.cache'
|
||||
contains results you don't want to keep, you may remove or edit it.
|
||||
|
||||
The file `configure.in' is used to create `configure' by a program
|
||||
called `autoconf'. You only need `configure.in' if you want to change
|
||||
it or regenerate `configure' using a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. You can give `configure'
|
||||
initial values for variables by setting them in the environment. Using
|
||||
a Bourne-compatible shell, you can do that on the command line like
|
||||
this:
|
||||
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
|
||||
|
||||
Or on systems that have the `env' program, you can do it like this:
|
||||
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
If you have to use a `make' that does not supports the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a time
|
||||
in the source code directory. After you have installed the package for
|
||||
one architecture, use `make distclean' before reconfiguring for another
|
||||
architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' will install the package's files in
|
||||
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||
installation prefix other than `/usr/local' by giving `configure' the
|
||||
option `--prefix=PATH'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||
PATH as the prefix for installing programs and libraries.
|
||||
Documentation and other data files will still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=PATH' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' can not figure out
|
||||
automatically, but needs to determine by the type of host the package
|
||||
will run on. Usually `configure' can figure that out, but if it prints
|
||||
a message saying it can not guess the host type, give it the
|
||||
`--host=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name with three fields:
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the host type.
|
||||
|
||||
If you are building compiler tools for cross-compiling, you can also
|
||||
use the `--target=TYPE' option to select the type of system they will
|
||||
produce code for and the `--build=TYPE' option to select the type of
|
||||
system on which you are compiling the package.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Operation Controls
|
||||
==================
|
||||
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Use and save the results of the tests in FILE instead of
|
||||
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
|
||||
debugging `configure'.
|
||||
|
||||
`--help'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`--version'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options.
|
@ -0,0 +1,24 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
# *************************************************************************
|
||||
# * GSM TA/ME library
|
||||
# *
|
||||
# * File: Makefile.am
|
||||
# *
|
||||
# * Purpose: Toplevel Makefile
|
||||
# *
|
||||
# * Author: Peter Hofmann (software@pxh.de)
|
||||
# *
|
||||
# * Created: 21.5.1999
|
||||
# *************************************************************************
|
||||
|
||||
SUBDIRS_ = po gsmlib apps tests doc scripts win32 ext
|
||||
|
||||
EXTRA_DIST = gsmlib.spec
|
||||
|
||||
if COMPILE_INTL
|
||||
SUBDIRS = intl $(SUBDIRS_) # po - make automake happy
|
||||
else
|
||||
SUBDIRS = $(SUBDIRS_) # po intl - make automake happy
|
||||
endif
|
||||
|
||||
all:
|
@ -0,0 +1,423 @@
|
||||
# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
|
||||
|
||||
# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
# *************************************************************************
|
||||
# * GSM TA/ME library
|
||||
# *
|
||||
# * File: Makefile.am
|
||||
# *
|
||||
# * Purpose: Toplevel Makefile
|
||||
# *
|
||||
# * Author: Peter Hofmann (software@pxh.de)
|
||||
# *
|
||||
# * Created: 21.5.1999
|
||||
# *************************************************************************
|
||||
|
||||
|
||||
SHELL = @SHELL@
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = @bindir@
|
||||
sbindir = @sbindir@
|
||||
libexecdir = @libexecdir@
|
||||
datadir = @datadir@
|
||||
sysconfdir = @sysconfdir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
localstatedir = @localstatedir@
|
||||
libdir = @libdir@
|
||||
infodir = @infodir@
|
||||
mandir = @mandir@
|
||||
includedir = @includedir@
|
||||
oldincludedir = /usr/include
|
||||
|
||||
DESTDIR =
|
||||
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
|
||||
top_builddir = .
|
||||
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
transform = @program_transform_name@
|
||||
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
host_alias = @host_alias@
|
||||
host_triplet = @host@
|
||||
AR = @AR@
|
||||
AS = @AS@
|
||||
BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
|
||||
CATOBJEXT = @CATOBJEXT@
|
||||
CC = @CC@
|
||||
CPP = @CPP@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
DATADIRNAME = @DATADIRNAME@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
ECHO = @ECHO@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
F77 = @F77@
|
||||
GCJ = @GCJ@
|
||||
GCJFLAGS = @GCJFLAGS@
|
||||
GENCAT = @GENCAT@
|
||||
GLIBC2 = @GLIBC2@
|
||||
GLIBC21 = @GLIBC21@
|
||||
GMSGFMT = @GMSGFMT@
|
||||
GSM_VERSION = @GSM_VERSION@
|
||||
HAVE_ASPRINTF = @HAVE_ASPRINTF@
|
||||
HAVE_LIB = @HAVE_LIB@
|
||||
HAVE_POSIX_PRINTF = @HAVE_POSIX_PRINTF@
|
||||
HAVE_SNPRINTF = @HAVE_SNPRINTF@
|
||||
HAVE_WPRINTF = @HAVE_WPRINTF@
|
||||
INSTOBJEXT = @INSTOBJEXT@
|
||||
INTLBISON = @INTLBISON@
|
||||
INTLLIBS = @INTLLIBS@
|
||||
INTLOBJS = @INTLOBJS@
|
||||
INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
|
||||
INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
|
||||
LIB = @LIB@
|
||||
LIBICONV = @LIBICONV@
|
||||
LIBINTL = @LIBINTL@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LN_S = @LN_S@
|
||||
LTLIB = @LTLIB@
|
||||
LTLIBICONV = @LTLIBICONV@
|
||||
LTLIBINTL = @LTLIBINTL@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MKINSTALLDIRS = @MKINSTALLDIRS@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
PACKAGE = @PACKAGE@
|
||||
POSUB = @POSUB@
|
||||
RANLIB = @RANLIB@
|
||||
RC = @RC@
|
||||
STRIP = @STRIP@
|
||||
USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
|
||||
USE_NLS = @USE_NLS@
|
||||
VERSION = @VERSION@
|
||||
|
||||
SUBDIRS_ = po gsmlib apps tests doc scripts win32 ext
|
||||
|
||||
EXTRA_DIST = gsmlib.spec
|
||||
@COMPILE_INTL_TRUE@SUBDIRS = intl $(SUBDIRS_) # po - make automake happy
|
||||
@COMPILE_INTL_FALSE@SUBDIRS = $(SUBDIRS_) # po intl - make automake happy
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs
|
||||
CONFIG_HEADER = gsm_config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
DIST_COMMON = README ./stamp-h.in ABOUT-NLS AUTHORS COPYING ChangeLog \
|
||||
INSTALL Makefile.am Makefile.in NEWS TODO acconfig.h acinclude.m4 \
|
||||
aclocal.m4 configure configure.in gsm_config.h.in
|
||||
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
TAR = tar
|
||||
GZIP_ENV = --best
|
||||
DIST_SUBDIRS = intl po gsmlib apps tests doc scripts win32 ext po \
|
||||
gsmlib apps tests doc scripts win32 ext
|
||||
all: all-redirect
|
||||
.SUFFIXES:
|
||||
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
|
||||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
|
||||
$(ACLOCAL_M4): configure.in acinclude.m4
|
||||
cd $(srcdir) && $(ACLOCAL)
|
||||
|
||||
config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
$(SHELL) ./config.status --recheck
|
||||
$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
|
||||
cd $(srcdir) && $(AUTOCONF)
|
||||
|
||||
gsm_config.h: stamp-h
|
||||
@if test ! -f $@; then \
|
||||
rm -f stamp-h; \
|
||||
$(MAKE) stamp-h; \
|
||||
else :; fi
|
||||
stamp-h: $(srcdir)/gsm_config.h.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES= CONFIG_HEADERS=gsm_config.h \
|
||||
$(SHELL) ./config.status
|
||||
@echo timestamp > stamp-h 2> /dev/null
|
||||
$(srcdir)/gsm_config.h.in: $(srcdir)/stamp-h.in
|
||||
@if test ! -f $@; then \
|
||||
rm -f $(srcdir)/stamp-h.in; \
|
||||
$(MAKE) $(srcdir)/stamp-h.in; \
|
||||
else :; fi
|
||||
$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h
|
||||
cd $(top_srcdir) && $(AUTOHEADER)
|
||||
@echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
|
||||
|
||||
mostlyclean-hdr:
|
||||
|
||||
clean-hdr:
|
||||
|
||||
distclean-hdr:
|
||||
-rm -f gsm_config.h
|
||||
|
||||
maintainer-clean-hdr:
|
||||
|
||||
# This directory's subdirectories are mostly independent; you can cd
|
||||
# into them and run `make' without going through this Makefile.
|
||||
# To change the values of `make' variables: instead of editing Makefiles,
|
||||
# (1) if the variable is set in `config.status', edit `config.status'
|
||||
# (which will cause the Makefiles to be regenerated when you run `make');
|
||||
# (2) otherwise, pass the desired values on the `make' command line.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
all-recursive install-data-recursive install-exec-recursive \
|
||||
installdirs-recursive install-recursive uninstall-recursive \
|
||||
check-recursive installcheck-recursive info-recursive dvi-recursive:
|
||||
@set fnord $(MAKEFLAGS); amf=$$2; \
|
||||
dot_seen=no; \
|
||||
target=`echo $@ | sed s/-recursive//`; \
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
echo "Making $$target in $$subdir"; \
|
||||
if test "$$subdir" = "."; then \
|
||||
dot_seen=yes; \
|
||||
local_target="$$target-am"; \
|
||||
else \
|
||||
local_target="$$target"; \
|
||||
fi; \
|
||||
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
||||
done; \
|
||||
if test "$$dot_seen" = "no"; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
|
||||
fi; test -z "$$fail"
|
||||
|
||||
mostlyclean-recursive clean-recursive distclean-recursive \
|
||||
maintainer-clean-recursive:
|
||||
@set fnord $(MAKEFLAGS); amf=$$2; \
|
||||
dot_seen=no; \
|
||||
rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
rev="$$subdir $$rev"; \
|
||||
test "$$subdir" != "." || dot_seen=yes; \
|
||||
done; \
|
||||
test "$$dot_seen" = "no" && rev=". $$rev"; \
|
||||
target=`echo $@ | sed s/-recursive//`; \
|
||||
for subdir in $$rev; do \
|
||||
echo "Making $$target in $$subdir"; \
|
||||
if test "$$subdir" = "."; then \
|
||||
local_target="$$target-am"; \
|
||||
else \
|
||||
local_target="$$target"; \
|
||||
fi; \
|
||||
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
||||
done && test -z "$$fail"
|
||||
tags-recursive:
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
|
||||
done
|
||||
|
||||
tags: TAGS
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP)
|
||||
list='$(SOURCES) $(HEADERS)'; \
|
||||
unique=`for i in $$list; do echo $$i; done | \
|
||||
awk ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
here=`pwd` && cd $(srcdir) \
|
||||
&& mkid -f$$here/ID $$unique $(LISP)
|
||||
|
||||
TAGS: tags-recursive $(HEADERS) $(SOURCES) gsm_config.h.in $(TAGS_DEPENDENCIES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||
if test "$$subdir" = .; then :; else \
|
||||
test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
|
||||
fi; \
|
||||
done; \
|
||||
list='$(SOURCES) $(HEADERS)'; \
|
||||
unique=`for i in $$list; do echo $$i; done | \
|
||||
awk ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
test -z "$(ETAGS_ARGS)gsm_config.h.in$$unique$(LISP)$$tags" \
|
||||
|| (cd $(srcdir) && etags -o $$here/TAGS $(ETAGS_ARGS) $$tags gsm_config.h.in $$unique $(LISP))
|
||||
|
||||
mostlyclean-tags:
|
||||
|
||||
clean-tags:
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID
|
||||
|
||||
maintainer-clean-tags:
|
||||
|
||||
distdir = $(PACKAGE)-$(VERSION)
|
||||
top_distdir = $(distdir)
|
||||
|
||||
# This target untars the dist file and tries a VPATH configuration. Then
|
||||
# it guarantees that the distribution is self-contained by making another
|
||||
# tarfile.
|
||||
distcheck: dist
|
||||
-rm -rf $(distdir)
|
||||
GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
|
||||
mkdir $(distdir)/=build
|
||||
mkdir $(distdir)/=inst
|
||||
dc_install_base=`cd $(distdir)/=inst && pwd`; \
|
||||
cd $(distdir)/=build \
|
||||
&& ../configure --with-included-gettext --srcdir=.. --prefix=$$dc_install_base \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) check \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) install \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) dist
|
||||
-rm -rf $(distdir)
|
||||
@banner="$(distdir).tar.gz is ready for distribution"; \
|
||||
dashes=`echo "$$banner" | sed s/./=/g`; \
|
||||
echo "$$dashes"; \
|
||||
echo "$$banner"; \
|
||||
echo "$$dashes"
|
||||
dist: distdir
|
||||
-chmod -R a+r $(distdir)
|
||||
GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
|
||||
-rm -rf $(distdir)
|
||||
dist-all: distdir
|
||||
-chmod -R a+r $(distdir)
|
||||
GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
|
||||
-rm -rf $(distdir)
|
||||
distdir: $(DISTFILES)
|
||||
-rm -rf $(distdir)
|
||||
mkdir $(distdir)
|
||||
-chmod 777 $(distdir)
|
||||
here=`cd $(top_builddir) && pwd`; \
|
||||
top_distdir=`cd $(distdir) && pwd`; \
|
||||
distdir=`cd $(distdir) && pwd`; \
|
||||
cd $(top_srcdir) \
|
||||
&& $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu Makefile
|
||||
@for file in $(DISTFILES); do \
|
||||
d=$(srcdir); \
|
||||
if test -d $$d/$$file; then \
|
||||
cp -pr $$d/$$file $(distdir)/$$file; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file || :; \
|
||||
fi; \
|
||||
done
|
||||
for subdir in $(DIST_SUBDIRS); do \
|
||||
if test "$$subdir" = .; then :; else \
|
||||
test -d $(distdir)/$$subdir \
|
||||
|| mkdir $(distdir)/$$subdir \
|
||||
|| exit 1; \
|
||||
chmod 777 $(distdir)/$$subdir; \
|
||||
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
info-am:
|
||||
info: info-recursive
|
||||
dvi-am:
|
||||
dvi: dvi-recursive
|
||||
check-am: all-am
|
||||
check: check-recursive
|
||||
installcheck-am:
|
||||
installcheck: installcheck-recursive
|
||||
all-recursive-am: gsm_config.h
|
||||
$(MAKE) $(AM_MAKEFLAGS) all-recursive
|
||||
|
||||
install-exec-am:
|
||||
install-exec: install-exec-recursive
|
||||
|
||||
install-data-am:
|
||||
install-data: install-data-recursive
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
install: install-recursive
|
||||
uninstall-am:
|
||||
uninstall: uninstall-recursive
|
||||
all-am: Makefile gsm_config.h
|
||||
all-redirect: all-recursive-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
|
||||
installdirs: installdirs-recursive
|
||||
installdirs-am:
|
||||
|
||||
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
|
||||
|
||||
maintainer-clean-generic:
|
||||
mostlyclean-am: mostlyclean-hdr mostlyclean-tags mostlyclean-generic
|
||||
|
||||
mostlyclean: mostlyclean-recursive
|
||||
|
||||
clean-am: clean-hdr clean-tags clean-generic mostlyclean-am
|
||||
|
||||
clean: clean-recursive
|
||||
|
||||
distclean-am: distclean-hdr distclean-tags distclean-generic clean-am
|
||||
-rm -f libtool
|
||||
|
||||
distclean: distclean-recursive
|
||||
-rm -f config.status
|
||||
|
||||
maintainer-clean-am: maintainer-clean-hdr maintainer-clean-tags \
|
||||
maintainer-clean-generic distclean-am
|
||||
@echo "This command is intended for maintainers to use;"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
|
||||
maintainer-clean: maintainer-clean-recursive
|
||||
-rm -f config.status
|
||||
|
||||
.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
|
||||
install-data-recursive uninstall-data-recursive install-exec-recursive \
|
||||
uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \
|
||||
all-recursive check-recursive installcheck-recursive info-recursive \
|
||||
dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \
|
||||
maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
|
||||
distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
|
||||
dvi-am dvi check check-am installcheck-am installcheck all-recursive-am \
|
||||
install-exec-am install-exec install-data-am install-data install-am \
|
||||
install uninstall-am uninstall all-redirect all-am all installdirs-am \
|
||||
installdirs mostlyclean-generic distclean-generic clean-generic \
|
||||
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
|
||||
|
||||
|
||||
all:
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
@ -0,0 +1,11 @@
|
||||
NEWS - 9.1.2000
|
||||
|
||||
Version 1.0 - first release with RPM support and binary packages
|
||||
|
||||
NEWS - 15.11.1999
|
||||
|
||||
BETA version (details see ChangeLog)
|
||||
|
||||
NEWS - 16.7.1999
|
||||
|
||||
initial release
|
@ -0,0 +1,166 @@
|
||||
INTRODUCTION
|
||||
|
||||
This distribution contains a library to access GSM mobile phones
|
||||
through GSM modems or IrDA devices. Features include:
|
||||
|
||||
* modification of phonebooks stored in the mobile phone or on the
|
||||
SIM card
|
||||
|
||||
* reading and writing of SMS messages stored in the mobile phone
|
||||
|
||||
* sending and reception of SMS messages
|
||||
|
||||
Additionally, some simple command line programs are provided to
|
||||
use these functionalities.
|
||||
|
||||
|
||||
REQUIREMENTS
|
||||
|
||||
You need a mobile phone that conforms to the GSM
|
||||
standards ETSI GSM 07.07, ETSI GSM 07.05, and others.
|
||||
Non-GSM mobile phones will not work! Additionally,
|
||||
to access the mobile phone from the computer you will probably need an
|
||||
GSM modem (that would be a PC-CARD, usually). There might be some
|
||||
mobile phones, however, that incorporate directly terminal
|
||||
adapter (TA) functionality. Access via IrDA interfaces is also
|
||||
reported to work.
|
||||
|
||||
If you want to compile the library yourself please also read
|
||||
doc/README.developers.
|
||||
|
||||
|
||||
INSTALLATION
|
||||
|
||||
This distribution uses autoconf/automake/libtool. See the file
|
||||
INSTALL for generic installation instructions. The default
|
||||
commands for installation under /usr/local would be:
|
||||
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
If there are any problems you can generate a debug version. See
|
||||
doc/README.developers for details.
|
||||
|
||||
|
||||
AVAILABLE DOCUMENTATION
|
||||
|
||||
For the command line tools UNIX manual pages are available in the
|
||||
doc subdirectory of this distribution. These are installed by
|
||||
default in the directories /usr/local/man1, man7, and man8.
|
||||
|
||||
See also the files doc/README.developers, doc/README.NLS and doc/FAQ.
|
||||
|
||||
|
||||
HARDWARE
|
||||
|
||||
The following mobile phone/GSM modem combinations are reported to
|
||||
be compatible in varying degrees with the current release:
|
||||
|
||||
- Nokia 6150/Xircom REM56G.100
|
||||
- Nokia 6150/Options "GSM-Ready(R) Cellular-Only" modem
|
||||
from Option International
|
||||
- Nokia 6210/- (Linux IrDA serial device)
|
||||
- Nokia 8810/- (Linux IrDA serial device)
|
||||
- Siemens S10D/Dr Neuhaus Gipsy Card GSM
|
||||
- Siemens S25/- (Linux IrDA serial device)
|
||||
- Siemens S35i/- (Linux IrDA serial device)
|
||||
- Siemens S45
|
||||
- Ericcson SH888/- (Linux IrDA serial device)
|
||||
- Ericsson 6050102/GM 12 GSM module
|
||||
- Ericsson T28s (firmware 000809 1106)
|
||||
- Ericsson T20e (firmware R3A007)
|
||||
- -/Siemens M20T (stand-alone GSM module)
|
||||
- -/Wavecom WM02 GSM (stand-alone GSM module)
|
||||
- Nokia 7110 (firware rev 4.80)/- (Linux IrDA serial device)
|
||||
- Nokia 8290 (USA GSM 1900MHz)/- (Linux IrDA serial device)
|
||||
- Falcom A2-1/- (stand-alone GSM module)
|
||||
- Ericsson R320s/- (Linux IrDA serial device)
|
||||
- Motorola Timeport 260/- (Serial cable and Linux IrDA serial device)
|
||||
- Motorola Timeport 250/- (Linux IrDA serial device)
|
||||
- Motorola Timeport P7389/- (Linux IrDA serial device)
|
||||
- Nokia Cellular Card Phone RPE-1 GSM900 and
|
||||
- Nokia Card Phone RPM-1 GSM900/1800
|
||||
- Nokia Cardphone/Compaq iPAQ
|
||||
- Omnipoint technologies Redhawk 2000 GSM modem
|
||||
- Ericsson T28 (but one firmware revision is reported to have problems)
|
||||
- Ericcson T65
|
||||
- Ericcson T39m/Bluetooth
|
||||
- Option International GlobeTrotter PCMCIA
|
||||
|
||||
Note 1: Some of the mobile phones have an integrated GSM modem
|
||||
that can be accessed via the Linux IrDA drivers.
|
||||
|
||||
Note 2: Some of the abovementioned phones have still some glitches
|
||||
with gsmlib (and I haven't tested them myself).
|
||||
|
||||
For the following phones I receive a lot of errors reports:
|
||||
|
||||
- Ericcson SH888: SMS function don't work with many firmware releases
|
||||
|
||||
This list is not exhaustive, there are probably many other types of
|
||||
phone or GSM modem that work with gsmlib. Just try it and report back
|
||||
to me!
|
||||
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
Even though care has been taken in the design and implementation
|
||||
of this software it can not be excluded that this software could
|
||||
destroy data in your mobile phone or may even render your mobile
|
||||
phone useless (by erroneous PIN settings, for example). The
|
||||
author will not be held responsible legally, financially, or in any
|
||||
other form for any kind of damage that might occur from using
|
||||
this software.
|
||||
|
||||
This software is provided "as is" and without any expressed or implied
|
||||
warranties, including, without limitation, the implied warranties of
|
||||
merchantibility and fitness for any particular purpose.
|
||||
|
||||
If you are not ready to accept these conditions please don't use
|
||||
this software.
|
||||
|
||||
|
||||
COPYING
|
||||
|
||||
This software is available on the LGPL (GNU LIBRARY GENERAL
|
||||
PUBLIC LICENSE), ie. it is allowed to link
|
||||
the library to commercial programs.
|
||||
|
||||
See the file COPYING for details on the license.
|
||||
|
||||
|
||||
BUGS
|
||||
|
||||
There still seem to be some problems with IrDA devices under
|
||||
Linux. There have been reports of gsmlib-based applications
|
||||
(eg. gsmctl) hanging upon startup after initializing the serial port
|
||||
/dev/ircomm. I would be thankful for any input on this problem.
|
||||
|
||||
If something does not work with your OS platform or the mobile/TA
|
||||
combination please send a complete trace of the compilation or the
|
||||
program execution that did fail. Make sure to compile with debugging
|
||||
information enabled. Otherwise it will not be possible for me to do
|
||||
much about the problem. Send bug reports to the mailing list or
|
||||
to software@pxh.de. I promise not to publish telephone numbers or other
|
||||
private information that might be contained in the execution traces
|
||||
that you send me.
|
||||
|
||||
|
||||
MAILING LISTS
|
||||
|
||||
There are now two mailings lists available for announcements and
|
||||
discussion of gsmlib-related issues (hosted on lists.over.net).
|
||||
Refer to these pages for information on subscription procedures
|
||||
and an archive of previous postings:
|
||||
|
||||
http://lists.over.net/mailman/listinfo/gsmlib-announce/
|
||||
for announcements regarding GSMLIB
|
||||
|
||||
http://lists.over.net/mailman/listinfo/gsmlib-devel/
|
||||
the GSMLIB development list
|
||||
|
||||
|
||||
AUTHOR
|
||||
|
||||
Peter Hofmann <software@pxh.de>.
|
@ -0,0 +1,289 @@
|
||||
This is my list of TODOs for development of this software (not
|
||||
necessarily in order of importance):
|
||||
|
||||
("+" = DONE)
|
||||
|
||||
+ handle:
|
||||
> --> AT+COPS=?
|
||||
> <--
|
||||
> <-- +COPS: (1,"AMENA",,"21403"),(3,"MOVISTAR",,"21407"),
|
||||
> <-- (3,"E VODAFONE",,"21401"),,(0,1),(2)
|
||||
> <--
|
||||
> <-- OK
|
||||
> gsmctl[ERROR]: expected comma (at position 45 of string '(1,"AMENA",,"21403"),(3,"MOVISTAR",,"21407"),')
|
||||
|
||||
+ extend README and web site with names of working phones (Siemens S45,...)
|
||||
|
||||
+ add workaround:
|
||||
> <ME0> Manufacturer: Nokia Mobile Phones
|
||||
> <ME1> Model: 8290
|
||||
> <ME2> Revision: SW5.22
|
||||
> <ME3> Serial Number: 010070303406434
|
||||
> <FUN> Functionality Level: 1
|
||||
> gsmctl[ERROR]: expected number, got '(2)'
|
||||
|
||||
- add fork to gsmsmsd
|
||||
|
||||
+ document "on" and "off" operations of gsmctl
|
||||
|
||||
- Just assume full functionality and issue AT+CGMF=0 if we haven't already
|
||||
done so for this MeTa.
|
||||
|
||||
+ make update po
|
||||
|
||||
+ add find function
|
||||
|
||||
+ specify exact location of manual files in /usr/man/man* in spec
|
||||
file, so that erase does not try to delete these directories
|
||||
|
||||
+ update PO
|
||||
|
||||
+ add option to gsmsendsms/gsmsmsd to request delivery reports
|
||||
|
||||
+ Fix CBM reception in gsmsmsd, see testcb.cc program
|
||||
|
||||
+ fix gsmsmsd:
|
||||
--> AT+CNMI=?
|
||||
<--
|
||||
<-- +CNMI: (1),(1),(0),(0),(0)
|
||||
<--
|
||||
<-- OK
|
||||
--> AT+CNMI=1,0,0,0,0
|
||||
<--
|
||||
<-- +CME ERROR: 003
|
||||
./gsmsmsd[ERROR]: ME/TA error 'operation not allowed' (code 003)
|
||||
|
||||
+ Wenn ich den SMS-Speicher auslesen möchte, bricht gsmlib ab, weil der
|
||||
Speicherplatz 1 auf der SIM-Karte nicht belegt ist. Das kann z.B.
|
||||
passieren, wenn man Nachrichten im Handy löscht. Es kommt der Fehlercode
|
||||
321 (Invalid memory index). Wie wäre es, in der Leseroutine alle
|
||||
ungültigen Plätze zu ignorieren und solange zu lesen, bis die Anzahl der
|
||||
vorhandenen Nachrichten im Speicher eingelesen ist?
|
||||
|
||||
+ document --charset option of gsmpb
|
||||
|
||||
+ Problems with PDUs with alphanumeric SCA, e.g.:
|
||||
07911497941902F00414D0E474989D769F5DE4320839001040122151820000
|
||||
|
||||
+ > 2. Ich kann mit meinem Nokia 6210 nicht den Telefon-SMS-Speicher
|
||||
auslesen. Dies liegt an der Speicherwahl, die vor dem Auslesen
|
||||
an das Telefon übermittelt wird. Von der gsmlib wird anscheinend
|
||||
immer die Anzahl der Speicher aus dem "CPMS=?"-Befehl genommen
|
||||
(z.B. "SM","SM","SM"). Notwendig ist es aber nur, die erste
|
||||
Position (zum Lesen und Löschen) bzw. die ersten beiden
|
||||
Positionen (zum Schreiben) zu benutzen.
|
||||
Das Nokia 6210 unterstützt aber an der ritten Stelle nur "SM",
|
||||
nicht "ME". So kann ich die SMS im Telefon leider nicht
|
||||
auslesen :-(
|
||||
|
||||
- add option to gsmpb/gsmssmstore deletion to delete ALL entries
|
||||
|
||||
- recheck Solaris port
|
||||
|
||||
+ cache character set settings in MeTa
|
||||
|
||||
+ add documentation for new gsmctl and gsmpb charset parameters
|
||||
|
||||
+ support characters sets other than GSM default alphabet for phone books
|
||||
|
||||
+ create non-existent files (gsmpb and gsmsmsstore)
|
||||
|
||||
+ rename libgsm to libgsmme, new major version 1
|
||||
|
||||
+ document sca/setsca operations/parameters in gsmctl
|
||||
|
||||
+ document option to set SCA in SMS-related apps
|
||||
|
||||
+ implement option to set SCA in SMS-related apps
|
||||
|
||||
+ convert NDEBUG test output from cout to cerr
|
||||
|
||||
+ test new gsm_unix_serial behaviour
|
||||
|
||||
+ apply checks for telephone number in gsm_sorted_phonebook
|
||||
|
||||
+ add interrupted() checks
|
||||
|
||||
+ check for gcc-2.95.2 in configure
|
||||
|
||||
- document custom backend options of gsmpb (and gsmsmsstore)
|
||||
|
||||
- /var/lock/LCK..modem
|
||||
|
||||
+ make gsmctl all continue even if there are some failures
|
||||
|
||||
+ CPIN thing
|
||||
|
||||
+ bring German translations up-to-date
|
||||
|
||||
+ document -I parameter
|
||||
|
||||
+ make chat routines robust against TAs that insist on echoing AT commands
|
||||
|
||||
+ ericsson sh 888:
|
||||
<-- AT+CLCK="P2",2,,1
|
||||
<--
|
||||
+CME ERROR: 4
|
||||
gsmctl[ERROR]: ME/TA error 'operation not supported' (code 4)
|
||||
|
||||
+ put README etc. into gsmlib package (not only devel)
|
||||
|
||||
+ make SMS decoding routines more robust against bad SMS (especially
|
||||
premature end of PDU)
|
||||
|
||||
+ stop gsm_sorted_sms_store.cc from copying back SMS that came from
|
||||
the SC (SMS_DELIVER, SMS_STATUS_REPORT, SMS_SUBMIT_REPORT). Their
|
||||
message type is ambiguous and the ME may misinterpret them.
|
||||
|
||||
+ gsmsmsd: reinitialize modem every hour or so (signal termination implemented)
|
||||
|
||||
+ implement store, flush and spool options of gsmsmsd,
|
||||
document them in man pages
|
||||
|
||||
+ test case for COPS answer numeric operator name in quotation marks
|
||||
(testparser.cc)
|
||||
|
||||
+ retry when initializing TA (ATZ/ATE0 sequences)
|
||||
|
||||
+ correctly parse malformed SMS PDUs without SCA with Ericsson phone,
|
||||
introduce Capability object for that. Ericsson ID:
|
||||
<ME0> Manufacturer: ERICSSON
|
||||
<ME1> Model: 6050102
|
||||
<ME2> Revision: 990225 1852 CXC112143
|
||||
<ME3> Serial Number: 520001690279310
|
||||
|
||||
+ Determine CPMS number of parameters for CPMS command (Ericsson
|
||||
phone/GM12 GSM modem):
|
||||
AT+CPMS?
|
||||
+CPMS: "ME",0,10,"ME",0,10
|
||||
AT+CPMS=?
|
||||
+CPMS: ("ME","SM"),("ME","SM")
|
||||
|
||||
+ accept string as numeric value when interpreting COPS=? response
|
||||
(Ericsson phone + GSM12 GSM module)
|
||||
|
||||
+ accept string as numeric value when interpreting COPS? response
|
||||
(Ericsson phone + GSM12 GSM module)
|
||||
|
||||
+ It would be nice if it was possible to send sms:es
|
||||
via gsmsmsd as well, via a spool directory or a socket (or stdin, in which
|
||||
case one can put another program in front of this program and then
|
||||
feed it with outgoing messages any way one wants). That way the program
|
||||
could be the gateway between programs and the sms network. Now one has
|
||||
to stop gsmsmsd to send an sms and that's not so elegant or write
|
||||
ones own program.
|
||||
|
||||
+ gsmsmsd geht davon aus, das ein platz frei ist und benutzt nur diesen....
|
||||
Wenn also eine SMS kommt, dann zieht es Sie raus, und löscht den
|
||||
Speicherplatz.
|
||||
Wenn aber die Karte voll ist, passiert gar nichts. Für eine automatisierte
|
||||
umgebung ist das schlecht. besser wäre es, bei startup von gsmsmsd alle
|
||||
Speicherplätze abzufrühstücken, und die Action aufzurufen.
|
||||
|
||||
+ Ein RING bringt den gsmsmsd ziemlich heftig aus dem Tritt. Hab jetzt ´ne
|
||||
Rufumleitung eingebaut.
|
||||
|
||||
+ Links section in homepage
|
||||
|
||||
+ AT+CNMI=? liefert bei mir folgendes zurück:
|
||||
+CNMI: (0-3),(0-3),(0-2),0,(0-1)
|
||||
Parameter 4 (<ds>) liefert also keine Liste sondern nur ein Int zurück, du
|
||||
versuchts aber ein ( zu parsen.
|
||||
Was sagt die ETSI-spec. dazu ?? Ist das konform ??
|
||||
|
||||
+ give name of command at beginning of synopsis in man pages
|
||||
|
||||
+ list combinations of mobiles phones/GSM modems in the README
|
||||
|
||||
+ test ALARM in case of timeout when writing or reading to TA
|
||||
|
||||
+ install headers in gsmlib subdirectory
|
||||
|
||||
+ RPM spec file
|
||||
|
||||
+ test index changes for sorted phonebook -> write second test case
|
||||
|
||||
+ sort phone numbers the same way in gsm_sorted_sms_store and
|
||||
gsm_sorted_phonebook
|
||||
|
||||
+ write glossary for all these nice abbreviations (TA, ME, SC, SME, TE)
|
||||
|
||||
+ HAVE_VSNPRINTF instead of HAVE_VPRINTF
|
||||
|
||||
+ internationalization of messages with GNU gettext. Files:
|
||||
+gsm_at.cc +gsm_parser.cc +gsm_sorted_phonebook.cc
|
||||
+gsm_error.cc +gsm_phonebook.cc +gsm_sorted_sms_store.cc
|
||||
+gsm_event.cc +gsm_sms.cc +gsm_unix_serial.cc
|
||||
+gsm_me_ta.cc +gsm_sms_codec.cc +gsm_util.cc
|
||||
+gsm_nls.cc +gsm_sms_store.cc
|
||||
+gsmctl.cc +gsmpb.cc +gsmsendsms.cc
|
||||
+gsmsmsd.cc +gsmsmsstore.cc
|
||||
|
||||
+ implement indexed phonebook ops in gsmpb.cc
|
||||
|
||||
+ describe phonebook file format in gsmpb.man
|
||||
|
||||
+ update list of compatible hardware in README
|
||||
|
||||
+ all #include <gsm_config.h> must be enclosed in #ifdef's
|
||||
|
||||
+ check for getopt_long in configure
|
||||
|
||||
+ remove asserts regarding lengths of numeric data types, put them
|
||||
into configure script
|
||||
(string)
|
||||
|
||||
+ sort options in apps/*.cc alphabetically
|
||||
|
||||
+ in gsm_sorted_sms_store compare telephone numbers numerically
|
||||
|
||||
+ introduce -v option to gsmpb and gsmsmsstore to report execution
|
||||
statistics (gives a nicer feeling to users)
|
||||
|
||||
+ test new synchronization function in gsmpb program
|
||||
|
||||
+ implement equality operator for SMSSToreEntry
|
||||
|
||||
+ test 'make install'
|
||||
|
||||
+ implement operations in the gsmctl program
|
||||
|
||||
+ test operations in the gsmctl program
|
||||
|
||||
+ document operations in the gsmctl program
|
||||
|
||||
+ rewrite test cases (compare output)
|
||||
|
||||
+ write gsm_sorted_sms_store module (along the lines of gsm_sorted_phonebook)
|
||||
|
||||
+ complete gsmsmsstore program (using abovementioned modules)
|
||||
|
||||
TODO low priority:
|
||||
|
||||
- implement SMS text mode
|
||||
|
||||
- The action command of gsmsmsd would be easier to make, if the program
|
||||
sent the values in environment variables instead (except the user data
|
||||
which could be sent on stdin).
|
||||
|
||||
+ Upgrade to latest autoheader, autoconf, libtool
|
||||
|
||||
- provide German translations for manual pages
|
||||
|
||||
- organize doc subdirectory for translated READMEs, manual pages
|
||||
|
||||
+ Win32 port
|
||||
|
||||
- test: optimization when accessing phonebooks: use size information
|
||||
available via AT command to stop reading entries known to be empty (I
|
||||
cannot test this with my hardware since CPBS? is not fully supported)
|
||||
|
||||
- make apps accept stdin or stdout
|
||||
|
||||
+ maybe strip leading and trailing whitespace from phonebook entries
|
||||
when reading them from ME/TA or file? (not done, perhaps users want to
|
||||
achieve special effects with white space)
|
||||
|
||||
- support international character sets (8-bit, 16-bit) in phonebook
|
||||
operations (I'd like to have input from users who need this)
|
||||
|
@ -0,0 +1,33 @@
|
||||
/* used by libtool*/
|
||||
#define PACKAGE 0
|
||||
|
||||
/* used by libtool*/
|
||||
#define VERSION 0
|
||||
|
||||
/* Define if getopt_long() available */
|
||||
#undef HAVE_GETOPT_LONG
|
||||
|
||||
/* Define if alarm() available */
|
||||
#undef HAVE_ALARM
|
||||
|
||||
/* Define if netinet/in.h header available */
|
||||
#undef HAVE_NETINET_IN_H
|
||||
|
||||
/* Define if string.h header available */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define for NLS */
|
||||
#undef ENABLE_NLS
|
||||
#undef HAVE_CATGETS
|
||||
#undef HAVE_GETTEXT
|
||||
#undef HAVE_LC_MESSAGES
|
||||
#undef HAVE_STPCPY
|
||||
|
||||
/* Define LOCALEDIR */
|
||||
#define LOCALEDIR "/usr/share/locale"
|
||||
|
||||
/* Define if libintl.h header available */
|
||||
#undef HAVE_LIBINTL_H
|
||||
|
||||
/* Define if vsnprintf() function available */
|
||||
#undef HAVE_VSNPRINTF
|
9704
src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/aclocal.m4
vendored
Normal file
9704
src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/aclocal.m4
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,36 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
# *************************************************************************
|
||||
# * GSM TA/ME library
|
||||
# *
|
||||
# * File: Makefile.am
|
||||
# *
|
||||
# * Purpose: apps Makefile
|
||||
# *
|
||||
# * Author: Peter Hofmann (software@pxh.de)
|
||||
# *
|
||||
# * Created: 5.6.1999
|
||||
# *************************************************************************
|
||||
|
||||
INCLUDES = -I..
|
||||
|
||||
bin_PROGRAMS = gsmsmsstore gsmctl gsmsmsd gsmpb gsmsendsms
|
||||
|
||||
# build gsmsmsd from gsmsmsd.cc and libgsmme.la
|
||||
gsmsmsd_SOURCES = gsmsmsd.cc
|
||||
gsmsmsd_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS)
|
||||
|
||||
# build gsmpb from gsmpb.cc and libgsmme.la
|
||||
gsmpb_SOURCES = gsmpb.cc
|
||||
gsmpb_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS)
|
||||
|
||||
# build gsmctl from gsmctl.cc and libgsmme.la
|
||||
gsmctl_SOURCES = gsmctl.cc
|
||||
gsmctl_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS)
|
||||
|
||||
# build gsmsendsms from gsmsendsms.cc and libgsmme.la
|
||||
gsmsendsms_SOURCES = gsmsendsms.cc
|
||||
gsmsendsms_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS)
|
||||
|
||||
# build gsmsmsstore from gsmsmsstore.cc and libgsmme.la
|
||||
gsmsmsstore_SOURCES = gsmsmsstore.cc
|
||||
gsmsmsstore_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS)
|
@ -0,0 +1,442 @@
|
||||
# Makefile.in generated by automake 1.6.3 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
# Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
# *************************************************************************
|
||||
# * GSM TA/ME library
|
||||
# *
|
||||
# * File: Makefile.am
|
||||
# *
|
||||
# * Purpose: apps Makefile
|
||||
# *
|
||||
# * Author: Peter Hofmann (software@pxh.de)
|
||||
# *
|
||||
# * Created: 5.6.1999
|
||||
# *************************************************************************
|
||||
SHELL = @SHELL@
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = @bindir@
|
||||
sbindir = @sbindir@
|
||||
libexecdir = @libexecdir@
|
||||
datadir = @datadir@
|
||||
sysconfdir = @sysconfdir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
localstatedir = @localstatedir@
|
||||
libdir = @libdir@
|
||||
infodir = @infodir@
|
||||
mandir = @mandir@
|
||||
includedir = @includedir@
|
||||
oldincludedir = /usr/include
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
top_builddir = ..
|
||||
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = @program_transform_name@
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
host_alias = @host_alias@
|
||||
host_triplet = @host@
|
||||
|
||||
EXEEXT = @EXEEXT@
|
||||
OBJEXT = @OBJEXT@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
AMTAR = @AMTAR@
|
||||
AS = @AS@
|
||||
AWK = @AWK@
|
||||
BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
|
||||
CATOBJEXT = @CATOBJEXT@
|
||||
CC = @CC@
|
||||
CPP = @CPP@
|
||||
CXX = @CXX@
|
||||
DATADIRNAME = @DATADIRNAME@
|
||||
DEPDIR = @DEPDIR@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
ECHO = @ECHO@
|
||||
GENCAT = @GENCAT@
|
||||
GLIBC21 = @GLIBC21@
|
||||
GMSGFMT = @GMSGFMT@
|
||||
GSM_VERSION = @GSM_VERSION@
|
||||
HAVE_LIB = @HAVE_LIB@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
INSTOBJEXT = @INSTOBJEXT@
|
||||
INTLBISON = @INTLBISON@
|
||||
INTLLIBS = @INTLLIBS@
|
||||
INTLOBJS = @INTLOBJS@
|
||||
INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
|
||||
LIB = @LIB@
|
||||
LIBICONV = @LIBICONV@
|
||||
LIBINTL = @LIBINTL@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LN_S = @LN_S@
|
||||
LTLIB = @LTLIB@
|
||||
LTLIBICONV = @LTLIBICONV@
|
||||
LTLIBINTL = @LTLIBINTL@
|
||||
MKINSTALLDIRS = @MKINSTALLDIRS@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
PACKAGE = @PACKAGE@
|
||||
POSUB = @POSUB@
|
||||
RANLIB = @RANLIB@
|
||||
STRIP = @STRIP@
|
||||
USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
|
||||
USE_NLS = @USE_NLS@
|
||||
VERSION = @VERSION@
|
||||
am__include = @am__include@
|
||||
am__quote = @am__quote@
|
||||
install_sh = @install_sh@
|
||||
|
||||
INCLUDES = -I..
|
||||
|
||||
bin_PROGRAMS = gsmsmsstore gsmctl gsmsmsd gsmpb gsmsendsms
|
||||
|
||||
# build gsmsmsd from gsmsmsd.cc and libgsmme.la
|
||||
gsmsmsd_SOURCES = gsmsmsd.cc
|
||||
gsmsmsd_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS)
|
||||
|
||||
# build gsmpb from gsmpb.cc and libgsmme.la
|
||||
gsmpb_SOURCES = gsmpb.cc
|
||||
gsmpb_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS)
|
||||
|
||||
# build gsmctl from gsmctl.cc and libgsmme.la
|
||||
gsmctl_SOURCES = gsmctl.cc
|
||||
gsmctl_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS)
|
||||
|
||||
# build gsmsendsms from gsmsendsms.cc and libgsmme.la
|
||||
gsmsendsms_SOURCES = gsmsendsms.cc
|
||||
gsmsendsms_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS)
|
||||
|
||||
# build gsmsmsstore from gsmsmsstore.cc and libgsmme.la
|
||||
gsmsmsstore_SOURCES = gsmsmsstore.cc
|
||||
gsmsmsstore_LDADD = ../gsmlib/libgsmme.la $(INTLLIBS)
|
||||
subdir = apps
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs
|
||||
CONFIG_HEADER = $(top_builddir)/gsm_config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
bin_PROGRAMS = gsmsmsstore$(EXEEXT) gsmctl$(EXEEXT) gsmsmsd$(EXEEXT) \
|
||||
gsmpb$(EXEEXT) gsmsendsms$(EXEEXT)
|
||||
PROGRAMS = $(bin_PROGRAMS)
|
||||
|
||||
am_gsmctl_OBJECTS = gsmctl.$(OBJEXT)
|
||||
gsmctl_OBJECTS = $(am_gsmctl_OBJECTS)
|
||||
gsmctl_DEPENDENCIES = ../gsmlib/libgsmme.la
|
||||
gsmctl_LDFLAGS =
|
||||
am_gsmpb_OBJECTS = gsmpb.$(OBJEXT)
|
||||
gsmpb_OBJECTS = $(am_gsmpb_OBJECTS)
|
||||
gsmpb_DEPENDENCIES = ../gsmlib/libgsmme.la
|
||||
gsmpb_LDFLAGS =
|
||||
am_gsmsendsms_OBJECTS = gsmsendsms.$(OBJEXT)
|
||||
gsmsendsms_OBJECTS = $(am_gsmsendsms_OBJECTS)
|
||||
gsmsendsms_DEPENDENCIES = ../gsmlib/libgsmme.la
|
||||
gsmsendsms_LDFLAGS =
|
||||
am_gsmsmsd_OBJECTS = gsmsmsd.$(OBJEXT)
|
||||
gsmsmsd_OBJECTS = $(am_gsmsmsd_OBJECTS)
|
||||
gsmsmsd_DEPENDENCIES = ../gsmlib/libgsmme.la
|
||||
gsmsmsd_LDFLAGS =
|
||||
am_gsmsmsstore_OBJECTS = gsmsmsstore.$(OBJEXT)
|
||||
gsmsmsstore_OBJECTS = $(am_gsmsmsstore_OBJECTS)
|
||||
gsmsmsstore_DEPENDENCIES = ../gsmlib/libgsmme.la
|
||||
gsmsmsstore_LDFLAGS =
|
||||
|
||||
DEFS = @DEFS@
|
||||
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
depcomp = $(SHELL) $(top_srcdir)/scripts/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/gsmctl.Po ./$(DEPDIR)/gsmpb.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/gsmsendsms.Po ./$(DEPDIR)/gsmsmsd.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/gsmsmsstore.Po
|
||||
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \
|
||||
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
|
||||
$(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
CXXLD = $(CXX)
|
||||
CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
|
||||
$(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
DIST_SOURCES = $(gsmctl_SOURCES) $(gsmpb_SOURCES) $(gsmsendsms_SOURCES) \
|
||||
$(gsmsmsd_SOURCES) $(gsmsmsstore_SOURCES)
|
||||
DIST_COMMON = Makefile.am Makefile.in
|
||||
SOURCES = $(gsmctl_SOURCES) $(gsmpb_SOURCES) $(gsmsendsms_SOURCES) $(gsmsmsd_SOURCES) $(gsmsmsstore_SOURCES)
|
||||
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .cc .lo .o .obj
|
||||
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu apps/Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
|
||||
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
|
||||
install-binPROGRAMS: $(bin_PROGRAMS)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(bindir)
|
||||
@list='$(bin_PROGRAMS)'; for p in $$list; do \
|
||||
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
|
||||
if test -f $$p \
|
||||
|| test -f $$p1 \
|
||||
; then \
|
||||
f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
|
||||
echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \
|
||||
$(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f; \
|
||||
else :; fi; \
|
||||
done
|
||||
|
||||
uninstall-binPROGRAMS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(bin_PROGRAMS)'; for p in $$list; do \
|
||||
f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
|
||||
echo " rm -f $(DESTDIR)$(bindir)/$$f"; \
|
||||
rm -f $(DESTDIR)$(bindir)/$$f; \
|
||||
done
|
||||
|
||||
clean-binPROGRAMS:
|
||||
@list='$(bin_PROGRAMS)'; for p in $$list; do \
|
||||
f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
|
||||
echo " rm -f $$p $$f"; \
|
||||
rm -f $$p $$f ; \
|
||||
done
|
||||
gsmctl$(EXEEXT): $(gsmctl_OBJECTS) $(gsmctl_DEPENDENCIES)
|
||||
@rm -f gsmctl$(EXEEXT)
|
||||
$(CXXLINK) $(gsmctl_LDFLAGS) $(gsmctl_OBJECTS) $(gsmctl_LDADD) $(LIBS)
|
||||
gsmpb$(EXEEXT): $(gsmpb_OBJECTS) $(gsmpb_DEPENDENCIES)
|
||||
@rm -f gsmpb$(EXEEXT)
|
||||
$(CXXLINK) $(gsmpb_LDFLAGS) $(gsmpb_OBJECTS) $(gsmpb_LDADD) $(LIBS)
|
||||
gsmsendsms$(EXEEXT): $(gsmsendsms_OBJECTS) $(gsmsendsms_DEPENDENCIES)
|
||||
@rm -f gsmsendsms$(EXEEXT)
|
||||
$(CXXLINK) $(gsmsendsms_LDFLAGS) $(gsmsendsms_OBJECTS) $(gsmsendsms_LDADD) $(LIBS)
|
||||
gsmsmsd$(EXEEXT): $(gsmsmsd_OBJECTS) $(gsmsmsd_DEPENDENCIES)
|
||||
@rm -f gsmsmsd$(EXEEXT)
|
||||
$(CXXLINK) $(gsmsmsd_LDFLAGS) $(gsmsmsd_OBJECTS) $(gsmsmsd_LDADD) $(LIBS)
|
||||
gsmsmsstore$(EXEEXT): $(gsmsmsstore_OBJECTS) $(gsmsmsstore_DEPENDENCIES)
|
||||
@rm -f gsmsmsstore$(EXEEXT)
|
||||
$(CXXLINK) $(gsmsmsstore_LDFLAGS) $(gsmsmsstore_OBJECTS) $(gsmsmsstore_LDADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT) core *.core
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsmctl.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsmpb.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsmsendsms.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsmsmsd.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsmsmsstore.Po@am__quote@
|
||||
|
||||
distclean-depend:
|
||||
-rm -rf ./$(DEPDIR)
|
||||
|
||||
.cc.o:
|
||||
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
$(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
|
||||
|
||||
.cc.obj:
|
||||
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
$(CXXCOMPILE) -c -o $@ `cygpath -w $<`
|
||||
|
||||
.cc.lo:
|
||||
@AMDEP_TRUE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
$(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
|
||||
distclean-libtool:
|
||||
-rm -f libtool
|
||||
uninstall-info-am:
|
||||
|
||||
ETAGS = etags
|
||||
ETAGSFLAGS =
|
||||
|
||||
tags: TAGS
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
mkid -fID $$unique
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|
||||
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$tags $$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& cd $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) $$here
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
top_distdir = ..
|
||||
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@list='$(DISTFILES)'; for file in $$list; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
dir="/$$dir"; \
|
||||
$(mkinstalldirs) "$(distdir)$$dir"; \
|
||||
else \
|
||||
dir=''; \
|
||||
fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
|
||||
fi; \
|
||||
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(PROGRAMS)
|
||||
|
||||
installdirs:
|
||||
$(mkinstalldirs) $(DESTDIR)$(bindir)
|
||||
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
|
||||
distclean-am: clean-am distclean-compile distclean-depend \
|
||||
distclean-generic distclean-libtool distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am:
|
||||
|
||||
install-exec-am: install-binPROGRAMS
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-man:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
||||
uninstall-am: uninstall-binPROGRAMS uninstall-info-am
|
||||
|
||||
.PHONY: GTAGS all all-am check check-am clean clean-binPROGRAMS \
|
||||
clean-generic clean-libtool distclean distclean-compile \
|
||||
distclean-depend distclean-generic distclean-libtool \
|
||||
distclean-tags distdir dvi dvi-am info info-am install \
|
||||
install-am install-binPROGRAMS install-data install-data-am \
|
||||
install-exec install-exec-am install-info install-info-am \
|
||||
install-man install-strip installcheck installcheck-am \
|
||||
installdirs maintainer-clean maintainer-clean-generic \
|
||||
mostlyclean mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool tags uninstall uninstall-am \
|
||||
uninstall-binPROGRAMS uninstall-info-am
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
@ -0,0 +1,635 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsmctl.cc
|
||||
// *
|
||||
// * Purpose: GSM mobile phone control program
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 11.7.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <gsm_config.h>
|
||||
#endif
|
||||
#include <gsmlib/gsm_nls.h>
|
||||
#include <string>
|
||||
#if defined(HAVE_GETOPT_LONG) || defined(WIN32)
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#include <strstream>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <gsmlib/gsm_me_ta.h>
|
||||
#include <gsmlib/gsm_util.h>
|
||||
#include <gsmlib/gsm_sysdep.h>
|
||||
#ifdef WIN32
|
||||
#include <gsmlib/gsm_win32_serial.h>
|
||||
#else
|
||||
#include <gsmlib/gsm_unix_serial.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace gsmlib;
|
||||
|
||||
// my ME
|
||||
|
||||
static MeTa *m;
|
||||
|
||||
// information parameters
|
||||
|
||||
enum InfoParameter {AllInfo, // print all info
|
||||
MeInfo, // MeInfo must be first!
|
||||
FunctionalityInfo,
|
||||
OperatorInfo,
|
||||
CurrentOperatorInfo,
|
||||
FacilityLockStateInfo,
|
||||
FacilityLockCapabilityInfo,
|
||||
PasswordInfo,
|
||||
PINInfo,
|
||||
CLIPInfo,
|
||||
CallForwardingInfo,
|
||||
BatteryInfo,
|
||||
BitErrorInfo,
|
||||
SCAInfo,
|
||||
CharSetInfo,
|
||||
SignalInfo}; // SignalInfo must be last!
|
||||
|
||||
// operation parameters
|
||||
|
||||
// FIXME operations not implemented yet
|
||||
|
||||
// options
|
||||
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
static struct option longOpts[] =
|
||||
{
|
||||
{"xonxoff", no_argument, (int*)NULL, 'X'},
|
||||
{"operation", required_argument, (int*)NULL, 'o'},
|
||||
{"device", required_argument, (int*)NULL, 'd'},
|
||||
{"baudrate", required_argument, (int*)NULL, 'b'},
|
||||
{"init", required_argument, (int*)NULL, 'I'},
|
||||
{"help", no_argument, (int*)NULL, 'h'},
|
||||
{"version", no_argument, (int*)NULL, 'v'},
|
||||
{(char*)NULL, 0, (int*)NULL, 0}
|
||||
};
|
||||
#else
|
||||
#define getopt_long(argc, argv, options, longopts, indexptr) \
|
||||
getopt(argc, argv, options)
|
||||
#endif
|
||||
|
||||
// helper function, prints forwarding info
|
||||
|
||||
void printForwardReason(string s, ForwardInfo &info)
|
||||
{
|
||||
cout << s << " "
|
||||
<< (info._active ? _("active ") : _("inactive "))
|
||||
<< _("number: ") << info._number
|
||||
<< _(" subaddr: ") << info._subAddr
|
||||
<< _(" time: ") << info._time << endl;
|
||||
}
|
||||
|
||||
// print information
|
||||
|
||||
static void printInfo(InfoParameter ip)
|
||||
{
|
||||
switch (ip)
|
||||
{
|
||||
case MeInfo:
|
||||
{
|
||||
MEInfo mei = m->getMEInfo();
|
||||
cout << _("<ME0> Manufacturer: ") << mei._manufacturer << endl
|
||||
<< _("<ME1> Model: ") << mei._model << endl
|
||||
<< _("<ME2> Revision: ") << mei._revision << endl
|
||||
<< _("<ME3> Serial Number: ") << mei._serialNumber << endl;
|
||||
break;
|
||||
}
|
||||
case FunctionalityInfo:
|
||||
{
|
||||
try {
|
||||
int fun;
|
||||
fun = m->getFunctionalityLevel();
|
||||
cout << _("<FUN> Functionality Level: ") << fun << endl;
|
||||
} catch (GsmException &x) {
|
||||
cout << _("<FUN> Functionality Level: ") << _("unsupported") << endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OperatorInfo:
|
||||
{
|
||||
int count = 0;
|
||||
vector<OPInfo> opis = m->getAvailableOPInfo();
|
||||
for (vector<OPInfo>::iterator i = opis.begin(); i != opis.end(); ++i)
|
||||
{
|
||||
cout << "<OP" << count << _("> Status: ");
|
||||
switch (i->_status)
|
||||
{
|
||||
case UnknownOPStatus: cout << _("unknown"); break;
|
||||
case CurrentOPStatus: cout << _("current"); break;
|
||||
case AvailableOPStatus: cout << _("available"); break;
|
||||
case ForbiddenOPStatus: cout << _("forbidden"); break;
|
||||
}
|
||||
cout << _(" Long name: '") << i->_longName << "' "
|
||||
<< _(" Short name: '") << i->_shortName << "' "
|
||||
<< _(" Numeric name: ") << i->_numericName << endl;
|
||||
++count;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CurrentOperatorInfo:
|
||||
{
|
||||
OPInfo opi = m->getCurrentOPInfo();
|
||||
cout << "<CURROP0>"
|
||||
<< _(" Long name: '") << opi._longName << "' "
|
||||
<< _(" Short name: '") << opi._shortName << "' "
|
||||
<< _(" Numeric name: ") << opi._numericName
|
||||
<< _(" Mode: ");
|
||||
switch (opi._mode)
|
||||
{
|
||||
case AutomaticOPMode: cout << _("automatic"); break;
|
||||
case ManualOPMode: cout << _("manual"); break;
|
||||
case DeregisterOPMode: cout << _("deregister"); break;
|
||||
case ManualAutomaticOPMode: cout << _("manual/automatic"); break;
|
||||
}
|
||||
cout << endl;
|
||||
break;
|
||||
}
|
||||
case FacilityLockStateInfo:
|
||||
{
|
||||
int count = 0;
|
||||
vector<string> fclc = m->getFacilityLockCapabilities();
|
||||
for (vector<string>::iterator i = fclc.begin(); i != fclc.end(); ++i)
|
||||
if (*i != "AB" && *i != "AG" && *i != "AC")
|
||||
{
|
||||
cout << "<FLSTAT" << count << "> '" << *i << "'";
|
||||
try
|
||||
{
|
||||
if (m->getFacilityLockStatus(*i, VoiceFacility))
|
||||
cout << _(" Voice");
|
||||
}
|
||||
catch (GsmException &e)
|
||||
{
|
||||
cout << _(" unknown");
|
||||
}
|
||||
try
|
||||
{
|
||||
if (m->getFacilityLockStatus(*i, DataFacility))
|
||||
cout << _(" Data");
|
||||
}
|
||||
catch (GsmException &e)
|
||||
{
|
||||
cout << _(" unknown");
|
||||
}
|
||||
try
|
||||
{
|
||||
if (m->getFacilityLockStatus(*i, FaxFacility))
|
||||
cout << _(" Fax");
|
||||
}
|
||||
catch (GsmException &e)
|
||||
{
|
||||
cout << _(" unknown");
|
||||
}
|
||||
cout << endl;
|
||||
++count;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FacilityLockCapabilityInfo:
|
||||
{
|
||||
cout << "<FLCAP0> ";
|
||||
vector<string> fclc = m->getFacilityLockCapabilities();
|
||||
for (vector<string>::iterator i = fclc.begin(); i != fclc.end(); ++i)
|
||||
cout << "'" << *i << "' ";
|
||||
cout << endl;
|
||||
break;
|
||||
}
|
||||
case PasswordInfo:
|
||||
{
|
||||
vector<PWInfo> pwi = m->getPasswords();
|
||||
int count = 0;
|
||||
for (vector<PWInfo>::iterator i = pwi.begin(); i != pwi.end(); ++i)
|
||||
{
|
||||
cout << "<PW" << count << "> '"
|
||||
<< i->_facility << "' " << i->_maxPasswdLen << endl;
|
||||
++count;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PINInfo:
|
||||
{
|
||||
cout << "<PIN0> " << m->getPINStatus() << endl;
|
||||
break;
|
||||
}
|
||||
case CLIPInfo:
|
||||
{
|
||||
cout << "<CLIP0> " << (m->getNetworkCLIP() ? _("on") : _("off")) << endl;
|
||||
break;
|
||||
}
|
||||
case CallForwardingInfo:
|
||||
{
|
||||
for (int r = 0; r < 4; ++r)
|
||||
{
|
||||
string text;
|
||||
switch (r)
|
||||
{
|
||||
case 0: text = _("UnconditionalReason"); break;
|
||||
case 1: text = _("MobileBusyReason"); break;
|
||||
case 2: text = _("NoReplyReason"); break;
|
||||
case 3: text = _("NotReachableReason"); break;
|
||||
}
|
||||
ForwardInfo voice, fax, data;
|
||||
m->getCallForwardInfo((ForwardReason)r, voice, fax, data);
|
||||
cout << "<FORW" << r << ".";
|
||||
printForwardReason("0> " + text + _(" Voice"), voice);
|
||||
cout << "<FORW" << r << ".";
|
||||
printForwardReason("1> " + text + _(" Data"), data);
|
||||
cout << "<FORW" << r << ".";
|
||||
printForwardReason("2> " + text + _(" Fax"), fax);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BatteryInfo:
|
||||
{
|
||||
cout << "<BATT0> ";
|
||||
int bcs = m->getBatteryChargeStatus();
|
||||
switch (bcs)
|
||||
{
|
||||
case 0: cout << _("0 ME is powered by the battery") << endl; break;
|
||||
case 1: cout << _("1 ME has a battery connected, but is not powered by it")
|
||||
<< endl; break;
|
||||
case 2: cout << _("2 ME does not have a battery connected") << endl; break;
|
||||
case 3:
|
||||
cout << _("3 Recognized power fault, calls inhibited") << endl;
|
||||
break;
|
||||
}
|
||||
cout << "<BATT1> " << m->getBatteryCharge() << endl;
|
||||
break;
|
||||
}
|
||||
case BitErrorInfo:
|
||||
{
|
||||
cout << "<BITERR0> " << m->getBitErrorRate() << endl;
|
||||
break;
|
||||
}
|
||||
case SCAInfo:
|
||||
{
|
||||
cout << "<SCA0> " << m->getServiceCentreAddress() << endl;
|
||||
break;
|
||||
}
|
||||
case CharSetInfo:
|
||||
{
|
||||
cout << "<CSET0> ";
|
||||
vector<string> cs = m->getSupportedCharSets();
|
||||
for (vector<string>::iterator i = cs.begin(); i != cs.end(); ++i)
|
||||
cout << "'" << *i << "' ";
|
||||
cout << endl;
|
||||
cout << "<CSET1> '" << m->getCurrentCharSet() << "'" << endl;
|
||||
break;
|
||||
}
|
||||
case SignalInfo:
|
||||
{
|
||||
cout << "<SIG0> " << m->getSignalStrength() << endl;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// convert facility class string of the form "", "all", or any combination
|
||||
// of "v" (voice), "d" (data), or "f" (fax) to numeric form
|
||||
|
||||
FacilityClass strToFacilityClass(string facilityClassS)
|
||||
{
|
||||
facilityClassS = lowercase(facilityClassS);
|
||||
FacilityClass facilityClass = (FacilityClass)0;
|
||||
if (facilityClassS == "all" || facilityClassS == "")
|
||||
return (FacilityClass)ALL_FACILITIES;
|
||||
|
||||
// OR in facility class bits
|
||||
for (unsigned int i = 0; i < facilityClassS.length(); ++i)
|
||||
if (facilityClassS[i] == 'v')
|
||||
facilityClass = (FacilityClass)(facilityClass | VoiceFacility);
|
||||
else if (facilityClassS[i] == 'd')
|
||||
facilityClass = (FacilityClass)(facilityClass | DataFacility);
|
||||
else if (facilityClassS[i] == 'f')
|
||||
facilityClass = (FacilityClass)(facilityClass | FaxFacility);
|
||||
else
|
||||
throw GsmException(
|
||||
stringPrintf(_("unknown facility class parameter '%c'"),
|
||||
facilityClassS[i]), ParameterError);
|
||||
|
||||
return facilityClass;
|
||||
}
|
||||
|
||||
// check if argc - optind is in range min..max
|
||||
// throw exception otherwise
|
||||
|
||||
void checkParamCount(int optind, int argc, int min, int max)
|
||||
{
|
||||
int paramCount = argc - optind;
|
||||
if (paramCount < min)
|
||||
throw GsmException(stringPrintf(_("not enough parameters, minimum number "
|
||||
"of parameters is %d"), min),
|
||||
ParameterError);
|
||||
else if (paramCount > max)
|
||||
throw GsmException(stringPrintf(_("too many parameters, maximum number "
|
||||
"of parameters is %d"), max),
|
||||
ParameterError);
|
||||
}
|
||||
|
||||
// *** main program
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
try
|
||||
{
|
||||
// handle command line options
|
||||
string device = "/dev/mobilephone";
|
||||
string operation;
|
||||
string baudrate;
|
||||
string initString = DEFAULT_INIT_STRING;
|
||||
bool swHandshake = false;
|
||||
|
||||
int opt;
|
||||
int dummy;
|
||||
while((opt = getopt_long(argc, argv, "I:o:d:b:hvX", longOpts, &dummy))
|
||||
!= -1)
|
||||
switch (opt)
|
||||
{
|
||||
case 'X':
|
||||
swHandshake = true;
|
||||
break;
|
||||
case 'I':
|
||||
initString = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
device = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
operation = optarg;
|
||||
break;
|
||||
case 'b':
|
||||
baudrate = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"),
|
||||
VERSION, __DATE__) << endl;
|
||||
exit(0);
|
||||
break;
|
||||
case 'h':
|
||||
cerr << argv[0] << _(": [-b baudrate][-d device][-h]"
|
||||
"[-I init string][-o operation]\n"
|
||||
" [-v][-X]{parameters}") << endl
|
||||
<< endl
|
||||
<< _(" -b, --baudrate baudrate to use for device "
|
||||
"(default: 38400)")
|
||||
<< endl
|
||||
<< _(" -d, --device sets the destination device to "
|
||||
"connect to") << endl
|
||||
<< _(" -h, --help prints this message") << endl
|
||||
<< _(" -I, --init device AT init sequence") << endl
|
||||
<< _(" -o, --operation operation to perform on the mobile \n"
|
||||
" phone with the specified parameters")
|
||||
<< endl
|
||||
<< _(" -v, --version prints version and exits") << endl
|
||||
<< _(" -X, --xonxoff switch on software handshake") << endl
|
||||
<< endl
|
||||
<< _(" parameters parameters to use for the operation\n"
|
||||
" (if an operation is given) or\n"
|
||||
" a specification which kind of\n"
|
||||
" information to read from the mobile "
|
||||
"phone")
|
||||
<< endl << endl
|
||||
<< _("Refer to gsmctl(1) for details on the available parameters"
|
||||
" and operations.")
|
||||
<< endl << endl;
|
||||
exit(0);
|
||||
break;
|
||||
case '?':
|
||||
throw GsmException(_("unknown option"), ParameterError);
|
||||
break;
|
||||
}
|
||||
|
||||
// open the port and ME/TA
|
||||
m = new MeTa(new
|
||||
#ifdef WIN32
|
||||
Win32SerialPort
|
||||
#else
|
||||
UnixSerialPort
|
||||
#endif
|
||||
(device,
|
||||
baudrate == "" ?
|
||||
DEFAULT_BAUD_RATE :
|
||||
baudRateStrToSpeed(baudrate),
|
||||
initString, swHandshake));
|
||||
|
||||
if (operation == "")
|
||||
{ // process info parameters
|
||||
for (int i = optind; i < argc; ++i)
|
||||
{
|
||||
string param = lowercase(argv[i]);
|
||||
if (param == "all")
|
||||
for (int ip = MeInfo; ip <= SignalInfo; ++ip)
|
||||
printInfo((InfoParameter)ip);
|
||||
else if (param == "me")
|
||||
printInfo(MeInfo);
|
||||
else if (param == "fun")
|
||||
printInfo(FunctionalityInfo);
|
||||
else if (param == "op")
|
||||
printInfo(OperatorInfo);
|
||||
else if (param == "currop")
|
||||
printInfo(CurrentOperatorInfo);
|
||||
else if (param == "flstat")
|
||||
printInfo(FacilityLockStateInfo);
|
||||
else if (param == "flcap")
|
||||
printInfo(FacilityLockCapabilityInfo);
|
||||
else if (param == "pw")
|
||||
printInfo(PasswordInfo);
|
||||
else if (param == "pin")
|
||||
printInfo(PINInfo);
|
||||
else if (param == "clip")
|
||||
printInfo(CLIPInfo);
|
||||
else if (param == "forw")
|
||||
printInfo(CallForwardingInfo);
|
||||
else if (param == "batt")
|
||||
printInfo(BatteryInfo);
|
||||
else if (param == "biterr")
|
||||
printInfo(BitErrorInfo);
|
||||
else if (param == "sig")
|
||||
printInfo(SignalInfo);
|
||||
else if (param == "sca")
|
||||
printInfo(SCAInfo);
|
||||
else if (param == "cset")
|
||||
printInfo(CharSetInfo);
|
||||
else
|
||||
throw GsmException(
|
||||
stringPrintf(_("unknown information parameter '%s'"),
|
||||
param.c_str()),
|
||||
ParameterError);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // process operation
|
||||
operation = lowercase(operation);
|
||||
if (operation == "dial")
|
||||
{
|
||||
// dial: number
|
||||
checkParamCount(optind, argc, 1, 1);
|
||||
|
||||
m->dial(argv[optind]);
|
||||
|
||||
// wait for keypress from stdin
|
||||
char c;
|
||||
read(1, &c, 1);
|
||||
}
|
||||
else if (operation == "on")
|
||||
{
|
||||
m->setFunctionalityLevel(1);
|
||||
}
|
||||
else if (operation == "off")
|
||||
{
|
||||
m->setFunctionalityLevel(0);
|
||||
}
|
||||
else if (operation == "pin")
|
||||
{
|
||||
// pin: PIN
|
||||
checkParamCount(optind, argc, 1, 1);
|
||||
|
||||
m->setPIN(argv[optind]);
|
||||
}
|
||||
else if (operation == "setop")
|
||||
{
|
||||
// setop: opmode numeric FIXME allow long and numeric too
|
||||
checkParamCount(optind, argc, 2, 2);
|
||||
string opmodeS = lowercase(argv[optind]);
|
||||
OPModes opmode;
|
||||
if (opmodeS == "automatic")
|
||||
opmode = AutomaticOPMode;
|
||||
else if (opmodeS == "manual")
|
||||
opmode = ManualOPMode;
|
||||
else if (opmodeS == "deregister")
|
||||
opmode = DeregisterOPMode;
|
||||
else if (opmodeS == "manualautomatic")
|
||||
opmode = ManualAutomaticOPMode;
|
||||
else
|
||||
throw GsmException(stringPrintf(_("unknown opmode parameter '%s'"),
|
||||
opmodeS.c_str()), ParameterError);
|
||||
|
||||
m->setCurrentOPInfo(opmode, "" , "", checkNumber(argv[optind + 1]));
|
||||
}
|
||||
else if (operation == "lock")
|
||||
{
|
||||
// lock: facility [facilityclass] [passwd]
|
||||
checkParamCount(optind, argc, 1, 3);
|
||||
string passwd = (argc - optind == 3) ?
|
||||
(string)argv[optind + 2] : (string)"";
|
||||
|
||||
m->lockFacility(argv[optind],
|
||||
(argc - optind >= 2) ?
|
||||
strToFacilityClass(argv[optind + 1]) :
|
||||
(FacilityClass)ALL_FACILITIES,
|
||||
passwd);
|
||||
}
|
||||
else if (operation == "unlock")
|
||||
{
|
||||
// unlock: facility [facilityclass] [passwd]
|
||||
checkParamCount(optind, argc, 1, 3);
|
||||
string passwd = argc - optind == 3 ? argv[optind + 2] : "";
|
||||
|
||||
m->unlockFacility(argv[optind],
|
||||
(argc - optind >= 2) ?
|
||||
strToFacilityClass(argv[optind + 1]) :
|
||||
(FacilityClass)ALL_FACILITIES,
|
||||
passwd);
|
||||
}
|
||||
else if (operation == "setpw")
|
||||
{
|
||||
// set password: facility oldpasswd newpasswd
|
||||
checkParamCount(optind, argc, 1, 3);
|
||||
string oldPasswd = argc - optind >= 2 ? argv[optind + 1] : "";
|
||||
string newPasswd = argc - optind == 3 ? argv[optind + 2] : "";
|
||||
|
||||
m->setPassword(argv[optind], oldPasswd, newPasswd);
|
||||
}
|
||||
else if (operation == "forw")
|
||||
{
|
||||
// call forwarding: mode reason number [facilityclass] [forwardtime]
|
||||
checkParamCount(optind, argc, 2, 5);
|
||||
|
||||
// get optional parameters facility class and forwardtime
|
||||
int forwardTime = argc - optind == 5 ? checkNumber(argv[optind + 4]) :
|
||||
NOT_SET;
|
||||
FacilityClass facilityClass =
|
||||
argc - optind >= 4 ? strToFacilityClass(argv[optind + 3]) :
|
||||
(FacilityClass)ALL_FACILITIES;
|
||||
|
||||
// get forward reason
|
||||
string reasonS = lowercase(argv[optind + 1]);
|
||||
ForwardReason reason;
|
||||
if (reasonS == "unconditional")
|
||||
reason = UnconditionalReason;
|
||||
else if (reasonS == "mobilebusy")
|
||||
reason = MobileBusyReason;
|
||||
else if (reasonS == "noreply")
|
||||
reason = NoReplyReason;
|
||||
else if (reasonS == "notreachable")
|
||||
reason = NotReachableReason;
|
||||
else if (reasonS == "all")
|
||||
reason = AllReasons;
|
||||
else if (reasonS == "allconditional")
|
||||
reason = AllConditionalReasons;
|
||||
else
|
||||
throw GsmException(
|
||||
stringPrintf(_("unknown forward reason parameter '%s'"),
|
||||
reasonS.c_str()), ParameterError);
|
||||
|
||||
// get mode
|
||||
string modeS = lowercase(argv[optind]);
|
||||
ForwardMode mode;
|
||||
if (modeS == "disable")
|
||||
mode = DisableMode;
|
||||
else if (modeS == "enable")
|
||||
mode = EnableMode;
|
||||
else if (modeS == "register")
|
||||
mode = RegistrationMode;
|
||||
else if (modeS == "erase")
|
||||
mode = ErasureMode;
|
||||
else
|
||||
throw GsmException(
|
||||
stringPrintf(_("unknown forward mode parameter '%s'"),
|
||||
modeS.c_str()), ParameterError);
|
||||
|
||||
m->setCallForwarding(reason, mode,
|
||||
(argc - optind >= 3) ? argv[optind + 2] : "",
|
||||
"", // subaddr
|
||||
facilityClass, forwardTime);
|
||||
}
|
||||
else if (operation == "setsca")
|
||||
{
|
||||
// set sca: number
|
||||
checkParamCount(optind, argc, 1, 1);
|
||||
m->setServiceCentreAddress(argv[optind]);
|
||||
}
|
||||
else if (operation == "cset")
|
||||
{
|
||||
// set charset: string
|
||||
checkParamCount(optind, argc, 1, 1);
|
||||
m->setCharSet(argv[optind]);
|
||||
}
|
||||
else
|
||||
throw GsmException(stringPrintf(_("unknown operation '%s'"),
|
||||
operation.c_str()), ParameterError);
|
||||
}
|
||||
}
|
||||
catch (GsmException &ge)
|
||||
{
|
||||
cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,507 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsmpb.cc
|
||||
// *
|
||||
// * Purpose: phonebook management program
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 24.6.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <gsm_config.h>
|
||||
#endif
|
||||
#include <gsmlib/gsm_nls.h>
|
||||
#include <string>
|
||||
#ifdef WIN32
|
||||
#include <gsmlib/gsm_win32_serial.h>
|
||||
#else
|
||||
#include <gsmlib/gsm_unix_serial.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#if defined(HAVE_GETOPT_LONG) || defined(WIN32)
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <gsmlib/gsm_me_ta.h>
|
||||
#include <gsmlib/gsm_util.h>
|
||||
#include <gsmlib/gsm_sorted_phonebook.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace gsmlib;
|
||||
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
static struct option longOpts[] =
|
||||
{
|
||||
{"xonxoff", no_argument, (int*)NULL, 'X'},
|
||||
{"phonebook", required_argument, (int*)NULL, 'p'},
|
||||
{"init", required_argument, (int*)NULL, 'I'},
|
||||
{"destination", required_argument, (int*)NULL, 'd'},
|
||||
{"source", required_argument, (int*)NULL, 's'},
|
||||
{"destination-backend", required_argument, (int*)NULL, 'D'},
|
||||
{"source-backend", required_argument, (int*)NULL, 'S'},
|
||||
{"baudrate", required_argument, (int*)NULL, 'b'},
|
||||
{"charset", required_argument, (int*)NULL, 't'},
|
||||
{"copy", no_argument, (int*)NULL, 'c'},
|
||||
{"synchronize", no_argument, (int*)NULL, 'y'},
|
||||
{"help", no_argument, (int*)NULL, 'h'},
|
||||
{"version", no_argument, (int*)NULL, 'v'},
|
||||
{"verbose", no_argument, (int*)NULL, 'V'},
|
||||
{"indexed", no_argument, (int*)NULL, 'i'},
|
||||
{(char*)NULL, 0, (int*)NULL, 0}
|
||||
};
|
||||
#else
|
||||
#define getopt_long(argc, argv, options, longopts, indexptr) \
|
||||
getopt(argc, argv, options)
|
||||
#endif
|
||||
|
||||
// insert those entries from sourcePhonebook into destPhonebook
|
||||
// that are not already present in destPhonebook
|
||||
|
||||
void insertNotPresent(SortedPhonebookRef sourcePhonebook,
|
||||
SortedPhonebookRef destPhonebook,
|
||||
bool indexed, bool verbose)
|
||||
{
|
||||
for (SortedPhonebookBase::iterator i = sourcePhonebook->begin();
|
||||
i != sourcePhonebook->end(); ++i)
|
||||
{
|
||||
pair<SortedPhonebookBase::iterator, SortedPhonebookBase::iterator> range;
|
||||
if (indexed)
|
||||
{
|
||||
int index = i->index();
|
||||
range = destPhonebook->equal_range(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
string text = i->text();
|
||||
range = destPhonebook->equal_range(text);
|
||||
}
|
||||
|
||||
// do nothing if the entry is already present in the destination
|
||||
bool alreadyPresent = false;
|
||||
for (SortedPhonebookBase::iterator j = range.first;
|
||||
j != range.second; ++j)
|
||||
{
|
||||
i->setUseIndex(indexed);
|
||||
if (i->telephone() == j->telephone())
|
||||
{
|
||||
alreadyPresent = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// ... else insert it
|
||||
if (! alreadyPresent)
|
||||
{
|
||||
if (verbose)
|
||||
{
|
||||
cout << stringPrintf(_("inserting '%s' tel# %s"),
|
||||
i->text().c_str(), i->telephone().c_str());
|
||||
if (indexed)
|
||||
cout << stringPrintf(_(" (index #%d)"), i->index());
|
||||
cout << endl;
|
||||
}
|
||||
i->setUseIndex(indexed);
|
||||
destPhonebook->insert(*i); // insert
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update those entries in destPhonebook, that
|
||||
// - have the same name as one entry in destPhonebook
|
||||
// - but have a different telephone number
|
||||
// this is only done if the name in question is unique in the destPhonebook
|
||||
// the case of several entries having the same in the sourcePhonebook
|
||||
// is handled - only the first is considered for updating
|
||||
|
||||
void updateEntries(SortedPhonebookRef sourcePhonebook,
|
||||
SortedPhonebookRef destPhonebook,
|
||||
bool verbose)
|
||||
{
|
||||
bool firstLoop = true;
|
||||
string lastText;
|
||||
|
||||
for (SortedPhonebookBase::iterator i = sourcePhonebook->begin();
|
||||
i != sourcePhonebook->end(); ++i)
|
||||
{
|
||||
string text = i->text();
|
||||
if (! firstLoop && text != lastText)
|
||||
{
|
||||
pair<SortedPhonebookBase::iterator,
|
||||
SortedPhonebookBase::iterator> range =
|
||||
destPhonebook->equal_range(text);
|
||||
|
||||
SortedPhonebookBase::iterator first = range.first;
|
||||
if (first != destPhonebook->end() && range.second == ++first)
|
||||
{ // just one text in the destPhonebook
|
||||
if (! (*range.first == *i)) // overwrite if different in destination
|
||||
{
|
||||
if (verbose)
|
||||
cout << stringPrintf(_("updating '%s' tel# %s to new tel# %s"),
|
||||
range.first->text().c_str(),
|
||||
range.first->telephone().c_str(),
|
||||
i->telephone().c_str())
|
||||
<< endl;
|
||||
|
||||
*range.first = *i;
|
||||
}
|
||||
}
|
||||
lastText = text;
|
||||
}
|
||||
firstLoop = false;
|
||||
}
|
||||
}
|
||||
|
||||
// the same but for indexed phonebooks
|
||||
|
||||
void updateEntriesIndexed(SortedPhonebookRef sourcePhonebook,
|
||||
SortedPhonebookRef destPhonebook,
|
||||
bool verbose)
|
||||
{
|
||||
for (SortedPhonebookBase::iterator i = sourcePhonebook->begin();
|
||||
i != sourcePhonebook->end(); ++i)
|
||||
{
|
||||
int index = i->index();
|
||||
|
||||
SortedPhonebookBase::iterator j = destPhonebook->find(index);
|
||||
|
||||
if (j != destPhonebook->end())
|
||||
{ // index present in the destPhonebook
|
||||
if (! (*j == *i)) // overwrite if different in destination
|
||||
{
|
||||
if (verbose)
|
||||
cout << stringPrintf(_("updating '%s' tel# %s to new tel# %s"
|
||||
"(index %d)"),
|
||||
j->text().c_str(),
|
||||
j->telephone().c_str(),
|
||||
i->telephone().c_str(), i->index())
|
||||
<< endl;
|
||||
|
||||
*j = *i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// delete those entries from destPhonebook, that are not present
|
||||
// in sourcePhonebook
|
||||
|
||||
void deleteNotPresent(SortedPhonebookRef sourcePhonebook,
|
||||
SortedPhonebookRef destPhonebook,
|
||||
bool indexed, bool verbose)
|
||||
{
|
||||
for (SortedPhonebookBase::iterator i = destPhonebook->begin();
|
||||
i != destPhonebook->end(); ++i)
|
||||
{
|
||||
pair<SortedPhonebookBase::iterator, SortedPhonebookBase::iterator> range;
|
||||
if (indexed)
|
||||
{
|
||||
int index = i->index();
|
||||
range = sourcePhonebook->equal_range(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
string text = i->text();
|
||||
range = sourcePhonebook->equal_range(text);
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
for (SortedPhonebookBase::iterator j = range.first;
|
||||
j != range.second; ++j)
|
||||
{
|
||||
i->setUseIndex(indexed);
|
||||
if (j->telephone() == i->telephone())
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (! found)
|
||||
{
|
||||
if (verbose)
|
||||
{
|
||||
cout << stringPrintf(_("deleting '%s' tel# %s"),
|
||||
i->text().c_str(), i->telephone().c_str());
|
||||
if (indexed)
|
||||
cout << stringPrintf(_(" (index #%d)"), i->index());
|
||||
cout << endl;
|
||||
}
|
||||
destPhonebook->erase(i);
|
||||
#ifdef BUGGY_MAP_ERASE
|
||||
deleteNotPresent(sourcePhonebook, destPhonebook, indexed, verbose);
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// *** main program
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
try
|
||||
{
|
||||
// handle command line options
|
||||
string destination;
|
||||
string source;
|
||||
string destinationBackend;
|
||||
string sourceBackend;
|
||||
string baudrate;
|
||||
bool doSynchronize = true;
|
||||
string phonebook;
|
||||
SortedPhonebookRef sourcePhonebook, destPhonebook;
|
||||
bool verbose = false;
|
||||
bool indexed = false;
|
||||
string initString = DEFAULT_INIT_STRING;
|
||||
bool swHandshake = false;
|
||||
string charSet;
|
||||
Ref<MeTa> sourceMeTa, destMeTa;
|
||||
|
||||
int opt;
|
||||
int dummy;
|
||||
while((opt = getopt_long(argc, argv, "I:p:s:d:b:cyhvViD:S:Xt:", longOpts,
|
||||
&dummy))
|
||||
!= -1)
|
||||
switch (opt)
|
||||
{
|
||||
case 'X':
|
||||
swHandshake = true;
|
||||
break;
|
||||
case 'I':
|
||||
initString = optarg;
|
||||
break;
|
||||
case 'V':
|
||||
verbose = true;
|
||||
break;
|
||||
case 'p':
|
||||
phonebook = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
destination = optarg;
|
||||
break;
|
||||
case 's':
|
||||
source = optarg;
|
||||
break;
|
||||
case 'D':
|
||||
destinationBackend = optarg;
|
||||
break;
|
||||
case 'S':
|
||||
sourceBackend = optarg;
|
||||
break;
|
||||
case 'b':
|
||||
baudrate = optarg;
|
||||
break;
|
||||
case 't':
|
||||
charSet = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
doSynchronize = false;
|
||||
break;
|
||||
case 'i':
|
||||
indexed = true;
|
||||
break;
|
||||
case 'y':
|
||||
doSynchronize = true;
|
||||
break;
|
||||
case 'v':
|
||||
cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"),
|
||||
VERSION, __DATE__) << endl;
|
||||
exit(0);
|
||||
break;
|
||||
case 'h':
|
||||
cerr << argv[0] << _(": [-b baudrate][-c][-d device or file][-h]"
|
||||
"[-I init string]\n"
|
||||
" [-p phonebook name][-s device or file]"
|
||||
"[-t charset][-v]"
|
||||
"[-V][-y][-X]") << endl
|
||||
<< endl
|
||||
<< _(" -b, --baudrate baudrate to use for device "
|
||||
"(default: 38400)")
|
||||
<< endl
|
||||
<< _(" -c, --copy copy source entries to destination")
|
||||
<< endl
|
||||
<< _(" -d, --destination sets the destination device to "
|
||||
"connect \n"
|
||||
" to, or the file to write") << endl
|
||||
<< _(" -D, --destination-backend sets the destination backend")
|
||||
<< endl
|
||||
<< _(" -h, --help prints this message") << endl
|
||||
<< _(" -i, --index takes index positions into account")
|
||||
<< endl
|
||||
<< _(" -I, --init device AT init sequence") << endl
|
||||
<< _(" -p, --phonebook name of phonebook to use") << endl
|
||||
<< _(" -s, --source sets the source device to connect to,\n"
|
||||
" or the file to read") << endl
|
||||
<< _(" -t, --charset sets the character set to use for\n"
|
||||
" phonebook entries") << endl
|
||||
<< _(" -S, --source-backend sets the source backend")
|
||||
<< endl
|
||||
<< _(" -v, --version prints version and exits") << endl
|
||||
<< _(" -V, --verbose print detailed progress messages")
|
||||
<< endl
|
||||
<< _(" -X, --xonxoff switch on software handshake") << endl
|
||||
<< _(" -y, --synchronize synchronize destination with source\n"
|
||||
" entries (destination is overwritten)\n"
|
||||
" (see gsmpb(1) for details)")
|
||||
<< endl << endl;
|
||||
exit(0);
|
||||
break;
|
||||
case '?':
|
||||
throw GsmException(_("unknown option"), ParameterError);
|
||||
break;
|
||||
}
|
||||
|
||||
// check if all parameters all present
|
||||
if (destination == "" || source == "")
|
||||
throw GsmException(_("both source and destination must be given"),
|
||||
ParameterError);
|
||||
|
||||
// start accessing source mobile phone or file
|
||||
if (sourceBackend != "")
|
||||
sourcePhonebook =
|
||||
CustomPhonebookRegistry::createPhonebook(sourceBackend, source);
|
||||
else if (source == "-")
|
||||
sourcePhonebook = new SortedPhonebook(true, indexed);
|
||||
else if (isFile(source))
|
||||
sourcePhonebook = new SortedPhonebook(source, indexed);
|
||||
else
|
||||
{
|
||||
if (phonebook == "")
|
||||
throw GsmException(_("phonebook name must be given"), ParameterError);
|
||||
|
||||
sourceMeTa = new MeTa(new
|
||||
#ifdef WIN32
|
||||
Win32SerialPort
|
||||
#else
|
||||
UnixSerialPort
|
||||
#endif
|
||||
(source,
|
||||
baudrate == "" ? DEFAULT_BAUD_RATE :
|
||||
baudRateStrToSpeed(baudrate), initString,
|
||||
swHandshake));
|
||||
if (charSet != "")
|
||||
sourceMeTa->setCharSet(charSet);
|
||||
sourcePhonebook =
|
||||
new SortedPhonebook(sourceMeTa->getPhonebook(phonebook));
|
||||
}
|
||||
|
||||
// make sure destination.c_str file exists
|
||||
if (destination != "")
|
||||
{
|
||||
try
|
||||
{
|
||||
ofstream f(destination.c_str(), ios::out | ios::app);
|
||||
}
|
||||
catch (exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// start accessing destination mobile phone or file
|
||||
if (destinationBackend != "")
|
||||
destPhonebook =
|
||||
CustomPhonebookRegistry::createPhonebook(destinationBackend,
|
||||
destination);
|
||||
else if (destination == "-")
|
||||
destPhonebook = new SortedPhonebook(false, indexed);
|
||||
else if (isFile(destination))
|
||||
destPhonebook = new SortedPhonebook(destination, indexed);
|
||||
else
|
||||
{
|
||||
if (phonebook == "")
|
||||
throw GsmException(_("phonebook name must be given"), ParameterError);
|
||||
|
||||
destMeTa = new MeTa(new
|
||||
#ifdef WIN32
|
||||
Win32SerialPort
|
||||
#else
|
||||
UnixSerialPort
|
||||
#endif
|
||||
(destination,
|
||||
baudrate == "" ? DEFAULT_BAUD_RATE :
|
||||
baudRateStrToSpeed(baudrate), initString,
|
||||
swHandshake));
|
||||
if (charSet != "")
|
||||
destMeTa->setCharSet(charSet);
|
||||
PhonebookRef destPb = destMeTa->getPhonebook(phonebook);
|
||||
|
||||
// check maximum lengths of source text and phonenumber when writing to
|
||||
// mobile phone
|
||||
unsigned int maxTextLen = destPb->getMaxTextLen();
|
||||
unsigned int maxTelLen = destPb->getMaxTelephoneLen();
|
||||
|
||||
for (SortedPhonebookBase::iterator i = sourcePhonebook->begin();
|
||||
i != sourcePhonebook->end(); ++i)
|
||||
if (i->text().length() > maxTextLen)
|
||||
throw GsmException(
|
||||
stringPrintf(_("text '%s' is too large to fit into destination "
|
||||
"(maximum size %d characters)"),
|
||||
i->text().c_str(), maxTextLen),
|
||||
ParameterError);
|
||||
else if (i->telephone().length() > maxTelLen)
|
||||
throw GsmException(
|
||||
stringPrintf(_("phone number '%s' is too large to fit into "
|
||||
"destination (maximum size %d characters)"),
|
||||
i->telephone().c_str(), maxTelLen),
|
||||
ParameterError);
|
||||
|
||||
// read phonebook
|
||||
destPhonebook = new SortedPhonebook(destPb);
|
||||
}
|
||||
|
||||
// now do the actual work
|
||||
if (doSynchronize)
|
||||
{ // synchronizing
|
||||
if (indexed)
|
||||
{
|
||||
sourcePhonebook->setSortOrder(ByIndex);
|
||||
destPhonebook->setSortOrder(ByIndex);
|
||||
// for an explanation see below
|
||||
updateEntriesIndexed(sourcePhonebook, destPhonebook, verbose);
|
||||
deleteNotPresent(sourcePhonebook, destPhonebook, true, verbose);
|
||||
insertNotPresent(sourcePhonebook, destPhonebook, true, verbose);
|
||||
}
|
||||
else
|
||||
{
|
||||
sourcePhonebook->setSortOrder(ByText);
|
||||
destPhonebook->setSortOrder(ByText);
|
||||
// the following is done to avoid superfluous writes to the TA
|
||||
// (that takes time) and keep updated (ie. telephone number changed)
|
||||
// entries at the same place
|
||||
// 1. update entries in place where just the number changed
|
||||
updateEntries(sourcePhonebook, destPhonebook, verbose);
|
||||
// 2. delete those that are not present anymore
|
||||
deleteNotPresent(sourcePhonebook, destPhonebook, false, verbose);
|
||||
// 3. insert the new ones
|
||||
insertNotPresent(sourcePhonebook, destPhonebook, false, verbose);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // copying
|
||||
destPhonebook->clear();
|
||||
for (SortedPhonebookBase::iterator i = sourcePhonebook->begin();
|
||||
i != sourcePhonebook->end(); ++i)
|
||||
{
|
||||
if (verbose)
|
||||
{
|
||||
cout << stringPrintf(_("inserting '%s' tel# %s"),
|
||||
i->text().c_str(), i->telephone().c_str());
|
||||
if (indexed)
|
||||
cout << stringPrintf(_(" (index #%d)"), i->index());
|
||||
cout << endl;
|
||||
}
|
||||
destPhonebook->insert(*i);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (GsmException &ge)
|
||||
{
|
||||
cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,257 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsmsendsms.cc
|
||||
// *
|
||||
// * Purpose: GSM sms send program
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 16.7.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <gsm_config.h>
|
||||
#endif
|
||||
#include <gsmlib/gsm_nls.h>
|
||||
#include <string>
|
||||
#ifdef WIN32
|
||||
#include <gsmlib/gsm_win32_serial.h>
|
||||
#else
|
||||
#include <gsmlib/gsm_unix_serial.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#if defined(HAVE_GETOPT_LONG) || defined(WIN32)
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <gsmlib/gsm_me_ta.h>
|
||||
#include <gsmlib/gsm_util.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace gsmlib;
|
||||
|
||||
// options
|
||||
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
static struct option longOpts[] =
|
||||
{
|
||||
{"requeststat", no_argument, (int*)NULL, 'r'},
|
||||
{"xonxoff", no_argument, (int*)NULL, 'X'},
|
||||
{"sca", required_argument, (int*)NULL, 'C'},
|
||||
{"device", required_argument, (int*)NULL, 'd'},
|
||||
{"init", required_argument, (int*)NULL, 'I'},
|
||||
{"concatenate", required_argument, (int*)NULL, 'c'},
|
||||
{"baudrate", required_argument, (int*)NULL, 'b'},
|
||||
{"test", no_argument, (int*)NULL, 't'},
|
||||
{"help", no_argument, (int*)NULL, 'h'},
|
||||
{"version", no_argument, (int*)NULL, 'v'},
|
||||
{(char*)NULL, 0, (int*)NULL, 0}
|
||||
};
|
||||
#else
|
||||
#define getopt_long(argc, argv, options, longopts, indexptr) \
|
||||
getopt(argc, argv, options)
|
||||
#endif
|
||||
|
||||
// convert /r and /n to CR and LF
|
||||
|
||||
static string unescapeString(char *line)
|
||||
{
|
||||
string result;
|
||||
bool escaped = false;
|
||||
int index = 0;
|
||||
|
||||
while (line[index] != 0 &&
|
||||
line[index] != CR && line[index] != LF)
|
||||
{
|
||||
if (escaped)
|
||||
{
|
||||
escaped = false;
|
||||
if (line[index] == 'r')
|
||||
result += CR;
|
||||
else if (line[index] == 'n')
|
||||
result += LF;
|
||||
else if (line[index] == '\\')
|
||||
result += '\\';
|
||||
else
|
||||
result += line[index];
|
||||
}
|
||||
else
|
||||
if (line[index] == '\\')
|
||||
escaped = true;
|
||||
else
|
||||
result += line[index];
|
||||
|
||||
++index;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// *** main program
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
try
|
||||
{
|
||||
// handle command line options
|
||||
string device = "/dev/mobilephone";
|
||||
bool test = false;
|
||||
string baudrate;
|
||||
Ref<GsmAt> at;
|
||||
string initString = DEFAULT_INIT_STRING;
|
||||
bool swHandshake = false;
|
||||
bool requestStatusReport = false;
|
||||
// service centre address (set on command line)
|
||||
string serviceCentreAddress;
|
||||
MeTa *m = NULL;
|
||||
string concatenatedMessageIdStr;
|
||||
int concatenatedMessageId = -1;
|
||||
|
||||
int opt;
|
||||
int dummy;
|
||||
while((opt = getopt_long(argc, argv, "c:C:I:d:b:thvXr", longOpts, &dummy))
|
||||
!= -1)
|
||||
switch (opt)
|
||||
{
|
||||
case 'c':
|
||||
concatenatedMessageIdStr = optarg;
|
||||
break;
|
||||
case 'C':
|
||||
serviceCentreAddress = optarg;
|
||||
break;
|
||||
case 'X':
|
||||
swHandshake = true;
|
||||
break;
|
||||
case 'I':
|
||||
initString = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
device = optarg;
|
||||
break;
|
||||
case 'b':
|
||||
baudrate = optarg;
|
||||
break;
|
||||
case 't':
|
||||
test = true;
|
||||
break;
|
||||
case 'r':
|
||||
requestStatusReport = true;
|
||||
break;
|
||||
case 'v':
|
||||
cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"),
|
||||
VERSION, __DATE__) << endl;
|
||||
exit(0);
|
||||
break;
|
||||
case 'h':
|
||||
cerr << argv[0] << _(": [-b baudrate][-c concatenatedID]"
|
||||
"[-C sca][-d device][-h][-I init string]\n"
|
||||
" [-t][-v][-X] phonenumber [text]") << endl
|
||||
<< endl
|
||||
<< _(" -b, --baudrate baudrate to use for device "
|
||||
"(default: 38400)")
|
||||
<< endl
|
||||
<< _(" -c, --concatenate ID for concatenated SMS messages")
|
||||
<< endl
|
||||
<< _(" -C, --sca SMS service centre address") << endl
|
||||
<< _(" -d, --device sets the destination device to connect "
|
||||
"to") << endl
|
||||
<< _(" -h, --help prints this message") << endl
|
||||
<< _(" -I, --init device AT init sequence") << endl
|
||||
<< _(" -r, --requeststat request SMS status report") << endl
|
||||
<< _(" -t, --test convert text to GSM alphabet and "
|
||||
"vice\n"
|
||||
" versa, no SMS message is sent") << endl
|
||||
<< _(" -v, --version prints version and exits")
|
||||
<< endl
|
||||
<< _(" -X, --xonxoff switch on software handshake") << endl
|
||||
<< endl
|
||||
<< _(" phonenumber recipient's phone number") << endl
|
||||
<< _(" text optional text of the SMS message\n"
|
||||
" if omitted: read from stdin")
|
||||
<< endl << endl;
|
||||
exit(0);
|
||||
break;
|
||||
case '?':
|
||||
throw GsmException(_("unknown option"), ParameterError);
|
||||
break;
|
||||
}
|
||||
|
||||
if (! test)
|
||||
{
|
||||
// open the port and ME/TA
|
||||
Ref<Port> port = new
|
||||
#ifdef WIN32
|
||||
Win32SerialPort
|
||||
#else
|
||||
UnixSerialPort
|
||||
#endif
|
||||
(device,
|
||||
baudrate == "" ? DEFAULT_BAUD_RATE :
|
||||
baudRateStrToSpeed(baudrate),
|
||||
initString, swHandshake);
|
||||
// switch message service level to 1
|
||||
// this enables acknowledgement PDUs
|
||||
m = new MeTa(port);
|
||||
m->setMessageService(1);
|
||||
|
||||
at = new GsmAt(*m);
|
||||
}
|
||||
|
||||
// check parameters
|
||||
if (optind == argc)
|
||||
throw GsmException(_("phone number and text missing"), ParameterError);
|
||||
|
||||
if (optind + 2 < argc)
|
||||
throw GsmException(_("more than two parameters given"), ParameterError);
|
||||
|
||||
if (concatenatedMessageIdStr != "")
|
||||
concatenatedMessageId = checkNumber(concatenatedMessageIdStr);
|
||||
|
||||
// get phone number
|
||||
string phoneNumber = argv[optind];
|
||||
|
||||
// get text
|
||||
string text;
|
||||
if (optind + 1 == argc)
|
||||
{ // read from stdin
|
||||
char s[1000];
|
||||
cin.get(s, 1000);
|
||||
text = unescapeString(s);
|
||||
if (text.length() > 160)
|
||||
throw GsmException(_("text is larger than 160 characters"),
|
||||
ParameterError);
|
||||
}
|
||||
else
|
||||
text = argv[optind + 1];
|
||||
|
||||
if (test)
|
||||
cout << gsmToLatin1(latin1ToGsm(text)) << endl;
|
||||
else
|
||||
{
|
||||
// send SMS
|
||||
Ref<SMSSubmitMessage> submitSMS = new SMSSubmitMessage();
|
||||
// set service centre address in new submit PDU if requested by user
|
||||
if (serviceCentreAddress != "")
|
||||
{
|
||||
Address sca(serviceCentreAddress);
|
||||
submitSMS->setServiceCentreAddress(sca);
|
||||
}
|
||||
submitSMS->setStatusReportRequest(requestStatusReport);
|
||||
Address destAddr(phoneNumber);
|
||||
submitSMS->setDestinationAddress(destAddr);
|
||||
if (concatenatedMessageId == -1)
|
||||
m->sendSMSs(submitSMS, text, true);
|
||||
else
|
||||
m->sendSMSs(submitSMS, text, false, concatenatedMessageId);
|
||||
}
|
||||
}
|
||||
catch (GsmException &ge)
|
||||
{
|
||||
cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,723 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsmsmsd.cc
|
||||
// *
|
||||
// * Purpose: SMS receiver daemon
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 5.6.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <gsm_config.h>
|
||||
#endif
|
||||
#include <gsmlib/gsm_nls.h>
|
||||
#include <string>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <io.h>
|
||||
#include <gsmlib/gsm_util.h>
|
||||
#include <gsmlib/gsm_win32_serial.h>
|
||||
#define popen _popen
|
||||
#define pclose _pclose
|
||||
#else
|
||||
#include <gsmlib/gsm_unix_serial.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
#if defined(HAVE_GETOPT_LONG) || defined(WIN32)
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <gsmlib/gsm_me_ta.h>
|
||||
#include <gsmlib/gsm_event.h>
|
||||
#include <cstring>
|
||||
|
||||
using namespace std;
|
||||
using namespace gsmlib;
|
||||
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
static struct option longOpts[] =
|
||||
{
|
||||
{"requeststat", no_argument, (int*)NULL, 'r'},
|
||||
{"direct", no_argument, (int*)NULL, 'D'},
|
||||
{"xonxoff", no_argument, (int*)NULL, 'X'},
|
||||
{"init", required_argument, (int*)NULL, 'I'},
|
||||
{"store", required_argument, (int*)NULL, 't'},
|
||||
{"device", required_argument, (int*)NULL, 'd'},
|
||||
{"spool", required_argument, (int*)NULL, 's'},
|
||||
{"sent", required_argument, (int*)NULL, 'S'},
|
||||
{"failed", required_argument, (int*)NULL, 'F'},
|
||||
{"priorities", required_argument, (int*)NULL, 'P'},
|
||||
#ifndef WIN32
|
||||
{"syslog", no_argument, (int*)NULL, 'L'},
|
||||
#endif
|
||||
{"sca", required_argument, (int*)NULL, 'C'},
|
||||
{"flush", no_argument, (int*)NULL, 'f'},
|
||||
{"concatenate", required_argument, (int*)NULL, 'c'},
|
||||
{"action", required_argument, (int*)NULL, 'a'},
|
||||
{"baudrate", required_argument, (int*)NULL, 'b'},
|
||||
{"help", no_argument, (int*)NULL, 'h'},
|
||||
{"version", no_argument, (int*)NULL, 'v'},
|
||||
{(char*)NULL, 0, (int*)NULL, 0}
|
||||
};
|
||||
#else
|
||||
#define getopt_long(argc, argv, options, longopts, indexptr) \
|
||||
getopt(argc, argv, options)
|
||||
#endif
|
||||
|
||||
// my ME
|
||||
|
||||
static MeTa *me = NULL;
|
||||
string receiveStoreName; // store name for received SMSs
|
||||
|
||||
// service centre address (set on command line)
|
||||
|
||||
static string serviceCentreAddress;
|
||||
|
||||
// ID if concatenated messages should be sent
|
||||
|
||||
static int concatenatedMessageId = -1;
|
||||
|
||||
// signal handler for terminate signal
|
||||
|
||||
bool terminateSent = false;
|
||||
|
||||
void terminateHandler(int signum)
|
||||
{
|
||||
terminateSent = true;
|
||||
}
|
||||
|
||||
// local class to handle SMS events
|
||||
|
||||
struct IncomingMessage
|
||||
{
|
||||
// used if new message is put into store
|
||||
int _index; // -1 means message want send directly
|
||||
string _storeName;
|
||||
// used if SMS message was sent directly to TA
|
||||
SMSMessageRef _newSMSMessage;
|
||||
// used if CB message was sent directly to TA
|
||||
CBMessageRef _newCBMessage;
|
||||
// used in both cases
|
||||
GsmEvent::SMSMessageType _messageType;
|
||||
|
||||
IncomingMessage() : _index(-1) {}
|
||||
};
|
||||
|
||||
vector<IncomingMessage> newMessages;
|
||||
|
||||
class EventHandler : public GsmEvent
|
||||
{
|
||||
public:
|
||||
// inherited from GsmEvent
|
||||
void SMSReception(SMSMessageRef newMessage,
|
||||
SMSMessageType messageType);
|
||||
void CBReception(CBMessageRef newMessage);
|
||||
void SMSReceptionIndication(string storeName, unsigned int index,
|
||||
SMSMessageType messageType);
|
||||
|
||||
virtual ~EventHandler() {}
|
||||
};
|
||||
|
||||
void EventHandler::SMSReception(SMSMessageRef newMessage,
|
||||
SMSMessageType messageType)
|
||||
{
|
||||
IncomingMessage m;
|
||||
m._messageType = messageType;
|
||||
m._newSMSMessage = newMessage;
|
||||
newMessages.push_back(m);
|
||||
}
|
||||
|
||||
void EventHandler::CBReception(CBMessageRef newMessage)
|
||||
{
|
||||
IncomingMessage m;
|
||||
m._messageType = GsmEvent::CellBroadcastSMS;
|
||||
m._newCBMessage = newMessage;
|
||||
newMessages.push_back(m);
|
||||
}
|
||||
|
||||
void EventHandler::SMSReceptionIndication(string storeName, unsigned int index,
|
||||
SMSMessageType messageType)
|
||||
{
|
||||
IncomingMessage m;
|
||||
m._index = index;
|
||||
|
||||
if (receiveStoreName != "" && ( storeName == "MT" || storeName == "mt"))
|
||||
m._storeName = receiveStoreName;
|
||||
else
|
||||
m._storeName = storeName;
|
||||
|
||||
m._messageType = messageType;
|
||||
newMessages.push_back(m);
|
||||
}
|
||||
|
||||
// execute action on string
|
||||
|
||||
void doAction(string action, string result)
|
||||
{
|
||||
if (action != "")
|
||||
{
|
||||
FILE *fd = popen(action.c_str(), "w");
|
||||
if (fd == NULL)
|
||||
throw GsmException(stringPrintf(_("could not execute '%s'"),
|
||||
action.c_str()), OSError);
|
||||
fputs(result.c_str(), fd);
|
||||
if (ferror(fd))
|
||||
throw GsmException(stringPrintf(_("error writing to '%s'"),
|
||||
action.c_str()), OSError);
|
||||
pclose(fd);
|
||||
}
|
||||
else
|
||||
// default if no action: output on stdout
|
||||
cout << result << endl;
|
||||
}
|
||||
|
||||
// send all SMS messages in spool dir
|
||||
|
||||
bool requestStatusReport = false;
|
||||
|
||||
void sendSMS(string spoolDirBase, string sentDirBase, string failedDirBase,
|
||||
unsigned int priority, bool enableSyslog, Ref<GsmAt> at)
|
||||
{
|
||||
string spoolDir = spoolDirBase;
|
||||
string sentDir = sentDirBase;
|
||||
string failedDir = failedDirBase;
|
||||
if ( priority >= 1 )
|
||||
{
|
||||
spoolDir = spoolDirBase + stringPrintf(_("%d"),priority);
|
||||
sentDir = sentDirBase + stringPrintf(_("%d"),priority);
|
||||
failedDir = failedDirBase + stringPrintf(_("%d"),priority);
|
||||
}
|
||||
if ( priority > 1 )
|
||||
sendSMS(spoolDirBase, sentDirBase, failedDirBase, priority-1, enableSyslog, at);
|
||||
if (spoolDirBase != "")
|
||||
{
|
||||
// look into spoolDir for any outgoing SMS that should be sent
|
||||
#ifdef WIN32
|
||||
struct _finddata_t fileInfo;
|
||||
long fileHandle;
|
||||
string pattern = spoolDir + "\\*";
|
||||
fileHandle = _findfirst(pattern.c_str(), &fileInfo);
|
||||
bool moreFiles = fileHandle != -1L;
|
||||
#else
|
||||
DIR *dir = opendir(spoolDir.c_str());
|
||||
if (dir == (DIR*)NULL)
|
||||
throw GsmException(
|
||||
stringPrintf(_("error when calling opendir('%s')"
|
||||
"(errno: %d/%s)"),
|
||||
spoolDir.c_str(), errno, strerror(errno)),
|
||||
OSError);
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
while (moreFiles)
|
||||
{
|
||||
if (strcmp(fileInfo.name, ".") != 0 &&
|
||||
strcmp(fileInfo.name, "..") != 0)
|
||||
#else
|
||||
struct dirent *entry;
|
||||
while ((entry = readdir(dir)) != (struct dirent*)NULL)
|
||||
if (strcmp(entry->d_name, ".") != 0 &&
|
||||
strcmp(entry->d_name, "..") != 0)
|
||||
#endif
|
||||
{
|
||||
if ( priority > 1 )
|
||||
sendSMS(spoolDirBase, sentDirBase, failedDirBase, priority-1, enableSyslog, at);
|
||||
// read in file
|
||||
// the first line is interpreted as the phone number
|
||||
// the rest is the message
|
||||
#ifdef WIN32
|
||||
string filename = spoolDir + "\\" + fileInfo.name;
|
||||
#else
|
||||
string filename = spoolDir + "/" + entry->d_name;
|
||||
#endif
|
||||
ifstream ifs(filename.c_str());
|
||||
if (! ifs)
|
||||
#ifndef WIN32
|
||||
if (enableSyslog)
|
||||
{
|
||||
syslog(LOG_WARNING, "Could not open SMS spool file %s",
|
||||
filename.c_str());
|
||||
if (failedDirBase != "") {
|
||||
string failedfilename = failedDir + "/" + entry->d_name;
|
||||
rename(filename.c_str(),failedfilename.c_str());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
throw GsmException(
|
||||
stringPrintf(_("count not open SMS spool file %s"),
|
||||
filename.c_str()), ParameterError);
|
||||
char phoneBuf[1001];
|
||||
ifs.getline(phoneBuf, 1000);
|
||||
for(int i=0;i<1000;i++)
|
||||
if(phoneBuf[i]=='\t' || phoneBuf[i]==0)
|
||||
{ // ignore everything after a <TAB> in the phone number
|
||||
phoneBuf[i]=0;
|
||||
break;
|
||||
}
|
||||
string text;
|
||||
while (! ifs.eof())
|
||||
{
|
||||
char c;
|
||||
ifs.get(c);
|
||||
text += c;
|
||||
}
|
||||
ifs.close();
|
||||
|
||||
// remove trailing newline/linefeed
|
||||
while (text[text.length() - 1] == '\n' ||
|
||||
text[text.length() - 1] == '\r')
|
||||
text = text.substr(0, text.length() - 1);
|
||||
|
||||
// send the message
|
||||
string phoneNumber(phoneBuf);
|
||||
Ref<SMSSubmitMessage> submitSMS = new SMSSubmitMessage();
|
||||
// set service centre address in new submit PDU if requested by user
|
||||
if (serviceCentreAddress != "")
|
||||
{
|
||||
Address sca(serviceCentreAddress);
|
||||
submitSMS->setServiceCentreAddress(sca);
|
||||
}
|
||||
submitSMS->setStatusReportRequest(requestStatusReport);
|
||||
Address destAddr(phoneNumber);
|
||||
submitSMS->setDestinationAddress(destAddr);
|
||||
try
|
||||
{
|
||||
if (concatenatedMessageId == -1)
|
||||
me->sendSMSs(submitSMS, text, true);
|
||||
else
|
||||
{
|
||||
// maximum for concatenatedMessageId is 255
|
||||
if (concatenatedMessageId > 256)
|
||||
concatenatedMessageId = 0;
|
||||
me->sendSMSs(submitSMS, text, false, concatenatedMessageId++);
|
||||
}
|
||||
#ifndef WIN32
|
||||
if (enableSyslog)
|
||||
syslog(LOG_NOTICE, "Sent SMS to %s from file %s", phoneBuf, filename.c_str());
|
||||
#endif
|
||||
if (sentDirBase != "") {
|
||||
#ifdef WIN32
|
||||
string sentfilename = sentDir + "\\" + fileInfo.name;
|
||||
#else
|
||||
string sentfilename = sentDir + "/" + entry->d_name;
|
||||
#endif
|
||||
rename(filename.c_str(),sentfilename.c_str());
|
||||
} else {
|
||||
unlink(filename.c_str());
|
||||
}
|
||||
}
|
||||
catch (GsmException &me)
|
||||
{
|
||||
#ifndef WIN32
|
||||
if (enableSyslog)
|
||||
syslog(LOG_WARNING, "Failed sending SMS to %s from file %s: %s", phoneBuf,
|
||||
filename.c_str(), me.what());
|
||||
else
|
||||
#endif
|
||||
cerr << "Failed sending SMS to " << phoneBuf << " from "
|
||||
<< filename << ": " << me.what() << endl;
|
||||
if (failedDirBase != "") {
|
||||
#ifdef WIN32
|
||||
string failedfilename = failedDir + "\\" + fileInfo.name;
|
||||
#else
|
||||
string failedfilename = failedDir + "/" + entry->d_name;
|
||||
#endif
|
||||
rename(filename.c_str(),failedfilename.c_str());
|
||||
}
|
||||
}
|
||||
#ifdef WIN32
|
||||
}
|
||||
moreFiles = _findnext(fileHandle, &fileInfo) == 0;
|
||||
#endif
|
||||
}
|
||||
#ifdef WIN32
|
||||
_findclose(fileHandle);
|
||||
#else
|
||||
closedir(dir);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
void syslogExit(int exitcode, int *dummy)
|
||||
{
|
||||
syslog(LOG_NOTICE, "exited (exit %d)",exitcode);
|
||||
}
|
||||
#endif
|
||||
|
||||
// *** main program
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
bool enableSyslog = false;
|
||||
try
|
||||
{
|
||||
string device = "/dev/mobilephone";
|
||||
string action;
|
||||
string baudrate;
|
||||
bool enableSMS = true;
|
||||
bool enableCB = true;
|
||||
bool enableStat = true;
|
||||
bool flushSMS = false;
|
||||
bool onlyReceptionIndication = true;
|
||||
string spoolDir;
|
||||
string sentDir = "";
|
||||
string failedDir = "";
|
||||
unsigned int priorities = 0;
|
||||
string initString = DEFAULT_INIT_STRING;
|
||||
bool swHandshake = false;
|
||||
string concatenatedMessageIdStr;
|
||||
|
||||
int opt;
|
||||
int dummy;
|
||||
while((opt = getopt_long(argc, argv, "c:C:I:t:fd:a:b:hvs:S:F:P:LXDr",
|
||||
longOpts, &dummy)) != -1)
|
||||
switch (opt)
|
||||
{
|
||||
case 'c':
|
||||
concatenatedMessageIdStr = optarg;
|
||||
break;
|
||||
case 'r':
|
||||
requestStatusReport = true;
|
||||
break;
|
||||
case 'D':
|
||||
onlyReceptionIndication = false;
|
||||
break;
|
||||
case 'X':
|
||||
swHandshake = true;
|
||||
break;
|
||||
case 'I':
|
||||
initString = optarg;
|
||||
break;
|
||||
case 't':
|
||||
receiveStoreName = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
device = optarg;
|
||||
break;
|
||||
case 'C':
|
||||
serviceCentreAddress = optarg;
|
||||
break;
|
||||
case 's':
|
||||
spoolDir = optarg;
|
||||
break;
|
||||
case 'L':
|
||||
enableSyslog = true;
|
||||
break;
|
||||
case 'S':
|
||||
sentDir = optarg;
|
||||
break;
|
||||
case 'F':
|
||||
failedDir = optarg;
|
||||
break;
|
||||
case 'P':
|
||||
priorities = abs(atoi(optarg));
|
||||
break;
|
||||
case 'f':
|
||||
flushSMS = true;
|
||||
break;
|
||||
case 'a':
|
||||
action = optarg;
|
||||
break;
|
||||
case 'b':
|
||||
baudrate = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"),
|
||||
VERSION, __DATE__) << endl;
|
||||
exit(0);
|
||||
break;
|
||||
case 'h':
|
||||
cerr << argv[0] << _(": [-a action][-b baudrate][-C sca][-d device]"
|
||||
"[-f][-h][-I init string]\n"
|
||||
" [-s spool dir][-t][-v]{sms_type}")
|
||||
<< endl << endl
|
||||
<< _(" -a, --action the action to execute when an SMS "
|
||||
"arrives\n"
|
||||
" (SMS is send to stdin of action)")
|
||||
<< endl
|
||||
<< _(" -b, --baudrate baudrate to use for device "
|
||||
"(default: 38400)")
|
||||
<< endl
|
||||
<< _(" -c, --concatenate start ID for concatenated SMS messages")
|
||||
<< endl
|
||||
<< _(" -C, --sca SMS service centre address") << endl
|
||||
<< _(" -d, --device sets the device to connect to") << endl
|
||||
<< _(" -D, --direct enable direct routing of SMSs") << endl
|
||||
<< _(" -f, --flush flush SMS from store") << endl
|
||||
<< _(" -F, --failed directory to move failed SMS to,") << endl
|
||||
<< _(" if unset, the SMS will be deleted") << endl
|
||||
<< _(" -h, --help prints this message") << endl
|
||||
<< _(" -I, --init device AT init sequence") << endl
|
||||
#ifndef WIN32
|
||||
<< _(" -L, --syslog log errors and information to syslog")
|
||||
<< endl
|
||||
#endif
|
||||
<< _(" -P, --priorities number of priority levels to use,") << endl
|
||||
<< _(" (default: none)") << endl
|
||||
<< _(" -r, --requeststat request SMS status report") << endl
|
||||
<< _(" -s, --spool spool directory for outgoing SMS")
|
||||
<< endl
|
||||
<< _(" -S, --sent directory to move sent SMS to,") << endl
|
||||
<< _(" if unset, the SMS will be deleted") << endl
|
||||
<< _(" -t, --store name of SMS store to use for flush\n"
|
||||
" and/or temporary SMS storage") << endl
|
||||
<< endl
|
||||
<< _(" -v, --version prints version and exits") << endl
|
||||
<< _(" -X, --xonxoff switch on software handshake") << endl
|
||||
<< endl
|
||||
<< _(" sms_type may be any combination of") << endl << endl
|
||||
<< _(" sms, no_sms controls reception of normal SMS")
|
||||
<< endl
|
||||
<< _(" cb, no_cb controls reception of cell broadcast"
|
||||
" messages") << endl
|
||||
<< _(" stat, no_stat controls reception of status reports")
|
||||
<< endl << endl
|
||||
<< _(" default is \"sms cb stat\"") << endl << endl
|
||||
<< _("If no action is given, the SMS is printed to stdout")
|
||||
<< endl << endl
|
||||
<< _("If -P is given, it activates the priority system and sets the") << endl
|
||||
<< _("number or levels to use. For every level, there must be directories") << endl
|
||||
<< _("named <spool directory>+<priority level>.") << endl
|
||||
<< _("For example \"-P 2 -s queue -S send -F failed\" needs the following") <<endl
|
||||
<< _("directories: queue1/ queue2/ send1/ send2/ failed1/ failed2/") <<endl
|
||||
<< _("Before sending one SMS from queue2, all pending SMS from queue1") <<endl
|
||||
<< _("will be sent.") <<endl
|
||||
<< endl << endl;
|
||||
exit(0);
|
||||
break;
|
||||
case '?':
|
||||
throw GsmException(_("unknown option"), ParameterError);
|
||||
break;
|
||||
}
|
||||
|
||||
// find out which kind of message to route
|
||||
for (int i = optind; i < argc; ++i)
|
||||
{
|
||||
string s = lowercase(argv[i]);
|
||||
if (s == "sms")
|
||||
enableSMS = true;
|
||||
else if (s == "no_sms")
|
||||
enableSMS = false;
|
||||
else if (s == "cb")
|
||||
enableCB = true;
|
||||
else if (s == "no_cb")
|
||||
enableCB = false;
|
||||
else if (s == "stat")
|
||||
enableStat = true;
|
||||
else if (s == "no_stat")
|
||||
enableStat = false;
|
||||
}
|
||||
|
||||
// check parameters
|
||||
if (concatenatedMessageIdStr != "")
|
||||
concatenatedMessageId = checkNumber(concatenatedMessageIdStr);
|
||||
|
||||
// register signal handler for terminate signal
|
||||
#ifndef WIN32
|
||||
struct sigaction terminateAction;
|
||||
terminateAction.sa_handler = terminateHandler;
|
||||
sigemptyset(&terminateAction.sa_mask);
|
||||
terminateAction.sa_flags = SA_RESTART;
|
||||
if (sigaction(SIGINT, &terminateAction, NULL) != 0 ||
|
||||
sigaction(SIGTERM, &terminateAction, NULL) != 0)
|
||||
#else
|
||||
if(signal(SIGINT, terminateHandler) == SIG_ERR ||
|
||||
signal(SIGTERM, terminateHandler) == SIG_ERR)
|
||||
#endif
|
||||
throw GsmException(
|
||||
stringPrintf(_("error when calling sigaction() (errno: %d/%s)"),
|
||||
errno, strerror(errno)),
|
||||
OSError);
|
||||
|
||||
// open GSM device
|
||||
me = new MeTa(new
|
||||
#ifdef WIN32
|
||||
Win32SerialPort
|
||||
#else
|
||||
UnixSerialPort
|
||||
#endif
|
||||
(device,
|
||||
baudrate == "" ? DEFAULT_BAUD_RATE :
|
||||
baudRateStrToSpeed(baudrate), initString,
|
||||
swHandshake));
|
||||
|
||||
// if flush option is given get all SMS from store and dispatch them
|
||||
if (flushSMS)
|
||||
{
|
||||
if (receiveStoreName == "")
|
||||
throw GsmException(_("store name must be given for flush option"),
|
||||
ParameterError);
|
||||
|
||||
SMSStoreRef store = me->getSMSStore(receiveStoreName);
|
||||
|
||||
for (SMSStore::iterator s = store->begin(); s != store->end(); ++s)
|
||||
if (! s->empty())
|
||||
{
|
||||
string result = _("Type of message: ");
|
||||
switch (s->message()->messageType())
|
||||
{
|
||||
case SMSMessage::SMS_DELIVER:
|
||||
result += _("SMS message\n");
|
||||
break;
|
||||
case SMSMessage::SMS_SUBMIT_REPORT:
|
||||
result += _("submit report message\n");
|
||||
break;
|
||||
case SMSMessage::SMS_STATUS_REPORT:
|
||||
result += _("status report message\n");
|
||||
break;
|
||||
}
|
||||
result += s->message()->toString();
|
||||
doAction(action, result);
|
||||
store->erase(s);
|
||||
}
|
||||
}
|
||||
|
||||
// set default SMS store if -t option was given or
|
||||
// read from ME otherwise
|
||||
if (receiveStoreName == "")
|
||||
{
|
||||
string dummy1, dummy2;
|
||||
me->getSMSStore(dummy1, dummy2, receiveStoreName );
|
||||
}
|
||||
else
|
||||
me->setSMSStore(receiveStoreName, 3);
|
||||
|
||||
// switch message service level to 1
|
||||
// this enables SMS routing to TA
|
||||
me->setMessageService(1);
|
||||
|
||||
// switch on SMS routing
|
||||
me->setSMSRoutingToTA(enableSMS, enableCB, enableStat,
|
||||
onlyReceptionIndication);
|
||||
|
||||
// register event handler to handle routed SMSs, CBMs, and status reports
|
||||
me->setEventHandler(new EventHandler());
|
||||
|
||||
// wait for new messages
|
||||
bool exitScheduled = false;
|
||||
while (1)
|
||||
{
|
||||
#ifdef WIN32
|
||||
::timeval timeoutVal;
|
||||
timeoutVal.tv_sec = 5;
|
||||
timeoutVal.tv_usec = 0;
|
||||
me->waitEvent((gsmlib::timeval *)&timeoutVal);
|
||||
#else
|
||||
struct timeval timeoutVal;
|
||||
timeoutVal.tv_sec = 5;
|
||||
timeoutVal.tv_usec = 0;
|
||||
me->waitEvent(&timeoutVal);
|
||||
#endif
|
||||
// if it returns, there was an event or a timeout
|
||||
while (newMessages.size() > 0)
|
||||
{
|
||||
// get first new message and remove it from the vector
|
||||
SMSMessageRef newSMSMessage = newMessages.begin()->_newSMSMessage;
|
||||
CBMessageRef newCBMessage = newMessages.begin()->_newCBMessage;
|
||||
GsmEvent::SMSMessageType messageType =
|
||||
newMessages.begin()->_messageType;
|
||||
int index = newMessages.begin()->_index;
|
||||
string storeName = newMessages.begin()->_storeName;
|
||||
newMessages.erase(newMessages.begin());
|
||||
|
||||
// process the new message
|
||||
string result = _("Type of message: ");
|
||||
switch (messageType)
|
||||
{
|
||||
case GsmEvent::NormalSMS:
|
||||
result += _("SMS message\n");
|
||||
break;
|
||||
case GsmEvent::CellBroadcastSMS:
|
||||
result += _("cell broadcast message\n");
|
||||
break;
|
||||
case GsmEvent::StatusReportSMS:
|
||||
result += _("status report message\n");
|
||||
break;
|
||||
}
|
||||
if (! newSMSMessage.isnull())
|
||||
result += newSMSMessage->toString();
|
||||
else if (! newCBMessage.isnull())
|
||||
result += newCBMessage->toString();
|
||||
else
|
||||
{
|
||||
SMSStoreRef store = me->getSMSStore(storeName);
|
||||
store->setCaching(false);
|
||||
|
||||
if (messageType == GsmEvent::CellBroadcastSMS)
|
||||
result += (*store.getptr())[index].cbMessage()->toString();
|
||||
else
|
||||
result += (*store.getptr())[index].message()->toString();
|
||||
|
||||
store->erase(store->begin() + index);
|
||||
}
|
||||
|
||||
// call the action
|
||||
doAction(action, result);
|
||||
}
|
||||
|
||||
// if no new SMS came in and program exit was scheduled, then exit
|
||||
if (exitScheduled)
|
||||
exit(0);
|
||||
|
||||
// handle terminate signal
|
||||
if (terminateSent)
|
||||
{
|
||||
exitScheduled = true;
|
||||
// switch off SMS routing
|
||||
try
|
||||
{
|
||||
me->setSMSRoutingToTA(false, false, false);
|
||||
}
|
||||
catch (GsmException &ge)
|
||||
{
|
||||
// some phones (e.g. Motorola Timeport 260) don't allow to switch
|
||||
// off SMS routing which results in an error. Just ignore this.
|
||||
}
|
||||
// the AT sequences involved in switching of SMS routing
|
||||
// may yield more SMS events, so go round the loop one more time
|
||||
}
|
||||
|
||||
// send spooled SMS
|
||||
if (! terminateSent)
|
||||
sendSMS(spoolDir, sentDir, failedDir, priorities, enableSyslog, me->getAt());
|
||||
}
|
||||
}
|
||||
catch (GsmException &ge)
|
||||
{
|
||||
cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl;
|
||||
if (ge.getErrorClass() == MeTaCapabilityError)
|
||||
cerr << argv[0] << _("[ERROR]: ")
|
||||
<< _("(try setting sms_type, please refer to gsmsmsd manpage)")
|
||||
<< endl;
|
||||
// switch off message routing, so that following invocations of gsmsmd
|
||||
// are not swamped with message deliveries while they start up
|
||||
if (me != NULL)
|
||||
{
|
||||
try
|
||||
{
|
||||
me->setSMSRoutingToTA(false, false, false);
|
||||
}
|
||||
catch (GsmException &ge)
|
||||
{
|
||||
// some phones (e.g. Motorola Timeport 260) don't allow to switch
|
||||
// off SMS routing which results in an error. Just ignore this.
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,434 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsmsmsstore.cc
|
||||
// *
|
||||
// * Purpose: SMS store management program
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 4.8.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <gsm_config.h>
|
||||
#endif
|
||||
#include <gsmlib/gsm_nls.h>
|
||||
#include <string>
|
||||
#include <ctype.h>
|
||||
#ifdef WIN32
|
||||
#include <gsmlib/gsm_win32_serial.h>
|
||||
#else
|
||||
#include <gsmlib/gsm_unix_serial.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#if defined(HAVE_GETOPT_LONG) || defined(WIN32)
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <gsmlib/gsm_me_ta.h>
|
||||
#include <gsmlib/gsm_util.h>
|
||||
#include <gsmlib/gsm_sorted_sms_store.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace gsmlib;
|
||||
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
static struct option longOpts[] =
|
||||
{
|
||||
{"xonxoff", no_argument, (int*)NULL, 'X'},
|
||||
{"init", required_argument, (int*)NULL, 'I'},
|
||||
{"store", required_argument, (int*)NULL, 't'},
|
||||
{"erase", no_argument, (int*)NULL, 'e'},
|
||||
{"add", no_argument, (int*)NULL, 'a'},
|
||||
{"list", no_argument, (int*)NULL, 'l'},
|
||||
{"destination", required_argument, (int*)NULL, 'd'},
|
||||
{"source", required_argument, (int*)NULL, 's'},
|
||||
{"baudrate", required_argument, (int*)NULL, 'b'},
|
||||
{"sca", required_argument, (int*)NULL, 'C'},
|
||||
{"copy", no_argument, (int*)NULL, 'c'},
|
||||
{"delete", no_argument, (int*)NULL, 'x'},
|
||||
{"backup", no_argument, (int*)NULL, 'k'},
|
||||
{"help", no_argument, (int*)NULL, 'h'},
|
||||
{"version", no_argument, (int*)NULL, 'v'},
|
||||
{"verbose", no_argument, (int*)NULL, 'V'},
|
||||
{(char*)NULL, 0, (int*)NULL, 0}
|
||||
};
|
||||
#else
|
||||
#define getopt_long(argc, argv, options, longopts, indexptr) \
|
||||
getopt(argc, argv, options)
|
||||
#endif
|
||||
|
||||
bool verbose = false; // true if --verbose option given
|
||||
|
||||
// type of operation to perform
|
||||
|
||||
enum Operation {CopyOp = 'c', BackupOp = 'k', DeleteOp = 'x',
|
||||
AddOp = 'a', ListOp = 'l', NoOp = 0};
|
||||
|
||||
// aux function, insert entry only if not already present in dest
|
||||
|
||||
void backup(SortedSMSStoreRef destStore, SMSStoreEntry &entry)
|
||||
{
|
||||
// the following only works because we know that the default sort order
|
||||
// is by date
|
||||
assert(destStore->sortOrder() == ByDate);
|
||||
|
||||
Timestamp date = entry.message()->serviceCentreTimestamp();
|
||||
pair<SortedSMSStore::iterator, SortedSMSStore::iterator> range =
|
||||
destStore->equal_range(date);
|
||||
|
||||
for (SortedSMSStore::iterator j = range.first;
|
||||
j != range.second; ++j)
|
||||
if (entry == *j)
|
||||
// do nothing if the entry is already present in the destination
|
||||
return;
|
||||
|
||||
if (verbose)
|
||||
cout << stringPrintf(_("inserting entry #%d from source into destination"),
|
||||
entry.index()) << endl
|
||||
<< entry.message()->toString();
|
||||
destStore->insert(entry); // insert
|
||||
}
|
||||
|
||||
// aux function, throw exception if operation != NoOp
|
||||
|
||||
void checkNoOp(Operation operation, int opt)
|
||||
{
|
||||
if (operation != NoOp)
|
||||
throw GsmException(stringPrintf(_("incompatible options '%c' and '%c'"),
|
||||
(char)operation, (char)opt),
|
||||
ParameterError);
|
||||
}
|
||||
|
||||
// *** main program
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
try
|
||||
{
|
||||
// handle command line options
|
||||
string destination;
|
||||
string source;
|
||||
string baudrate;
|
||||
string storeName;
|
||||
char operation = NoOp;
|
||||
SortedSMSStoreRef sourceStore, destStore;
|
||||
bool useIndices = false; // use indices in delete, copy, backup op
|
||||
string initString = DEFAULT_INIT_STRING;
|
||||
bool swHandshake = false;
|
||||
// service centre address (set on command line)
|
||||
string serviceCentreAddress;
|
||||
Ref<MeTa> sourceMeTa, destMeTa;
|
||||
|
||||
int opt;
|
||||
int dummy;
|
||||
while((opt = getopt_long(argc, argv, "I:t:s:d:b:cxlakhvVXC:",
|
||||
longOpts, &dummy))
|
||||
!= -1)
|
||||
switch (opt)
|
||||
{
|
||||
case 'C':
|
||||
serviceCentreAddress = optarg;
|
||||
break;
|
||||
case 'X':
|
||||
swHandshake = true;
|
||||
break;
|
||||
case 'I':
|
||||
initString = optarg;
|
||||
break;
|
||||
case 'V':
|
||||
verbose = true;
|
||||
break;
|
||||
case 't':
|
||||
storeName = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
destination = optarg;
|
||||
break;
|
||||
case 's':
|
||||
source = optarg;
|
||||
break;
|
||||
case 'b':
|
||||
baudrate = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
checkNoOp((Operation)operation, opt);
|
||||
operation = CopyOp;
|
||||
break;
|
||||
case 'x':
|
||||
checkNoOp((Operation)operation, opt);
|
||||
operation = DeleteOp;
|
||||
break;
|
||||
case 'l':
|
||||
checkNoOp((Operation)operation, opt);
|
||||
operation = ListOp;
|
||||
break;
|
||||
case 'a':
|
||||
checkNoOp((Operation)operation, opt);
|
||||
operation = AddOp;
|
||||
break;
|
||||
case 'k':
|
||||
checkNoOp((Operation)operation, opt);
|
||||
operation = BackupOp;
|
||||
break;
|
||||
case 'v':
|
||||
cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"),
|
||||
VERSION, __DATE__) << endl;
|
||||
exit(0);
|
||||
break;
|
||||
case 'h':
|
||||
cerr << argv[0] << _(": [-a][-b baudrate][-c][-C sca]"
|
||||
"[-d device or file]\n"
|
||||
" [-h][-I init string][-k][-l]"
|
||||
"[-s device or file]"
|
||||
"[-t SMS store name]\n [-v][-V][-x][-X]"
|
||||
"{indices}|[phonenumber text]") << endl
|
||||
<< endl
|
||||
<< _(" -a, --add add new SMS submit message\n"
|
||||
" (phonenumber and text) to destination")
|
||||
<< endl
|
||||
<< _(" -b, --baudrate baudrate to use for device "
|
||||
"(default: 38400)")
|
||||
<< endl
|
||||
<< _(" -c, --copy copy source entries to destination\n"
|
||||
" (if indices are given, "
|
||||
"copy only these entries)") << endl
|
||||
<< _(" -C, --sca SMS service centre address") << endl
|
||||
<< _(" -d, --destination sets the destination device to\n"
|
||||
" connect to, or the file to write to")
|
||||
<< endl
|
||||
<< _(" -h, --help prints this message") << endl
|
||||
<< _(" -I, --init device AT init sequence") << endl
|
||||
<< _(" -k, --backup backup new entries to destination\n"
|
||||
" (if indices are given, "
|
||||
"copy only these entries)") << endl
|
||||
<< _(" -l, --list list source to stdout") << endl
|
||||
<< _(" -s, --source sets the source device to connect to,\n"
|
||||
" or the file to read") << endl
|
||||
<< _(" -t, --store name of SMS store to use") << endl
|
||||
<< _(" -v, --version prints version and exits") << endl
|
||||
<< _(" -V, --verbose print detailed progress messages")
|
||||
<< endl
|
||||
<< _(" -x, --delete delete entries denoted by indices")
|
||||
<< endl
|
||||
<< _(" -X, --xonxoff switch on software handshake") << endl
|
||||
<< endl;
|
||||
exit(0);
|
||||
break;
|
||||
case '?':
|
||||
throw GsmException(_("unknown option"), ParameterError);
|
||||
break;
|
||||
}
|
||||
|
||||
// check if parameters are complete
|
||||
if (operation == NoOp)
|
||||
throw GsmException(_("no operation option given"), ParameterError);
|
||||
if (operation == BackupOp || operation == CopyOp)
|
||||
if (destination.length() == 0 || source.length() == 0)
|
||||
throw GsmException(_("both source and destination required"),
|
||||
ParameterError);
|
||||
if (operation == ListOp)
|
||||
{
|
||||
if (destination.length() != 0)
|
||||
throw GsmException(_("destination must not be given"), ParameterError);
|
||||
if (source.length() == 0)
|
||||
throw GsmException(_("source required"), ParameterError);
|
||||
}
|
||||
if (operation == AddOp || operation == DeleteOp)
|
||||
{
|
||||
if (source.length() != 0)
|
||||
throw GsmException(_("source must not be given"), ParameterError);
|
||||
if (destination.length() == 0)
|
||||
throw GsmException(_("destination required"), ParameterError);
|
||||
}
|
||||
if (operation == CopyOp || operation == DeleteOp || operation == BackupOp)
|
||||
{
|
||||
// check if all indices are numbers
|
||||
for (int i = optind; i < argc; ++i)
|
||||
for (char *pp = argv[i]; *pp != 0; ++pp)
|
||||
if (! isdigit(*pp))
|
||||
throw GsmException(stringPrintf(_("expected number, got '%s'"),
|
||||
argv[i]), ParameterError);
|
||||
useIndices = optind != argc;
|
||||
}
|
||||
else if (operation == AddOp)
|
||||
{
|
||||
if (optind + 2 < argc)
|
||||
throw GsmException(_("more than two parameters given"),
|
||||
ParameterError);
|
||||
if (optind + 2 > argc)
|
||||
throw GsmException(_("not enough parameters given"),
|
||||
ParameterError);
|
||||
}
|
||||
else
|
||||
if (optind != argc)
|
||||
throw GsmException(_("unexpected parameters"), ParameterError);
|
||||
|
||||
// start accessing source store or file if required by operation
|
||||
if (operation == CopyOp || operation == BackupOp || operation == ListOp)
|
||||
if (source == "-")
|
||||
sourceStore = new SortedSMSStore(true);
|
||||
else if (isFile(source))
|
||||
sourceStore = new SortedSMSStore(source);
|
||||
else
|
||||
{
|
||||
if (storeName == "")
|
||||
throw GsmException(_("store name must be given"), ParameterError);
|
||||
|
||||
sourceMeTa = new MeTa(new
|
||||
#ifdef WIN32
|
||||
Win32SerialPort
|
||||
#else
|
||||
UnixSerialPort
|
||||
#endif
|
||||
(source,
|
||||
baudrate == "" ? DEFAULT_BAUD_RATE :
|
||||
baudRateStrToSpeed(baudrate), initString,
|
||||
swHandshake));
|
||||
sourceStore = new SortedSMSStore(sourceMeTa->getSMSStore(storeName));
|
||||
}
|
||||
|
||||
// make sure destination file exists if specified
|
||||
// Use isFile() for its exception-throwing properties, and discard
|
||||
// return value cos we don't care (yet) whether it's a device or a
|
||||
// regular file.
|
||||
if (destination != "")
|
||||
isFile(destination);
|
||||
|
||||
// start accessing destination store or file
|
||||
if (operation == CopyOp || operation == BackupOp || operation == AddOp ||
|
||||
operation == DeleteOp)
|
||||
if (destination == "-")
|
||||
destStore = new SortedSMSStore(false);
|
||||
else if (isFile(destination))
|
||||
destStore = new SortedSMSStore(destination);
|
||||
else
|
||||
{
|
||||
if (storeName == "")
|
||||
throw GsmException(_("store name must be given"), ParameterError);
|
||||
|
||||
destMeTa = new MeTa(new
|
||||
#ifdef WIN32
|
||||
Win32SerialPort
|
||||
#else
|
||||
UnixSerialPort
|
||||
#endif
|
||||
(destination,
|
||||
baudrate == "" ? DEFAULT_BAUD_RATE :
|
||||
baudRateStrToSpeed(baudrate), initString,
|
||||
swHandshake));
|
||||
destStore = new SortedSMSStore(destMeTa->getSMSStore(storeName));
|
||||
}
|
||||
|
||||
// now do the actual work
|
||||
switch (operation)
|
||||
{
|
||||
case BackupOp:
|
||||
{
|
||||
sourceStore->setSortOrder(ByIndex); // needed in loop
|
||||
|
||||
if (useIndices)
|
||||
for (int i = optind; i < argc; ++i)
|
||||
{
|
||||
SortedSMSStore::iterator j = sourceStore->find(atoi(argv[i]));
|
||||
if (j == sourceStore->end())
|
||||
throw GsmException(stringPrintf(_("no index '%s' in source"),
|
||||
argv[i]), ParameterError);
|
||||
backup(destStore, *j);
|
||||
}
|
||||
else
|
||||
for (SortedSMSStore::iterator i = sourceStore->begin();
|
||||
i != sourceStore->end(); ++i)
|
||||
backup(destStore, *i);
|
||||
break;
|
||||
}
|
||||
case CopyOp:
|
||||
{
|
||||
destStore->clear();
|
||||
if (! useIndices) // copy all entries
|
||||
{
|
||||
for (SortedSMSStore::iterator i = sourceStore->begin();
|
||||
i != sourceStore->end(); ++i)
|
||||
{
|
||||
if (verbose)
|
||||
cout << stringPrintf(_("inserting entry #%d from source "
|
||||
"into destination"), i->index()) << endl
|
||||
<< i->message()->toString();
|
||||
destStore->insert(*i);
|
||||
}
|
||||
}
|
||||
else // copy indexed entries
|
||||
{
|
||||
sourceStore->setSortOrder(ByIndex); // needed in loop
|
||||
|
||||
for (int i = optind; i < argc; ++i)
|
||||
{
|
||||
SortedSMSStore::iterator j = sourceStore->find(atoi(argv[i]));
|
||||
if (j == sourceStore->end())
|
||||
throw GsmException(stringPrintf(_("no index '%s' in source"),
|
||||
argv[i]), ParameterError);
|
||||
if (verbose)
|
||||
cout << stringPrintf(_("inserting entry #%d from source into "
|
||||
"destination"), j->index()) << endl
|
||||
<< j->message()->toString();
|
||||
destStore->insert(*j);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ListOp:
|
||||
{
|
||||
for (SortedSMSStore::iterator i = sourceStore->begin();
|
||||
i != sourceStore->end(); ++i)
|
||||
cout << stringPrintf(_("index #%d"), i->index()) << endl
|
||||
<< i->message()->toString();
|
||||
break;
|
||||
}
|
||||
case AddOp:
|
||||
{
|
||||
SMSMessageRef sms = new SMSSubmitMessage(argv[optind + 1], argv[optind]);
|
||||
// set service centre address in new submit PDU if requested by user
|
||||
if (serviceCentreAddress != "")
|
||||
{
|
||||
Address sca(serviceCentreAddress);
|
||||
sms->setServiceCentreAddress(sca);
|
||||
}
|
||||
if (verbose)
|
||||
cout << _("inserting new entry into destination") << endl
|
||||
<< sms->toString();
|
||||
destStore->insert(sms);
|
||||
break;
|
||||
}
|
||||
case DeleteOp:
|
||||
{
|
||||
destStore->setSortOrder(ByIndex);
|
||||
for (int i = optind; i < argc; ++i)
|
||||
{
|
||||
int index = atoi(argv[i]);
|
||||
if (verbose)
|
||||
{
|
||||
SortedSMSStore::iterator e = destStore->find(index);
|
||||
if (e != destStore->end())
|
||||
cout << stringPrintf(_("deleting entry #%d from destination"),
|
||||
index) << endl
|
||||
<< e->message()->toString();
|
||||
}
|
||||
if (destStore->erase(index) != 1)
|
||||
throw GsmException(stringPrintf(_("no index '%s' in destination"),
|
||||
argv[i]), ParameterError);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (GsmException &ge)
|
||||
{
|
||||
cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
30623
src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/configure
vendored
Executable file
30623
src/mod/endpoints/mod_gsmopen/gsmlib/gsmlib-1.10-patched-13ubuntu/configure
vendored
Executable file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,131 @@
|
||||
dnl *************************************************************************
|
||||
dnl * GSM TA/ME library
|
||||
dnl *
|
||||
dnl * File: configure.in
|
||||
dnl *
|
||||
dnl * Purpose: autoconf configure script template
|
||||
dnl *
|
||||
dnl * Author: Peter Hofmann (software@pxh.de)
|
||||
dnl *
|
||||
dnl * Created: 11.11.1999
|
||||
dnl *************************************************************************
|
||||
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(gsmlib/gsm_error.h)
|
||||
|
||||
dnl Other
|
||||
AC_CONFIG_AUX_DIR(scripts)
|
||||
AC_PROG_INSTALL
|
||||
|
||||
dnl check for libintl
|
||||
AC_CHECK_LIB(intl, textdomain)
|
||||
|
||||
dnl use config header
|
||||
AM_CONFIG_HEADER(gsm_config.h)
|
||||
|
||||
dnl use automake
|
||||
AM_INIT_AUTOMAKE(gsmlib, 1.10)
|
||||
|
||||
dnl change to no if you want no shared libraries for debugging purposes
|
||||
AM_ENABLE_SHARED(yes)
|
||||
|
||||
dnl use -O2 optimization by default
|
||||
if test "$CXXFLAGS" = ""; then
|
||||
CXXFLAGS="-O2"
|
||||
fi
|
||||
|
||||
dnl comment out this line to get extensive debugging output and asserts
|
||||
dnl CXXFLAGS="-DNDEBUG $CXXFLAGS"
|
||||
|
||||
dnl uncomment to get translations without installing gsmlib
|
||||
dnl CXXFLAGS="-DLOCAL_TRANSLATIONS $CXXFLAGS"
|
||||
|
||||
dnl check _REENTRANT in header files
|
||||
if test x"`egrep _REENTRANT /usr/include/features.h`" != x; then
|
||||
CXXFLAGS="-D_REENTRANT $CXXFLAGS"
|
||||
CFLAGS="-D_REENTRANT $CFLAGS"
|
||||
fi
|
||||
|
||||
dnl output all warnings
|
||||
CXXFLAGS="-Wall $CXXFLAGS"
|
||||
|
||||
dnl use libtool
|
||||
AM_PROG_LIBTOOL
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CPP
|
||||
AC_PROG_CXX
|
||||
|
||||
dnl check for gcc 2.95.x
|
||||
AC_TRY_RUN([
|
||||
#include <unistd.h>
|
||||
main()
|
||||
{
|
||||
#if defined(__GNUC__) && \
|
||||
! (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95))
|
||||
return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
],,
|
||||
[echo "need at least gcc 2.95 to compile correctly"
|
||||
exit 1])
|
||||
|
||||
dnl check for alloca
|
||||
AC_FUNC_ALLOCA
|
||||
|
||||
dnl check for getopt_long in the C library
|
||||
AC_CHECK_LIB(c, getopt_long, AC_DEFINE(HAVE_GETOPT_LONG))
|
||||
|
||||
dnl check for alarm in the C library
|
||||
AC_CHECK_LIB(c, alarm, AC_DEFINE(HAVE_ALARM))
|
||||
|
||||
dnl check for netinet/in.h header
|
||||
AC_CHECK_HEADERS(netinet/in.h)
|
||||
|
||||
dnl check for string.h header
|
||||
AC_CHECK_HEADERS(string.h)
|
||||
|
||||
dnl check for libintl.h header
|
||||
AC_CHECK_HEADERS(libintl.h)
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
|
||||
dnl check for vsnprintf()
|
||||
dnl AC_FUNC_VPRINTF
|
||||
AC_EGREP_HEADER(vsnprintf, stdio.h, AC_DEFINE(HAVE_VSNPRINTF))
|
||||
|
||||
dnl checks for builtin data type sizes
|
||||
AC_CHECK_SIZEOF(unsigned short int, 2)
|
||||
AC_CHECK_SIZEOF(unsigned long int, 4)
|
||||
AC_CHECK_SIZEOF(unsigned int, 4)
|
||||
|
||||
dnl Project-specific settings
|
||||
GSM_VERSION="1:4:0"
|
||||
AC_SUBST(GSM_VERSION)
|
||||
|
||||
dnl national language support (NLS)
|
||||
LINGUAS="de"
|
||||
ALL_LINGUAS=$LINGUAS
|
||||
AM_GNU_GETTEXT
|
||||
|
||||
dnl set locale dir (FIXME there must be a better way)
|
||||
_localedir=`eval "echo $datadir/locale"`
|
||||
if test "$_localedir" = "NONE/share/locale"; then
|
||||
AC_DEFINE_UNQUOTED(LOCALEDIR, "/usr/local/share/locale")
|
||||
else
|
||||
_localedir=`echo \"$_localedir\"`
|
||||
AC_DEFINE_UNQUOTED(LOCALEDIR, $_localedir)
|
||||
fi
|
||||
|
||||
dnl whether to compile the intl directory
|
||||
AM_CONDITIONAL(COMPILE_INTL, test x$USE_INCLUDED_LIBINTL = xyes)
|
||||
|
||||
AC_OUTPUT(Makefile gsmlib/Makefile tests/Makefile apps/Makefile win32/Makefile
|
||||
doc/Makefile scripts/Makefile intl/Makefile po/Makefile.in
|
||||
ext/Makefile,
|
||||
echo timestamp > stamp-h)
|
||||
|
||||
dnl repair Makefile in po subdir
|
||||
dnl sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile
|
@ -0,0 +1,3 @@
|
||||
# /etc/cron.d/gsm-utils: crontab fragment for gsm-utils
|
||||
|
||||
*/5 * * * * root if [ -x /usr/bin/gsmsmsrequeue ]; then /usr/bin/gsmsmsrequeue; fi
|
@ -0,0 +1,13 @@
|
||||
PHONEDEV=/dev/mobilephone # or /dev/ttyS0 or /dev/ircomm0
|
||||
BAUDRATE=9600
|
||||
PIN="" # or 1234
|
||||
|
||||
SPOOLDIR=/var/spool/sms
|
||||
PRIORITIES=3
|
||||
|
||||
SMSADMIN=root
|
||||
SUBJECT="SMS delivery report:"
|
||||
|
||||
SMSPROCESSOR="" # or /usr/bin/gsmsmsprocessor
|
||||
|
||||
do_accounting () { true; } # it's your turn
|
@ -0,0 +1,81 @@
|
||||
#! /bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: gsm-utils
|
||||
# Required-Start: $remote_fs $syslog
|
||||
# Required-Stop: $remote_fs $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Start daemon at boot time
|
||||
# Description: Enable service provided by daemon.
|
||||
### END INIT INFO
|
||||
#
|
||||
# /etc/init.d/gsm-utils: Controls the GSM SMS send daemon
|
||||
#
|
||||
# written by Matthias Goebl <matthias@goebl.net>
|
||||
|
||||
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
||||
DAEMON=/usr/bin/gsmsmsd
|
||||
NAME=gsmsmsd
|
||||
DESC="GSM SMS send daemon"
|
||||
|
||||
test -x $DAEMON || exit 0
|
||||
|
||||
PHONEDEV=/dev/mobilephone # or /dev/ttyS0 or /dev/ircomm0
|
||||
BAUDRATE=9600
|
||||
PIN="" # or 1234
|
||||
SMSPROCESSOR="" # or /usr/bin/gsmsmsprocessor
|
||||
SPOOLDIR=/var/spool/sms
|
||||
PRIORITIES=3
|
||||
STARTOPTS=""
|
||||
SMSUSER="gsmsms:gsmsms"
|
||||
test -r /etc/default/gsm-utils && . /etc/default/gsm-utils # for overwriting some parameters
|
||||
|
||||
OPTIONS="-d $PHONEDEV -b $BAUDRATE -L -P $PRIORITIES"
|
||||
OPTIONS="$OPTIONS -s $SPOOLDIR/queue -S $SPOOLDIR/sent -F $SPOOLDIR/failed"
|
||||
test -n "$SMSPROCESSOR" && OPTIONS="$OPTIONS -a $SMSPROCESSOR"
|
||||
test -n "$SMSUSER" && STARTOPTS="$STARTOPTS --chuid $SMSUSER"
|
||||
test -r /etc/default/gsm-utils && . /etc/default/gsm-utils # for overwriting OPTIONS
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo -n "Starting $DESC: "
|
||||
if [ -n "$PIN" ];then
|
||||
echo -n "entering PIN.. "
|
||||
(
|
||||
# This is ugly.. But if the PIN is already entered, the ME returns
|
||||
# "ERROR" and makes gsmctl retrying..
|
||||
/usr/bin/gsmctl -d $PHONEDEV -b $BAUDRATE -I "+cpin=$PIN" &
|
||||
PID=$!
|
||||
sleep 3
|
||||
kill $PID 2>/dev/null
|
||||
) >/dev/null 2>&1
|
||||
fi
|
||||
echo -n "$NAME"
|
||||
start-stop-daemon --start --quiet --pidfile /var/run/gsm-utils/$NAME.pid \
|
||||
--make-pidfile --background $STARTOPTS --exec $DAEMON -- $OPTIONS
|
||||
echo "."
|
||||
;;
|
||||
stop)
|
||||
echo -n "Stopping $DESC: $NAME "
|
||||
start-stop-daemon --stop --quiet --pidfile /var/run/gsm-utils/$NAME.pid \
|
||||
--exec $DAEMON
|
||||
sleep 5
|
||||
echo "."
|
||||
;;
|
||||
restart|force-reload)
|
||||
echo -n "Restarting $DESC: $NAME"
|
||||
start-stop-daemon --stop --quiet --pidfile /var/run/gsm-utils/$NAME.pid \
|
||||
--make-pidfile --background $STARTOPTS --exec $DAEMON -- $OPTIONS
|
||||
sleep 5
|
||||
start-stop-daemon --start --quiet --pidfile /var/run/gsm-utils/$NAME.pid \
|
||||
--make-pidfile --background --exec $DAEMON -- $OPTIONS
|
||||
echo "."
|
||||
;;
|
||||
*)
|
||||
N=/etc/init.d/gsm-utils
|
||||
echo "Usage: $N {start|stop|restart|force-reload}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
@ -0,0 +1,48 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# /usr/bin/gsmsmsrequeue: Re-queues failed SMS
|
||||
#
|
||||
# written by Matthias Goebl <matthias@goebl.net>
|
||||
|
||||
SPOOLDIR=/var/spool/sms
|
||||
PRIORITIES=3
|
||||
SMSADMIN=root
|
||||
SUBJECT="SMS delivery report:"
|
||||
|
||||
send_notify()
|
||||
{
|
||||
tmpfile="$SPOOLDIR/tmp/"`basename "$1"`
|
||||
status="$2"
|
||||
if mv "$1" "$tmpfile" 2>/dev/null; then
|
||||
# extract the first tab-separated field after the phone number as
|
||||
# email-address to send the notification to
|
||||
mailto=` cat "$tmpfile" | sed -ne '1s/^[^ ]* \([^ ]*\).*/\1/p' `
|
||||
test -z "$mailto" && mailto="$SMSADMIN"
|
||||
cat "$tmpfile" | mail -s "$SUBJECT $status" "$mailto"
|
||||
rm "$tmpfile"
|
||||
fi
|
||||
}
|
||||
do_accounting()
|
||||
{
|
||||
true;
|
||||
}
|
||||
|
||||
test -r /etc/default/gsm-utils && . /etc/default/gsm-utils
|
||||
|
||||
for p in `seq 1 $PRIORITIES`; do
|
||||
ls "$SPOOLDIR/failed$p" | while read file; do
|
||||
if expr "$file" : ".*rrrrrrrrrrrr" >/dev/null; then
|
||||
send_notify "$SPOOLDIR/failed$p/$file" "failed"
|
||||
else
|
||||
# re-queue SMS
|
||||
mv "$SPOOLDIR/failed$p/$file" "$SPOOLDIR/queue$p/${file}r" 2>/dev/null
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
for p in `seq 1 $PRIORITIES`; do
|
||||
ls "$SPOOLDIR/sent$p" | while read file; do
|
||||
do_accounting "$SPOOLDIR/sent$p/$file" "sent"
|
||||
send_notify "$SPOOLDIR/sent$p/$file" "sent"
|
||||
done
|
||||
done
|
@ -0,0 +1,34 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# /usr/bin/gsmsmsspool: Queues SMS for sending
|
||||
#
|
||||
# written by Matthias Goebl <matthias@goebl.net>
|
||||
|
||||
SPOOLDIR=/var/spool/sms
|
||||
PRIORITIES=3
|
||||
test -r /etc/default/gsm-utils && . /etc/default/gsm-utils
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Usage: gsmsmsspool NUMBER [MESSAGE]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
priority=$PRIORITIES # default priority
|
||||
test -n "$GSMSMS_PRIORITY" && priority="$GSMSMS_PRIORITY"
|
||||
mailto=`id -un`
|
||||
test -n "$GSMSMS_NOTIFY" && mailto="$GSMSMS_NOTIFY"
|
||||
|
||||
tmpfile="$SPOOLDIR/tmp/`date +%s`.$$"
|
||||
umask 022
|
||||
echo "$1 $mailto" > "$tmpfile"
|
||||
if [ -n "$2" ]; then
|
||||
echo "$2" | head -c 160 >> "$tmpfile"
|
||||
else
|
||||
head -c 160 >> "$tmpfile"
|
||||
fi
|
||||
|
||||
if [ "`id -un`" = "root" ]; then
|
||||
chown gsmsms:gsmsms "$tmpfile"
|
||||
fi
|
||||
|
||||
mv "$tmpfile" "$SPOOLDIR/queue$priority/"
|
@ -0,0 +1,284 @@
|
||||
gsmlib (1.10-13) unstable; urgency=low
|
||||
|
||||
* Ack NMU, Thanks Michael, Christoph & Petter
|
||||
* debian/control add Homepage:
|
||||
* Update debian/copyright; gsm-lib/COPYING actually specifies LGPL:
|
||||
- fixes lintian:copyright-without-copyright-notice
|
||||
* Update manpages fixes lintian:hyphen-used-as-minus-sign
|
||||
* Update debian/gsm-utils.init
|
||||
- fixes lintian:init.d-script-missing-lsb-short-description
|
||||
* Bug fixes from ubuntu
|
||||
- Don't install contrib/gsm-utils.init dh_installinit debian/gsm-utils.init
|
||||
- Create /var/run/gsm-utils
|
||||
* Add case 'L' to apps/gsmsmsd.cc - thks to Andrew Suffield
|
||||
- syslog support does not work (Closes: #346240)
|
||||
* gsm-utils.init really call restart with --stop first
|
||||
- init script calls --start twice (Closes: #377448)
|
||||
* Explictly set /bin/bash: gsmsmsspool & gsmsmsrequeue
|
||||
- bashism in /bin/sh script (Closes: #464981)
|
||||
- gsmsmsrequeue contains bashism or function error (Closes: #459396)
|
||||
* Patch apps/gsmsmsstore.cc - thks Isaac Wilcox
|
||||
- gsmsmsstore device existence check causes problems with RFCOMM
|
||||
devices (Closes: #340179)
|
||||
* Only start gsmsmsd if set in /etc/default/gsm-utils. crontab -> examples
|
||||
- gsmsmsd should be optional / start only if told so in
|
||||
/etc/default/gsm-utils (Closes: #474093)
|
||||
* Apply patch from Stefan Katerkamp & Jacob Nevins
|
||||
- Gsmsendsms fails with SonyEricsson W880 (fix included) (Closes:
|
||||
#413341)
|
||||
|
||||
-- Mark Purcell <msp@debian.org> Mon, 06 Oct 2008 15:01:49 +1100
|
||||
|
||||
gsmlib (1.10-12.5) unstable; urgency=low
|
||||
|
||||
* Non-maintainer upload.
|
||||
* Yet another bashism that was later on reported on the old bug report, thus
|
||||
again closes: #464981
|
||||
* Also found a shell related problem in debian/rules and fixed it.
|
||||
* Bumped standard to 3.7.3.
|
||||
|
||||
-- Michael Meskes <meskes@debian.org> Mon, 14 Apr 2008 10:48:19 +0200
|
||||
|
||||
gsmlib (1.10-12.4) unstable; urgency=low
|
||||
|
||||
* Non-maintainer upload.
|
||||
* Argh, somehow I mananged to upload without fixing the bug completely,
|
||||
sorry. Added those missing braces, closes: #464981.
|
||||
|
||||
-- Michael Meskes <meskes@debian.org> Wed, 09 Apr 2008 14:46:08 +0200
|
||||
|
||||
gsmlib (1.10-12.3) unstable; urgency=high
|
||||
|
||||
* Non-maintainer upload.
|
||||
* Removed bashism in contrib/gsmsmsrequeue (Closes: #464981).
|
||||
|
||||
-- Michael Meskes <meskes@debian.org> Sun, 06 Apr 2008 15:37:35 +0200
|
||||
|
||||
gsmlib (1.10-12.2) unstable; urgency=low
|
||||
|
||||
* Non-maintainer upload.
|
||||
* Fix FTBFS with GCC 4.3: 'strerror' was not declared in this scope, thanks
|
||||
to Cyril Brulebois for the patch (Closes: #455402).
|
||||
|
||||
-- Christoph Berg <myon@debian.org> Fri, 04 Apr 2008 18:01:05 +0200
|
||||
|
||||
gsmlib (1.10-12.1) unstable; urgency=low
|
||||
|
||||
* Non-maintainer upload to solve release goal.
|
||||
* Add LSB dependency header to init.d scripts (Closes: #464061).
|
||||
|
||||
-- Petter Reinholdtsen <pere@debian.org> Fri, 28 Mar 2008 11:39:20 +0100
|
||||
|
||||
gsmlib (1.10-12) unstable; urgency=low
|
||||
|
||||
* addgroup --system gsmsms works better. Thanks Jon
|
||||
* only delete gsmsms on purge
|
||||
- gsm-utils: deletes and recreates the gsmsms user on each upgrade
|
||||
(Closes: #346238)
|
||||
- gsm-utils fails installation / addgroup: The user gsmsms; does
|
||||
not exist (Closes: #445404)
|
||||
* lintian cleanup: debian-rules-ignores-make-clean-error substvar-
|
||||
source-version-is-deprecated
|
||||
* Scripts are installed +x
|
||||
- gsm-utils: uselessly installs non-executable scripts into /usr/bin
|
||||
(Closes: #346230)
|
||||
* Remove bogus symlink
|
||||
- gsm-utils: wrong symlink for manpage gsmsiectl.1 (Closes: #322382)
|
||||
- gsm-utils: gsmsiectl.1 dangling symlink (Closes: #399582)
|
||||
* debian/gsm-utils.init reload/restart was not calling --stop. Thanks
|
||||
Barry
|
||||
- init script calls --start twice (Closes: #377448)
|
||||
|
||||
-- Mark Purcell <msp@debian.org> Mon, 08 Oct 2007 21:44:00 +0100
|
||||
|
||||
gsmlib (1.10-11) unstable; urgency=low
|
||||
|
||||
* Create system group gsmsms - Thanks Emmanuel
|
||||
- gsm-utils: creates group in non-system gid range (Closes: #353967)
|
||||
- gsm-utils: postinst should create system grp gsmsms (Closes:
|
||||
#390266)
|
||||
* Upgrade to compat 4
|
||||
* Apply gcc-4.3 patch from Martin
|
||||
- FTBFS with GCC 4.3: missing #includes (Closes: #417222)
|
||||
|
||||
-- Mark Purcell <msp@debian.org> Sat, 29 Sep 2007 18:22:56 +0100
|
||||
|
||||
gsmlib (1.10-10) unstable; urgency=low
|
||||
|
||||
* FTBFS with G++ 4.1: extra qualifications (Closes: #356109)
|
||||
|
||||
-- Mark Purcell <msp@debian.org> Sat, 20 May 2006 21:54:42 +0100
|
||||
|
||||
gsmlib (1.10-9) unstable; urgency=low
|
||||
|
||||
* library package needs to be renamed (libstdc++ allocator change)
|
||||
(Closes: #339179)
|
||||
|
||||
-- Mark Purcell <msp@debian.org> Mon, 21 Nov 2005 21:19:51 +0000
|
||||
|
||||
gsmlib (1.10-8) unstable; urgency=low
|
||||
|
||||
* removal of automake1.6 (Closes: #335123)
|
||||
* fails with dash [bashisms in scripts] (Closes: #309834)
|
||||
* Update libtool Fixes: gsmlib(GNU/k*BSD): FTBFS: out of date libtool scripts (Closes:
|
||||
#319688)
|
||||
* [INTL:de] German PO file corrections (Closes: #314060)
|
||||
* Fix: old-fsf-address-in-copyright-file
|
||||
|
||||
-- Mark Purcell <msp@debian.org> Thu, 3 Nov 2005 22:40:19 +0000
|
||||
|
||||
gsmlib (1.10-7) unstable; urgency=low
|
||||
|
||||
* C++ 4.0 transition
|
||||
* Closes: #315864: Missing manpages
|
||||
* gsm-utils: maintainer-script-needs-depends-on-adduser postinst
|
||||
|
||||
-- Mark Purcell <msp@debian.org> Sat, 23 Jul 2005 00:46:31 +1000
|
||||
|
||||
gsmlib (1.10-6) unstable; urgency=low
|
||||
|
||||
* Rebuild for invalid dependancies
|
||||
* Closes: #258056: libgsmme 99% cpu usage
|
||||
- Patch from Emard
|
||||
* Closes: #274382: FTBFS with gcc-3.4: template-id `operator<
|
||||
<>' for `bool gsmlib::operator<(const
|
||||
gsmlib::MapKey<gsmlib::SortedPhonebookBase>&, const
|
||||
gsmlib::MapKey<gsmlib::SortedPhonebookBase>&)' does not
|
||||
match any template declaration
|
||||
- Patch from Andreas Jochens
|
||||
* Closes: #294251: FTBFS (amd64/gcc-4.0): explicit qualification in
|
||||
declaration of `bool gsmlib::operator<(const
|
||||
gsmlib::MapKey<SortedStore>&, const
|
||||
gsmlib::MapKey<SortedStore>&)'
|
||||
- Patch from Andreas Jochens
|
||||
* Closes: #200189: Patch and contribution
|
||||
+ Added multi-queue-priority-system and syslog patch (Matthias Goebl)
|
||||
+ Included init, spool and requeue scripts for gsmsmsd (Matthias Goebl)
|
||||
+ gsmsmsd runs with own user and group (gsmsms:gsmsms) (Matthias Goebl)
|
||||
|
||||
-- Mark Purcell <msp@debian.org> Tue, 17 May 2005 11:34:45 +0100
|
||||
|
||||
gsmlib (1.10-5) unstable; urgency=low
|
||||
|
||||
* Change Section: libdevel
|
||||
* gsm_unix_serial.cc patch from Daniel Schepler to fix g++-3.3
|
||||
compliation. Thanks. (Closes: Bug#195151)
|
||||
|
||||
-- Mark Purcell <msp@debian.org> Sat, 19 Jul 2003 15:57:28 +1000
|
||||
|
||||
gsmlib (1.10-4) unstable; urgency=low
|
||||
|
||||
* Include file descriptor leak patch from Edd Dumbill (Closes:
|
||||
Bug#168475)
|
||||
* lintian cleanup: description-synopsis-might-not-be-phrased-properly
|
||||
* lintian cleanup: configure-generated-file-in-source
|
||||
|
||||
-- Mark Purcell <msp@debian.org> Sun, 9 Feb 2003 14:04:54 +1100
|
||||
|
||||
gsmlib (1.10-3) unstable; urgency=low
|
||||
|
||||
* New Maintainer (Closes: Bug#180061). Thanks Mikael for your work.
|
||||
|
||||
-- Mark Purcell <msp@debian.org> Sat, 8 Feb 2003 16:55:26 +1100
|
||||
|
||||
gsmlib (1.10-2) unstable; urgency=low
|
||||
|
||||
* Rebuild to use the new c++ ABI (GCC 3.2)
|
||||
|
||||
-- Mikael Hedin <micce@debian.org> Thu, 23 Jan 2003 20:57:50 +0100
|
||||
|
||||
gsmlib (1.10-1) unstable; urgency=low
|
||||
|
||||
* New upstrem release.
|
||||
|
||||
-- Mikael Hedin <micce@debian.org> Wed, 6 Nov 2002 17:44:17 +0100
|
||||
|
||||
gsmlib (1.9-2) unstable; urgency=low
|
||||
|
||||
* Made new rules for the config.guess/sub update thing (closes: #146865,
|
||||
#146867).
|
||||
|
||||
-- Mikael Hedin <micce@debian.org> Tue, 14 May 2002 09:28:03 +0200
|
||||
|
||||
gsmlib (1.9-1) unstable; urgency=low
|
||||
|
||||
* New upstream version.
|
||||
* Use chrpath to get rid of rpaths.
|
||||
* Add mini-manpage for gsmsiexfer.
|
||||
* Remove b-d on auto-stuff, we don't use them.
|
||||
|
||||
-- Mikael Hedin <micce@debian.org> Mon, 13 May 2002 22:10:28 +0200
|
||||
|
||||
gsmlib (1.8-2) unstable; urgency=low
|
||||
|
||||
* Removed b-d on gcc 3.0, as they are no longer nessecary.
|
||||
|
||||
-- Mikael Hedin <micce@debian.org> Thu, 24 Jan 2002 12:59:07 +0100
|
||||
|
||||
gsmlib (1.8-1) unstable; urgency=low
|
||||
|
||||
* New upstream version.
|
||||
* Revert the arch hack, now it should compile with either g++.
|
||||
* Include the new lib in libgsmme1. Run dh_makeshlibs -V because of this.
|
||||
* Added info for gsmsiectl in gsmctl(1).
|
||||
|
||||
-- Mikael Hedin <micce@debian.org> Wed, 9 Jan 2002 22:38:45 +0100
|
||||
|
||||
gsmlib (1.7-2) unstable; urgency=low
|
||||
|
||||
* gsm-utils: Added shlibs:Depends (closes: #126127).
|
||||
* Spelling correction (closes: #124705, #124972)
|
||||
* Rm libgsmme1.postins, and let dh_makeshlibs take care of ldconfig.
|
||||
* Made explicit arch list without sparc and arm, they cannot use g++-3.0
|
||||
right now.
|
||||
|
||||
-- Mikael Hedin <micce@debian.org> Sat, 22 Dec 2001 20:27:54 +0100
|
||||
|
||||
gsmlib (1.7-1) unstable; urgency=low
|
||||
|
||||
* New upstream
|
||||
* Use gcc-3.0 and g++-3.0, 2.95 doesn't compile.
|
||||
|
||||
-- Mikael Hedin <micce@debian.org> Thu, 1 Nov 2001 10:24:33 +0100
|
||||
|
||||
gsmlib (1.6-5) unstable; urgency=low
|
||||
|
||||
* Updated manpage (closes: #110973)
|
||||
* Corrected problem with OP status (closes: #110970)
|
||||
|
||||
-- Mikael Hedin <micce@debian.org> Sat, 8 Sep 2001 18:12:17 +0200
|
||||
|
||||
gsmlib (1.6-4) unstable; urgency=low
|
||||
|
||||
* Support DEB_BUILD_OPTIONS
|
||||
* Changed libgsmme-dev to section devel.
|
||||
* Reran libtoolize.
|
||||
* Lots of small patches to compile with g++-3.0. (Closes: #104411)
|
||||
* Removed dh_testversion.
|
||||
|
||||
-- Mikael Hedin <micce@debian.org> Thu, 12 Jul 2001 16:06:23 +0200
|
||||
|
||||
gsmlib (1.6-3) unstable; urgency=low
|
||||
|
||||
* Various minor corrections.
|
||||
|
||||
-- Mikael Hedin <mikael.hedin@irf.se> Thu, 8 Mar 2001 16:24:07 +0100
|
||||
|
||||
gsmlib (1.6-2) unstable; urgency=low
|
||||
|
||||
* Dont install INSTALL. Correct indentation for libgsmme1 description.
|
||||
|
||||
-- Mikael Hedin <mikael.hedin@irf.se> Tue, 6 Mar 2001 14:55:05 +0100
|
||||
|
||||
gsmlib (1.6-1) unstable; urgency=low
|
||||
|
||||
* New upstream version.
|
||||
|
||||
-- Mikael Hedin <mikael.hedin@irf.se> Mon, 29 Jan 2001 17:57:21 +0100
|
||||
|
||||
gsmlib (1.5-1) unstable; urgency=low
|
||||
|
||||
* Initial Release.
|
||||
|
||||
-- Mikael Hedin <mikael.hedin@irf.se> Thu, 14 Dec 2000 01:06:40 +0100
|
||||
|
@ -0,0 +1 @@
|
||||
4
|
@ -0,0 +1,45 @@
|
||||
Source: gsmlib
|
||||
Section: comm
|
||||
Priority: extra
|
||||
Maintainer: Mark Purcell <msp@debian.org>
|
||||
Build-Depends: debhelper (>= 3.0.0), chrpath
|
||||
Standards-Version: 3.7.3
|
||||
Homepage: http://www.pxh.de/fs/gsmlib/
|
||||
|
||||
Package: libgsmme-dev
|
||||
Section: libdevel
|
||||
Architecture: any
|
||||
Depends: libgsmme1c2a (= ${binary:Version}), libc6-dev
|
||||
Description: Header files and static libraries for gsmlib
|
||||
Headers and static libraries for use when compiling programs with
|
||||
gsmlib.
|
||||
.
|
||||
gsmlib is a library for access to a GSM mobile phone using the
|
||||
standards ETSI GSM 07.07, ETSI GSM 07.05, and others.
|
||||
|
||||
Package: libgsmme1c2a
|
||||
Conflicts: libgsmme1, libgsmme1c102, libgsmme1c2
|
||||
Replaces: libgsmme1c102, libgsmme1c2
|
||||
Section: libs
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}
|
||||
Description: GSM mobile phone access library
|
||||
Library to access GSM mobile phones through GSM modems or IrDA devices.
|
||||
Features include:
|
||||
.
|
||||
* modification of phone books stored in the mobile phone or on the
|
||||
SIM card
|
||||
* reading and writing of SMS messages stored in the mobile phone
|
||||
* sending and reception of SMS messages
|
||||
.
|
||||
gsmlib uses standard ETSI GSM 07.07, ETSI GSM 07.05, and others.
|
||||
|
||||
Package: gsm-utils
|
||||
Section: comm
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, adduser
|
||||
Description: GSM mobile phone access applications
|
||||
Some simple command line programs to access a GSM mobile phone via
|
||||
GSM modem or IrDA. Functions include: modification of phone books and
|
||||
reading, writing, sending and receiving SMS messages. Uses the GSM
|
||||
standards ETSI GSM 07.07, ETSI GSM 07.05, and others.
|
@ -0,0 +1,34 @@
|
||||
This package was debianized by Mikael Hedin <mikael.hedin@irf.se> on
|
||||
Thu, 14 Dec 2000 01:06:40 +0100.
|
||||
|
||||
It was downloaded from http://www.pxh.de/fs/gsmlib/index.html
|
||||
|
||||
Upstream Author: Peter Hofmann <software@pxh.de>
|
||||
|
||||
ext/gsmsiexfer.cc:// * Author: Christian W. Zuckschwerdt <zany@triq.net>
|
||||
|
||||
Copyright:
|
||||
|
||||
Copyright (C) 1999-2002 Peter Hofmann <software@pxh.de>
|
||||
|
||||
License:
|
||||
|
||||
This package is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This package 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this package; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
On Debian systems, the complete text of the GNU Lesser General
|
||||
Public License can be found in `/usr/share/common-licenses/LGPL'.
|
||||
|
||||
The Debian packaging is (C) 2000, Mikael Hedin <mikael.hedin@irf.se> and
|
||||
is licensed under the GPL, see `/usr/share/common-licenses/GPL'.
|
@ -0,0 +1 @@
|
||||
/var/run/gsm-utils
|
@ -0,0 +1,3 @@
|
||||
# /etc/cron.d/gsm-utils: crontab fragment for gsm-utils
|
||||
|
||||
*/5 * * * * root if [ -x /usr/bin/gsmsmsrequeue ]; then /usr/bin/gsmsmsrequeue; fi
|
@ -0,0 +1,18 @@
|
||||
PHONEDEV=/dev/mobilephone # or /dev/ttyS0 or /dev/ircomm0
|
||||
BAUDRATE=9600
|
||||
PIN="" # or 1234
|
||||
|
||||
# RUNGSMSMS: If set to anything other that 'yes', the asterisk init.d script
|
||||
# will not run. The default is 'yes'.
|
||||
# You should probaly also install the crontab from /usr/share/doc/gsm-utils/examples
|
||||
RUNGSMSMS=no
|
||||
|
||||
SPOOLDIR=/var/spool/sms
|
||||
PRIORITIES=3
|
||||
|
||||
SMSADMIN=root
|
||||
SUBJECT="SMS delivery report:"
|
||||
|
||||
SMSPROCESSOR="" # or /usr/bin/gsmsmsprocessor
|
||||
|
||||
do_accounting () { true; } # it's your turn
|
@ -0,0 +1,11 @@
|
||||
var/spool/sms/queue1
|
||||
var/spool/sms/queue2
|
||||
var/spool/sms/queue3
|
||||
var/spool/sms/sent1
|
||||
var/spool/sms/sent2
|
||||
var/spool/sms/sent3
|
||||
var/spool/sms/failed1
|
||||
var/spool/sms/failed2
|
||||
var/spool/sms/failed3
|
||||
var/spool/sms/tmp
|
||||
var/run/gsm-utils
|
@ -0,0 +1,4 @@
|
||||
NEWS
|
||||
README
|
||||
TODO
|
||||
doc/FAQ
|
@ -0,0 +1,2 @@
|
||||
contrib/gsm-utils.cron.d
|
||||
contrib/gsm-utils.init
|
@ -0,0 +1,87 @@
|
||||
#! /bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: gsm-utils
|
||||
# Required-Start: $remote_fs $syslog
|
||||
# Required-Stop: $remote_fs $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Start daemon at boot time
|
||||
# Description: Enable service provided by daemon.
|
||||
### END INIT INFO
|
||||
#
|
||||
# /etc/init.d/gsm-utils: Controls the GSM SMS send daemon
|
||||
#
|
||||
# written by Matthias Goebl <matthias@goebl.net>
|
||||
|
||||
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
|
||||
DAEMON=/usr/bin/gsmsmsd
|
||||
NAME=gsmsmsd
|
||||
DESC="GSM SMS send daemon"
|
||||
|
||||
test -x $DAEMON || exit 0
|
||||
|
||||
if [ "$RUNGSMSMS" != "yes" ];then
|
||||
echo "GSM SMS deamon not yet configured. Edit /etc/default/gsm-utils first."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
PHONEDEV=/dev/mobilephone # or /dev/ttyS0 or /dev/ircomm0
|
||||
BAUDRATE=9600
|
||||
PIN="" # or 1234
|
||||
SMSPROCESSOR="" # or /usr/bin/gsmsmsprocessor
|
||||
SPOOLDIR=/var/spool/sms
|
||||
PRIORITIES=3
|
||||
STARTOPTS=""
|
||||
SMSUSER="gsmsms:gsmsms"
|
||||
test -r /etc/default/gsm-utils && . /etc/default/gsm-utils # for overwriting some parameters
|
||||
|
||||
OPTIONS="-d $PHONEDEV -b $BAUDRATE -L -P $PRIORITIES"
|
||||
OPTIONS="$OPTIONS -s $SPOOLDIR/queue -S $SPOOLDIR/sent -F $SPOOLDIR/failed"
|
||||
test -n "$SMSPROCESSOR" && OPTIONS="$OPTIONS -a $SMSPROCESSOR"
|
||||
test -n "$SMSUSER" && STARTOPTS="$STARTOPTS --chuid $SMSUSER"
|
||||
test -r /etc/default/gsm-utils && . /etc/default/gsm-utils # for overwriting OPTIONS
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo -n "Starting $DESC: "
|
||||
if [ -n "$PIN" ];then
|
||||
echo -n "entering PIN.. "
|
||||
(
|
||||
# This is ugly.. But if the PIN is already entered, the ME returns
|
||||
# "ERROR" and makes gsmctl retrying..
|
||||
/usr/bin/gsmctl -d $PHONEDEV -b $BAUDRATE -I "+cpin=$PIN" &
|
||||
PID=$!
|
||||
sleep 3
|
||||
kill $PID 2>/dev/null
|
||||
) >/dev/null 2>&1
|
||||
fi
|
||||
echo -n "$NAME"
|
||||
start-stop-daemon --start --quiet --pidfile /var/run/gsm-utils/$NAME.pid \
|
||||
--make-pidfile --background $STARTOPTS --exec $DAEMON -- $OPTIONS
|
||||
echo "."
|
||||
;;
|
||||
stop)
|
||||
echo -n "Stopping $DESC: $NAME "
|
||||
start-stop-daemon --stop --quiet --pidfile /var/run/gsm-utils/$NAME.pid \
|
||||
--exec $DAEMON
|
||||
sleep 5
|
||||
echo "."
|
||||
;;
|
||||
restart|force-reload)
|
||||
echo -n "Restarting $DESC: $NAME"
|
||||
start-stop-daemon --stop --quiet --pidfile /var/run/gsm-utils/$NAME.pid \
|
||||
--make-pidfile --background --exec $DAEMON -- $OPTIONS
|
||||
sleep 5
|
||||
start-stop-daemon --start --quiet --pidfile /var/run/gsm-utils/$NAME.pid \
|
||||
--make-pidfile --background $STARTOPTS --exec $DAEMON -- $OPTIONS
|
||||
echo "."
|
||||
;;
|
||||
*)
|
||||
N=/etc/init.d/gsm-utils
|
||||
echo "Usage: $N {start|stop|restart|force-reload}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
@ -0,0 +1,28 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
# create gsmsms group if necessary.
|
||||
if ! grep -q ^gsmsms: /etc/group; then
|
||||
# echo Adding system group: gsmsms.
|
||||
addgroup --system gsmsms
|
||||
fi
|
||||
|
||||
# create gsmsms user if necessary.
|
||||
if ! grep -q ^gsmsms: /etc/passwd; then
|
||||
# echo Adding system user: gsmsms.
|
||||
adduser --system --ingroup gsmsms \
|
||||
--no-create-home --home /var/spool/sms gsmsms
|
||||
fi
|
||||
|
||||
# allow gsmsms to use serial lines
|
||||
if ! groups gsmsms | grep -q dialout ; then
|
||||
adduser gsmsms dialout
|
||||
fi
|
||||
|
||||
# echo Updating spool directory structure: /var/spool/sms
|
||||
chown -R gsmsms:gsmsms /var/spool/sms /var/run/gsm-utils
|
||||
chmod 700 /var/spool/sms/*
|
||||
chmod 750 /var/spool/sms
|
||||
chmod 730 /var/spool/sms/queue* /var/spool/sms/tmp
|
||||
|
||||
# Add the rest automatically..
|
||||
#DEBHELPER#
|
@ -0,0 +1,43 @@
|
||||
#!/bin/sh
|
||||
# postrm script for #PACKAGE#
|
||||
#
|
||||
# see: dh_installdeb(1)
|
||||
|
||||
set -e
|
||||
|
||||
# summary of how this script can be called:
|
||||
# * <postrm> `remove'
|
||||
# * <postrm> `purge'
|
||||
# * <old-postrm> `upgrade' <new-version>
|
||||
# * <new-postrm> `failed-upgrade' <old-version>
|
||||
# * <new-postrm> `abort-install'
|
||||
# * <new-postrm> `abort-install' <old-version>
|
||||
# * <new-postrm> `abort-upgrade' <old-version>
|
||||
# * <disappearer's-postrm> `disappear' <overwriter>
|
||||
# <overwriter-version>
|
||||
# for details, see http://www.debian.org/doc/debian-policy/ or
|
||||
# the debian-policy package
|
||||
|
||||
|
||||
case "$1" in
|
||||
remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
|
||||
;;
|
||||
|
||||
purge)
|
||||
deluser gsmsms
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "postrm called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# dh_installdeb will replace this with shell code automatically
|
||||
# generated by other debhelper scripts.
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
||||
|
||||
|
@ -0,0 +1,29 @@
|
||||
.\" -*- eval: (nroff-mode) -*-
|
||||
.de TQ
|
||||
.br
|
||||
.ns
|
||||
.TP \\$1
|
||||
..
|
||||
.\" Like TP, but if specified indent is more than half
|
||||
.\" the current line-length - indent, use the default indent.
|
||||
.de Tp
|
||||
.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP
|
||||
.el .TP "\\$1"
|
||||
..
|
||||
.TH GSMSIEXFER 1 "" "gsmsiexfer"
|
||||
.SH NAME
|
||||
gsmsiexfer \- Siemens ME file transfer program for Siemens phones S25, S35, S45, ME45, SL45
|
||||
.SH SYNOPSIS
|
||||
.B gsmsiexfer \-\-help
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
\fIgsmsiexer\fP comes with no man page. Try gsmsiexfer \-\-help, or
|
||||
read the source.
|
||||
.PP
|
||||
.SH "SEE ALSO"
|
||||
.BR gsminfo(7),
|
||||
.BR gsmctl(1),
|
||||
.BR gsmsendsms(1),
|
||||
.BR gsmsmsd(8),
|
||||
.BR gsmsmsstore(1).
|
||||
|
@ -0,0 +1,2 @@
|
||||
doc/README.developers
|
||||
doc/README.NLS
|
@ -0,0 +1,129 @@
|
||||
#!/usr/bin/make -f
|
||||
|
||||
# Uncomment this to turn on verbose mode.
|
||||
#export DH_VERBOSE=1
|
||||
|
||||
# shared library versions, option 1
|
||||
#version=2.0.5
|
||||
#major=2
|
||||
# option 2, assuming the library is created as src/.libs/libfoo.so.2.0.5 or so
|
||||
me_version=`ls gsmlib/.libs/libgsmme*.so.* | \
|
||||
awk '{if (match($$0,/[0-9]+\.[0-9]+\.[0-9]+$$/)) print substr($$0,RSTART)}'`
|
||||
me_major=`ls gsmlib/.libs/libgsmme*.so.* | \
|
||||
awk '{if (match($$0,/\.so\.[0-9]+$$/)) print substr($$0,RSTART+4)}'`
|
||||
ex_version=`ls ext/.libs/libgsmext*.so.* | \
|
||||
awk '{if (match($$0,/[0-9]+\.[0-9]+\.[0-9]+$$/)) print substr($$0,RSTART)}'`
|
||||
ex_major=`ls ext/.libs/libgsmext*.so.* | \
|
||||
awk '{if (match($$0,/\.so\.[0-9]+$$/)) print substr($$0,RSTART+4)}'`
|
||||
|
||||
|
||||
export DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
|
||||
export DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
|
||||
|
||||
|
||||
# FOR AUTOCONF 2.13 ONLY
|
||||
ifeq ($(DEB_BUILD_GNU_TYPE), $(DEB_HOST_GNU_TYPE))
|
||||
confflags += $(DEB_HOST_GNU_TYPE)
|
||||
else
|
||||
confflags += --host $(DEB_BUILD_GNU_TYPE) --build $(DEB_HOST_GNU_TYPE)
|
||||
endif
|
||||
|
||||
ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
|
||||
CFLAGS += -g
|
||||
CXXFLAGS += -g
|
||||
endif
|
||||
|
||||
configure: configure-stamp
|
||||
configure-stamp:
|
||||
dh_testdir
|
||||
# Add here commands to configure the package.
|
||||
CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" INSTALL_PROGRAM=$(INSTALL_PROGRAM) \
|
||||
./configure $(confflags) --prefix=/usr --mandir=\$${prefix}/share/man \
|
||||
--infodir=\$${prefix}/share/info
|
||||
|
||||
touch configure-stamp
|
||||
|
||||
build: configure-stamp build-stamp
|
||||
build-stamp:
|
||||
dh_testdir
|
||||
|
||||
# Add here commands to compile the package.
|
||||
$(MAKE)
|
||||
|
||||
touch build-stamp
|
||||
|
||||
clean:
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
|
||||
# Add here commands to clean up after the build process.
|
||||
[ ! -f Makefile ] || $(MAKE) distclean
|
||||
rm -f build-stamp configure-stamp config.log config.status po/de.gmo
|
||||
|
||||
-test -r /usr/share/misc/config.sub && \
|
||||
cp -f /usr/share/misc/config.sub scripts/config.sub
|
||||
-test -r /usr/share/misc/config.guess && \
|
||||
cp -f /usr/share/misc/config.guess scripts/config.guess
|
||||
|
||||
dh_clean
|
||||
|
||||
install: build
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
dh_clean -k
|
||||
dh_installdirs
|
||||
dh_installdirs -pgsm-utils
|
||||
|
||||
# Add here commands to install the package into debian/gsmlib.
|
||||
$(MAKE) install DESTDIR=$(CURDIR)/debian/tmp
|
||||
chrpath -d debian/tmp/usr/bin/*
|
||||
cp contrib/gsmsmsspool contrib/gsmsmsrequeue debian/tmp/usr/bin
|
||||
|
||||
|
||||
# Build architecture-independent files here.
|
||||
binary-indep: build install
|
||||
# We have nothing to do by default.
|
||||
|
||||
# Build architecture-dependent files here.
|
||||
binary-arch: build install
|
||||
dh_testdir
|
||||
dh_testroot
|
||||
#
|
||||
# build libgsmlib${major} package by moving files from gsmlib-dev
|
||||
#
|
||||
dh_movefiles -plibgsmme$(me_major)c2a \
|
||||
usr/lib/libgsmme.so.$(me_major) \
|
||||
usr/lib/libgsmme.so.$(me_version) \
|
||||
usr/lib/libgsmext.so.$(ex_major) \
|
||||
usr/lib/libgsmext.so.$(ex_version) \
|
||||
usr/share/locale
|
||||
|
||||
dh_movefiles -plibgsmme-dev \
|
||||
usr/include \
|
||||
usr/lib
|
||||
|
||||
dh_movefiles -pgsm-utils \
|
||||
usr/bin
|
||||
|
||||
|
||||
dh_installdocs
|
||||
dh_installexamples
|
||||
dh_installmenu
|
||||
dh_installinit
|
||||
dh_installcron
|
||||
dh_installman -pgsm-utils debian/*.1 debian/tmp/usr/share/man/man*/*
|
||||
dh_installinfo
|
||||
dh_installchangelogs ChangeLog
|
||||
dh_link
|
||||
dh_strip
|
||||
dh_compress
|
||||
dh_fixperms
|
||||
dh_makeshlibs -V
|
||||
dh_installdeb
|
||||
dh_shlibdeps -ldebian/libgsmme1c2a/usr/lib
|
||||
dh_gencontrol
|
||||
dh_md5sums
|
||||
dh_builddeb
|
||||
|
||||
binary: binary-indep binary-arch
|
||||
.PHONY: build clean binary-indep binary-arch binary install configure
|
@ -0,0 +1,2 @@
|
||||
version=2
|
||||
http://www.pxh.de/fs/gsmlib/download/content.html gsmlib-(.*)\.tar\.gz
|
@ -0,0 +1,101 @@
|
||||
*** 1. I get the error
|
||||
/usr/local/bin/gsmsmsd [ERROR]: cannot route status report message to TE
|
||||
|
||||
Some phones/modems cannot route all kinds of SMS to the TE
|
||||
(computer). Please try
|
||||
|
||||
gsmsmsd no_stat
|
||||
|
||||
This is documented in the gsmsmsd manual page.
|
||||
|
||||
|
||||
*** 2. Siemens M20T expects an initial PIN.
|
||||
|
||||
For the Siemens M20T an initial PIN must be send once (probably when
|
||||
it is switched on or the computer is powered on). This PIN is used for
|
||||
all subsequent invocations of gsmlib-based programs. The trick is to
|
||||
issue the following program (eg. in the rc-scripts of the operating system):
|
||||
|
||||
gsmctl -I "+cpin=<MY PIN>"
|
||||
|
||||
|
||||
*** 3. Sending SMS with or retrieving SMS from my Ericsson SH888 does
|
||||
not work.
|
||||
|
||||
Set the environment variable GSMLIB_SH888_FIX:
|
||||
|
||||
export GSMLIB_SH888_FIX=1 (bash)
|
||||
setenv GSMLIB_SH888_FIX 1 (tcsh)
|
||||
|
||||
If it works now, I need your model number. You could just enter
|
||||
"AT+CGMM" in a terminal program and send me the results. Alternatively
|
||||
set the environment variable GSMLIB_DEBUG=2 and me the dump.
|
||||
|
||||
*** 4. I get the error "ME/TA error 'Unidentified subscriber' (code
|
||||
28)" when trying to send SMS using gsmsendsms or gsmsmsd.
|
||||
|
||||
The SMS service centre address (SCA, the phone number of the centre that is
|
||||
accepting SMS for delivery) is not set correctly in your phone. There
|
||||
are three ways to correct this:
|
||||
|
||||
1. set the default SCA (example is for Germany T-D1):
|
||||
|
||||
gsmctl -o setsca "+491710760000"
|
||||
|
||||
2. Use the menus of your phone to set the SMS SCA.
|
||||
|
||||
3. Use the option "--sca 1234567" for the gsmsmsd, gsmsmsstore, and
|
||||
gsmsendsms programs. This tries to set the SCA in the SMS itself (does
|
||||
not change default SCA) and might not work with all phones.
|
||||
|
||||
*** 5. gsmlib works unreliably with my phone.
|
||||
|
||||
Try another baudrate, even higher baudrates sometimes work better then
|
||||
lower ones.
|
||||
|
||||
*** 6. On Win32 accessing the COM device fails.
|
||||
|
||||
Use COMx: (x is the number of the COM device) instead of the UNIX
|
||||
device name. If this doesn't work use "\\.\COMx:".
|
||||
|
||||
*** 7. Windows 2000 Does Not Support Mapping Virtual COM Ports to
|
||||
Infrared Ports.
|
||||
|
||||
Windows 2000 users should follow the instructions in
|
||||
support.microsoft.com article Q252795 in order to connect with their
|
||||
mobile.
|
||||
|
||||
*** 8. gcc-compiled shared C++ libraries do not work properly on some
|
||||
commercial UNIX systems and with older version of gcc.
|
||||
|
||||
The symptoms may be that the program dumps core on exceptions (AIX) or that
|
||||
global constructors are not called (Solaris).
|
||||
|
||||
Try to compile gsmlib with
|
||||
|
||||
./configure --disable-shared --enable-static
|
||||
|
||||
if you encounter strange problems.
|
||||
|
||||
*** 9. How to support unicode?
|
||||
|
||||
You need 6 steps:
|
||||
|
||||
1. set datacodingschema to DCS_SIXTEEN_BIT_ALPHABET
|
||||
|
||||
2. set your locale correctly, for example, my locale, china.
|
||||
setlocale(LC_ALL, "chs");
|
||||
|
||||
3. translate MBCS(multiple byte character set) string to unicode string.
|
||||
wchar_t wstr[ 1000 ];
|
||||
memset(wstr, 0, 2000);
|
||||
mbstowcs(wstr, data.c_str(), data.length());
|
||||
|
||||
4. get unicode string length.
|
||||
int wcs_len = wcslen(wstr);
|
||||
|
||||
5. change unicode string to net order.
|
||||
for (int i = 0; i < wcs_len; i++)
|
||||
wstr[ i ] = htons(wstr[ i ]);
|
||||
|
||||
6. put unicode string into pdu.
|
@ -0,0 +1,33 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
# *************************************************************************
|
||||
# * GSM TA/ME library
|
||||
# *
|
||||
# * File: Makefile.am
|
||||
# *
|
||||
# * Purpose: doc Makefile
|
||||
# *
|
||||
# * Author: Peter Hofmann (software@pxh.de)
|
||||
# *
|
||||
# * Created: 11.6.1999
|
||||
# *************************************************************************
|
||||
|
||||
man_MANS = gsmsmsd.8 gsmctl.1 gsmpb.1 gsmsendsms.1 gsmsmsstore.1 gsminfo.7
|
||||
|
||||
EXTRA_DIST = gsmsmsd.man gsmctl.man gsmpb.man gsmsendsms.man \
|
||||
gsmsmsstore.man gsmlib.lsm gsminfo.man \
|
||||
README.NLS README.developers FAQ
|
||||
|
||||
%.1: %.man
|
||||
sed -e "s/##VERSION##/$(VERSION)/g;s/##DATE##/`date`/g" \
|
||||
$< > $@
|
||||
|
||||
%.7: %.man
|
||||
sed -e "s/##VERSION##/$(VERSION)/g;s/##DATE##/`date`/g" \
|
||||
$< > $@
|
||||
|
||||
%.8: %.man
|
||||
sed -e "s/##VERSION##/$(VERSION)/g;s/##DATE##/`date`/g" \
|
||||
$< > $@
|
||||
|
||||
clean-local:
|
||||
rm -f *.1 *.7 *.8
|
@ -0,0 +1,412 @@
|
||||
# Makefile.in generated by automake 1.6.3 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
# Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
# *************************************************************************
|
||||
# * GSM TA/ME library
|
||||
# *
|
||||
# * File: Makefile.am
|
||||
# *
|
||||
# * Purpose: doc Makefile
|
||||
# *
|
||||
# * Author: Peter Hofmann (software@pxh.de)
|
||||
# *
|
||||
# * Created: 11.6.1999
|
||||
# *************************************************************************
|
||||
SHELL = @SHELL@
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = @bindir@
|
||||
sbindir = @sbindir@
|
||||
libexecdir = @libexecdir@
|
||||
datadir = @datadir@
|
||||
sysconfdir = @sysconfdir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
localstatedir = @localstatedir@
|
||||
libdir = @libdir@
|
||||
infodir = @infodir@
|
||||
mandir = @mandir@
|
||||
includedir = @includedir@
|
||||
oldincludedir = /usr/include
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
top_builddir = ..
|
||||
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = @program_transform_name@
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
host_alias = @host_alias@
|
||||
host_triplet = @host@
|
||||
|
||||
EXEEXT = @EXEEXT@
|
||||
OBJEXT = @OBJEXT@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
AMTAR = @AMTAR@
|
||||
AS = @AS@
|
||||
AWK = @AWK@
|
||||
BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
|
||||
CATOBJEXT = @CATOBJEXT@
|
||||
CC = @CC@
|
||||
CPP = @CPP@
|
||||
CXX = @CXX@
|
||||
DATADIRNAME = @DATADIRNAME@
|
||||
DEPDIR = @DEPDIR@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
ECHO = @ECHO@
|
||||
GENCAT = @GENCAT@
|
||||
GLIBC21 = @GLIBC21@
|
||||
GMSGFMT = @GMSGFMT@
|
||||
GSM_VERSION = @GSM_VERSION@
|
||||
HAVE_LIB = @HAVE_LIB@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
INSTOBJEXT = @INSTOBJEXT@
|
||||
INTLBISON = @INTLBISON@
|
||||
INTLLIBS = @INTLLIBS@
|
||||
INTLOBJS = @INTLOBJS@
|
||||
INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
|
||||
LIB = @LIB@
|
||||
LIBICONV = @LIBICONV@
|
||||
LIBINTL = @LIBINTL@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LN_S = @LN_S@
|
||||
LTLIB = @LTLIB@
|
||||
LTLIBICONV = @LTLIBICONV@
|
||||
LTLIBINTL = @LTLIBINTL@
|
||||
MKINSTALLDIRS = @MKINSTALLDIRS@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
PACKAGE = @PACKAGE@
|
||||
POSUB = @POSUB@
|
||||
RANLIB = @RANLIB@
|
||||
STRIP = @STRIP@
|
||||
USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
|
||||
USE_NLS = @USE_NLS@
|
||||
VERSION = @VERSION@
|
||||
am__include = @am__include@
|
||||
am__quote = @am__quote@
|
||||
install_sh = @install_sh@
|
||||
|
||||
man_MANS = gsmsmsd.8 gsmctl.1 gsmpb.1 gsmsendsms.1 gsmsmsstore.1 gsminfo.7
|
||||
|
||||
EXTRA_DIST = gsmsmsd.man gsmctl.man gsmpb.man gsmsendsms.man \
|
||||
gsmsmsstore.man gsmlib.lsm gsminfo.man \
|
||||
README.NLS README.developers FAQ
|
||||
|
||||
subdir = doc
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs
|
||||
CONFIG_HEADER = $(top_builddir)/gsm_config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
DIST_SOURCES =
|
||||
|
||||
NROFF = nroff
|
||||
MANS = $(man_MANS)
|
||||
DIST_COMMON = Makefile.am Makefile.in
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu doc/Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
|
||||
distclean-libtool:
|
||||
-rm -f libtool
|
||||
uninstall-info-am:
|
||||
|
||||
man1dir = $(mandir)/man1
|
||||
install-man1: $(man1_MANS) $(man_MANS)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(man1dir)
|
||||
@list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
|
||||
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
|
||||
for i in $$l2; do \
|
||||
case "$$i" in \
|
||||
*.1*) list="$$list $$i" ;; \
|
||||
esac; \
|
||||
done; \
|
||||
for i in $$list; do \
|
||||
if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
|
||||
else file=$$i; fi; \
|
||||
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
|
||||
case "$$ext" in \
|
||||
1*) ;; \
|
||||
*) ext='1' ;; \
|
||||
esac; \
|
||||
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
|
||||
inst=`echo $$inst | sed -e 's/^.*\///'`; \
|
||||
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
|
||||
echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \
|
||||
$(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \
|
||||
done
|
||||
uninstall-man1:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
|
||||
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
|
||||
for i in $$l2; do \
|
||||
case "$$i" in \
|
||||
*.1*) list="$$list $$i" ;; \
|
||||
esac; \
|
||||
done; \
|
||||
for i in $$list; do \
|
||||
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
|
||||
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
|
||||
inst=`echo $$inst | sed -e 's/^.*\///'`; \
|
||||
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
|
||||
echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \
|
||||
rm -f $(DESTDIR)$(man1dir)/$$inst; \
|
||||
done
|
||||
|
||||
man7dir = $(mandir)/man7
|
||||
install-man7: $(man7_MANS) $(man_MANS)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(man7dir)
|
||||
@list='$(man7_MANS) $(dist_man7_MANS) $(nodist_man7_MANS)'; \
|
||||
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
|
||||
for i in $$l2; do \
|
||||
case "$$i" in \
|
||||
*.7*) list="$$list $$i" ;; \
|
||||
esac; \
|
||||
done; \
|
||||
for i in $$list; do \
|
||||
if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
|
||||
else file=$$i; fi; \
|
||||
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
|
||||
case "$$ext" in \
|
||||
7*) ;; \
|
||||
*) ext='7' ;; \
|
||||
esac; \
|
||||
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
|
||||
inst=`echo $$inst | sed -e 's/^.*\///'`; \
|
||||
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
|
||||
echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man7dir)/$$inst"; \
|
||||
$(INSTALL_DATA) $$file $(DESTDIR)$(man7dir)/$$inst; \
|
||||
done
|
||||
uninstall-man7:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(man7_MANS) $(dist_man7_MANS) $(nodist_man7_MANS)'; \
|
||||
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
|
||||
for i in $$l2; do \
|
||||
case "$$i" in \
|
||||
*.7*) list="$$list $$i" ;; \
|
||||
esac; \
|
||||
done; \
|
||||
for i in $$list; do \
|
||||
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
|
||||
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
|
||||
inst=`echo $$inst | sed -e 's/^.*\///'`; \
|
||||
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
|
||||
echo " rm -f $(DESTDIR)$(man7dir)/$$inst"; \
|
||||
rm -f $(DESTDIR)$(man7dir)/$$inst; \
|
||||
done
|
||||
|
||||
man8dir = $(mandir)/man8
|
||||
install-man8: $(man8_MANS) $(man_MANS)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(man8dir)
|
||||
@list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
|
||||
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
|
||||
for i in $$l2; do \
|
||||
case "$$i" in \
|
||||
*.8*) list="$$list $$i" ;; \
|
||||
esac; \
|
||||
done; \
|
||||
for i in $$list; do \
|
||||
if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
|
||||
else file=$$i; fi; \
|
||||
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
|
||||
case "$$ext" in \
|
||||
8*) ;; \
|
||||
*) ext='8' ;; \
|
||||
esac; \
|
||||
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
|
||||
inst=`echo $$inst | sed -e 's/^.*\///'`; \
|
||||
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
|
||||
echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \
|
||||
$(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \
|
||||
done
|
||||
uninstall-man8:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
|
||||
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
|
||||
for i in $$l2; do \
|
||||
case "$$i" in \
|
||||
*.8*) list="$$list $$i" ;; \
|
||||
esac; \
|
||||
done; \
|
||||
for i in $$list; do \
|
||||
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
|
||||
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
|
||||
inst=`echo $$inst | sed -e 's/^.*\///'`; \
|
||||
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
|
||||
echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \
|
||||
rm -f $(DESTDIR)$(man8dir)/$$inst; \
|
||||
done
|
||||
tags: TAGS
|
||||
TAGS:
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
top_distdir = ..
|
||||
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@list='$(DISTFILES)'; for file in $$list; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
dir="/$$dir"; \
|
||||
$(mkinstalldirs) "$(distdir)$$dir"; \
|
||||
else \
|
||||
dir=''; \
|
||||
fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
|
||||
fi; \
|
||||
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(MANS)
|
||||
|
||||
installdirs:
|
||||
$(mkinstalldirs) $(DESTDIR)$(man1dir) $(DESTDIR)$(man7dir) $(DESTDIR)$(man8dir)
|
||||
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-libtool clean-local mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
|
||||
distclean-am: clean-am distclean-generic distclean-libtool
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am: install-man
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-man: install-man1 install-man7 install-man8
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
|
||||
|
||||
uninstall-am: uninstall-info-am uninstall-man
|
||||
|
||||
uninstall-man: uninstall-man1 uninstall-man7 uninstall-man8
|
||||
|
||||
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
|
||||
clean-local distclean distclean-generic distclean-libtool \
|
||||
distdir dvi dvi-am info info-am install install-am install-data \
|
||||
install-data-am install-exec install-exec-am install-info \
|
||||
install-info-am install-man install-man1 install-man7 \
|
||||
install-man8 install-strip installcheck installcheck-am \
|
||||
installdirs maintainer-clean maintainer-clean-generic \
|
||||
mostlyclean mostlyclean-generic mostlyclean-libtool uninstall \
|
||||
uninstall-am uninstall-info-am uninstall-man uninstall-man1 \
|
||||
uninstall-man7 uninstall-man8
|
||||
|
||||
|
||||
%.1: %.man
|
||||
sed -e "s/##VERSION##/$(VERSION)/g;s/##DATE##/`date`/g" \
|
||||
$< > $@
|
||||
|
||||
%.7: %.man
|
||||
sed -e "s/##VERSION##/$(VERSION)/g;s/##DATE##/`date`/g" \
|
||||
$< > $@
|
||||
|
||||
%.8: %.man
|
||||
sed -e "s/##VERSION##/$(VERSION)/g;s/##DATE##/`date`/g" \
|
||||
$< > $@
|
||||
|
||||
clean-local:
|
||||
rm -f *.1 *.7 *.8
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
@ -0,0 +1,72 @@
|
||||
0 Introduction
|
||||
--------------
|
||||
|
||||
This version of gsmlib contains national language support (NLS) using
|
||||
the GNU (or OS-supplied) gettext library. gettext eases the handling
|
||||
of translations of (usually english) output messages to other
|
||||
languages by introducing the concept of message catalogs.
|
||||
|
||||
Message catalogs can exist in various formats. The human-readable and
|
||||
-editable format is the PO file format. I have written a PO-file for
|
||||
the german language (de.po). These human-readable files are then
|
||||
translated to MO files which can be used by the gettext library.
|
||||
|
||||
Please refer to the GNU gettext documentation (at the time of this
|
||||
writing gettext-0.10) for further details.
|
||||
|
||||
|
||||
1 Compiling gsmlib with localized messages
|
||||
------------------------------------------
|
||||
|
||||
Gsmlib is compiled by default with NLS enabled. If you don't want
|
||||
NLS invoke configure with the option
|
||||
|
||||
./configure --disable-nls
|
||||
|
||||
|
||||
2 Adding new message dialogs
|
||||
----------------------------
|
||||
|
||||
1. Edit the ALL_LINGUAS line in "source/configure.in" and add your
|
||||
language, eg. French:
|
||||
|
||||
ALL_LINGUAS="de fr"
|
||||
|
||||
2. Execute "autoconf" to create a new "configure" script (possible
|
||||
problem: incompatible "autoconf")
|
||||
|
||||
3. Now issue "./configure" in the "sources" directory.
|
||||
|
||||
4. go to the "po" subdirectory
|
||||
|
||||
5. do a "touch fr.po" to create an initially empty PO-file.
|
||||
|
||||
6. do a "make update-po". This extracts all the strings from the files
|
||||
listed in "POTFILES" and puts them with empty translations into "fr.po"
|
||||
(it also updates existing po-Files such as "de.po").
|
||||
|
||||
7. Now use the editor of your choice to provide translations in
|
||||
"fr.po". There is an emacs major mode (po-mode) that eases this
|
||||
process.
|
||||
|
||||
8. now issue "make". This causes an "fr.mo" to be created.
|
||||
|
||||
|
||||
3 Adding new strings to gsmlib source code
|
||||
------------------------------------------
|
||||
|
||||
1. If you add new strings to the gsmlib source code that need
|
||||
translation enclose them with "_(" and ")" (see gettext documentation
|
||||
for special cases).
|
||||
|
||||
2. go to the "po" directory.
|
||||
|
||||
3. do a "make update-po". This updates all existing PO-files (removing
|
||||
obsolete translations, providing new, emptry entries).
|
||||
|
||||
4. Provide translations for the new, empty entries (ideally using
|
||||
emacs po-mode)
|
||||
|
||||
5. now issue "make". This causes up-to-date MO-files to be created.
|
||||
|
||||
|
@ -0,0 +1,138 @@
|
||||
OVERVIEW
|
||||
|
||||
The GSM library is written in C++ and uses the latest C++
|
||||
features: namespaces, exceptions, the standard template library.
|
||||
|
||||
The actual library source code is in the gsmlib subdirectory of
|
||||
this distribution. The following modules are available:
|
||||
|
||||
gsm_alloca.h OS-specific alloca defines
|
||||
gsm_at.h Utility classes for AT command sequence handling
|
||||
gsm_error.h Error codes and error handling functions
|
||||
gsm_event.h Event handler interface
|
||||
gsm_me_ta.h Mobile Equipment/Terminal Adapter and SMS functions
|
||||
(ETSI GSM 07.07 and 07.05)
|
||||
gsm_parser.h Parser to parse MA/TA result strings
|
||||
gsm_phonebook.h Phonebook management functions
|
||||
gsm_port.h Abstract port definition
|
||||
gsm_sms.h SMS functions (ETSI GSM 07.05)
|
||||
gsm_sms_codec.h Coder and Encoder for SMS TPDUs
|
||||
gsm_sms_store.h SMS functions, SMS store (ETSI GSM 07.05)
|
||||
gsm_sorted_phonebook.h Alphabetically sorted phonebook
|
||||
(residing in files or in the ME)
|
||||
gsm_sorted_sms_store.h Sorted SMS store
|
||||
(sorted by address, time or type)
|
||||
(residing in files or in the ME)
|
||||
gsm_unix_serial.h UNIX serial port implementation
|
||||
gsm_util.h Various utilities
|
||||
|
||||
|
||||
REQUIREMENTS
|
||||
|
||||
I have used egcs-1.1.2 and libstdc++.so.2.8.0 for compiling the
|
||||
library and all programs. Older probably don't work because of
|
||||
missing features.
|
||||
|
||||
|
||||
AVAILABLE DOCUMENTATION
|
||||
|
||||
If you want to do your own programming using the GSM library please
|
||||
refer to the extensively documented header files or to the example
|
||||
programs in the test or apps subdirectory.
|
||||
|
||||
I have used the following documentation to develop this software:
|
||||
|
||||
gts_gsm_02.30_v5.2.0.pdf
|
||||
gts_gsm_03.40_v5.3.0.pdf
|
||||
gts_gsm_04.11_v5.1.0.pdf
|
||||
gts_gsm_02.82_v5.0.0.pdf
|
||||
gts_gsm_03.41_v5.2.0.pdf
|
||||
gts_gsm_07.05_v5.3.0.pdf
|
||||
gts_gsm_03.38_v5.3.0.pdf
|
||||
gts_gsm_04.08_v5.1.0.pdf
|
||||
gts_gsm_07.07_v5.0.0.pdf
|
||||
|
||||
Due to copyright reasons I cannot include this documentation in
|
||||
this distribution. You can download it from the ETSI website
|
||||
(www.etsi.org) for free, though.
|
||||
|
||||
|
||||
COMPILATION
|
||||
|
||||
The code is automatically compiled without debugging code enabled
|
||||
(mostly assert()'s).
|
||||
|
||||
If there are any problems you can generate a debug version
|
||||
by issuing
|
||||
|
||||
CXXFLAGS="-g" ./configure --disable-shared
|
||||
|
||||
To switch on asserts and additional debugging output change the line
|
||||
|
||||
CXXFLAGS="-DNEBUG $CXXFLAGS"
|
||||
|
||||
in configure.in do
|
||||
|
||||
dnl CXXFLAGS="-DNEBUG $CXXFLAGS"
|
||||
|
||||
Then regenerate configure by executing autoconf.
|
||||
|
||||
You must use at least gcc-2.95.2 to compile gsmlib successfully.
|
||||
|
||||
|
||||
TESTS
|
||||
|
||||
The tests directory contains a number of software tests. Two kinds
|
||||
of test programs are provided: Those, that run without a mobile
|
||||
phone and those that require a mobile phone to be connected to a
|
||||
serial port.
|
||||
|
||||
No access to mobile phone needed:
|
||||
runparser.sh Test the parser for AT responses
|
||||
runsms.sh Test SMS message encoding and decoding routines
|
||||
runspb.sh Test sorted phonebook module
|
||||
runssms.sh Test sorted SMS store module
|
||||
|
||||
Give mobile phone device as argument:
|
||||
testsms2 Manipulate SMS store in the mobile phone (read/write)
|
||||
testgsmlib Test the gsm_me_ta module (readonly)
|
||||
testpb Dump all phonebooks in the mobile phone to the stdout
|
||||
(readonly)
|
||||
testpb2 Manipulate phonebook in the mobile phone (read/write)
|
||||
|
||||
The tests that do not require a mobile phone can be executed by
|
||||
issuing "make check" in the tests subdirectory. The others must be
|
||||
invoked manually. WARNING: These tests alter the contents of the
|
||||
mobile phone's phonebook or SMS message memory!!! Make sure, that
|
||||
you understand what the test does and be prepared for loss of data in
|
||||
the mobile phone.
|
||||
|
||||
HINTS
|
||||
|
||||
- By default gsmlib is compiled with NDEBUG set. There are lots
|
||||
of assert()s all over the library that may help to find problems
|
||||
in programs that use the library. Disable NDEBUG to get best
|
||||
debugging support.
|
||||
|
||||
CUSTOM BACKENDS
|
||||
|
||||
gsmlib now allows custom backends to be defined for sorted phonebooks
|
||||
and sorted SMS stores. This can be used to store phonebook entries in
|
||||
relational databases or LDAP servers. The interfaces are defined in
|
||||
gsm_sorted_phonebook_base.h and gsm_sorted_sms_store_base.h,
|
||||
respectively.
|
||||
|
||||
To register a custom backend (eg. for sorted phonebooks) follow
|
||||
these steps:
|
||||
|
||||
1. Define a subclass of CustomPhonebookFactory.
|
||||
|
||||
2. Define a static initializer class in your module that uses the
|
||||
interface CustomPhonebookRegistry::registerCustomPhonebookFactory()
|
||||
to make your custom backend available.
|
||||
|
||||
3. Link your module to any application that should use your custom
|
||||
backend. The gsmpb and gsmsmsstore programs are prepared to use the
|
||||
CustomPhonebookRegistry class to obtain your custom backend
|
||||
objects.
|
||||
|
@ -0,0 +1,683 @@
|
||||
.TH GSMCTL 8 "##DATE##" "gsmctl v##VERSION##"
|
||||
.SH NAME
|
||||
gsmctl, gsmsiectl \- GSM mobile phone control program
|
||||
.SH SYNOPSIS
|
||||
.B gsmctl
|
||||
.RB [\| \-b
|
||||
.IR baudrate \|]
|
||||
.RB [\| \-\-baudrate
|
||||
.IR baudrate\| ]
|
||||
.RB [ \|\-d
|
||||
.IR device\| ]
|
||||
.RB [ \|\-\-device
|
||||
.IR device\fP ]
|
||||
.RB [ \|\-h\| ]
|
||||
.RB [ \|\-\-help\| ]
|
||||
.RB [ \|\-I
|
||||
.IR "init string" \|]
|
||||
.RB [ \|\-\-init
|
||||
.IR "init string" \|]
|
||||
.RB [ \|\-v\| ]
|
||||
.RB [ \|\-\-version\| ]
|
||||
.RB [ \|\-X\| ]
|
||||
.RB [ \|\-\-xonxoff\| ]
|
||||
.BI \-o \ operation
|
||||
.RB | \ \-\-operation
|
||||
.IR operation \ |
|
||||
.I parameters
|
||||
.PP
|
||||
.B gsmsiectl
|
||||
.RB [\| \-b
|
||||
.IR baudrate \|]
|
||||
.RB [\| \-\-baudrate
|
||||
.IR baudrate\| ]
|
||||
.RB [ \|\-d
|
||||
.IR device\| ]
|
||||
.RB [ \|\-\-device
|
||||
.IR device\fP ]
|
||||
.RB [ \|\-h\| ]
|
||||
.RB [ \|\-\-help\| ]
|
||||
.RB [ \|\-I
|
||||
.IR "init string" \|]
|
||||
.RB [ \|\-\-init
|
||||
.IR "init string" \|]
|
||||
.RB [ \|\-v\| ]
|
||||
.RB [ \|\-\-version\| ]
|
||||
.RB [ \|\-X\| ]
|
||||
.RB [ \|\-\-xonxoff\| ]
|
||||
.BI \-o \ operation
|
||||
.RB | \ \-\-operation
|
||||
.IR operation \ |
|
||||
.I parameters
|
||||
.SH DESCRIPTION
|
||||
.B gsmctl
|
||||
can request information from or perform operations on an GSM mobile
|
||||
phone.
|
||||
.PP
|
||||
.B gsmctl
|
||||
attaches itself to the
|
||||
.I device
|
||||
given on the command line (usually an GSM modem) using the specified
|
||||
.IR baudrate .
|
||||
If no
|
||||
.I device
|
||||
is given, the device
|
||||
.I /dev/mobilephone
|
||||
is used. If no
|
||||
.I baudrate
|
||||
is given, a default baud rate of 38400 is used.
|
||||
.PP
|
||||
.B gsmctl
|
||||
can be used in to modes: If no
|
||||
.B \-\-operation
|
||||
option is given the
|
||||
.I parameters
|
||||
specify the status information to be retrieved from
|
||||
the mobile phone. See the section
|
||||
.B STATUS INFORMATION
|
||||
for more details. If an
|
||||
.B \-\-operation
|
||||
option is given the requested
|
||||
.I operation
|
||||
is performed on the mobile using the
|
||||
.IR parameters .
|
||||
See the section
|
||||
.B OPERATIONS
|
||||
for more details.
|
||||
.PP
|
||||
.B gsmsiectl
|
||||
is the same program with some extension for Siemens mobile phones.
|
||||
Some extra
|
||||
.B OPERATIONS
|
||||
are available in this case.
|
||||
.PP
|
||||
Error messages are printed to the standard error output. If the
|
||||
program terminates on error the error code 1 is returned.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BI \-b\ baudrate ,\ \-\-baudrate\ baudrate
|
||||
The baud rate to use. Defaults to 38400.
|
||||
.TP
|
||||
.BI \-d\ device ,\ \-\-device\ device
|
||||
The device to which the GSM modem is connected. The default is
|
||||
.IR /dev/mobilephone .
|
||||
.TP
|
||||
.B \-h,\ \-\-help
|
||||
Prints an option summary.
|
||||
.TP
|
||||
.BI \-I\ "init string" ,\ \-\-init\ "init string"
|
||||
Initialization string to send to the TA (default: "E0"). Note that the
|
||||
sequence "ATZ" is sent first.
|
||||
.TP
|
||||
.BI \-o\ operation ,\ \-\-operation\ operation
|
||||
This option is used to perform an operation on the mobile phone. Refer
|
||||
to the section
|
||||
.B OPERATIONS
|
||||
for more information on the available
|
||||
operations and the
|
||||
.I parameters
|
||||
required for each operation.
|
||||
.TP
|
||||
.B \-v,\ \-\-version
|
||||
Prints the program version.
|
||||
.TP
|
||||
.B \-X,\ \-\-xonxoff
|
||||
Uses software handshaking (XON/XOFF) for accessing the device.
|
||||
.SH STATUS INFORMATION
|
||||
If called without the
|
||||
.B \-\-operation
|
||||
option
|
||||
.B gsmctl
|
||||
prints out default mobile phone status information as specified by the
|
||||
.I parameters
|
||||
described below:
|
||||
.TP 7
|
||||
.B ALL
|
||||
Prints all available information.
|
||||
.TP 7
|
||||
.B BATT
|
||||
Prints out information about the current battery status. Two lines of
|
||||
the form "<BATT0> text" and "<BATT1> charge" are printed. Text may be
|
||||
of "0 ME is powered by the battery", "1 ME has a battery connected,
|
||||
but is not powered by it", "2 ME does not have a battery connected",
|
||||
or "3 Recognized power fault, calls inhibited". Charge is a number in
|
||||
the range 0..100 where 0 means that the battery is empty or not
|
||||
connected and 100 means full charge.
|
||||
.TP 7
|
||||
.B BITERR
|
||||
Prints information about the current bit error rate. The output is of
|
||||
form "<BITERR0> value" where value can be of 0..7, 99 (99 means not
|
||||
available or not detectable).
|
||||
.TP 7
|
||||
.B CLIP
|
||||
This option prints a line of the form "<CLIP0> on" if caller line
|
||||
identification is turned on in the network, "<CLIP0> off" otherwise.
|
||||
.TP 7
|
||||
.B CSET
|
||||
Display info about charsets. The output is in the form "<CSET0>
|
||||
available" and "<CSET1> current", which describes the charsets
|
||||
available and which is current.
|
||||
.TP 7
|
||||
.B CURROP
|
||||
Prints information about the current operator. The output line has the
|
||||
form "<CURROP0> Long name: \'xxxx\' Short name: \'yyyy\' Numeric Name: zzzz".
|
||||
.TP 7
|
||||
.B FLCAP
|
||||
Prints out the two-letter names of available facility locks. The
|
||||
meaning of standardized facility lock names is as follows:
|
||||
.RS
|
||||
.TP 3
|
||||
.I CS
|
||||
Lock control surface (eg. phone keyboard)
|
||||
.TP 3
|
||||
.I PS
|
||||
Lock phone to SIM card (mobile phone asks password when other than
|
||||
current SIM card inserted)
|
||||
.TP 3
|
||||
.I SC
|
||||
Lock SIM card (SIM asks password in mobile phone power-up and when
|
||||
this lock command issued)
|
||||
.TP 3
|
||||
.I AO
|
||||
Barr all outgoing calls
|
||||
.TP 3
|
||||
.I OI
|
||||
Barr outgoing international calls
|
||||
.TP 3
|
||||
.I OX
|
||||
Barr outgoing international calls except to home country
|
||||
.TP 3
|
||||
.I AI
|
||||
Barr all incoming calls
|
||||
.TP 3
|
||||
.I IR
|
||||
Barr incoming calls when roaming outside the home country
|
||||
.TP 3
|
||||
.I NT
|
||||
Barr incoming calls from numbers not stored to TA memory
|
||||
.TP 3
|
||||
.I NM
|
||||
Barr incoming calls from numbers not stored to mobile phone memory
|
||||
.TP 3
|
||||
.I NS
|
||||
Barr incoming calls from numbers not stored to SIM memory
|
||||
.TP 3
|
||||
.I NA
|
||||
Barr incoming calls from numbers not stored in Any memory
|
||||
.TP 3
|
||||
.I AB
|
||||
All Barring services (FIXME)
|
||||
.TP 3
|
||||
.I AG
|
||||
All outGoing barring services (FIXME)
|
||||
.TP 3
|
||||
.I AC
|
||||
All inComing barring services (FIXME)
|
||||
.TP 3
|
||||
.I FD
|
||||
SIM fixed dialling memory feature (if PIN2 authentication has not been
|
||||
done during the current session, PIN2 is required as <passwd>)
|
||||
.PP
|
||||
Note that mobile phones may implement facility locks not documented
|
||||
here.
|
||||
.RE
|
||||
.TP 7
|
||||
.B FLSTAT
|
||||
Prints information about the status of facility locking in the mobile
|
||||
phone. For each facility a line of the form "<FLSTATn> \'facilityname\'
|
||||
classes" is printed. The classes may be "Voice", "Data", and/or "Fax"
|
||||
depending on the class for which the facility is enabled. If "unknown"
|
||||
is printed out this means that the TA is not able to report the
|
||||
status. If the facility is not enabled for any class, no class
|
||||
identifier is printed. See
|
||||
.B FLCAP
|
||||
for information about the available two-letter names of facility
|
||||
locks.
|
||||
.TP 7
|
||||
.B FORW
|
||||
Prints information about call forwarding enabled in the mobile
|
||||
phone. For each combination of reason (UnconditionalReason,
|
||||
MobileBusyReason, NoReplyReason, and NotReachableReason) and class
|
||||
(Voice, Data, and Fax) a line of the form "<FORWn.m> reason class
|
||||
number: xxx subaddr: yyy time: zzz" is printed. The time is the number
|
||||
of seconds to wait before forwarding in case of NoReplyReason.
|
||||
.TP 7
|
||||
.B ME
|
||||
Prints manufacturer, model, revision, and serial number of
|
||||
the mobile phone (ME = mobile equipment). Output lines are numbered from
|
||||
"<ME0>" to "<ME3>".
|
||||
.TP 7
|
||||
.B OP
|
||||
Prints information about the currently available mobile network
|
||||
operators. For each operator an output line of the form "<OPn> status
|
||||
Long name: \'xxxx\' Short name: \'yyyy\' Numeric name: zzz" is returned
|
||||
where status may be of:
|
||||
.RS
|
||||
.TP 10
|
||||
.I unknown
|
||||
The status of the operator is unknown.
|
||||
.TP
|
||||
.I current
|
||||
This is the currently selected operator.
|
||||
.TP
|
||||
.I available
|
||||
This operator is available for selection.
|
||||
.TP
|
||||
.I forbidden
|
||||
This operator is not available for selection, ie. not
|
||||
accessible with this SIM card.
|
||||
.RE
|
||||
.TP 7
|
||||
.B PIN
|
||||
Prints information about the current PIN status. The output is of
|
||||
form "<PIN0> status". Where status can be one of the following lines:
|
||||
.RS
|
||||
.TP 10
|
||||
.I READY
|
||||
ME is not pending for any password.
|
||||
.TP
|
||||
.I SIM PIN
|
||||
ME is waiting SIM PIN to be given.
|
||||
.TP
|
||||
.I SIM PUK
|
||||
ME is waiting SIM PUK to be given.
|
||||
.TP
|
||||
.I PH\-SIM PIN
|
||||
ME is waiting phone/-to/-SIM card password to be given.
|
||||
.TP
|
||||
.I PH/-FSIM PIN
|
||||
ME is waiting phone/-to/-very first SIM card password to be given.
|
||||
.TP
|
||||
.I PH/-FSIM PUK
|
||||
ME is waiting phone/-to/-very first SIM card unblocking password to be
|
||||
given.
|
||||
.TP
|
||||
.I SIM PIN2
|
||||
ME is waiting SIM PIN2 to be given.
|
||||
.TP
|
||||
.I SIM PUK2
|
||||
ME is waiting SIM PUK2 to be given.
|
||||
.TP
|
||||
.I PH/-NET PIN
|
||||
ME is waiting network personalisation password to be given.
|
||||
.TP
|
||||
.I PH/-NET PUK
|
||||
ME is waiting network personalisation unblocking password to be given.
|
||||
.TP
|
||||
.I PH/-NETSUB PIN
|
||||
ME is waiting network subset personalisation password to be given.
|
||||
.RE
|
||||
.TP 7
|
||||
.B PW
|
||||
Facilities in the mobile phone may be protected by passwords (ie. PINs
|
||||
or PUKs). This option prints out lines of the form "<PWn>
|
||||
\'facilityname\' len" for each facility for which a facility lock
|
||||
password exists. See
|
||||
.B FLCAP
|
||||
for information about the available two-letter names of facility
|
||||
locks.
|
||||
.TP 7
|
||||
.B SCA
|
||||
Reports the default SMS service centre address currently set in the
|
||||
mobile phone.
|
||||
.TP 7
|
||||
.B SIG
|
||||
Prints information about the current network signal
|
||||
strength. The output is of the form "<SIG0> value". Following values
|
||||
are possible:
|
||||
.TP
|
||||
.po +7
|
||||
.I 0
|
||||
-113 dBm or less
|
||||
.TP
|
||||
.I 1
|
||||
-111 dBm
|
||||
.TP
|
||||
.I 2...30
|
||||
-109... -53 dBm (in steps of 2 dBm)
|
||||
.TP
|
||||
.I 31
|
||||
-51 dBm or greater
|
||||
.TP
|
||||
.I 99
|
||||
not known or not detectable
|
||||
.PP
|
||||
.po
|
||||
.SH OPERATIONS
|
||||
.TP
|
||||
.BI dial\ number
|
||||
Dials
|
||||
.IR number .
|
||||
After dialling
|
||||
.B gsmctl
|
||||
waits for a <CR> keypress to terminate.
|
||||
.PP
|
||||
.B forw
|
||||
.IR mode\ reason\ number\ [\| facilityclass\| ]\ [ forwardtime ]
|
||||
.RS
|
||||
Changes the call forwarding behaviour in the network.
|
||||
.I mode
|
||||
can be any of:
|
||||
.RS 3
|
||||
.I disable
|
||||
Call forwarding is disabled.
|
||||
.PP
|
||||
.I enable
|
||||
Call forwarding is enabled. The call forwarding reason, number, and
|
||||
(optionally) forwardtime must be registered beforehand.
|
||||
.PP
|
||||
.I register
|
||||
This registers the call forwarding reason, number, and forwardtime in
|
||||
the network.
|
||||
.PP
|
||||
.I erase
|
||||
This is the counterpart to register. It erase the call forwarding info
|
||||
in the network.
|
||||
.RE
|
||||
.PP
|
||||
.I reason
|
||||
can be any of:
|
||||
.RS 3
|
||||
.I unconditional
|
||||
This applies to every call.
|
||||
.PP
|
||||
.I mobilebusy
|
||||
The mobile phone is busy.
|
||||
.PP
|
||||
.I noreply
|
||||
The call is not answered in \fIforwardtime\fP seconds.
|
||||
.PP
|
||||
.I notreachable
|
||||
Mobile phone cannot be reached (ie. switched off).
|
||||
.PP
|
||||
.I all
|
||||
This refers to all forwarding reasons.
|
||||
.PP
|
||||
.I allconditional
|
||||
This refers to all conditional forward reasons
|
||||
.RI ( mobilebusy ,\ noreply ,\ notreachable ).
|
||||
.RE
|
||||
.PP
|
||||
.I number
|
||||
is the number the incoming call is forwarded to. See the explanation
|
||||
for
|
||||
.I lock
|
||||
operation for the meaning of
|
||||
.IR facilityclass .
|
||||
The default for
|
||||
.I forwardtime
|
||||
is 20 seconds if omitted.
|
||||
.I forwardtime
|
||||
can be in the range 1..30.
|
||||
.RE
|
||||
.PP
|
||||
.TP
|
||||
.BI off
|
||||
Sets functionality level of the phone to 0 (low functionality). The
|
||||
effects of this command depend on the phone (eg. sets low power
|
||||
consumption).
|
||||
.PP
|
||||
.TP
|
||||
.BI on
|
||||
Sets functionality level of the phone to 1 (high functionality). The
|
||||
effects of this command depend on the phone.
|
||||
.PP
|
||||
.TP
|
||||
.BI pin\ pin
|
||||
Sets PIN code. Use
|
||||
.BI gsmctl\ pin
|
||||
to get the current pin status.
|
||||
.PP
|
||||
.B lock
|
||||
.IR facility\ [\| facilityclass \|]\ [\| passwd \|]
|
||||
.RS
|
||||
Locks the named facility. Use
|
||||
.BI gsmctl\ flcap
|
||||
to get a list of supported facilities. The
|
||||
.I facilityclass
|
||||
can be any of:
|
||||
.RS 3
|
||||
.I all
|
||||
Voice, data, and fax.
|
||||
.PP
|
||||
.I v\ vf\ vd\ f\ fd\ d
|
||||
Any combination of voice, data and fax.
|
||||
.RE
|
||||
.PP
|
||||
The default is \fIall\fP if \fIfacilityclass\fP is omitted. The
|
||||
\fIpasswd\fP is password for the facility. If no password is given
|
||||
this parameter can be omitted.
|
||||
.RE
|
||||
.PP
|
||||
.BI setop\ opmode\ numericname
|
||||
.RS
|
||||
Sets the current operator to
|
||||
.IR numericname .
|
||||
Use
|
||||
.BI gsmctl\ op
|
||||
to get a list of operators with their numeric codes.
|
||||
.I opmode
|
||||
can be any of:
|
||||
.RS 3
|
||||
.I automatic
|
||||
.PP
|
||||
.I manual
|
||||
.PP
|
||||
.I deregister
|
||||
Deregister from network.
|
||||
.PP
|
||||
.I manualautomatic
|
||||
If manual selection fails, automatic mode is entered.
|
||||
.RE
|
||||
.RE
|
||||
.PP
|
||||
.B setpw
|
||||
.IR facility\ [\| oldpasswd\| ]\ [\| newpasswd\| ]
|
||||
.RS
|
||||
Sets the password for the facility. If one of the passwords is omitted
|
||||
this means that the facility has no password protection. Passwords are
|
||||
PIN1, PIN2, PUK etc.
|
||||
.RE
|
||||
.TP
|
||||
.BI setsca\ service\ centre\ address
|
||||
Sets the default SMS service centre address.
|
||||
.PP
|
||||
.B unlock
|
||||
.IR facility\ [\| facilityclass\| ]\ [ \|passwd\| ]
|
||||
.RS
|
||||
This is the reverse operation to \fBlock\fP. See above for a
|
||||
description of the parameters.
|
||||
.RE
|
||||
.PP
|
||||
.B Extra operators for gsmsiectl:
|
||||
.PP
|
||||
.B cset
|
||||
.RS
|
||||
Charset info.
|
||||
.RE
|
||||
.PP
|
||||
.B pbook
|
||||
.RS
|
||||
Phone book info.
|
||||
.RE
|
||||
.PP
|
||||
.B signal
|
||||
.RS
|
||||
Signal tone info.
|
||||
.RE
|
||||
.PP
|
||||
.B ring
|
||||
.RS
|
||||
Ringing tone info.
|
||||
.RE
|
||||
.PP
|
||||
.B binary
|
||||
.RS
|
||||
Binary info.
|
||||
.RE
|
||||
.SH EXAMPLES
|
||||
The following invocation of
|
||||
.I gsmctl
|
||||
prints out all available status information for the mobile phone
|
||||
connected to
|
||||
.B /dev/mobilephone
|
||||
.PP
|
||||
.nf
|
||||
.IP "" 3
|
||||
gsmctl all
|
||||
.fi
|
||||
.PP
|
||||
The output could look like (lines edited to fit):
|
||||
.RS 3
|
||||
.PP
|
||||
.PD 0
|
||||
<ME0> Manufacturer: SIEMENS
|
||||
.HP
|
||||
<ME1> Model: S10
|
||||
.HP
|
||||
<ME2> Revision: 06
|
||||
.HP
|
||||
<ME3> Serial Number: 448058511817585
|
||||
.HP
|
||||
<OP0> Status: available Long name: 'D1/-TELEKOM' Short name: '' Numeric name: 26201
|
||||
.HP
|
||||
<OP1> Status: forbidden Long name: 'D2 PRIVAT' Short name: '' Numeric name: 26202
|
||||
.HP
|
||||
<CURROP0> Long name: 'D1/-TELEKOM' Short name: '' Numeric name: 26201 Mode: automatic
|
||||
.HP
|
||||
<FLSTAT0> 'CS'
|
||||
.HP
|
||||
<FLSTAT1> 'PS'
|
||||
.HP
|
||||
<FLSTAT2> 'SC' Voice Data Fax
|
||||
.HP
|
||||
<FLSTAT3> 'AO'
|
||||
.HP
|
||||
<FLSTAT4> 'OI'
|
||||
.HP
|
||||
<FLSTAT5> 'OX'
|
||||
.HP
|
||||
<FLSTAT6> 'AI'
|
||||
.HP
|
||||
<FLSTAT7> 'IR'
|
||||
.HP
|
||||
<FLCAP0> 'CS' 'PS' 'SC' 'AO' 'OI' 'OX' 'AI' 'IR' 'AB' 'AG' 'AC'
|
||||
.HP
|
||||
<PW0> 'PS' 8
|
||||
.HP
|
||||
<PW1> 'SC' 8
|
||||
.HP
|
||||
<PW2> 'AO' 4
|
||||
.HP
|
||||
<PW3> 'OI' 4
|
||||
.HP
|
||||
<PW4> 'OX' 4
|
||||
.HP
|
||||
<PW5> 'AI' 4
|
||||
.HP
|
||||
<PW6> 'IR' 4
|
||||
.HP
|
||||
<PW7> 'AB' 4
|
||||
.HP
|
||||
<PW8> 'AG' 4
|
||||
.HP
|
||||
<PW9> 'AC' 4
|
||||
.HP
|
||||
<CLIP0> on
|
||||
.HP
|
||||
<FORW0.0> UnconditionalReason Voice inactive number: subaddr: time: -1
|
||||
.HP
|
||||
<FORW0.1> UnconditionalReason Data inactive number: subaddr: time: -1
|
||||
.HP
|
||||
<FORW0.2> UnconditionalReason Fax inactive number: subaddr: time: -1
|
||||
.HP
|
||||
<FORW1.0> MobileBusyReason Voice active number: +494012345678 subaddr: time: -1
|
||||
.HP
|
||||
<FORW1.1> MobileBusyReason Data inactive number: subaddr: time: -1
|
||||
.HP
|
||||
<FORW1.2> MobileBusyReason Fax inactive number: subaddr: time: -1
|
||||
.HP
|
||||
<FORW2.0> NoReplyReason Voice active number: +494012345678 subaddr: time: 20
|
||||
.HP
|
||||
<FORW2.1> NoReplyReason Data inactive number: subaddr: time: -1
|
||||
.HP
|
||||
<FORW2.2> NoReplyReason Fax inactive number: subaddr: time: -1
|
||||
.HP
|
||||
<FORW3.0> NotReachableReason Voice active number: +494012345678 subaddr: time: -1
|
||||
.HP
|
||||
<FORW3.1> NotReachableReason Data inactive number: subaddr: time: -1
|
||||
.HP
|
||||
<FORW3.2> NotReachableReason Fax inactive number: subaddr: time: -1
|
||||
.HP
|
||||
<BATT0> 0 ME is powered by the battery
|
||||
.HP
|
||||
<BATT1> 100
|
||||
.HP
|
||||
<BITERR0> 0
|
||||
.HP
|
||||
<SIG0> 19
|
||||
.RE
|
||||
.PD
|
||||
.PP
|
||||
The following locks the keys on the mobile phone:
|
||||
.nf
|
||||
.IP "" 3
|
||||
gsmctl -o lock cs
|
||||
.fi
|
||||
.PP
|
||||
This changes the SIM card PIN from 1234 to 2345:
|
||||
.nf
|
||||
.IP "" 3
|
||||
gsmctl -o setpw sc 1234 2345
|
||||
.fi
|
||||
.PP
|
||||
Switch off all call forwarding (actually erase the numbers):
|
||||
.nf
|
||||
.IP "" 3
|
||||
gsmctl -o forw erase all
|
||||
.fi
|
||||
.PP
|
||||
Switch on call forwarding to German D1 voice box:
|
||||
.nf
|
||||
.IP "" 3
|
||||
gsmctl -o forw register notreachable 3313
|
||||
gsmctl -o forw enable notreachable
|
||||
.fi
|
||||
.PP
|
||||
.SH FILES
|
||||
.TP
|
||||
.B /dev/mobilephone
|
||||
Default mobile phone device.
|
||||
.SH AUTHOR
|
||||
Peter Hofmann <software@pxh.de>
|
||||
.SH BUGS
|
||||
Report bugs to software@pxh.de. Include a complete, self-ncontained
|
||||
example that will allow the bug to be reproduced, and say which
|
||||
version of \fIgsmctl\fP you are using.
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 1999 Peter Hofmann
|
||||
.PP
|
||||
.B gsmctl
|
||||
is free software; you can redistribute it and/or modify it under the
|
||||
terms of the GNU Library General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
.PP
|
||||
.B gsmctl
|
||||
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 Library General Public
|
||||
License for more details.
|
||||
.PP
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with
|
||||
.BR gsmctl ;
|
||||
see the file COPYING. If not, write to the Free Software Foundation,
|
||||
675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
.SH "SEE ALSO"
|
||||
.BR gsminfo (7),
|
||||
.BR gsmpb (1),
|
||||
.BR gsmsendsms (1),
|
||||
.BR gsmsmsd (8),
|
||||
.BR gsmsmsstore (1).
|
||||
|
@ -0,0 +1,56 @@
|
||||
.\" -*- eval: (nroff-mode) -*-
|
||||
.de TQ
|
||||
.br
|
||||
.ns
|
||||
.TP \\$1
|
||||
..
|
||||
.\" Like TP, but if specified indent is more than half
|
||||
.\" the current line-length - indent, use the default indent.
|
||||
.de Tp
|
||||
.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP
|
||||
.el .TP "\\$1"
|
||||
..
|
||||
.TH GSMINFO 7 "##DATE##" "gsmctl v##VERSION##"
|
||||
.PP
|
||||
.SH NAME
|
||||
gsminfo \- GSM general information
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
\fIgsmlib\fP is a library to access GSM mobile phones through GSM
|
||||
modems or via IrDA devices. In the \fIgsmlib\fP documentation and error
|
||||
messages the following abbreviations are used:
|
||||
.TP .7i
|
||||
\fBME\fP
|
||||
Mobile Equipment. The mobile phone, usually.
|
||||
.TP .7i
|
||||
\fBSC\fP
|
||||
Service Centre. In the context of this documentation, the center
|
||||
responsible for sending and relaying SMs.
|
||||
.TP .7i
|
||||
\fBSM\fP
|
||||
Short Message.
|
||||
.TP .7i
|
||||
\fBSME\fP
|
||||
Short Message Equipment. Usually the mobile phone.
|
||||
.TP .7i
|
||||
\fBTA\fP
|
||||
Terminal Adapter. This can be a GSM modem PC card or it can be
|
||||
integrated into the ME.
|
||||
.TP .7i
|
||||
\fBTE\fP
|
||||
Terminal Equipment. This is the device to which the TA is connected,
|
||||
usually the computer.
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
Peter Hofmann <software@pxh.de>
|
||||
.PP
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 1999 Peter Hofmann
|
||||
.PP
|
||||
.SH "SEE ALSO"
|
||||
.BR gsmctl(1),
|
||||
.BR gsmpb(1),
|
||||
.BR gsmsendsms(1),
|
||||
.BR gsmsmsd(8),
|
||||
.BR gsmsmsstore(1).
|
||||
|
@ -0,0 +1,20 @@
|
||||
Begin3
|
||||
Title: gsmlib
|
||||
Version: 1.0
|
||||
Entered-date: 29JUL99
|
||||
Description: This distribution contains a library to access
|
||||
GSM mobile phones through GSM modems. Features include:
|
||||
* modification of phonebooks stored in the
|
||||
mobile phone or on the SIM card
|
||||
* reading and writing of SMS messages stored in
|
||||
the mobile phone
|
||||
* sending and reception of SMS messages
|
||||
Additionally, some simple command line programs are
|
||||
provided to use these functionalities.
|
||||
Keywords: gsm mobile phone modem sms
|
||||
Author: Peter Hofmann <software@pxh.de>
|
||||
Maintained-by: Peter Hofmann <software@pxh.de>
|
||||
Primary-site: http://www.pxh.de/fs/gsmlib/
|
||||
Platforms: Linux
|
||||
Copying-policy: LGPL
|
||||
End
|
@ -0,0 +1,245 @@
|
||||
.\" -*- eval: (nroff-mode) -*-
|
||||
.de TQ
|
||||
.br
|
||||
.ns
|
||||
.TP \\$1
|
||||
..
|
||||
.\" Like TP, but if specified indent is more than half
|
||||
.\" the current line-length - indent, use the default indent.
|
||||
.de Tp
|
||||
.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP
|
||||
.el .TP "\\$1"
|
||||
..
|
||||
.TH GSMPB 8 "##DATE##" "gsmpb v##VERSION##"
|
||||
.SH NAME
|
||||
gsmpb \- GSM mobile phone phonebook manipulation program
|
||||
.SH SYNOPSIS
|
||||
.B gsmpb
|
||||
[ \fB\-b\fP \fIbaudrate\fP ]
|
||||
[ \fB\-\-baudrate\fP \fIbaudrate\fP ]
|
||||
[ \fB\-c\fP ]
|
||||
[ \fB\-\-copy\fP ]
|
||||
[ \fB\-d\fP \fIdestination device or file\fP ]
|
||||
[ \fB\-\-destination\fP \fIdestination device or file\fP ]
|
||||
[ \fB\-h\fP ]
|
||||
[ \fB\-\-help\fP ]
|
||||
[ \fB\-i\fP ]
|
||||
[ \fB\-\-index\fP ]
|
||||
[ \fB\-I\fP \fIinit string\fP ]
|
||||
[ \fB\-\-init\fP \fIinit string\fP ]
|
||||
[ \fB\-p\fP \fIphonebook name\fP ]
|
||||
[ \fB\-\-phonebook\fP \fIphonebook name\fP ]
|
||||
[ \fB\-s\fP \fIsource device or file\fP ]
|
||||
[ \fB\-\-source\fP \fIsource device or file\fP ]
|
||||
[ \fB\-t\fP \fIcharacter set\fP ]
|
||||
[ \fB\-\-charset\fP \fIcharacter set\fP ]
|
||||
[ \fB\-v\fP ]
|
||||
[ \fB\-\-version\fP ]
|
||||
[ \fB\-V\fP ]
|
||||
[ \fB\-\-verbose\fP ]
|
||||
[ \fB\-X\fP ]
|
||||
[ \fB\-\-xonxoff\fP ]
|
||||
[ \fB\-y\fP ]
|
||||
[ \fB\-\-synchronize\fP ]
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
\fIgsmpb\fP can store or retrieve phonebook entries residing in a GSM
|
||||
mobile phone's phonebook to or from a file. A synchronization mode is
|
||||
also available.
|
||||
.PP
|
||||
\fIgsmpb\fP reads entries from the source which can be a mobile phone
|
||||
(if a serial device file is given) or a file (if a file name is
|
||||
given). The source is never modified. \fIgsmpb\fP writes phonebook
|
||||
entries to a destination file or device. Depending on the mode the
|
||||
source is copied to the destination file, thus overwriting the
|
||||
destination, or the destination is synchronized with regard to the
|
||||
source which is the default (details see below).
|
||||
.PP
|
||||
If "\-" is given as the parameter for the \fB\-\-source\fP or
|
||||
\fB\-\-destination\fP options, the phonebook is read from standard input
|
||||
and/or written to standard output, respectively.
|
||||
.PP
|
||||
Phonebook entries names are encoded using the GSM default alphabet in
|
||||
the mobile phone, whereas they are stored using the Latin\-1 encoding
|
||||
in phonebook files. When reading phonebook entries from a mobile phone
|
||||
entry names are converted from the GSM default to Latin\-1. Characters
|
||||
that can not be converted to Latin\-1 are encoded as character code
|
||||
172 (Latin\-1 boolean "not"). When writing file-based phonebook entries
|
||||
to a mobile phone a conversion to the GSM default alphabet takes
|
||||
place. Characters that can not be converted are encoded as GSM delta
|
||||
(code 16). If the default character set has been changed using the
|
||||
\fB\-\-charset\fP option no conversion takes place.
|
||||
.PP
|
||||
Error messages are printed to the standard error output. If the program
|
||||
terminates on error the error code 1 is returned.
|
||||
.PP
|
||||
.SH OPTIONS
|
||||
.TP .7i
|
||||
\fB\-b\fP \fIbaudrate\fP, \fB\-\-baudrate\fP \fIbaudrate\fP
|
||||
The baud rate to use. The default baudrate is 38400.
|
||||
.TP .7i
|
||||
\fB\-c\fP, \fB\-\-copy\fP
|
||||
This causes the contents of the source to be copied to the
|
||||
destination. After this operation the destination has exactly the same
|
||||
contents as the source.
|
||||
.TP .7i
|
||||
\fB\-d\fP \fIdestination\fP, \fB\-\-destination\fP \fIdestination\fP
|
||||
The destination device or file.
|
||||
.TP .7i
|
||||
\fB\-h\fP, \fB\-\-help\fP
|
||||
Prints an option summary.
|
||||
.TP .7i
|
||||
\fB\-I\fP \fIinit string\fP, \fB\-\-init\fP \fIinit string\fP
|
||||
Initialization string to send to the TA (default: "E0"). Note that the
|
||||
sequence "ATZ" is sent first.
|
||||
.TP .7i
|
||||
\fB\-i\fP, \fB\-\-index\fP
|
||||
If the index position is given, \fIgsmpb\fP preserves the assignment
|
||||
of entries to memory slots in the mobile phone's phonebook. This can
|
||||
be used to backup phonebook entries with their position into a
|
||||
phonebook file or to change the position of entries by editing a
|
||||
phonebook file and writing them back to the mobile phone.
|
||||
If this option is given the phonebook file used as the source
|
||||
must contain indices for every entry. Additionally, these indices must
|
||||
be unique, ie. it is not allowed to assign one entry twice to a
|
||||
specific position in the mobile phone's phonebook.
|
||||
.TP .7i
|
||||
\fB\-p\fP \fIphonebook\fP, \fB\-\-phonebook\fP \fIphonebook\fP
|
||||
The name of the phonebook to read from or write to. This is only used
|
||||
for device sources and destinations. Commonly available phonebooks
|
||||
are:
|
||||
.TP .3i
|
||||
.po +0.7i
|
||||
.ll 5.8i
|
||||
\fIFD\fP
|
||||
SIM fixdialling\-phonebook
|
||||
.TP .3i
|
||||
\fILD\fP
|
||||
SIM last\-dialling\-phonebook
|
||||
.TP .3i
|
||||
\fIME\fP
|
||||
ME phonebook
|
||||
.TP .3i
|
||||
\fIMT\fP
|
||||
combined ME and SIM phonebook
|
||||
.TP .3i
|
||||
\fISM\fP
|
||||
SIM phonebook
|
||||
.TP .3i
|
||||
\fITA\fP
|
||||
TA phonebook
|
||||
.TP .7i
|
||||
.po -0.7i
|
||||
.ll 6.5i
|
||||
\fB\-s\fP \fIsource\fP, \fB\-\-source\fP \fIsource\fP
|
||||
The source device or file.
|
||||
.TP
|
||||
\fB\-t\fP \fIcharacter set\fP, \fB\-\-charset\fP \fIcharacter set\fP
|
||||
Set the character set to use for phonebook operations (default is the
|
||||
GSM default alphabet).
|
||||
.TP
|
||||
\fB\-v\fP, \fB\-\-version\fP
|
||||
Prints the program version.
|
||||
.TP .7i
|
||||
\fB\-V\fP, \fB\-\-verbose\fP
|
||||
Prints out a detailed progress report.
|
||||
.TP .7i
|
||||
\fB\-X\fP, \fB\-\-xonxoff\fP
|
||||
Uses software handshaking (XON/XOFF) for accessing the device.
|
||||
.TP .7i
|
||||
\fB\-y\fP, \fB\-\-synchronize\fP
|
||||
This causes the contents of the source to be synchronized with the
|
||||
destination (default). Synchronization in this context means:
|
||||
.TP .2i
|
||||
.po +0.7i
|
||||
.ll 5.8i
|
||||
\-
|
||||
If the source contains an entry with a name that does not exist in the
|
||||
destination this entry is added to the destination.
|
||||
.TP .2i
|
||||
\-
|
||||
If the source contains an entry with a name that can also be found in
|
||||
the destination, the entry in the destination is overwritten (ie. the
|
||||
telephone number is updated). Exception: More then one entry with the
|
||||
name exists in the destination. In this case the new entry ist just added.
|
||||
.TP .2i
|
||||
\-
|
||||
Entries in the destination that do not exist in the source are
|
||||
deleted.
|
||||
.PP
|
||||
Note that synchronization has the following properties that differ
|
||||
from copying: This algorithm does not change the location of unchanged
|
||||
entries in the destination phonebook. The synchronization function
|
||||
is not case-sensitive when comparing names.
|
||||
.PP
|
||||
.po -0.7i
|
||||
.ll 6.5i
|
||||
.SH PHONEBOOK FILE FORMAT
|
||||
Phonebook entries are stored in phonebook files that are meant to be
|
||||
human-readable and -editable. There is one phonebook entry per line,
|
||||
and each line has the format:
|
||||
.PP
|
||||
.nf
|
||||
index|text|phone number
|
||||
.fi
|
||||
.PP
|
||||
The fields have the following meanings:
|
||||
.TP .7i
|
||||
\fIindex\fP
|
||||
The index of the entry which must be a positive number. The index may
|
||||
also be empty. Indices can be used in conjunction with the
|
||||
\fB\-\-index\fP option to store the entry into a specific position in
|
||||
the mobile phone.
|
||||
.TP .7i
|
||||
\fItext\fP
|
||||
Descriptive text for the entry. The text may contain the special
|
||||
characters '\\', '|', carriage return (ASCII code 13), or line feed
|
||||
(ASCII code 10). These must be written "\\\\", "\\|", "\\r", "\\n",
|
||||
respectively. The text should only contain characters that can be
|
||||
encoded using the GSM default alphabet (see comments above).
|
||||
.TP .7i
|
||||
\fIphone number\fP
|
||||
Phone numbers can only contains the digits 0\-9 and the '+' sign. A '+'
|
||||
sign denotes an international number.
|
||||
.PP
|
||||
.SH EXAMPLES
|
||||
The following invocation of \fIgsmpb\fP synchronizes the mobile phone's
|
||||
SIM phonebook with the file $HOME/.phonebook:
|
||||
.PP
|
||||
.nf
|
||||
gsmpb \-\-synchronize \-b 19200 \-d /dev/mobilephone \\
|
||||
\-s $HOME/.phonebook \-p "SM"
|
||||
.fi
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
Peter Hofmann <software@pxh.de>
|
||||
.PP
|
||||
.SH BUGS
|
||||
Report bugs to software@pxh.de. Include a complete, self-contained
|
||||
example that will allow the bug to be reproduced, and say which
|
||||
version of \fIgsmpb\fP you are using.
|
||||
.PP
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 1999 Peter Hofmann
|
||||
.LP
|
||||
\fIgsmpb\fP is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Library General Public License as published by the Free
|
||||
Software Foundation; either version 2, or (at your option) any later
|
||||
version.
|
||||
.LP
|
||||
\fIgsmpb\fP 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 Library General Public License
|
||||
for more details.
|
||||
.LP
|
||||
You should have received a copy of the GNU Library General Public License along
|
||||
with \fIgsmpb\fP; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
.PP
|
||||
.SH "SEE ALSO"
|
||||
.BR gsminfo(7),
|
||||
.BR gsmctl(1),
|
||||
.BR gsmsendsms(1),
|
||||
.BR gsmsmsd(8),
|
||||
.BR gsmsmsstore(1).
|
||||
|
@ -0,0 +1,154 @@
|
||||
.\" -*- eval: (nroff-mode) -*-
|
||||
.de TQ
|
||||
.br
|
||||
.ns
|
||||
.TP \\$1
|
||||
..
|
||||
.\" Like TP, but if specified indent is more than half
|
||||
.\" the current line-length - indent, use the default indent.
|
||||
.de Tp
|
||||
.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP
|
||||
.el .TP "\\$1"
|
||||
..
|
||||
.TH GSMSENDSMS 8 "##DATE##" "gsmsendsms v##VERSION##"
|
||||
.PP
|
||||
.SH NAME
|
||||
gsmsendsms \- SMS message sender utility
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
.B gsmsendsms
|
||||
[ \fB\-b\fP \fIbaudrate\fP ]
|
||||
[ \fB\-\-baudrate\fP \fIbaudrate\fP ]
|
||||
[ \fB\-c\fP \fIconcatenatedID\fP ]
|
||||
[ \fB\-\-concatenate\fP \fIconcatenatedID\fP ]
|
||||
[ \fB\-C\fP \fIservice centre address\fP ]
|
||||
[ \fB\-\-sca\fP \fIservice centre address\fP ]
|
||||
[ \fB\-d\fP \fIdevice\fP ]
|
||||
[ \fB\-\-device\fP \fIdevice\fP ]
|
||||
[ \fB\-h\fP ]
|
||||
[ \fB\-\-help\fP ]
|
||||
[ \fB\-I\fP \fIinit string\fP ]
|
||||
[ \fB\-\-init\fP \fIinit string\fP ]
|
||||
[ \fB\-r\fP ]
|
||||
[ \fB\-\-requeststat\fP ]
|
||||
[ \fB\-t\fP ]
|
||||
[ \fB\-\-test\fP ]
|
||||
[ \fB\-v\fP ]
|
||||
[ \fB\-\-version\fP ]
|
||||
[ \fB\-X\fP ]
|
||||
[ \fB\-\-xonxoff\fP ]
|
||||
\fIphonenumber\fP
|
||||
[ \fItext\fP ]
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
\fIgsmsendsms\fP sends SMS short messages using an GSM mobile phone.
|
||||
.PP
|
||||
\fIgsmsendsms\fP attaches itself to the \fIdevice\fP given on the command
|
||||
line (usually an GSM modem) using the specified \fIbaudrate\fP. If no
|
||||
\fIdevice\fP is given, the device \fI/dev/mobilephone\fP is used. If
|
||||
no \fIbaudrate\fP is given, a default baud rate of 38400 is used.
|
||||
.PP
|
||||
\fIgsmsendsms\fP accepts a phone number (recipient address) and the
|
||||
short message text as parameters. The text may have a maximum length
|
||||
of 160 characters which is the maximum SMS message length. The GSM
|
||||
default alphabet is used for encoding. ASCII and Latin\-1 characters
|
||||
that can not be encoded using the GSM default alphabet are converted
|
||||
to the GSM delta character (GSM code 16).
|
||||
.PP
|
||||
Error messages are printed to the standard error output. If the program
|
||||
terminates on error the error code 1 is returned.
|
||||
.PP
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-b\fP \fIbaudrate\fP, \fB\-\-baudrate\fP \fIbaudrate\fP
|
||||
The baud rate to use.
|
||||
.TP
|
||||
\fB\-c\fP \fIconcatenatedID\fP, \fB\-\-concatenate\fP \fIconcatenatedID\fP
|
||||
If an ID is given, large SMSs are split into several, concatenated
|
||||
SMSs. All SMSs have the same ID and are numbered consecutively so that
|
||||
the receiving phone can assemble them in the correct order. IDs must
|
||||
be in the range 0..255. Not all receiving phones will support
|
||||
concatenated SMSs (and display them as separate SMSs),
|
||||
since all the numbering and ID information is
|
||||
carried in the user data header element at the beginning of the SMS
|
||||
user data. This information may show up as garbage in such phones.
|
||||
.TP
|
||||
\fB\-C\fP \fIservice centre address\fP, \fB\-\-sca\fP \fIservice centre address\fP
|
||||
Sets the service centre address to use for all SUBMIT SMSs (may not
|
||||
work with some phones).
|
||||
.TP
|
||||
\fB\-d\fP \fIdevice\fP, \fB\-\-device\fP \fIdevice\fP
|
||||
The device to which the GSM modem is connected. The default is
|
||||
\fI/dev/mobilephone\fP.
|
||||
.TP
|
||||
\fB\-h\fP, \fB\-\-help\fP
|
||||
Prints an option summary.
|
||||
.TP
|
||||
\fB-I\fP \fIinit string\fP, \fB\-\-init\fP \fIinit string\fP
|
||||
Initialization string to send to the TA (default: "E0"). Note that the
|
||||
sequence "ATZ" is sent first.
|
||||
.TP
|
||||
\fB\-r\fP, \fB\-\-requeststat\fP
|
||||
Request status reports for sent SMS.
|
||||
.TP
|
||||
\fB\-t\fP, \fB\-\-test\fP
|
||||
If this option is given the text is converted
|
||||
to the GSM default alphabet and back to Latin\-1. This option can be
|
||||
used to find out how ASCII or Latin\-1 texts are converted to the GSM
|
||||
default alphabet. Characters that can not be converted to the GSM default
|
||||
alphabet are reported as ASCII code 172 (Latin\-1 boolean "not")
|
||||
after this double conversion. No SMS messages are sent, a connection
|
||||
to a mobile phone is not established.
|
||||
.TP
|
||||
\fB\-v\fP, \fB\-\-version\fP
|
||||
Prints the program version.
|
||||
.TP
|
||||
\fB\-X\fP, \fB\-\-xonxoff\fP
|
||||
Uses software handshaking (XON/XOFF) for accessing the device.
|
||||
.PP
|
||||
.SH EXAMPLES
|
||||
The following two invocations of \fIgsmsendsms\fP each send the same
|
||||
SMS message to the number "1234":
|
||||
.PP
|
||||
.nf
|
||||
gsmsendsms \-d /dev/ttyS2 \-b 19200 1234 "This is a test."
|
||||
echo "This is a test." | gsmsendsms \-d /dev/ttyS2 \-b 19200 1234
|
||||
.fi
|
||||
.PP
|
||||
.SH FILES
|
||||
.TP 1.4i
|
||||
.B /dev/mobilephone
|
||||
Default mobile phone device.
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
Peter Hofmann <software@pxh.de>
|
||||
.PP
|
||||
.SH BUGS
|
||||
Report bugs to software@pxh.de. Include a complete, self-contained
|
||||
example that will allow the bug to be reproduced, and say which
|
||||
version of \fIgsmsendsms\fP you are using.
|
||||
.PP
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 1999 Peter Hofmann
|
||||
.LP
|
||||
\fIgsmsendsms\fP is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Library General Public License as published by the Free
|
||||
Software Foundation; either version 2, or (at your option) any later
|
||||
version.
|
||||
.LP
|
||||
\fIgsmsendsms\fP 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
|
||||
Library General Public License for more details.
|
||||
.LP
|
||||
You should have received a copy of the GNU Library General Public License along
|
||||
with \fIgsmsendsms\fP; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
.PP
|
||||
.SH "SEE ALSO"
|
||||
.BR gsminfo(7),
|
||||
.BR gsmpb(1),
|
||||
.BR gsmctl(1),
|
||||
.BR gsmsmsd(8),
|
||||
.BR gsmsmsstore(1).
|
||||
|
@ -0,0 +1,269 @@
|
||||
.\" -*- eval: (nroff-mode) -*-
|
||||
.de TQ
|
||||
.br
|
||||
.ns
|
||||
.TP \\$1
|
||||
..
|
||||
.\" Like TP, but if specified indent is more than half
|
||||
.\" the current line-length - indent, use the default indent.
|
||||
.de Tp
|
||||
.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP
|
||||
.el .TP "\\$1"
|
||||
..
|
||||
.TH GSMSMSD 8 "##DATE##" "gsmsmsd v##VERSION##"
|
||||
.PP
|
||||
.SH NAME
|
||||
gsmsmsd \- SMS message reception daemon
|
||||
.PP
|
||||
.SH SYNOPSIS
|
||||
.B gsmsmsd
|
||||
[ \fB\-a\fP \fIaction\fP ]
|
||||
[ \fB\-\-action\fP \fIaction\fP ]
|
||||
[ \fB\-b\fP \fIbaudrate\fP ]
|
||||
[ \fB\-\-baudrate\fP \fIbaudrate\fP ]
|
||||
[ \fB\-c\fP \fIconcatenatedID\fP ]
|
||||
[ \fB\-\-concatenate\fP \fIconcatenatedID\fP ]
|
||||
[ \fB\-C\fP \fIservice centre address\fP ]
|
||||
[ \fB\-\-sca\fP \fIservice centre address\fP ]
|
||||
[ \fB\-d\fP \fIdevice\fP ]
|
||||
[ \fB\-\-device\fP \fIdevice\fP ]
|
||||
[ \fB\-D\fP ]
|
||||
[ \fB\-\-direct\fP ]
|
||||
[ \fB\-f\fP ]
|
||||
[ \fB\-\-flush\fP ]
|
||||
[ \fB\-h\fP ]
|
||||
[ \fB\-\-help\fP ]
|
||||
[ \fB\-I\fP \fIinit string\fP ]
|
||||
[ \fB\-\-init\fP \fIinit string\fP ]
|
||||
[ \fB\-r\fP ]
|
||||
[ \fB\-\-requeststat\fP ]
|
||||
[ \fB\-s\fP \fIspool directory\fP ]
|
||||
[ \fB\-\-spool\fP \fIspool directory\fP ]
|
||||
[ \fB\-t\fP \fISMS store name\fP ]
|
||||
[ \fB\-\-store\fP \fISMS store name\fP ]
|
||||
[ \fB\-v\fP ]
|
||||
[ \fB\-\-version\fP ]
|
||||
[ \fB\-X\fP ]
|
||||
[ \fB\-\-xonxoff\fP ]
|
||||
{ \fIsms_type\fP }
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
\fIgsmsmsd\fP reads new incoming SMS from the mobile phone and
|
||||
dispatches them to a user-defined action. Additionally it can send SMS
|
||||
message that it reads from a spooldir.
|
||||
.PP
|
||||
\fIgsmsmsd\fP attaches itself to the \fIdevice\fP given on the command
|
||||
line (usually an GSM modem) using the specified \fIbaudrate\fP and
|
||||
waits for incoming SMS messages. If no \fIdevice\fP is given, the
|
||||
device \fI/dev/mobilephone\fP is used. If no \fIbaudrate\fP is given, a
|
||||
default baud rate of 38400 is used.
|
||||
.PP
|
||||
If no action is given, the SMS message is printed to the standard
|
||||
output. If an \fIaction\fP is specified the \fIaction\fP is excecuted using the
|
||||
shell and the SMS message is written to the standard input of the action.
|
||||
.PP
|
||||
\fIgsmsmsd\fP needs one empty storage slot for SMS messages in the
|
||||
mobile phone, otherwise SMS reception will not work. The SMS store to
|
||||
use for temporary storage of incoming SMS can be selected using the
|
||||
\fB\-\-store\fP option, otherwise the ME default store is used.
|
||||
.PP
|
||||
To terminate \fIgsmsmsd\fP cleanly (without losing SMS messages) one
|
||||
should send either SIGINT (CTRL\-C on the command line) or SIGTERM to
|
||||
the process.
|
||||
.PP
|
||||
Error messages are printed to the standard error output. If the program
|
||||
terminates on error the error code 1 is returned.
|
||||
.PP
|
||||
\fIsms_type\fP may be any combination of:
|
||||
.TP
|
||||
\fIsms\fP, \fIno_sms\fP
|
||||
Controls reception of normal SMS messages.
|
||||
.TP
|
||||
\fIcb\fP, \fIno_cb\fP
|
||||
Controls reception of cell broadcast messages.
|
||||
.TP
|
||||
\fIstat\fP, \fIno_stat\fP
|
||||
Controls reception of status reports.
|
||||
.PP
|
||||
The default is \fIsms\fP, \fIcb\fP, and \fIstat\fP.
|
||||
.PP
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-a\fP \fIaction\fP, \fB\-\-action\fP \fIaction\fP
|
||||
The action to execute for each incoming SMS message. If no action
|
||||
is given the SMS is written to the standard output.
|
||||
.TP
|
||||
\fB\-b\fP \fIbaudrate\fP, \fB\-\-baudrate\fP \fIbaudrate\fP
|
||||
The baud rate to use.
|
||||
.TP
|
||||
\fB\-c\fP \fIconcatenatedID\fP, \fB\-\-concatenate\fP \fIconcatenatedID\fP
|
||||
If an ID is given, large SMSs are split into several, concatenated
|
||||
SMSs. All SMSs have the same ID and are numbered consecutively so that
|
||||
the receiving phone can assemble them in the correct order. IDs must
|
||||
be in the range 0..255. This number is increased by one for every
|
||||
outgoing concatenated SMS and wraps around after 255.
|
||||
Not all receiving phones will support
|
||||
concatenated SMSs (and display them as separate SMSs),
|
||||
since all the numbering and ID information is
|
||||
carried in the user data header element at the beginning of the SMS
|
||||
user data. This information may show up as garbage in such phones.
|
||||
.TP
|
||||
\fB\-C\fP \fIservice centre address\fP, \fB\-\-sca\fP \fIservice centre address\fP
|
||||
Sets the service centre address to use for all SUBMIT SMSs (may not
|
||||
work with some phones).
|
||||
.TP
|
||||
\fB\-d\fP \fIdevice\fP, \fB\-\-device\fP \fIdevice\fP
|
||||
The device to which the GSM modem is connected. The default is
|
||||
\fI/dev/mobilephone\fP.
|
||||
.TP
|
||||
\fB\-D\fP, \fB\-\-direct\fP
|
||||
Enables direct routing of incoming SMS messages to the TE. This is not
|
||||
supported by many mobile phone/GSM modem combinations. Therefore, the
|
||||
default is to store incoming SMS temporarily before processing them in
|
||||
the indicated store.
|
||||
.TP
|
||||
\fB\-f\fP, \fB\-\-flush\fP
|
||||
This option causes \fIgsmsmsd\fP to flush (ie. read and erase)
|
||||
existing SMS messages from
|
||||
the SMS store selected by the \fB\-\-store\fP option. The action given
|
||||
by the \fB\-\-action\fP option is executed on each of the flushed
|
||||
SMS. This option should be used to ensure that enough space is
|
||||
available in the SMS store for temporary storage of incoming SMS,
|
||||
otherwise incoming SMS might be ignored silently by the ME.
|
||||
.TP
|
||||
\fB\-h\fP, \fB\-\-help\fP
|
||||
Prints an option summary.
|
||||
.TP
|
||||
\fB\-I\fP \fIinit string\fP, \fB\-\-init\fP \fIinit string\fP
|
||||
Initialization string to send to the TA (default: "E0"). Note that the
|
||||
sequence "ATZ" is sent first.
|
||||
.TP
|
||||
\fB\-r\fP, \fB\-\-requeststat\fP
|
||||
Request status reports for sent SMS. Note: This option only makes
|
||||
sense if the phone supports routing of status reports to the
|
||||
TE. Otherwise the status reports might show on the phone's display or
|
||||
get lost.
|
||||
.TP
|
||||
\fB\-s\fP \fIspool directory\fP, \fB\-\-spool\fP \fIspool directory\fP
|
||||
This option sets the spool directory where \fIgsmsmsd\fP expects SMS
|
||||
messages to send. The format of SMS files is very simple: The first
|
||||
line contains the phone number of the recipient. Everything else after
|
||||
the first line is interpreted as the SMS text. Please refer to
|
||||
.BR gsmsendsms(1)
|
||||
for details on the SMS text character set and maximum length.
|
||||
\fIgsmsmsd\fP polls the spool directory every 5 seconds. Sent
|
||||
SMS message files are removed.
|
||||
.TP
|
||||
\fB\-t\fP \fISMS store name\fP, \fB\-\-store\fP \fISMS store name\fP
|
||||
The name of the SMS store to read from (for the \fB\-\-flush\fP option)
|
||||
or write to (for temporary SMS storage). This option must
|
||||
be must be used in conjunction with the \fB\-\-flush\fP option. If this
|
||||
option is omitted the ME uses it's default SMS store for temporary
|
||||
storage of incoming SMS. A commonly available message
|
||||
store is "SM" (SIM card).
|
||||
.TP
|
||||
\fB\-v\fP, \fB\-\-version\fP
|
||||
Prints the program version.
|
||||
.TP
|
||||
\fB\-X\fP, \fB\-\-xonxoff\fP
|
||||
Uses software handshaking (XON/XOFF) for accessing the device.
|
||||
.PP
|
||||
.SH EXAMPLES
|
||||
The following invocation of \fIgsmsmsd\fP sends each incoming SMS message
|
||||
as a mail to the user "smsadmin":
|
||||
.PP
|
||||
.nf
|
||||
gsmsmsd \-d /dev/ttyS2 \-b 19200 \-a "mail smsadmin"
|
||||
.fi
|
||||
.PP
|
||||
This is the format of SMS deliver messages as output from \fIgsmsmsd\fP:
|
||||
.PP
|
||||
.nf
|
||||
----------------------------------------------------------------
|
||||
Message type: SMS\-DELIVER
|
||||
SC address: '491710762100'
|
||||
More messages to send: 1
|
||||
Reply path: 0
|
||||
User data header indicator: 0
|
||||
Status report indication: 0
|
||||
Originating address: '01805000102'
|
||||
Protocol identifier: 0x39
|
||||
Data coding scheme: default alphabet
|
||||
SC timestamp: 17.12.98 14:10:55(+0100)
|
||||
User data length: 159
|
||||
User data header: 0x
|
||||
User data: 'Nicht vergessen! Die XtraWeihnachtsverlosung lauft
|
||||
noch bis zum 24.12. Nutzen Sie jetzt Ihre Gewinnchance und faxen
|
||||
Sie Ihren Teiln.-Gutschein an 0180/5000 056'
|
||||
----------------------------------------------------------------
|
||||
.fi
|
||||
.PP
|
||||
This is the format of SMS status report messages as output from \fIgsmsmsd\fP:
|
||||
.PP
|
||||
.nf
|
||||
----------------------------------------------------------------
|
||||
Message type: SMS\-STATUS\-REPORT
|
||||
SC address: ''
|
||||
More messages to send: 0
|
||||
Status report qualifier: 0
|
||||
Message reference: 0
|
||||
Recipient address: ''
|
||||
SC timestamp: 00.00.00 00:00:00(+0000)
|
||||
Discharge time: 00.00.00 00:00:00(+0000)
|
||||
Status: 0x0 'Short message received by the SME'
|
||||
----------------------------------------------------------------
|
||||
.fi
|
||||
.PP
|
||||
The following invocation of \fIgsmsmsd\fP flushes all existing
|
||||
messages from the "SM" SMS store and looks in the "/tmp/spooldir"
|
||||
directory for SMS to send:
|
||||
.PP
|
||||
.nf
|
||||
gsmsmsd \-d /dev/ttyS2 \-\-spool /tmp/spooldir \-f \-\-store sm \\
|
||||
\-\-action 'mail smsadmin'
|
||||
.fi
|
||||
.PP
|
||||
.SH FILES
|
||||
.TP 1.4i
|
||||
.B /dev/mobilephone
|
||||
Default mobile phone device.
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
Peter Hofmann <software@pxh.de>
|
||||
.PP
|
||||
.SH BUGS
|
||||
Cell broadcast SMS message reception has not been tested, but it has
|
||||
been enabled in the \fIgsmsmsd\fP daemon.
|
||||
.PP
|
||||
The mobile phone device is blocked when the \fIgsmsmsd\fP daemon is
|
||||
running, ie. it cannot be used for data transfer or from the other
|
||||
programs of this suite (\fIgsmpb\fP, \fIgsmsms\fP).
|
||||
.PP
|
||||
Report bugs to software@pxh.de. Include a complete, self-contained
|
||||
example that will allow the bug to be reproduced, and say which
|
||||
version of \fIgsmsmsd\fP you are using.
|
||||
.PP
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 1999 Peter Hofmann
|
||||
.LP
|
||||
\fIgsmsmsd\fP is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Library General Public License as published by the Free
|
||||
Software Foundation; either version 2, or (at your option) any later
|
||||
version.
|
||||
.LP
|
||||
\fIgsmsmsd\fP 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
|
||||
Library General Public License for more details.
|
||||
.LP
|
||||
You should have received a copy of the GNU Library General Public License along
|
||||
with \fIgsmsmsd\fP; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
.PP
|
||||
.SH "SEE ALSO"
|
||||
.BR gsminfo(7),
|
||||
.BR gsmpb(1),
|
||||
.BR gsmctl(1),
|
||||
.BR gsmsendsms(1),
|
||||
.BR gsmsmsstore(1).
|
||||
|
@ -0,0 +1,185 @@
|
||||
.\" -*- eval: (nroff-mode) -*-
|
||||
.de TQ
|
||||
.br
|
||||
.ns
|
||||
.TP \\$1
|
||||
..
|
||||
.\" Like TP, but if specified indent is more than half
|
||||
.\" the current line-length - indent, use the default indent.
|
||||
.de Tp
|
||||
.ie \\n(.$=0:((0\\$1)*2u>(\\n(.lu-\\n(.iu)) .TP
|
||||
.el .TP "\\$1"
|
||||
..
|
||||
.TH GSMSMSSTORE 8 "##DATE##" "gsmsmsstore v##VERSION##"
|
||||
.SH NAME
|
||||
gsmsmsstore \- SMS store manipulation program
|
||||
.SH SYNOPSIS
|
||||
.B gsmsmsstore
|
||||
[ \fB\-a\fP ]
|
||||
[ \fB\-\-add\fP ]
|
||||
[ \fB\-b\fP \fIbaudrate\fP ]
|
||||
[ \fB\-\-baudrate\fP \fIbaudrate\fP ]
|
||||
[ \fB\-c\fP ]
|
||||
[ \fB\-\-copy\fP ]
|
||||
[ \fB\-C\fP \fIservice centre address\fP ]
|
||||
[ \fB\-\-sca\fP \fIservice centre address\fP ]
|
||||
[ \fB\-d\fP \fIdestination device or file\fP ]
|
||||
[ \fB\-\-destination\fP \fIdestination device or file\fP ]
|
||||
[ \fB\-h\fP ]
|
||||
[ \fB\-\-help\fP ]
|
||||
[ \fB\-I\fP \fIinit string\fP ]
|
||||
[ \fB\-\-init\fP \fIinit string\fP ]
|
||||
[ \fB\-k\fP ]
|
||||
[ \fB\-\-backup\fP ]
|
||||
[ \fB\-l\fP ]
|
||||
[ \fB\-\-list\fP ]
|
||||
[ \fB\-s\fP \fIsource device or file\fP ]
|
||||
[ \fB\-\-source\fP \fIsource device or file\fP ]
|
||||
[ \fB\-t\fP \fISMS store name\fP ]
|
||||
[ \fB\-\-store\fP \fISMS store name\fP ]
|
||||
[ \fB\-v\fP ]
|
||||
[ \fB\-\-version\fP ]
|
||||
[ \fB\-V\fP ]
|
||||
[ \fB\-\-verbose\fP ]
|
||||
[ \fB\-x\fP ]
|
||||
[ \fB\-\-delete\fP ]
|
||||
[ \fB\-X\fP ]
|
||||
[ \fB\-\-xonxoff\fP ]
|
||||
{ \fIindices\fP }
|
||||
[ \fIphonenumber\fP \fItext\fP ]
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
\fIgsmsmsstore\fP can store or retrieve SMS messages entries residing
|
||||
in a GSM mobile phone's SMS store to or from a file, add SMS messages
|
||||
to a store, or list the store's contents. Additionally, it is possible
|
||||
to add SMS submit messages to a store.
|
||||
.PP
|
||||
\fIgsmsmsstore\fP reads entries from the source which can be a mobile
|
||||
phone (if a serial device file is given) or a file (if a file name is
|
||||
given). The source is never modified. \fIgsmsmsstore\fP writes SMS
|
||||
messages to a destination file or device in the case of \fB\-\-copy\fP,
|
||||
\fB\-\-backup\fP, and \fB\-\-add\fP.
|
||||
.PP
|
||||
The \fB\-\-list\fP option does not change any file but just lists the
|
||||
contents to standard output.
|
||||
.PP
|
||||
The \fB\-\-backup\fP and \fB\-\-copy\fP options require both source and
|
||||
destination files or devices. The \fB\-\-list\fP option requires a
|
||||
source. The \fB\-\-add\fP and \fB\-\-delete\fP options require a
|
||||
destination file or device.
|
||||
.PP
|
||||
If "\-" is given as the parameter for the \fB\-\-source\fP or
|
||||
\fB\-\-destination\fP options, the SMS store is read from standard input
|
||||
and/or written to standard output, respectively.
|
||||
.PP
|
||||
SMS message files are not human-readable.
|
||||
.PP
|
||||
Error messages are printed to the standard error output. If the program
|
||||
terminates on error the error code 1 is returned.
|
||||
.PP
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-a\fP, \fB\-\-add\fP
|
||||
Adds an SMS submit message with recipient address \fIphonenumber\fP and
|
||||
text \fItext\fP to the destination.
|
||||
.TP
|
||||
\fB\-b\fP \fIbaudrate\fP, \fB\-\-baudrate\fP \fIbaudrate\fP
|
||||
The baud rate to use. The default baudrate is 38400.
|
||||
.TP
|
||||
\fB\-c\fP, \fB\-\-copy\fP
|
||||
This causes the contents of the source to be copied to the
|
||||
destination. After this operation the destination has exactly the same
|
||||
contents as the source. If \fIindices\fP are given on the command
|
||||
line only those SMS messages denoted by the indices are copied to the
|
||||
destination.
|
||||
.TP
|
||||
\fB\-C\fP \fIservice centre address\fP, \fB\-\-sca\fP \fIservice centre address\fP
|
||||
Sets the service centre address to use for all SUBMIT SMSs (may not
|
||||
work with some phones).
|
||||
.TP
|
||||
\fB\-d\fP \fIdestination\fP, \fB\-\-destination\fP \fIdestination\fP
|
||||
The destination device or file.
|
||||
.TP
|
||||
\fB\-h\fP, \fB\-\-help\fP
|
||||
Prints an option summary.
|
||||
.TP
|
||||
\fB\-I\fP \fIinit string\fP, \fB\-\-init\fP \fIinit string\fP
|
||||
Initialization string to send to the TA (default: "E0"). Note that the
|
||||
sequence "ATZ" is sent first.
|
||||
.TP
|
||||
\fB\-k\fP, \fB\-\-backup\fP
|
||||
This causes those entries to be added from the source to the
|
||||
destination that are not already present in the destination. If
|
||||
\fIindices\fP are given on the command line only those SMS messages
|
||||
denoted by the indices are backed up (ie. added) to the destination.
|
||||
.TP
|
||||
\fB\-l\fP, \fB\-\-list\fP
|
||||
Prints out the entire contents of the source in human-readable form.
|
||||
.TP
|
||||
\fB\-s\fP \fIsource\fP, \fB\-\-source\fP \fIsource\fP
|
||||
The source device or file.
|
||||
.TP
|
||||
\fB\-t\fP \fISMS store name\fP, \fB\-\-store\fP \fISMS store name\fP
|
||||
The name of the SMS store to read from or write to. This information is
|
||||
only used for device sources and destinations. A commonly available message
|
||||
store is "SM" (SIM card).
|
||||
.TP
|
||||
\fB\-v\fP, \fB\-\-version\fP
|
||||
Prints the program version.
|
||||
.TP
|
||||
\fB\-V\fP, \fB\-\-verbose\fP
|
||||
Prints out a detailed progress report.
|
||||
.TP
|
||||
\fB\-x\fP, \fB\-\-delete\fP
|
||||
Delete the SMS messages as denoted by the \fIindices\fP from the destination.
|
||||
.TP
|
||||
\fB\-X\fP, \fB\-\-xonxoff\fP
|
||||
Uses software handshaking (XON/XOFF) for accessing the device.
|
||||
.PP
|
||||
.SH EXAMPLES
|
||||
The following command lists all entries in the mobile phone connected
|
||||
to \fI/dev/mobilephone\fP to the standard output:
|
||||
.PP
|
||||
.nf
|
||||
gsmsmsstore \-b 19200 \-s /dev/mobilephone \-t SM \-l
|
||||
.fi
|
||||
.PP
|
||||
The following adds entries 4, 7, and 10 from the device
|
||||
\fI/dev/mobilephone\fP to the file \fIsmsstore\fP:
|
||||
.PP
|
||||
.nf
|
||||
gsmsmsstore \-s /dev/mobilephone \-d /home/fred/smsstore
|
||||
\-t SM \-b 4 7 10
|
||||
.fi
|
||||
.PP
|
||||
.SH AUTHOR
|
||||
Peter Hofmann <software@pxh.de>
|
||||
.PP
|
||||
.SH BUGS
|
||||
Report bugs to software@pxh.de. Include a complete, self-contained
|
||||
example that will allow the bug to be reproduced, and say which
|
||||
version of \fIgsmsmsstore\fP you are using.
|
||||
.PP
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 1999 Peter Hofmann
|
||||
.LP
|
||||
\fIgsmsmsstore\fP is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2, or (at
|
||||
your option) any later version.
|
||||
.LP
|
||||
\fIgsmsmsstore\fP 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
|
||||
Library General Public License for more details.
|
||||
.LP
|
||||
You should have received a copy of the GNU Library General Public License
|
||||
along with \fIgsmsmsstore\fP; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
.PP
|
||||
.SH "SEE ALSO"
|
||||
.BR gsminfo(7),
|
||||
.BR gsmctl(1),
|
||||
.BR gsmpb(1),
|
||||
.BR gsmsendsms(1),
|
||||
.BR gsmsmsd(8).
|
@ -0,0 +1,40 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
# *************************************************************************
|
||||
# * GSM TA/ME library
|
||||
# *
|
||||
# * File: Makefile.am
|
||||
# *
|
||||
# * Purpose: Makefile for phone-specific extensions
|
||||
# *
|
||||
# * Author: Peter Hofmann (software@pxh.de)
|
||||
# *
|
||||
# * Created: 16.12.2001
|
||||
# *************************************************************************
|
||||
|
||||
INCLUDES = -I..
|
||||
|
||||
EXTRA_DIST = README.sieme
|
||||
|
||||
# build addon library
|
||||
lib_LTLIBRARIES = libgsmext.la
|
||||
|
||||
libgsmext_la_SOURCES = gsm_sie_me.cc
|
||||
|
||||
libgsmext_la_LDFLAGS = -version-info $(GSM_VERSION)
|
||||
|
||||
gsmincludedir = $(includedir)/gsmlib
|
||||
|
||||
gsminclude_HEADERS = gsm_sie_me.h
|
||||
|
||||
# build programs
|
||||
bin_PROGRAMS = gsmsiectl gsmsiexfer
|
||||
|
||||
# build gsmsiectl from gsmsiectl.cc and libgsmme.la
|
||||
gsmsiectl_SOURCES = gsmsiectl.cc
|
||||
gsmsiectl_LDADD = ../gsmlib/libgsmme.la libgsmext.la $(INTLLIBS)
|
||||
|
||||
# build gsmsiexfer from gsmsiexfer.cc and libgsmme.la
|
||||
gsmsiexfer_SOURCES = gsmsiexfer.cc
|
||||
gsmsiexfer_LDADD = ../gsmlib/libgsmme.la libgsmext.la $(INTLLIBS)
|
||||
|
||||
|
@ -0,0 +1,480 @@
|
||||
# Makefile.in generated by automake 1.6.3 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
# Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
# *************************************************************************
|
||||
# * GSM TA/ME library
|
||||
# *
|
||||
# * File: Makefile.am
|
||||
# *
|
||||
# * Purpose: Makefile for phone-specific extensions
|
||||
# *
|
||||
# * Author: Peter Hofmann (software@pxh.de)
|
||||
# *
|
||||
# * Created: 16.12.2001
|
||||
# *************************************************************************
|
||||
SHELL = @SHELL@
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = @bindir@
|
||||
sbindir = @sbindir@
|
||||
libexecdir = @libexecdir@
|
||||
datadir = @datadir@
|
||||
sysconfdir = @sysconfdir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
localstatedir = @localstatedir@
|
||||
libdir = @libdir@
|
||||
infodir = @infodir@
|
||||
mandir = @mandir@
|
||||
includedir = @includedir@
|
||||
oldincludedir = /usr/include
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
top_builddir = ..
|
||||
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = @program_transform_name@
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
host_alias = @host_alias@
|
||||
host_triplet = @host@
|
||||
|
||||
EXEEXT = @EXEEXT@
|
||||
OBJEXT = @OBJEXT@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
AMTAR = @AMTAR@
|
||||
AS = @AS@
|
||||
AWK = @AWK@
|
||||
BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
|
||||
CATOBJEXT = @CATOBJEXT@
|
||||
CC = @CC@
|
||||
CPP = @CPP@
|
||||
CXX = @CXX@
|
||||
DATADIRNAME = @DATADIRNAME@
|
||||
DEPDIR = @DEPDIR@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
ECHO = @ECHO@
|
||||
GENCAT = @GENCAT@
|
||||
GLIBC21 = @GLIBC21@
|
||||
GMSGFMT = @GMSGFMT@
|
||||
GSM_VERSION = @GSM_VERSION@
|
||||
HAVE_LIB = @HAVE_LIB@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
INSTOBJEXT = @INSTOBJEXT@
|
||||
INTLBISON = @INTLBISON@
|
||||
INTLLIBS = @INTLLIBS@
|
||||
INTLOBJS = @INTLOBJS@
|
||||
INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
|
||||
LIB = @LIB@
|
||||
LIBICONV = @LIBICONV@
|
||||
LIBINTL = @LIBINTL@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LN_S = @LN_S@
|
||||
LTLIB = @LTLIB@
|
||||
LTLIBICONV = @LTLIBICONV@
|
||||
LTLIBINTL = @LTLIBINTL@
|
||||
MKINSTALLDIRS = @MKINSTALLDIRS@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
PACKAGE = @PACKAGE@
|
||||
POSUB = @POSUB@
|
||||
RANLIB = @RANLIB@
|
||||
STRIP = @STRIP@
|
||||
USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
|
||||
USE_NLS = @USE_NLS@
|
||||
VERSION = @VERSION@
|
||||
am__include = @am__include@
|
||||
am__quote = @am__quote@
|
||||
install_sh = @install_sh@
|
||||
|
||||
INCLUDES = -I..
|
||||
|
||||
EXTRA_DIST = README.sieme
|
||||
|
||||
# build addon library
|
||||
lib_LTLIBRARIES = libgsmext.la
|
||||
|
||||
libgsmext_la_SOURCES = gsm_sie_me.cc
|
||||
|
||||
libgsmext_la_LDFLAGS = -version-info $(GSM_VERSION)
|
||||
|
||||
gsmincludedir = $(includedir)/gsmlib
|
||||
|
||||
gsminclude_HEADERS = gsm_sie_me.h
|
||||
|
||||
# build programs
|
||||
bin_PROGRAMS = gsmsiectl gsmsiexfer
|
||||
|
||||
# build gsmsiectl from gsmsiectl.cc and libgsmme.la
|
||||
gsmsiectl_SOURCES = gsmsiectl.cc
|
||||
gsmsiectl_LDADD = ../gsmlib/libgsmme.la libgsmext.la $(INTLLIBS)
|
||||
|
||||
# build gsmsiexfer from gsmsiexfer.cc and libgsmme.la
|
||||
gsmsiexfer_SOURCES = gsmsiexfer.cc
|
||||
gsmsiexfer_LDADD = ../gsmlib/libgsmme.la libgsmext.la $(INTLLIBS)
|
||||
subdir = ext
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs
|
||||
CONFIG_HEADER = $(top_builddir)/gsm_config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
LTLIBRARIES = $(lib_LTLIBRARIES)
|
||||
|
||||
libgsmext_la_LIBADD =
|
||||
am_libgsmext_la_OBJECTS = gsm_sie_me.lo
|
||||
libgsmext_la_OBJECTS = $(am_libgsmext_la_OBJECTS)
|
||||
bin_PROGRAMS = gsmsiectl$(EXEEXT) gsmsiexfer$(EXEEXT)
|
||||
PROGRAMS = $(bin_PROGRAMS)
|
||||
|
||||
am_gsmsiectl_OBJECTS = gsmsiectl.$(OBJEXT)
|
||||
gsmsiectl_OBJECTS = $(am_gsmsiectl_OBJECTS)
|
||||
gsmsiectl_DEPENDENCIES = ../gsmlib/libgsmme.la libgsmext.la
|
||||
gsmsiectl_LDFLAGS =
|
||||
am_gsmsiexfer_OBJECTS = gsmsiexfer.$(OBJEXT)
|
||||
gsmsiexfer_OBJECTS = $(am_gsmsiexfer_OBJECTS)
|
||||
gsmsiexfer_DEPENDENCIES = ../gsmlib/libgsmme.la libgsmext.la
|
||||
gsmsiexfer_LDFLAGS =
|
||||
|
||||
DEFS = @DEFS@
|
||||
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
depcomp = $(SHELL) $(top_srcdir)/scripts/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/gsm_sie_me.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/gsmsiectl.Po ./$(DEPDIR)/gsmsiexfer.Po
|
||||
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \
|
||||
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
|
||||
$(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
CXXLD = $(CXX)
|
||||
CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
|
||||
$(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
DIST_SOURCES = $(libgsmext_la_SOURCES) $(gsmsiectl_SOURCES) \
|
||||
$(gsmsiexfer_SOURCES)
|
||||
HEADERS = $(gsminclude_HEADERS)
|
||||
|
||||
DIST_COMMON = $(gsminclude_HEADERS) Makefile.am Makefile.in
|
||||
SOURCES = $(libgsmext_la_SOURCES) $(gsmsiectl_SOURCES) $(gsmsiexfer_SOURCES)
|
||||
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .cc .lo .o .obj
|
||||
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu ext/Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
|
||||
libLTLIBRARIES_INSTALL = $(INSTALL)
|
||||
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(libdir)
|
||||
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
|
||||
if test -f $$p; then \
|
||||
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f"; \
|
||||
$(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f; \
|
||||
else :; fi; \
|
||||
done
|
||||
|
||||
uninstall-libLTLIBRARIES:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
|
||||
p="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p"; \
|
||||
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
|
||||
done
|
||||
|
||||
clean-libLTLIBRARIES:
|
||||
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
|
||||
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
|
||||
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
|
||||
test -z "$dir" && dir=.; \
|
||||
echo "rm -f \"$${dir}/so_locations\""; \
|
||||
rm -f "$${dir}/so_locations"; \
|
||||
done
|
||||
libgsmext.la: $(libgsmext_la_OBJECTS) $(libgsmext_la_DEPENDENCIES)
|
||||
$(CXXLINK) -rpath $(libdir) $(libgsmext_la_LDFLAGS) $(libgsmext_la_OBJECTS) $(libgsmext_la_LIBADD) $(LIBS)
|
||||
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
|
||||
install-binPROGRAMS: $(bin_PROGRAMS)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(bindir)
|
||||
@list='$(bin_PROGRAMS)'; for p in $$list; do \
|
||||
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
|
||||
if test -f $$p \
|
||||
|| test -f $$p1 \
|
||||
; then \
|
||||
f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
|
||||
echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \
|
||||
$(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f; \
|
||||
else :; fi; \
|
||||
done
|
||||
|
||||
uninstall-binPROGRAMS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(bin_PROGRAMS)'; for p in $$list; do \
|
||||
f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
|
||||
echo " rm -f $(DESTDIR)$(bindir)/$$f"; \
|
||||
rm -f $(DESTDIR)$(bindir)/$$f; \
|
||||
done
|
||||
|
||||
clean-binPROGRAMS:
|
||||
@list='$(bin_PROGRAMS)'; for p in $$list; do \
|
||||
f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
|
||||
echo " rm -f $$p $$f"; \
|
||||
rm -f $$p $$f ; \
|
||||
done
|
||||
gsmsiectl$(EXEEXT): $(gsmsiectl_OBJECTS) $(gsmsiectl_DEPENDENCIES)
|
||||
@rm -f gsmsiectl$(EXEEXT)
|
||||
$(CXXLINK) $(gsmsiectl_LDFLAGS) $(gsmsiectl_OBJECTS) $(gsmsiectl_LDADD) $(LIBS)
|
||||
gsmsiexfer$(EXEEXT): $(gsmsiexfer_OBJECTS) $(gsmsiexfer_DEPENDENCIES)
|
||||
@rm -f gsmsiexfer$(EXEEXT)
|
||||
$(CXXLINK) $(gsmsiexfer_LDFLAGS) $(gsmsiexfer_OBJECTS) $(gsmsiexfer_LDADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT) core *.core
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_sie_me.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsmsiectl.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsmsiexfer.Po@am__quote@
|
||||
|
||||
distclean-depend:
|
||||
-rm -rf ./$(DEPDIR)
|
||||
|
||||
.cc.o:
|
||||
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
$(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
|
||||
|
||||
.cc.obj:
|
||||
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
$(CXXCOMPILE) -c -o $@ `cygpath -w $<`
|
||||
|
||||
.cc.lo:
|
||||
@AMDEP_TRUE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
$(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
|
||||
distclean-libtool:
|
||||
-rm -f libtool
|
||||
uninstall-info-am:
|
||||
gsmincludeHEADERS_INSTALL = $(INSTALL_HEADER)
|
||||
install-gsmincludeHEADERS: $(gsminclude_HEADERS)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(gsmincludedir)
|
||||
@list='$(gsminclude_HEADERS)'; for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " $(gsmincludeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(gsmincludedir)/$$f"; \
|
||||
$(gsmincludeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(gsmincludedir)/$$f; \
|
||||
done
|
||||
|
||||
uninstall-gsmincludeHEADERS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(gsminclude_HEADERS)'; for p in $$list; do \
|
||||
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " rm -f $(DESTDIR)$(gsmincludedir)/$$f"; \
|
||||
rm -f $(DESTDIR)$(gsmincludedir)/$$f; \
|
||||
done
|
||||
|
||||
ETAGS = etags
|
||||
ETAGSFLAGS =
|
||||
|
||||
tags: TAGS
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
mkid -fID $$unique
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|
||||
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$tags $$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& cd $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) $$here
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
top_distdir = ..
|
||||
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@list='$(DISTFILES)'; for file in $$list; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
dir="/$$dir"; \
|
||||
$(mkinstalldirs) "$(distdir)$$dir"; \
|
||||
else \
|
||||
dir=''; \
|
||||
fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
|
||||
fi; \
|
||||
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS)
|
||||
install-binPROGRAMS: install-libLTLIBRARIES
|
||||
|
||||
|
||||
installdirs:
|
||||
$(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(bindir) $(DESTDIR)$(gsmincludedir)
|
||||
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
|
||||
clean-libtool mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
|
||||
distclean-am: clean-am distclean-compile distclean-depend \
|
||||
distclean-generic distclean-libtool distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am: install-gsmincludeHEADERS
|
||||
|
||||
install-exec-am: install-binPROGRAMS install-libLTLIBRARIES
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-man:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
||||
uninstall-am: uninstall-binPROGRAMS uninstall-gsmincludeHEADERS \
|
||||
uninstall-info-am uninstall-libLTLIBRARIES
|
||||
|
||||
.PHONY: GTAGS all all-am check check-am clean clean-binPROGRAMS \
|
||||
clean-generic clean-libLTLIBRARIES clean-libtool distclean \
|
||||
distclean-compile distclean-depend distclean-generic \
|
||||
distclean-libtool distclean-tags distdir dvi dvi-am info \
|
||||
info-am install install-am install-binPROGRAMS install-data \
|
||||
install-data-am install-exec install-exec-am \
|
||||
install-gsmincludeHEADERS install-info install-info-am \
|
||||
install-libLTLIBRARIES install-man install-strip installcheck \
|
||||
installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||
mostlyclean-generic mostlyclean-libtool tags uninstall \
|
||||
uninstall-am uninstall-binPROGRAMS uninstall-gsmincludeHEADERS \
|
||||
uninstall-info-am uninstall-libLTLIBRARIES
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
@ -0,0 +1,75 @@
|
||||
Extended support for Siemens mobile phones via gsmlib
|
||||
-----------------------------------------------------
|
||||
|
||||
* Hardware:
|
||||
|
||||
Supported phones: S25, S35, S45, ME45, SL45
|
||||
Tested phones: S45, ME45
|
||||
|
||||
* Feature list:
|
||||
|
||||
- ACM: Output ACM (accumulated call meter) and ACMmax => maybe not
|
||||
|
||||
- BNR/BNW: Binary read and write => yes, xfer
|
||||
|
||||
- CID: Output card ID => maybe
|
||||
|
||||
- CKS: Output SIM card status => maybe
|
||||
|
||||
- CNI: Output call number information => maybe
|
||||
|
||||
- DBR: Database Read => yes, phonebook
|
||||
|
||||
- DLD: Delete the "last number redial" memory => maybe dangerous?
|
||||
|
||||
- GAUTH: Select Type of Authentication for PPP => no
|
||||
|
||||
- ICO: Icon control => no
|
||||
|
||||
- LCK: Switch locks on and off => yes, lock/unlock
|
||||
|
||||
- LNG: Language settings => maybe
|
||||
|
||||
- MGL: List SMS => no
|
||||
|
||||
- MGO: SMS overflow indicator => no
|
||||
|
||||
- MGR: Read SMS (same as AT+CMGR) => no
|
||||
|
||||
- MSO: Switch device off => maybe not
|
||||
|
||||
- NFS: Select NF hardware => maybe
|
||||
|
||||
- NFV: Set the volume => maybe
|
||||
|
||||
- PBC: Seek in telephone book => no
|
||||
|
||||
- PBG: Sorted telephone book => yes
|
||||
|
||||
- PBS: Select a telephone book => yes
|
||||
|
||||
- PIC: Output PIN counter => maybe
|
||||
|
||||
- PLM: Read the PLMN list => yes
|
||||
|
||||
- PLR/PLW: read/write preferred-operator list => yes
|
||||
|
||||
- PST: Play Signal Tone => yes
|
||||
|
||||
- PWD: Change password to a lock => maybe
|
||||
|
||||
- RTC: Set the ringing tone => yes
|
||||
|
||||
- STK: SIM toolkit => no
|
||||
|
||||
|
||||
* Additional References
|
||||
|
||||
http://www.s45-world.net/vissie.htm
|
||||
|
||||
|
||||
* Author and contact
|
||||
|
||||
Christian W. Zuckschwerdt <zany@triq.net>
|
||||
http://triq.net/gsm.html
|
||||
|
@ -0,0 +1,258 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_sie_me.cc
|
||||
// *
|
||||
// * Purpose: Mobile Equipment/Terminal Adapter and SMS functions
|
||||
// * (According to "AT command set for S45 Siemens mobile phones"
|
||||
// * v1.8, 26. July 2001 - Common AT prefix is "^S")
|
||||
// *
|
||||
// * Author: Christian W. Zuckschwerdt <zany@triq.net>
|
||||
// *
|
||||
// * Created: 2001-12-15
|
||||
// *************************************************************************
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <gsm_config.h>
|
||||
#endif
|
||||
#include <gsmlib/gsm_nls.h>
|
||||
#include <gsmlib/gsm_me_ta.h>
|
||||
#include <gsmlib/gsm_parser.h>
|
||||
#include <gsmlib/gsm_util.h>
|
||||
#include <gsm_sie_me.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace gsmlib;
|
||||
|
||||
// SieMe members
|
||||
|
||||
void SieMe::init() throw(GsmException)
|
||||
{
|
||||
}
|
||||
|
||||
SieMe::SieMe(Ref<Port> port) throw(GsmException) : MeTa::MeTa(port)
|
||||
{
|
||||
// initialize Siemens ME
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
vector<string> SieMe::getSupportedPhonebooks() throw(GsmException)
|
||||
{
|
||||
Parser p(_at->chat("^SPBS=?", "^SPBS:"));
|
||||
return p.parseStringList();
|
||||
}
|
||||
|
||||
string SieMe::getCurrentPhonebook() throw(GsmException)
|
||||
{
|
||||
if (_lastPhonebookName == "")
|
||||
{
|
||||
Parser p(_at->chat("^SPBS?", "^SPBS:"));
|
||||
// answer is e.g. ^SPBS: "SM",41,250
|
||||
_lastPhonebookName = p.parseString();
|
||||
p.parseComma();
|
||||
int _currentNumberOfEntries = p.parseInt();
|
||||
p.parseComma();
|
||||
int _maxNumberOfEntries = p.parseInt();
|
||||
}
|
||||
return _lastPhonebookName;
|
||||
}
|
||||
|
||||
void SieMe::setPhonebook(string phonebookName) throw(GsmException)
|
||||
{
|
||||
if (phonebookName != _lastPhonebookName)
|
||||
{
|
||||
_at->chat("^SPBS=\"" + phonebookName + "\"");
|
||||
_lastPhonebookName = phonebookName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IntRange SieMe:: getSupportedSignalTones() throw(GsmException)
|
||||
{
|
||||
Parser p(_at->chat("^SPST=?", "^SPST:"));
|
||||
// ^SPST: (0-4),(0,1)
|
||||
IntRange typeRange = p.parseRange();
|
||||
p.parseComma();
|
||||
vector<bool> volumeList = p.parseIntList();
|
||||
return typeRange;
|
||||
}
|
||||
|
||||
void SieMe:: playSignalTone(int tone) throw(GsmException)
|
||||
{
|
||||
_at->chat("^SPST=" + intToStr(tone) + ",1");
|
||||
}
|
||||
|
||||
void SieMe:: stopSignalTone(int tone) throw(GsmException)
|
||||
{
|
||||
_at->chat("^SPST=" + intToStr(tone) + ",0");
|
||||
}
|
||||
|
||||
|
||||
IntRange SieMe::getSupportedRingingTones() throw(GsmException) // (AT^SRTC=?)
|
||||
{
|
||||
Parser p(_at->chat("^SRTC=?", "^SRTC:"));
|
||||
// ^SRTC: (0-42),(1-5)
|
||||
IntRange typeRange = p.parseRange();
|
||||
p.parseComma();
|
||||
IntRange volumeRange = p.parseRange();
|
||||
return typeRange;
|
||||
}
|
||||
|
||||
int SieMe::getCurrentRingingTone() throw(GsmException) // (AT^SRTC?)
|
||||
{
|
||||
Parser p(_at->chat("^SRTC?", "^SRTC:"));
|
||||
// ^SRTC: 41,2,0
|
||||
int type = p.parseInt();
|
||||
p.parseComma();
|
||||
int volume = p.parseInt();
|
||||
p.parseComma();
|
||||
int ringing = p.parseInt();
|
||||
return type;
|
||||
}
|
||||
|
||||
void SieMe::setRingingTone(int tone, int volume) throw(GsmException)
|
||||
{
|
||||
_at->chat("^SRTC=" + intToStr(tone) + "," + intToStr(volume));
|
||||
}
|
||||
|
||||
void SieMe:: playRingingTone() throw(GsmException)
|
||||
{
|
||||
// get ringing bool
|
||||
Parser p(_at->chat("^SRTC?", "^SRTC:"));
|
||||
// ^SRTC: 41,2,0
|
||||
int type = p.parseInt();
|
||||
p.parseComma();
|
||||
int volume = p.parseInt();
|
||||
p.parseComma();
|
||||
int ringing = p.parseInt();
|
||||
|
||||
if (ringing == 0)
|
||||
toggleRingingTone();
|
||||
}
|
||||
|
||||
void SieMe::stopRingingTone() throw(GsmException)
|
||||
{
|
||||
// get ringing bool
|
||||
Parser p(_at->chat("^SRTC?", "^SRTC:"));
|
||||
// ^SRTC: 41,2,0
|
||||
int type = p.parseInt();
|
||||
p.parseComma();
|
||||
int volume = p.parseInt();
|
||||
p.parseComma();
|
||||
int ringing = p.parseInt();
|
||||
|
||||
if (ringing == 1)
|
||||
toggleRingingTone();
|
||||
}
|
||||
|
||||
void SieMe::toggleRingingTone() throw(GsmException) // (AT^SRTC)
|
||||
{
|
||||
_at->chat("^SRTC");
|
||||
}
|
||||
|
||||
// Siemens get supported binary read
|
||||
vector<ParameterRange> SieMe::getSupportedBinaryReads() throw(GsmException)
|
||||
{
|
||||
Parser p(_at->chat("^SBNR=?", "^SBNR:"));
|
||||
// ^SBNR: ("bmp",(0-3)),("mid",(0-4)),("vcf",(0-500)),("vcs",(0-50))
|
||||
|
||||
return p.parseParameterRangeList();
|
||||
}
|
||||
|
||||
// Siemens get supported binary write
|
||||
vector<ParameterRange> SieMe::getSupportedBinaryWrites() throw(GsmException)
|
||||
{
|
||||
Parser p(_at->chat("^SBNW=?", "^SBNW:"));
|
||||
// ^SBNW: ("bmp",(0-3)),("mid",(0-4)),("vcf",(0-500)),("vcs",(0-50)),("t9d",(0))
|
||||
|
||||
return p.parseParameterRangeList();
|
||||
}
|
||||
|
||||
// Siemens Binary Read
|
||||
BinaryObject SieMe::getBinary(string type, int subtype) throw(GsmException)
|
||||
{
|
||||
// expect several response lines
|
||||
vector<string> result;
|
||||
result = _at->chatv("^SBNR=\"" + type + "\"," + intToStr(subtype), "^SBNR:");
|
||||
// "bmp",0,1,5 <CR><LF> pdu <CR><LF> "bmp",0,2,5 <CR><LF> ...
|
||||
// most likely to be PDUs of 382 chars (191 * 2)
|
||||
string pdu;
|
||||
int fragmentCount = 0;
|
||||
for (vector<string>::iterator i = result.begin(); i != result.end(); ++i)
|
||||
{
|
||||
++fragmentCount;
|
||||
// parse header
|
||||
Parser p(*i);
|
||||
string fragmentType = p.parseString();
|
||||
if (fragmentType != type)
|
||||
throw GsmException(_("bad PDU type"), ChatError);
|
||||
p.parseComma();
|
||||
int fragmentSubtype = p.parseInt();
|
||||
if (fragmentSubtype != subtype)
|
||||
throw GsmException(_("bad PDU subtype"), ChatError);
|
||||
p.parseComma();
|
||||
int fragmentNumber = p.parseInt();
|
||||
if (fragmentNumber != fragmentCount)
|
||||
throw GsmException(_("bad PDU number"), ChatError);
|
||||
p.parseComma();
|
||||
int numberOfFragments = p.parseInt();
|
||||
if (fragmentNumber > numberOfFragments)
|
||||
throw GsmException(_("bad PDU number"), ChatError);
|
||||
|
||||
// concat pdu fragment
|
||||
++i;
|
||||
pdu += *i;
|
||||
}
|
||||
|
||||
BinaryObject bnr;
|
||||
bnr._type = type;
|
||||
bnr._subtype = subtype;
|
||||
bnr._size = pdu.length() / 2;
|
||||
bnr._data = new unsigned char[pdu.length() / 2];
|
||||
if (! hexToBuf(pdu, bnr._data))
|
||||
throw GsmException(_("bad hexadecimal PDU format"), ChatError);
|
||||
|
||||
return bnr;
|
||||
}
|
||||
|
||||
// Siemens Binary Write
|
||||
void SieMe::setBinary(string type, int subtype, BinaryObject obj)
|
||||
throw(GsmException)
|
||||
{
|
||||
if (obj._size <= 0)
|
||||
throw GsmException(_("bad object"), ParameterError);
|
||||
|
||||
// Limitation: The maximum pdu size is 176 bytes (or 352 characters)
|
||||
// this should be a configurable field
|
||||
int maxPDUsize = 176;
|
||||
int numberOfPDUs = (obj._size + maxPDUsize - 1) / maxPDUsize;
|
||||
unsigned char *p = obj._data;
|
||||
|
||||
for (int i = 1; i <= numberOfPDUs; ++i)
|
||||
{
|
||||
// construct pdu
|
||||
int size = maxPDUsize;
|
||||
if (i == numberOfPDUs)
|
||||
size = obj._size - (numberOfPDUs - 1) * maxPDUsize;
|
||||
string pdu = bufToHex(p, size);
|
||||
p += size;
|
||||
|
||||
cout << "processing " << i << " of " << numberOfPDUs
|
||||
<< " of " << size << " bytes." << endl;
|
||||
cout << "^SBNW=\"" + type + "\"," + intToStr(subtype) + ","
|
||||
+ intToStr(i) + "," + intToStr(numberOfPDUs) << endl;
|
||||
cout << pdu << endl;
|
||||
|
||||
_at->sendPdu("^SBNW=\"" + type + "\"," + intToStr(subtype) + ","
|
||||
+ intToStr(i) + "," + intToStr(numberOfPDUs), "",
|
||||
pdu, true);
|
||||
cout << "OK" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,99 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_sie_me.h
|
||||
// *
|
||||
// * Purpose: Mobile Equipment/Terminal Adapter and SMS functions
|
||||
// * (According to "AT command set for S45 Siemens mobile phones"
|
||||
// * v1.8, 26. July 2001 - Common AT prefix is "^S")
|
||||
// *
|
||||
// * Author: Christian W. Zuckschwerdt <zany@triq.net>
|
||||
// *
|
||||
// * Created: 2001-12-15
|
||||
// *************************************************************************
|
||||
|
||||
#ifndef GSM_SIE_ME_H
|
||||
#define GSM_SIE_ME_H
|
||||
|
||||
#include <gsmlib/gsm_error.h>
|
||||
#include <gsmlib/gsm_at.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gsmlib
|
||||
{
|
||||
// *** Siemens mobile phone binary objects (bitmap, midi, vcal, vcard)
|
||||
|
||||
struct BinaryObject
|
||||
{
|
||||
string _type; // Object type
|
||||
int _subtype; // Object subtype (storage number)
|
||||
unsigned char *_data; // Object binary data
|
||||
int _size; // Object data size
|
||||
};
|
||||
|
||||
// *** this class allows extended access to Siemens moblie phones
|
||||
|
||||
class SieMe : public MeTa
|
||||
{
|
||||
private:
|
||||
// init ME/TA to sensible defaults
|
||||
void init() throw(GsmException);
|
||||
|
||||
public:
|
||||
// initialize a new MeTa object given the port
|
||||
SieMe(Ref<Port> port) throw(GsmException);
|
||||
|
||||
|
||||
// get the current phonebook in the Siemens ME
|
||||
vector<string> getSupportedPhonebooks() throw(GsmException);// (AT^SPBS=?)
|
||||
|
||||
// get the current phonebook in the Siemens ME
|
||||
string getCurrentPhonebook() throw(GsmException); // (AT^SPBS?)
|
||||
|
||||
// set the current phonebook in the Siemens ME
|
||||
// remember the last phonebook set for optimisation
|
||||
void setPhonebook(string phonebookName) throw(GsmException); // (AT^SPBS=)
|
||||
|
||||
|
||||
// Siemens get supported signal tones
|
||||
IntRange getSupportedSignalTones() throw(GsmException); // (AT^SPST=?)
|
||||
|
||||
// Siemens set ringing tone
|
||||
void playSignalTone(int tone) throw(GsmException); // (AT^SRTC=x,1)
|
||||
|
||||
// Siemens set ringing tone
|
||||
void stopSignalTone(int tone) throw(GsmException); // (AT^SRTC=x,0)
|
||||
|
||||
|
||||
// Siemens get ringing tone
|
||||
IntRange getSupportedRingingTones() throw(GsmException); // (AT^SRTC=?)
|
||||
// Siemens get ringing tone
|
||||
int getCurrentRingingTone() throw(GsmException); // (AT^SRTC?)
|
||||
// Siemens set ringing tone
|
||||
void setRingingTone(int tone, int volume) throw(GsmException);// (AT^SRTC=)
|
||||
// Siemens set ringing tone on
|
||||
void playRingingTone() throw(GsmException);
|
||||
// Siemens set ringing tone of
|
||||
void stopRingingTone() throw(GsmException);
|
||||
// Siemens toggle ringing tone
|
||||
void toggleRingingTone() throw(GsmException); // (AT^SRTC)
|
||||
|
||||
// Siemens get supported binary read
|
||||
vector<ParameterRange> getSupportedBinaryReads() throw(GsmException);
|
||||
|
||||
// Siemens get supported binary write
|
||||
vector<ParameterRange> getSupportedBinaryWrites() throw(GsmException);
|
||||
|
||||
// Siemens Binary Read
|
||||
BinaryObject getBinary(string type, int subtype) throw(GsmException);
|
||||
|
||||
// Siemens Binary Write
|
||||
void setBinary(string type, int subtype, BinaryObject obj)
|
||||
throw(GsmException);
|
||||
};
|
||||
};
|
||||
|
||||
#endif // GSM_ME_TA_H
|
@ -0,0 +1,698 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsmsiectl.cc
|
||||
// *
|
||||
// * Purpose: GSM Siemens mobile phone control program
|
||||
// *
|
||||
// * Author: Christian W. Zuckschwerdt <zany@triq.net>
|
||||
// *
|
||||
// * Created: 2001-12-15
|
||||
// *************************************************************************
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <gsm_config.h>
|
||||
#endif
|
||||
#include <gsmlib/gsm_nls.h>
|
||||
#include <string>
|
||||
#if defined(HAVE_GETOPT_LONG) || defined(WIN32)
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#include <strstream>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <gsmlib/gsm_me_ta.h>
|
||||
#include <gsm_sie_me.h>
|
||||
#include <gsmlib/gsm_util.h>
|
||||
#include <gsmlib/gsm_sysdep.h>
|
||||
#ifdef WIN32
|
||||
#include <gsmlib/gsm_win32_serial.h>
|
||||
#else
|
||||
#include <gsmlib/gsm_unix_serial.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace gsmlib;
|
||||
|
||||
// my ME
|
||||
|
||||
static SieMe *m;
|
||||
|
||||
// information parameters
|
||||
|
||||
enum InfoParameter {AllInfo, // print all info
|
||||
MeInfo, // MeInfo must be first!
|
||||
OperatorInfo,
|
||||
CurrentOperatorInfo,
|
||||
FacilityLockStateInfo,
|
||||
FacilityLockCapabilityInfo,
|
||||
PasswordInfo,
|
||||
CLIPInfo,
|
||||
CallForwardingInfo,
|
||||
BatteryInfo,
|
||||
BitErrorInfo,
|
||||
SCAInfo,
|
||||
CharSetInfo,
|
||||
PhonebookInfo, // extended Siemens info
|
||||
SignalToneInfo,
|
||||
RingingToneInfo,
|
||||
BinaryInfo,
|
||||
SignalInfo}; // SignalInfo must be last!
|
||||
|
||||
// operation parameters
|
||||
|
||||
// FIXME operations not implemented yet
|
||||
|
||||
// options
|
||||
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
static struct option longOpts[] =
|
||||
{
|
||||
{"xonxoff", no_argument, (int*)NULL, 'X'},
|
||||
{"operation", required_argument, (int*)NULL, 'o'},
|
||||
{"device", required_argument, (int*)NULL, 'd'},
|
||||
{"baudrate", required_argument, (int*)NULL, 'b'},
|
||||
{"init", required_argument, (int*)NULL, 'I'},
|
||||
{"help", no_argument, (int*)NULL, 'h'},
|
||||
{"version", no_argument, (int*)NULL, 'v'},
|
||||
{(char*)NULL, 0, (int*)NULL, 0}
|
||||
};
|
||||
#else
|
||||
#define getopt_long(argc, argv, options, longopts, indexptr) \
|
||||
getopt(argc, argv, options)
|
||||
#endif
|
||||
|
||||
// helper function, prints forwarding info
|
||||
|
||||
void printForwardReason(string s, ForwardInfo &info)
|
||||
{
|
||||
cout << s << " "
|
||||
<< (info._active ? _("active ") : _("inactive "))
|
||||
<< _("number: ") << info._number
|
||||
<< _(" subaddr: ") << info._subAddr
|
||||
<< _(" time: ") << info._time << endl;
|
||||
}
|
||||
|
||||
// helper function, prints integer range
|
||||
|
||||
void printIntRange(IntRange ir)
|
||||
{
|
||||
cout << "(" << ir._low;
|
||||
if (ir._high != NOT_SET)
|
||||
cout << "-" << ir._high;
|
||||
cout << ")";
|
||||
}
|
||||
|
||||
// helper function, prints parameter range
|
||||
|
||||
void printParameterRange(ParameterRange pr)
|
||||
{
|
||||
cout << "(\"" << pr._parameter << "\",";
|
||||
printIntRange(pr._range);
|
||||
cout << ")";
|
||||
}
|
||||
|
||||
// print information
|
||||
|
||||
static void printInfo(InfoParameter ip)
|
||||
{
|
||||
switch (ip)
|
||||
{
|
||||
case MeInfo:
|
||||
{
|
||||
MEInfo mei = m->getMEInfo();
|
||||
cout << _("<ME0> Manufacturer: ") << mei._manufacturer << endl
|
||||
<< _("<ME1> Model: ") << mei._model << endl
|
||||
<< _("<ME2> Revision: ") << mei._revision << endl
|
||||
<< _("<ME3> Serial Number: ") << mei._serialNumber << endl;
|
||||
break;
|
||||
}
|
||||
case OperatorInfo:
|
||||
{
|
||||
int count = 0;
|
||||
vector<OPInfo> opis = m->getAvailableOPInfo();
|
||||
for (vector<OPInfo>::iterator i = opis.begin(); i != opis.end(); ++i)
|
||||
{
|
||||
cout << "<OP" << count << _("> Status: ");
|
||||
switch (i->_status)
|
||||
{
|
||||
case UnknownOPStatus: cout << _("unknown"); break;
|
||||
case CurrentOPStatus: cout << _("current"); break;
|
||||
case AvailableOPStatus: cout << _("available"); break;
|
||||
case ForbiddenOPStatus: cout << _("forbidden"); break;
|
||||
}
|
||||
cout << _(" Long name: '") << i->_longName << "' "
|
||||
<< _(" Short name: '") << i->_shortName << "' "
|
||||
<< _(" Numeric name: ") << i->_numericName << endl;
|
||||
++count;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CurrentOperatorInfo:
|
||||
{
|
||||
OPInfo opi = m->getCurrentOPInfo();
|
||||
cout << "<CURROP0>"
|
||||
<< _(" Long name: '") << opi._longName << "' "
|
||||
<< _(" Short name: '") << opi._shortName << "' "
|
||||
<< _(" Numeric name: ") << opi._numericName
|
||||
<< _(" Mode: ");
|
||||
switch (opi._mode)
|
||||
{
|
||||
case AutomaticOPMode: cout << _("automatic"); break;
|
||||
case ManualOPMode: cout << _("manual"); break;
|
||||
case DeregisterOPMode: cout << _("deregister"); break;
|
||||
case ManualAutomaticOPMode: cout << _("manual/automatic"); break;
|
||||
}
|
||||
cout << endl;
|
||||
break;
|
||||
}
|
||||
case FacilityLockStateInfo:
|
||||
{
|
||||
int count = 0;
|
||||
vector<string> fclc = m->getFacilityLockCapabilities();
|
||||
for (vector<string>::iterator i = fclc.begin(); i != fclc.end(); ++i)
|
||||
if (*i != "AB" && *i != "AG" && *i != "AC")
|
||||
{
|
||||
cout << "<FLSTAT" << count << "> '" << *i << "'";
|
||||
try
|
||||
{
|
||||
if (m->getFacilityLockStatus(*i, VoiceFacility))
|
||||
cout << _(" Voice");
|
||||
}
|
||||
catch (GsmException &e)
|
||||
{
|
||||
cout << _(" unknown");
|
||||
}
|
||||
try
|
||||
{
|
||||
if (m->getFacilityLockStatus(*i, DataFacility))
|
||||
cout << _(" Data");
|
||||
}
|
||||
catch (GsmException &e)
|
||||
{
|
||||
cout << _(" unknown");
|
||||
}
|
||||
try
|
||||
{
|
||||
if (m->getFacilityLockStatus(*i, FaxFacility))
|
||||
cout << _(" Fax");
|
||||
}
|
||||
catch (GsmException &e)
|
||||
{
|
||||
cout << _(" unknown");
|
||||
}
|
||||
cout << endl;
|
||||
++count;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FacilityLockCapabilityInfo:
|
||||
{
|
||||
cout << "<FLCAP0> ";
|
||||
vector<string> fclc = m->getFacilityLockCapabilities();
|
||||
for (vector<string>::iterator i = fclc.begin(); i != fclc.end(); ++i)
|
||||
cout << "'" << *i << "' ";
|
||||
cout << endl;
|
||||
break;
|
||||
}
|
||||
case PasswordInfo:
|
||||
{
|
||||
vector<PWInfo> pwi = m->getPasswords();
|
||||
int count = 0;
|
||||
for (vector<PWInfo>::iterator i = pwi.begin(); i != pwi.end(); ++i)
|
||||
{
|
||||
cout << "<PW" << count << "> '"
|
||||
<< i->_facility << "' " << i->_maxPasswdLen << endl;
|
||||
++count;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CLIPInfo:
|
||||
{
|
||||
cout << "<CLIP0> " << (m->getNetworkCLIP() ? _("on") : _("off")) << endl;
|
||||
break;
|
||||
}
|
||||
case CallForwardingInfo:
|
||||
{
|
||||
for (int r = 0; r < 4; ++r)
|
||||
{
|
||||
string text;
|
||||
switch (r)
|
||||
{
|
||||
case 0: text = _("UnconditionalReason"); break;
|
||||
case 1: text = _("MobileBusyReason"); break;
|
||||
case 2: text = _("NoReplyReason"); break;
|
||||
case 3: text = _("NotReachableReason"); break;
|
||||
}
|
||||
ForwardInfo voice, fax, data;
|
||||
m->getCallForwardInfo((ForwardReason)r, voice, fax, data);
|
||||
cout << "<FORW" << r << ".";
|
||||
printForwardReason("0> " + text + _(" Voice"), voice);
|
||||
cout << "<FORW" << r << ".";
|
||||
printForwardReason("1> " + text + _(" Data"), data);
|
||||
cout << "<FORW" << r << ".";
|
||||
printForwardReason("2> " + text + _(" Fax"), fax);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BatteryInfo:
|
||||
{
|
||||
cout << "<BATT0> ";
|
||||
int bcs = m->getBatteryChargeStatus();
|
||||
switch (bcs)
|
||||
{
|
||||
case 0: cout << _("0 ME is powered by the battery") << endl; break;
|
||||
case 1: cout << _("1 ME has a battery connected, but is not powered by it")
|
||||
<< endl; break;
|
||||
case 2: cout << _("2 ME does not have a battery connected") << endl; break;
|
||||
case 3:
|
||||
cout << _("3 Recognized power fault, calls inhibited") << endl;
|
||||
break;
|
||||
}
|
||||
cout << "<BATT1> " << m->getBatteryCharge() << endl;
|
||||
break;
|
||||
}
|
||||
case BitErrorInfo:
|
||||
{
|
||||
cout << "<BITERR0> " << m->getBitErrorRate() << endl;
|
||||
break;
|
||||
}
|
||||
case SCAInfo:
|
||||
{
|
||||
cout << "<SCA0> " << m->getServiceCentreAddress() << endl;
|
||||
break;
|
||||
}
|
||||
case CharSetInfo:
|
||||
{
|
||||
cout << "<CSET0> ";
|
||||
vector<string> cs = m->getSupportedCharSets();
|
||||
for (vector<string>::iterator i = cs.begin(); i != cs.end(); ++i)
|
||||
cout << "'" << *i << "' ";
|
||||
cout << endl;
|
||||
cout << "<CSET1> '" << m->getCurrentCharSet() << "'" << endl;
|
||||
break;
|
||||
}
|
||||
case SignalInfo:
|
||||
{
|
||||
cout << "<SIG0> " << m->getSignalStrength() << endl;
|
||||
break;
|
||||
}
|
||||
case PhonebookInfo:
|
||||
{
|
||||
cout << "<PBOOK0> ";
|
||||
vector<string> pb = m->getSupportedPhonebooks();
|
||||
for (vector<string>::iterator i = pb.begin(); i != pb.end(); ++i)
|
||||
cout << "'" << *i << "' ";
|
||||
cout << endl;
|
||||
cout << "<PBOOK1> '" << m->getCurrentPhonebook() << "'" << endl;
|
||||
break;
|
||||
}
|
||||
case SignalToneInfo:
|
||||
{
|
||||
cout << "<SIGNAL0> ";
|
||||
IntRange st = m->getSupportedSignalTones();
|
||||
printIntRange(st);
|
||||
cout << endl;
|
||||
// cout << "<SIGT1> '" << m->getCurrentSignalTone() << "'" << endl;
|
||||
break;
|
||||
}
|
||||
case RingingToneInfo:
|
||||
{
|
||||
cout << "<RING0> ";
|
||||
IntRange rt = m->getSupportedRingingTones();
|
||||
printIntRange(rt);
|
||||
cout << endl;
|
||||
cout << "<RING1> " << m->getCurrentRingingTone() << endl;
|
||||
break;
|
||||
}
|
||||
case BinaryInfo:
|
||||
{
|
||||
cout << "<BIN0> ";
|
||||
vector<ParameterRange> bnr = m->getSupportedBinaryReads();
|
||||
for (vector<ParameterRange>::iterator i = bnr.begin(); i != bnr.end(); ++i)
|
||||
{
|
||||
printParameterRange(*i);
|
||||
cout << " ";
|
||||
}
|
||||
cout << endl;
|
||||
cout << "<BIN1> ";
|
||||
vector<ParameterRange> bnw = m->getSupportedBinaryWrites();
|
||||
for (vector<ParameterRange>::iterator i = bnw.begin(); i != bnw.end(); ++i)
|
||||
{
|
||||
printParameterRange(*i);
|
||||
cout << " ";
|
||||
}
|
||||
cout << endl;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// convert facility class string of the form "", "all", or any combination
|
||||
// of "v" (voice), "d" (data), or "f" (fax) to numeric form
|
||||
|
||||
FacilityClass strToFacilityClass(string facilityClassS)
|
||||
{
|
||||
facilityClassS = lowercase(facilityClassS);
|
||||
FacilityClass facilityClass = (FacilityClass)0;
|
||||
if (facilityClassS == "all" || facilityClassS == "")
|
||||
return (FacilityClass)ALL_FACILITIES;
|
||||
|
||||
// OR in facility class bits
|
||||
for (unsigned int i = 0; i < facilityClassS.length(); ++i)
|
||||
if (facilityClassS[i] == 'v')
|
||||
facilityClass = (FacilityClass)(facilityClass | VoiceFacility);
|
||||
else if (facilityClassS[i] == 'd')
|
||||
facilityClass = (FacilityClass)(facilityClass | DataFacility);
|
||||
else if (facilityClassS[i] == 'f')
|
||||
facilityClass = (FacilityClass)(facilityClass | FaxFacility);
|
||||
else
|
||||
throw GsmException(
|
||||
stringPrintf(_("unknown facility class parameter '%c'"),
|
||||
facilityClassS[i]), ParameterError);
|
||||
|
||||
return facilityClass;
|
||||
}
|
||||
|
||||
// check if argc - optind is in range min..max
|
||||
// throw exception otherwise
|
||||
|
||||
void checkParamCount(int optind, int argc, int min, int max)
|
||||
{
|
||||
int paramCount = argc - optind;
|
||||
if (paramCount < min)
|
||||
throw GsmException(stringPrintf(_("not enough parameters, minimum number "
|
||||
"of parameters is %d"), min),
|
||||
ParameterError);
|
||||
else if (paramCount > max)
|
||||
throw GsmException(stringPrintf(_("too many parameters, maximum number "
|
||||
"of parameters is %d"), max),
|
||||
ParameterError);
|
||||
}
|
||||
|
||||
// *** main program
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
try
|
||||
{
|
||||
// handle command line options
|
||||
string device = "/dev/mobilephone";
|
||||
string operation;
|
||||
string baudrate;
|
||||
string initString = DEFAULT_INIT_STRING;
|
||||
bool swHandshake = false;
|
||||
|
||||
int opt;
|
||||
int dummy;
|
||||
while((opt = getopt_long(argc, argv, "I:o:d:b:hvX", longOpts, &dummy))
|
||||
!= -1)
|
||||
switch (opt)
|
||||
{
|
||||
case 'X':
|
||||
swHandshake = true;
|
||||
break;
|
||||
case 'I':
|
||||
initString = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
device = optarg;
|
||||
break;
|
||||
case 'o':
|
||||
operation = optarg;
|
||||
break;
|
||||
case 'b':
|
||||
baudrate = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"),
|
||||
VERSION, __DATE__) << endl;
|
||||
exit(0);
|
||||
break;
|
||||
case 'h':
|
||||
cerr << argv[0] << _(": [-b baudrate][-d device][-h]"
|
||||
"[-I init string][-o operation]\n"
|
||||
" [-v][-X]{parameters}") << endl
|
||||
<< endl
|
||||
<< _(" -b, --baudrate baudrate to use for device "
|
||||
"(default: 38400)")
|
||||
<< endl
|
||||
<< _(" -d, --device sets the destination device to "
|
||||
"connect to") << endl
|
||||
<< _(" -h, --help prints this message") << endl
|
||||
<< _(" -I, --init device AT init sequence") << endl
|
||||
<< _(" -o, --operation operation to perform on the mobile \n"
|
||||
" phone with the specified parameters")
|
||||
<< endl
|
||||
<< _(" -v, --version prints version and exits") << endl
|
||||
<< _(" -X, --xonxoff switch on software handshake") << endl
|
||||
<< endl
|
||||
<< _(" parameters parameters to use for the operation\n"
|
||||
" (if an operation is given) or\n"
|
||||
" a specification which kind of\n"
|
||||
" information to read from the mobile "
|
||||
"phone")
|
||||
<< endl << endl
|
||||
<< _("Refer to gsmctl(1) for details on the available parameters"
|
||||
" and operations.")
|
||||
<< endl << endl;
|
||||
exit(0);
|
||||
break;
|
||||
case '?':
|
||||
throw GsmException(_("unknown option"), ParameterError);
|
||||
break;
|
||||
}
|
||||
|
||||
// open the port and ME/TA
|
||||
m = new SieMe(new
|
||||
#ifdef WIN32
|
||||
Win32SerialPort
|
||||
#else
|
||||
UnixSerialPort
|
||||
#endif
|
||||
(device,
|
||||
baudrate == "" ?
|
||||
DEFAULT_BAUD_RATE :
|
||||
baudRateStrToSpeed(baudrate),
|
||||
initString, swHandshake));
|
||||
|
||||
if (operation == "")
|
||||
{ // process info parameters
|
||||
for (int i = optind; i < argc; ++i)
|
||||
{
|
||||
string param = lowercase(argv[i]);
|
||||
if (param == "all")
|
||||
for (int ip = MeInfo; ip <= SignalInfo; ++ip)
|
||||
printInfo((InfoParameter)ip);
|
||||
else if (param == "me")
|
||||
printInfo(MeInfo);
|
||||
else if (param == "op")
|
||||
printInfo(OperatorInfo);
|
||||
else if (param == "currop")
|
||||
printInfo(CurrentOperatorInfo);
|
||||
else if (param == "flstat")
|
||||
printInfo(FacilityLockStateInfo);
|
||||
else if (param == "flcap")
|
||||
printInfo(FacilityLockCapabilityInfo);
|
||||
else if (param == "pw")
|
||||
printInfo(PasswordInfo);
|
||||
else if (param == "clip")
|
||||
printInfo(CLIPInfo);
|
||||
else if (param == "forw")
|
||||
printInfo(CallForwardingInfo);
|
||||
else if (param == "batt")
|
||||
printInfo(BatteryInfo);
|
||||
else if (param == "biterr")
|
||||
printInfo(BitErrorInfo);
|
||||
else if (param == "sig")
|
||||
printInfo(SignalInfo);
|
||||
else if (param == "sca")
|
||||
printInfo(SCAInfo);
|
||||
else if (param == "cset")
|
||||
printInfo(CharSetInfo);
|
||||
else if (param == "pbook")
|
||||
printInfo(PhonebookInfo);
|
||||
else if (param == "signal")
|
||||
printInfo(SignalToneInfo);
|
||||
else if (param == "ring")
|
||||
printInfo(RingingToneInfo);
|
||||
else if (param == "binary")
|
||||
printInfo(BinaryInfo);
|
||||
else
|
||||
throw GsmException(
|
||||
stringPrintf(_("unknown information parameter '%s'"),
|
||||
param.c_str()),
|
||||
ParameterError);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // process operation
|
||||
operation = lowercase(operation);
|
||||
if (operation == "dial")
|
||||
{
|
||||
// dial: number
|
||||
checkParamCount(optind, argc, 1, 1);
|
||||
|
||||
m->dial(argv[optind]);
|
||||
|
||||
// wait for keypress from stdin
|
||||
char c;
|
||||
read(1, &c, 1);
|
||||
}
|
||||
else if (operation == "setop")
|
||||
{
|
||||
// setop: opmode numeric FIXME allow long and numeric too
|
||||
checkParamCount(optind, argc, 2, 2);
|
||||
string opmodeS = lowercase(argv[optind]);
|
||||
OPModes opmode;
|
||||
if (opmodeS == "automatic")
|
||||
opmode = AutomaticOPMode;
|
||||
else if (opmodeS == "manual")
|
||||
opmode = ManualOPMode;
|
||||
else if (opmodeS == "deregister")
|
||||
opmode = DeregisterOPMode;
|
||||
else if (opmodeS == "manualautomatic")
|
||||
opmode = ManualAutomaticOPMode;
|
||||
else
|
||||
throw GsmException(stringPrintf(_("unknown opmode parameter '%s'"),
|
||||
opmodeS.c_str()), ParameterError);
|
||||
|
||||
m->setCurrentOPInfo(opmode, "" , "", checkNumber(argv[optind + 1]));
|
||||
}
|
||||
else if (operation == "lock")
|
||||
{
|
||||
// lock: facility [facilityclass] [passwd]
|
||||
checkParamCount(optind, argc, 1, 3);
|
||||
string passwd = (argc - optind == 3) ?
|
||||
(string)argv[optind + 2] : (string)"";
|
||||
|
||||
m->lockFacility(argv[optind],
|
||||
(argc - optind >= 2) ?
|
||||
strToFacilityClass(argv[optind + 1]) :
|
||||
(FacilityClass)ALL_FACILITIES,
|
||||
passwd);
|
||||
}
|
||||
else if (operation == "unlock")
|
||||
{
|
||||
// unlock: facility [facilityclass] [passwd]
|
||||
checkParamCount(optind, argc, 1, 3);
|
||||
string passwd = argc - optind == 3 ? argv[optind + 2] : "";
|
||||
|
||||
m->unlockFacility(argv[optind],
|
||||
(argc - optind >= 2) ?
|
||||
strToFacilityClass(argv[optind + 1]) :
|
||||
(FacilityClass)ALL_FACILITIES,
|
||||
passwd);
|
||||
}
|
||||
else if (operation == "setpw")
|
||||
{
|
||||
// set password: facility oldpasswd newpasswd
|
||||
checkParamCount(optind, argc, 1, 3);
|
||||
string oldPasswd = argc - optind >= 2 ? argv[optind + 1] : "";
|
||||
string newPasswd = argc - optind == 3 ? argv[optind + 2] : "";
|
||||
|
||||
m->setPassword(argv[optind], oldPasswd, newPasswd);
|
||||
}
|
||||
else if (operation == "forw")
|
||||
{
|
||||
// call forwarding: mode reason number [facilityclass] [forwardtime]
|
||||
checkParamCount(optind, argc, 2, 5);
|
||||
|
||||
// get optional parameters facility class and forwardtime
|
||||
int forwardTime = argc - optind == 5 ? checkNumber(argv[optind + 4]) :
|
||||
NOT_SET;
|
||||
FacilityClass facilityClass =
|
||||
argc - optind >= 4 ? strToFacilityClass(argv[optind + 3]) :
|
||||
(FacilityClass)ALL_FACILITIES;
|
||||
|
||||
// get forward reason
|
||||
string reasonS = lowercase(argv[optind + 1]);
|
||||
ForwardReason reason;
|
||||
if (reasonS == "unconditional")
|
||||
reason = UnconditionalReason;
|
||||
else if (reasonS == "mobilebusy")
|
||||
reason = MobileBusyReason;
|
||||
else if (reasonS == "noreply")
|
||||
reason = NoReplyReason;
|
||||
else if (reasonS == "notreachable")
|
||||
reason = NotReachableReason;
|
||||
else if (reasonS == "all")
|
||||
reason = AllReasons;
|
||||
else if (reasonS == "allconditional")
|
||||
reason = AllConditionalReasons;
|
||||
else
|
||||
throw GsmException(
|
||||
stringPrintf(_("unknown forward reason parameter '%s'"),
|
||||
reasonS.c_str()), ParameterError);
|
||||
|
||||
// get mode
|
||||
string modeS = lowercase(argv[optind]);
|
||||
ForwardMode mode;
|
||||
if (modeS == "disable")
|
||||
mode = DisableMode;
|
||||
else if (modeS == "enable")
|
||||
mode = EnableMode;
|
||||
else if (modeS == "register")
|
||||
mode = RegistrationMode;
|
||||
else if (modeS == "erase")
|
||||
mode = ErasureMode;
|
||||
else
|
||||
throw GsmException(
|
||||
stringPrintf(_("unknown forward mode parameter '%s'"),
|
||||
modeS.c_str()), ParameterError);
|
||||
|
||||
m->setCallForwarding(reason, mode,
|
||||
(argc - optind >= 3) ? argv[optind + 2] : "",
|
||||
"", // subaddr
|
||||
facilityClass, forwardTime);
|
||||
}
|
||||
else if (operation == "setsca")
|
||||
{
|
||||
// set sca: number
|
||||
checkParamCount(optind, argc, 1, 1);
|
||||
m->setServiceCentreAddress(argv[optind]);
|
||||
}
|
||||
else if (operation == "cset")
|
||||
{
|
||||
// set charset: string
|
||||
checkParamCount(optind, argc, 1, 1);
|
||||
m->setCharSet(argv[optind]);
|
||||
}
|
||||
else if (operation == "signal")
|
||||
{
|
||||
// play signal tone: int
|
||||
checkParamCount(optind, argc, 1, 1);
|
||||
int tone = atoi(argv[optind]);
|
||||
m->playSignalTone(tone);
|
||||
}
|
||||
else if (operation == "setrt")
|
||||
{
|
||||
// set ringing tone: int int
|
||||
checkParamCount(optind, argc, 2, 2);
|
||||
int tone = atoi(argv[optind]);
|
||||
int volume = atoi(argv[optind + 1]);
|
||||
m->setRingingTone(tone, volume);
|
||||
}
|
||||
else if (operation == "playrt")
|
||||
{
|
||||
// play/stop ringing tone
|
||||
m->toggleRingingTone();
|
||||
}
|
||||
else
|
||||
throw GsmException(stringPrintf(_("unknown operation '%s'"),
|
||||
operation.c_str()), ParameterError);
|
||||
}
|
||||
}
|
||||
catch (GsmException &ge)
|
||||
{
|
||||
cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,292 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsmsiexfer.cc
|
||||
// *
|
||||
// * Purpose: Siemens ME file transfer program
|
||||
// *
|
||||
// * Author: Christian W. Zuckschwerdt <zany@triq.net>
|
||||
// *
|
||||
// * Created: 2001-12-16
|
||||
// *************************************************************************
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <gsm_config.h>
|
||||
#endif
|
||||
#include <gsmlib/gsm_nls.h>
|
||||
#include <string>
|
||||
#ifdef WIN32
|
||||
#include <gsmlib/gsm_win32_serial.h>
|
||||
#else
|
||||
#include <gsmlib/gsm_unix_serial.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#if defined(HAVE_GETOPT_LONG) || defined(WIN32)
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <gsmlib/gsm_me_ta.h>
|
||||
#include <gsm_sie_me.h>
|
||||
#include <gsmlib/gsm_util.h>
|
||||
#include <gsmlib/gsm_sorted_phonebook.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace gsmlib;
|
||||
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
static struct option longOpts[] =
|
||||
{
|
||||
{"xonxoff", no_argument, (int*)NULL, 'X'},
|
||||
{"init", required_argument, (int*)NULL, 'I'},
|
||||
{"destination", required_argument, (int*)NULL, 'd'},
|
||||
{"source", required_argument, (int*)NULL, 's'},
|
||||
{"baudrate", required_argument, (int*)NULL, 'b'},
|
||||
{"type", required_argument, (int*)NULL, 't'},
|
||||
{"subtype", required_argument, (int*)NULL, 'i'},
|
||||
{"help", no_argument, (int*)NULL, 'h'},
|
||||
{"version", no_argument, (int*)NULL, 'v'},
|
||||
{"verbose", no_argument, (int*)NULL, 'V'},
|
||||
{(char*)NULL, 0, (int*)NULL, 0}
|
||||
};
|
||||
#else
|
||||
#define getopt_long(argc, argv, options, longopts, indexptr) \
|
||||
getopt(argc, argv, options)
|
||||
#endif
|
||||
|
||||
// I f*ck up this file IO thing.
|
||||
|
||||
// read binary object from stdin
|
||||
BinaryObject readBinaryFile(istream &ifs, string filename)
|
||||
{
|
||||
size_t size = 10000; // Bad coder, no biscuits!
|
||||
BinaryObject bnr;
|
||||
bnr._data = new unsigned char[size];
|
||||
ifs.read((char*)bnr._data, size);
|
||||
bnr._size = ifs.gcount();
|
||||
return bnr;
|
||||
}
|
||||
|
||||
// read binary object from file
|
||||
BinaryObject readFile(string filename)
|
||||
{
|
||||
// open the file
|
||||
ifstream ifs(filename.c_str());
|
||||
if (ifs.bad())
|
||||
throw GsmException(stringPrintf(_("cannot open file '%s'"),
|
||||
filename.c_str()),
|
||||
OSError);
|
||||
// and read the file
|
||||
return readBinaryFile(ifs, filename);
|
||||
}
|
||||
|
||||
// read binary object from stdin
|
||||
BinaryObject readFile(bool fromStdin)
|
||||
{
|
||||
// read from stdin
|
||||
// if (fromStdin)
|
||||
return readBinaryFile(cin, (string)_("<STDIN>"));
|
||||
}
|
||||
|
||||
// write binary object to file
|
||||
void writeBinaryFile(ostream &ofs, string filename, BinaryObject bnw)
|
||||
{
|
||||
// well just dump the data
|
||||
ofs.write((char*)bnw._data, bnw._size);
|
||||
}
|
||||
|
||||
// write binary object
|
||||
void writeFile(string filename, BinaryObject obj)
|
||||
{
|
||||
// open the file
|
||||
ofstream ofs(filename.c_str());
|
||||
if (ofs.bad())
|
||||
throw GsmException(stringPrintf(_("cannot open file '%s'"),
|
||||
filename.c_str()),
|
||||
OSError);
|
||||
// and read the file
|
||||
writeBinaryFile(ofs, filename, obj);
|
||||
}
|
||||
|
||||
// write binary object to stdout
|
||||
void writeFile(bool toStdout, BinaryObject obj)
|
||||
{
|
||||
// if (toStdout)
|
||||
writeBinaryFile(cout, (string)_("<STDIN>"), obj);
|
||||
}
|
||||
|
||||
// *** main program
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
try
|
||||
{
|
||||
// handle command line options
|
||||
string destination;
|
||||
string source;
|
||||
string baudrate;
|
||||
string type;
|
||||
string subtype;
|
||||
int subtypeN;
|
||||
bool verbose = false;
|
||||
string initString = DEFAULT_INIT_STRING;
|
||||
bool swHandshake = false;
|
||||
Ref<SieMe> sourceMeTa, destMeTa;
|
||||
BinaryObject sourceObject;
|
||||
|
||||
int opt;
|
||||
int dummy;
|
||||
while((opt = getopt_long(argc, argv, "XI:s:d:b:hvVt:i:", longOpts,
|
||||
&dummy))
|
||||
!= -1)
|
||||
switch (opt)
|
||||
{
|
||||
case 'X':
|
||||
swHandshake = true;
|
||||
break;
|
||||
case 'I':
|
||||
initString = optarg;
|
||||
break;
|
||||
case 'V':
|
||||
verbose = true;
|
||||
break;
|
||||
case 't':
|
||||
type = optarg;
|
||||
break;
|
||||
case 'i':
|
||||
subtype = optarg;
|
||||
subtypeN = atoi(optarg);
|
||||
break;
|
||||
case 'd':
|
||||
destination = optarg;
|
||||
break;
|
||||
case 's':
|
||||
source = optarg;
|
||||
break;
|
||||
case 'b':
|
||||
baudrate = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"),
|
||||
VERSION, __DATE__) << endl;
|
||||
exit(0);
|
||||
break;
|
||||
case 'h':
|
||||
cerr << argv[0] << _(": [-b baudrate][-c][-d device or file][-h]"
|
||||
"[-I init string]\n"
|
||||
" [-p phonebook name][-s device or file]"
|
||||
"[-t charset][-v]"
|
||||
"[-V][-y][-X]") << endl
|
||||
<< endl
|
||||
<< _(" -b, --baudrate baudrate to use for device "
|
||||
"(default: 38400)")
|
||||
<< endl
|
||||
<< _(" -c, --copy copy source entries to destination")
|
||||
<< endl
|
||||
<< _(" -d, --destination sets the destination device to "
|
||||
"connect \n"
|
||||
" to, or the file to write") << endl
|
||||
<< _(" -D, --destination-backend sets the destination backend")
|
||||
<< endl
|
||||
<< _(" -h, --help prints this message") << endl
|
||||
<< _(" -i, --index takes index positions into account")
|
||||
<< endl
|
||||
<< _(" -I, --init device AT init sequence") << endl
|
||||
<< _(" -p, --phonebook name of phonebook to use") << endl
|
||||
<< _(" -s, --source sets the source device to connect to,\n"
|
||||
" or the file to read") << endl
|
||||
<< _(" -t, --charset sets the character set to use for\n"
|
||||
" phonebook entries") << endl
|
||||
<< _(" -S, --source-backend sets the source backend")
|
||||
<< endl
|
||||
<< _(" -v, --version prints version and exits") << endl
|
||||
<< _(" -V, --verbose print detailed progress messages")
|
||||
<< endl
|
||||
<< _(" -X, --xonxoff switch on software handshake") << endl
|
||||
<< _(" -y, --synchronize synchronize destination with source\n"
|
||||
" entries (destination is overwritten)\n"
|
||||
" (see gsmpb(1) for details)")
|
||||
<< endl << endl;
|
||||
exit(0);
|
||||
break;
|
||||
case '?':
|
||||
throw GsmException(_("unknown option"), ParameterError);
|
||||
break;
|
||||
}
|
||||
|
||||
// check if all parameters all present
|
||||
if (destination == "" || source == "")
|
||||
throw GsmException(_("both source and destination must be given"),
|
||||
ParameterError);
|
||||
|
||||
// start accessing source mobile phone or file
|
||||
if (source == "-")
|
||||
sourceObject = readFile(true);
|
||||
else if (isFile(source))
|
||||
sourceObject = readFile(source);
|
||||
else
|
||||
{
|
||||
if (type == "")
|
||||
throw GsmException(_("type be given"), ParameterError);
|
||||
if (subtype == "")
|
||||
throw GsmException(_("subtype be given"), ParameterError);
|
||||
|
||||
sourceMeTa = new SieMe(new
|
||||
#ifdef WIN32
|
||||
Win32SerialPort
|
||||
#else
|
||||
UnixSerialPort
|
||||
#endif
|
||||
(source,
|
||||
baudrate == "" ? DEFAULT_BAUD_RATE :
|
||||
baudRateStrToSpeed(baudrate), initString,
|
||||
swHandshake));
|
||||
sourceObject = sourceMeTa->getBinary(type, subtypeN);
|
||||
}
|
||||
|
||||
// make sure destination.c_str file exists
|
||||
if (destination != "")
|
||||
{
|
||||
try
|
||||
{
|
||||
ofstream f(destination.c_str(), ios::out | ios::app);
|
||||
}
|
||||
catch (exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// start accessing destination mobile phone or file
|
||||
if (destination == "-")
|
||||
writeFile(true, sourceObject);
|
||||
else if (isFile(destination))
|
||||
writeFile(destination, sourceObject);
|
||||
else
|
||||
{
|
||||
if (type == "")
|
||||
throw GsmException(_("type must be given"), ParameterError);
|
||||
if (subtype == "")
|
||||
throw GsmException(_("subtype must be given"), ParameterError);
|
||||
|
||||
destMeTa = new SieMe(new
|
||||
#ifdef WIN32
|
||||
Win32SerialPort
|
||||
#else
|
||||
UnixSerialPort
|
||||
#endif
|
||||
(destination,
|
||||
baudrate == "" ? DEFAULT_BAUD_RATE :
|
||||
baudRateStrToSpeed(baudrate), initString,
|
||||
swHandshake));
|
||||
destMeTa->setBinary(type, subtypeN, sourceObject);
|
||||
}
|
||||
}
|
||||
catch (GsmException &ge)
|
||||
{
|
||||
cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
--- ./gsmlib/gsm_me_ta.h~ 2006-03-09 19:15:59.000000000 +0000
|
||||
+++ ./gsmlib/gsm_me_ta.h 2006-03-09 19:16:31.000000000 +0000
|
||||
@@ -291,8 +291,8 @@
|
||||
// 3 disable phone receive RF circuits only
|
||||
// 4 disable phone both transmit and receive RF circuits
|
||||
// 5...127 implementation-defined
|
||||
- int MeTa::getFunctionalityLevel() throw(GsmException);
|
||||
- void MeTa::setFunctionalityLevel(int level) throw(GsmException);
|
||||
+ int getFunctionalityLevel() throw(GsmException);
|
||||
+ void setFunctionalityLevel(int level) throw(GsmException);
|
||||
|
||||
// return battery charge status (+CBC):
|
||||
// 0 ME is powered by the battery
|
||||
@@ -386,13 +386,13 @@
|
||||
void setCallWaitingLockStatus(FacilityClass cl,
|
||||
bool lock)throw(GsmException);
|
||||
|
||||
- void MeTa::setCLIRPresentation(bool enable) throw(GsmException);
|
||||
+ void setCLIRPresentation(bool enable) throw(GsmException);
|
||||
//(+CLIR)
|
||||
|
||||
// 0:according to the subscription of the CLIR service
|
||||
// 1:CLIR invocation
|
||||
// 2:CLIR suppression
|
||||
- int MeTa::getCLIRPresentation() throw(GsmException);
|
||||
+ int getCLIRPresentation() throw(GsmException);
|
||||
|
||||
friend class Phonebook;
|
||||
friend class SMSStore;
|
@ -0,0 +1,344 @@
|
||||
/* gsm_config.h.in. Generated from configure.in by autoheader. */
|
||||
/* used by libtool*/
|
||||
#define PACKAGE 0
|
||||
|
||||
/* used by libtool*/
|
||||
#define VERSION 0
|
||||
|
||||
/* Define if getopt_long() available */
|
||||
#undef HAVE_GETOPT_LONG
|
||||
|
||||
/* Define if alarm() available */
|
||||
#undef HAVE_ALARM
|
||||
|
||||
/* Define if netinet/in.h header available */
|
||||
#undef HAVE_NETINET_IN_H
|
||||
|
||||
/* Define if string.h header available */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define for NLS */
|
||||
#undef ENABLE_NLS
|
||||
#undef HAVE_CATGETS
|
||||
#undef HAVE_GETTEXT
|
||||
#undef HAVE_LC_MESSAGES
|
||||
#undef HAVE_STPCPY
|
||||
|
||||
/* Define LOCALEDIR */
|
||||
#define LOCALEDIR "/usr/share/locale"
|
||||
|
||||
/* Define if libintl.h header available */
|
||||
#undef HAVE_LIBINTL_H
|
||||
|
||||
/* Define if vsnprintf() function available */
|
||||
#undef HAVE_VSNPRINTF
|
||||
|
||||
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
|
||||
systems. This function is required for `alloca.c' support on those systems.
|
||||
*/
|
||||
#undef CRAY_STACKSEG_END
|
||||
|
||||
/* Define to 1 if using `alloca.c'. */
|
||||
#undef C_ALLOCA
|
||||
|
||||
/* Define to 1 if translation of program messages to the user's native
|
||||
language is requested. */
|
||||
#undef ENABLE_NLS
|
||||
|
||||
/* Define to 1 if you have `alloca', as a function or macro. */
|
||||
#undef HAVE_ALLOCA
|
||||
|
||||
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
|
||||
*/
|
||||
#undef HAVE_ALLOCA_H
|
||||
|
||||
/* Define to 1 if you have the <argz.h> header file. */
|
||||
#undef HAVE_ARGZ_H
|
||||
|
||||
/* Define to 1 if you have the `asprintf' function. */
|
||||
#undef HAVE_ASPRINTF
|
||||
|
||||
/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the
|
||||
CoreFoundation framework. */
|
||||
#undef HAVE_CFLOCALECOPYCURRENT
|
||||
|
||||
/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in
|
||||
the CoreFoundation framework. */
|
||||
#undef HAVE_CFPREFERENCESCOPYAPPVALUE
|
||||
|
||||
/* Define if the GNU dcgettext() function is already present or preinstalled.
|
||||
*/
|
||||
#undef HAVE_DCGETTEXT
|
||||
|
||||
/* Define to 1 if you have the declaration of `feof_unlocked', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_FEOF_UNLOCKED
|
||||
|
||||
/* Define to 1 if you have the declaration of `fgets_unlocked', and to 0 if
|
||||
you don't. */
|
||||
#undef HAVE_DECL_FGETS_UNLOCKED
|
||||
|
||||
/* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_GETC_UNLOCKED
|
||||
|
||||
/* Define to 1 if you have the declaration of `_snprintf', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL__SNPRINTF
|
||||
|
||||
/* Define to 1 if you have the declaration of `_snwprintf', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL__SNWPRINTF
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the `fwprintf' function. */
|
||||
#undef HAVE_FWPRINTF
|
||||
|
||||
/* Define to 1 if you have the `getcwd' function. */
|
||||
#undef HAVE_GETCWD
|
||||
|
||||
/* Define to 1 if you have the `getegid' function. */
|
||||
#undef HAVE_GETEGID
|
||||
|
||||
/* Define to 1 if you have the `geteuid' function. */
|
||||
#undef HAVE_GETEUID
|
||||
|
||||
/* Define to 1 if you have the `getgid' function. */
|
||||
#undef HAVE_GETGID
|
||||
|
||||
/* Define to 1 if you have the `getpagesize' function. */
|
||||
#undef HAVE_GETPAGESIZE
|
||||
|
||||
/* Define if the GNU gettext() function is already present or preinstalled. */
|
||||
#undef HAVE_GETTEXT
|
||||
|
||||
/* Define to 1 if you have the `getuid' function. */
|
||||
#undef HAVE_GETUID
|
||||
|
||||
/* Define if you have the iconv() function. */
|
||||
#undef HAVE_ICONV
|
||||
|
||||
/* Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>. */
|
||||
#undef HAVE_INTMAX_T
|
||||
|
||||
/* Define if <inttypes.h> exists and doesn't clash with <sys/types.h>. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define if <inttypes.h> exists, doesn't clash with <sys/types.h>, and
|
||||
declares uintmax_t. */
|
||||
#undef HAVE_INTTYPES_H_WITH_UINTMAX
|
||||
|
||||
/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
|
||||
#undef HAVE_LANGINFO_CODESET
|
||||
|
||||
/* Define if your <locale.h> file defines LC_MESSAGES. */
|
||||
#undef HAVE_LC_MESSAGES
|
||||
|
||||
/* Define to 1 if you have the `intl' library (-lintl). */
|
||||
#undef HAVE_LIBINTL
|
||||
|
||||
/* Define to 1 if you have the <libintl.h> header file. */
|
||||
#undef HAVE_LIBINTL_H
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
#undef HAVE_LOCALE_H
|
||||
|
||||
/* Define if you have the 'long double' type. */
|
||||
#undef HAVE_LONG_DOUBLE
|
||||
|
||||
/* Define if you have the 'long long' type. */
|
||||
#undef HAVE_LONG_LONG
|
||||
|
||||
/* Define to 1 if you have the <malloc.h> header file. */
|
||||
#undef HAVE_MALLOC_H
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `mempcpy' function. */
|
||||
#undef HAVE_MEMPCPY
|
||||
|
||||
/* Define to 1 if you have a working `mmap' system call. */
|
||||
#undef HAVE_MMAP
|
||||
|
||||
/* Define to 1 if you have the `munmap' function. */
|
||||
#undef HAVE_MUNMAP
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#undef HAVE_NETINET_IN_H
|
||||
|
||||
/* Define to 1 if you have the <nl_types.h> header file. */
|
||||
#undef HAVE_NL_TYPES_H
|
||||
|
||||
/* Define if your printf() function supports format strings with positions. */
|
||||
#undef HAVE_POSIX_PRINTF
|
||||
|
||||
/* Define to 1 if you have the `putenv' function. */
|
||||
#undef HAVE_PUTENV
|
||||
|
||||
/* Define to 1 if you have the `setenv' function. */
|
||||
#undef HAVE_SETENV
|
||||
|
||||
/* Define to 1 if you have the `setlocale' function. */
|
||||
#undef HAVE_SETLOCALE
|
||||
|
||||
/* Define to 1 if you have the `snprintf' function. */
|
||||
#undef HAVE_SNPRINTF
|
||||
|
||||
/* Define to 1 if you have the <stddef.h> header file. */
|
||||
#undef HAVE_STDDEF_H
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define if <stdint.h> exists, doesn't clash with <sys/types.h>, and declares
|
||||
uintmax_t. */
|
||||
#undef HAVE_STDINT_H_WITH_UINTMAX
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the `stpcpy' function. */
|
||||
#undef HAVE_STPCPY
|
||||
|
||||
/* Define to 1 if you have the `strcasecmp' function. */
|
||||
#undef HAVE_STRCASECMP
|
||||
|
||||
/* Define to 1 if you have the `strdup' function. */
|
||||
#undef HAVE_STRDUP
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the `strtoul' function. */
|
||||
#undef HAVE_STRTOUL
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#undef HAVE_SYS_PARAM_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the `tsearch' function. */
|
||||
#undef HAVE_TSEARCH
|
||||
|
||||
/* Define if you have the 'uintmax_t' type in <stdint.h> or <inttypes.h>. */
|
||||
#undef HAVE_UINTMAX_T
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define if you have the 'unsigned long long' type. */
|
||||
#undef HAVE_UNSIGNED_LONG_LONG
|
||||
|
||||
/* Define if you have the 'wchar_t' type. */
|
||||
#undef HAVE_WCHAR_T
|
||||
|
||||
/* Define to 1 if you have the `wcslen' function. */
|
||||
#undef HAVE_WCSLEN
|
||||
|
||||
/* Define if you have the 'wint_t' type. */
|
||||
#undef HAVE_WINT_T
|
||||
|
||||
/* Define to 1 if you have the `__argz_count' function. */
|
||||
#undef HAVE___ARGZ_COUNT
|
||||
|
||||
/* Define to 1 if you have the `__argz_next' function. */
|
||||
#undef HAVE___ARGZ_NEXT
|
||||
|
||||
/* Define to 1 if you have the `__argz_stringify' function. */
|
||||
#undef HAVE___ARGZ_STRINGIFY
|
||||
|
||||
/* Define to 1 if you have the `__fsetlocking' function. */
|
||||
#undef HAVE___FSETLOCKING
|
||||
|
||||
/* Define as const if the declaration of iconv() needs const. */
|
||||
#undef ICONV_CONST
|
||||
|
||||
/* Define if integer division by zero raises signal SIGFPE. */
|
||||
#undef INTDIV0_RAISES_SIGFPE
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define if <inttypes.h> exists and defines unusable PRI* macros. */
|
||||
#undef PRI_MACROS_BROKEN
|
||||
|
||||
/* The size of a `unsigned int', as computed by sizeof. */
|
||||
#undef SIZEOF_UNSIGNED_INT
|
||||
|
||||
/* The size of a `unsigned long int', as computed by sizeof. */
|
||||
#undef SIZEOF_UNSIGNED_LONG_INT
|
||||
|
||||
/* The size of a `unsigned short int', as computed by sizeof. */
|
||||
#undef SIZEOF_UNSIGNED_SHORT_INT
|
||||
|
||||
/* Define as the maximum value of type 'size_t', if the system doesn't define
|
||||
it. */
|
||||
#undef SIZE_MAX
|
||||
|
||||
/* If using the C implementation of alloca, define if you know the
|
||||
direction of stack growth for your system; otherwise it will be
|
||||
automatically deduced at run-time.
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||
#undef STACK_DIRECTION
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
#undef const
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
#undef inline
|
||||
#endif
|
||||
|
||||
/* Define to `long' if <sys/types.h> does not define. */
|
||||
#undef off_t
|
||||
|
||||
/* Define as the type of the result of subtracting two pointers, if the system
|
||||
doesn't define it. */
|
||||
#undef ptrdiff_t
|
||||
|
||||
/* Define to empty if the C compiler doesn't support this keyword. */
|
||||
#undef signed
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> does not define. */
|
||||
#undef size_t
|
||||
|
||||
/* Define to unsigned long or unsigned long long if <stdint.h> and
|
||||
<inttypes.h> don't define. */
|
||||
#undef uintmax_t
|
@ -0,0 +1,11 @@
|
||||
var/spool/sms/queue1
|
||||
var/spool/sms/queue2
|
||||
var/spool/sms/queue3
|
||||
var/spool/sms/sent1
|
||||
var/spool/sms/sent2
|
||||
var/spool/sms/sent3
|
||||
var/spool/sms/failed1
|
||||
var/spool/sms/failed2
|
||||
var/spool/sms/failed3
|
||||
var/spool/sms/tmp
|
||||
var/run/gsm-utils
|
@ -0,0 +1,28 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
# create gsmsms group if necessary.
|
||||
if ! grep -q ^gsmsms: /etc/group; then
|
||||
# echo Adding system group: gsmsms.
|
||||
addgroup gsmsms
|
||||
fi
|
||||
|
||||
# create gsmsms user if necessary.
|
||||
if ! grep -q ^gsmsms: /etc/passwd; then
|
||||
# echo Adding system user: gsmsms.
|
||||
adduser --system --ingroup gsmsms \
|
||||
--no-create-home --home /var/spool/sms gsmsms
|
||||
fi
|
||||
|
||||
# allow gsmsms to use serial lines
|
||||
if ! groups gsmsms | grep -q dialout ; then
|
||||
adduser gsmsms dialout
|
||||
fi
|
||||
|
||||
# echo Updating spool directory structure: /var/spool/sms
|
||||
chown -R gsmsms:gsmsms /var/spool/sms /var/run/gsm-utils
|
||||
chmod 700 /var/spool/sms/*
|
||||
chmod 750 /var/spool/sms
|
||||
chmod 730 /var/spool/sms/queue* /var/spool/sms/tmp
|
||||
|
||||
# Add the rest automatically..
|
||||
#DEBHELPER#
|
@ -0,0 +1,7 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
deluser gsmsms || true
|
||||
delgroup gsmsms || true
|
||||
|
||||
# Add the rest automatically..
|
||||
#DEBHELPER#
|
@ -0,0 +1,2 @@
|
||||
gsmsmsspool.1
|
||||
gsmsmsrequeue.8
|
@ -0,0 +1,92 @@
|
||||
%define LIBVER 1.0.4
|
||||
Summary: Library to access GSM mobile phones through GSM modems
|
||||
Name: gsmlib
|
||||
Version: 1.10
|
||||
Release: 1
|
||||
Source: gsmlib-%{version}.tar.gz
|
||||
Group: System Environment/Libraries
|
||||
Copyright: GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
URL: http://www.pxh.de/fs/gsmlib/
|
||||
Vendor: Peter Hofmann <software@pxh.de>
|
||||
Buildroot: /var/tmp/gsmlib-root
|
||||
|
||||
%package devel
|
||||
Summary: Development tools for programs which will use the gsmlib library.
|
||||
Group: Development/Libraries
|
||||
Requires: gsmlib
|
||||
|
||||
%package ext
|
||||
Summary: Extensions to gsmlib to support non-standard phone features.
|
||||
Group: Development/Libraries
|
||||
Requires: gsmlib
|
||||
|
||||
%description
|
||||
This distribution contains a library to access
|
||||
GSM mobile phones through GSM modems. Features include:
|
||||
* modification of phonebooks stored in the
|
||||
mobile phone or on the SIM card
|
||||
* reading and writing of SMS messages stored in
|
||||
the mobile phone
|
||||
* sending and reception of SMS messages
|
||||
Additionally, some simple command line programs are
|
||||
provided to use these functionalities.
|
||||
|
||||
%description devel
|
||||
The gsmlib-devel package includes the header files and static libraries
|
||||
necessary for developing programs which use the gsmlib library.
|
||||
|
||||
%description ext
|
||||
The extension package of gsmlib contains programs, libraries, and
|
||||
documentation to support non-standard features of GSM phones. The
|
||||
following phones/phone types are currently supported:
|
||||
* Siemens GSM phones
|
||||
|
||||
%prep
|
||||
%setup
|
||||
|
||||
%build
|
||||
CXXFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr
|
||||
make
|
||||
|
||||
%install
|
||||
make DESTDIR="$RPM_BUILD_ROOT" install
|
||||
|
||||
%post -p /sbin/ldconfig
|
||||
|
||||
%postun -p /sbin/ldconfig
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
/usr/lib/libgsmme.so
|
||||
/usr/lib/libgsmme.so.%{LIBVER}
|
||||
/usr/bin/gsmsmsstore
|
||||
/usr/bin/gsmctl
|
||||
/usr/bin/gsmsmsd
|
||||
/usr/bin/gsmpb
|
||||
/usr/bin/gsmsendsms
|
||||
/usr/man/man1/gsmctl.1.gz
|
||||
/usr/man/man7/gsminfo.7.gz
|
||||
/usr/man/man1/gsmpb.1.gz
|
||||
/usr/man/man1/gsmsendsms.1.gz
|
||||
/usr/man/man8/gsmsmsd.8.gz
|
||||
/usr/man/man1/gsmsmsstore.1.gz
|
||||
/usr/share/locale/de/LC_MESSAGES/gsmlib.mo
|
||||
|
||||
%doc README INSTALL ABOUT-NLS AUTHORS COPYING NEWS TODO
|
||||
%doc doc/README.NLS doc/README.developers doc/FAQ ChangeLog
|
||||
|
||||
%files devel
|
||||
%defattr(-,root,root)
|
||||
/usr/lib/libgsmme.a
|
||||
/usr/include/gsmlib
|
||||
|
||||
%files ext
|
||||
/usr/bin/gsmsiectl
|
||||
/usr/bin/gsmsiexfer
|
||||
/usr/lib/libgsmext.so
|
||||
/usr/lib/libgsmext.so.%{LIBVER}
|
||||
|
||||
%doc ext/README.sieme
|
@ -0,0 +1,38 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
# *************************************************************************
|
||||
# * GSM TA/ME library
|
||||
# *
|
||||
# * File: Makefile.am
|
||||
# *
|
||||
# * Purpose: GSM library Makefile
|
||||
# *
|
||||
# * Author: Peter Hofmann (software@pxh.de)
|
||||
# *
|
||||
# * Created: 5.5.1999
|
||||
# *************************************************************************
|
||||
|
||||
INCLUDES = -I..
|
||||
|
||||
lib_LTLIBRARIES = libgsmme.la
|
||||
|
||||
libgsmme_la_SOURCES = gsm_phonebook.cc gsm_util.cc gsm_unix_serial.cc \
|
||||
gsm_me_ta.cc gsm_at.cc gsm_error.cc gsm_parser.cc \
|
||||
gsm_sms.cc gsm_sms_codec.cc gsm_sms_store.cc \
|
||||
gsm_event.cc gsm_sorted_phonebook.cc \
|
||||
gsm_sorted_sms_store.cc gsm_nls.cc \
|
||||
gsm_sorted_phonebook_base.cc gsm_cb.cc
|
||||
|
||||
gsmincludedir = $(includedir)/gsmlib
|
||||
|
||||
gsminclude_HEADERS = gsm_at.h gsm_parser.h gsm_sms.h gsm_unix_serial.h \
|
||||
gsm_error.h gsm_phonebook.h gsm_sms_codec.h \
|
||||
gsm_util.h gsm_me_ta.h gsm_port.h gsm_sms_store.h \
|
||||
gsm_event.h gsm_sorted_phonebook.h \
|
||||
gsm_sorted_sms_store.h gsm_map_key.h \
|
||||
gsm_sorted_phonebook_base.h gsm_cb.h
|
||||
|
||||
noinst_HEADERS = gsm_nls.h gsm_sysdep.h
|
||||
|
||||
libgsmme_la_LDFLAGS = -version-info $(GSM_VERSION)
|
||||
|
||||
EXTRA_DIST = gsm_win32_serial.h gsm_win32_serial.cc
|
@ -0,0 +1,461 @@
|
||||
# Makefile.in generated by automake 1.6.3 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
# Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
# *************************************************************************
|
||||
# * GSM TA/ME library
|
||||
# *
|
||||
# * File: Makefile.am
|
||||
# *
|
||||
# * Purpose: GSM library Makefile
|
||||
# *
|
||||
# * Author: Peter Hofmann (software@pxh.de)
|
||||
# *
|
||||
# * Created: 5.5.1999
|
||||
# *************************************************************************
|
||||
SHELL = @SHELL@
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = @bindir@
|
||||
sbindir = @sbindir@
|
||||
libexecdir = @libexecdir@
|
||||
datadir = @datadir@
|
||||
sysconfdir = @sysconfdir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
localstatedir = @localstatedir@
|
||||
libdir = @libdir@
|
||||
infodir = @infodir@
|
||||
mandir = @mandir@
|
||||
includedir = @includedir@
|
||||
oldincludedir = /usr/include
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
top_builddir = ..
|
||||
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = @program_transform_name@
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
host_alias = @host_alias@
|
||||
host_triplet = @host@
|
||||
|
||||
EXEEXT = @EXEEXT@
|
||||
OBJEXT = @OBJEXT@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
AMTAR = @AMTAR@
|
||||
AS = @AS@
|
||||
AWK = @AWK@
|
||||
BUILD_INCLUDED_LIBINTL = @BUILD_INCLUDED_LIBINTL@
|
||||
CATOBJEXT = @CATOBJEXT@
|
||||
CC = @CC@
|
||||
CPP = @CPP@
|
||||
CXX = @CXX@
|
||||
DATADIRNAME = @DATADIRNAME@
|
||||
DEPDIR = @DEPDIR@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
ECHO = @ECHO@
|
||||
GENCAT = @GENCAT@
|
||||
GLIBC21 = @GLIBC21@
|
||||
GMSGFMT = @GMSGFMT@
|
||||
GSM_VERSION = @GSM_VERSION@
|
||||
HAVE_LIB = @HAVE_LIB@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
INSTOBJEXT = @INSTOBJEXT@
|
||||
INTLBISON = @INTLBISON@
|
||||
INTLLIBS = @INTLLIBS@
|
||||
INTLOBJS = @INTLOBJS@
|
||||
INTL_LIBTOOL_SUFFIX_PREFIX = @INTL_LIBTOOL_SUFFIX_PREFIX@
|
||||
LIB = @LIB@
|
||||
LIBICONV = @LIBICONV@
|
||||
LIBINTL = @LIBINTL@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LN_S = @LN_S@
|
||||
LTLIB = @LTLIB@
|
||||
LTLIBICONV = @LTLIBICONV@
|
||||
LTLIBINTL = @LTLIBINTL@
|
||||
MKINSTALLDIRS = @MKINSTALLDIRS@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
PACKAGE = @PACKAGE@
|
||||
POSUB = @POSUB@
|
||||
RANLIB = @RANLIB@
|
||||
STRIP = @STRIP@
|
||||
USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
|
||||
USE_NLS = @USE_NLS@
|
||||
VERSION = @VERSION@
|
||||
am__include = @am__include@
|
||||
am__quote = @am__quote@
|
||||
install_sh = @install_sh@
|
||||
|
||||
INCLUDES = -I..
|
||||
|
||||
lib_LTLIBRARIES = libgsmme.la
|
||||
|
||||
libgsmme_la_SOURCES = gsm_phonebook.cc gsm_util.cc gsm_unix_serial.cc \
|
||||
gsm_me_ta.cc gsm_at.cc gsm_error.cc gsm_parser.cc \
|
||||
gsm_sms.cc gsm_sms_codec.cc gsm_sms_store.cc \
|
||||
gsm_event.cc gsm_sorted_phonebook.cc \
|
||||
gsm_sorted_sms_store.cc gsm_nls.cc \
|
||||
gsm_sorted_phonebook_base.cc gsm_cb.cc
|
||||
|
||||
|
||||
gsmincludedir = $(includedir)/gsmlib
|
||||
|
||||
gsminclude_HEADERS = gsm_at.h gsm_parser.h gsm_sms.h gsm_unix_serial.h \
|
||||
gsm_error.h gsm_phonebook.h gsm_sms_codec.h \
|
||||
gsm_util.h gsm_me_ta.h gsm_port.h gsm_sms_store.h \
|
||||
gsm_event.h gsm_sorted_phonebook.h \
|
||||
gsm_sorted_sms_store.h gsm_map_key.h \
|
||||
gsm_sorted_phonebook_base.h gsm_cb.h
|
||||
|
||||
|
||||
noinst_HEADERS = gsm_nls.h gsm_sysdep.h
|
||||
|
||||
libgsmme_la_LDFLAGS = -version-info $(GSM_VERSION)
|
||||
|
||||
EXTRA_DIST = gsm_win32_serial.h gsm_win32_serial.cc
|
||||
subdir = gsmlib
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs
|
||||
CONFIG_HEADER = $(top_builddir)/gsm_config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
LTLIBRARIES = $(lib_LTLIBRARIES)
|
||||
|
||||
libgsmme_la_LIBADD =
|
||||
am_libgsmme_la_OBJECTS = gsm_phonebook.lo gsm_util.lo gsm_unix_serial.lo \
|
||||
gsm_me_ta.lo gsm_at.lo gsm_error.lo gsm_parser.lo gsm_sms.lo \
|
||||
gsm_sms_codec.lo gsm_sms_store.lo gsm_event.lo \
|
||||
gsm_sorted_phonebook.lo gsm_sorted_sms_store.lo gsm_nls.lo \
|
||||
gsm_sorted_phonebook_base.lo gsm_cb.lo
|
||||
libgsmme_la_OBJECTS = $(am_libgsmme_la_OBJECTS)
|
||||
|
||||
DEFS = @DEFS@
|
||||
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
depcomp = $(SHELL) $(top_srcdir)/scripts/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/gsm_at.Plo ./$(DEPDIR)/gsm_cb.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_error.Plo ./$(DEPDIR)/gsm_event.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_me_ta.Plo ./$(DEPDIR)/gsm_nls.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_parser.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_phonebook.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_sms.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_sms_codec.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_sms_store.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_sorted_phonebook.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_sorted_phonebook_base.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_sorted_sms_store.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_unix_serial.Plo \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/gsm_util.Plo
|
||||
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \
|
||||
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
|
||||
$(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
CXXLD = $(CXX)
|
||||
CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
|
||||
$(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
DIST_SOURCES = $(libgsmme_la_SOURCES)
|
||||
HEADERS = $(gsminclude_HEADERS) $(noinst_HEADERS)
|
||||
|
||||
DIST_COMMON = $(gsminclude_HEADERS) $(noinst_HEADERS) Makefile.am \
|
||||
Makefile.in
|
||||
SOURCES = $(libgsmme_la_SOURCES)
|
||||
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .cc .lo .o .obj
|
||||
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu gsmlib/Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
|
||||
libLTLIBRARIES_INSTALL = $(INSTALL)
|
||||
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(libdir)
|
||||
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
|
||||
if test -f $$p; then \
|
||||
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f"; \
|
||||
$(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f; \
|
||||
else :; fi; \
|
||||
done
|
||||
|
||||
uninstall-libLTLIBRARIES:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
|
||||
p="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p"; \
|
||||
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
|
||||
done
|
||||
|
||||
clean-libLTLIBRARIES:
|
||||
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
|
||||
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
|
||||
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
|
||||
test -z "$dir" && dir=.; \
|
||||
echo "rm -f \"$${dir}/so_locations\""; \
|
||||
rm -f "$${dir}/so_locations"; \
|
||||
done
|
||||
libgsmme.la: $(libgsmme_la_OBJECTS) $(libgsmme_la_DEPENDENCIES)
|
||||
$(CXXLINK) -rpath $(libdir) $(libgsmme_la_LDFLAGS) $(libgsmme_la_OBJECTS) $(libgsmme_la_LIBADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT) core *.core
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_at.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_cb.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_error.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_event.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_me_ta.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_nls.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_parser.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_phonebook.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_sms.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_sms_codec.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_sms_store.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_sorted_phonebook.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_sorted_phonebook_base.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_sorted_sms_store.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_unix_serial.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsm_util.Plo@am__quote@
|
||||
|
||||
distclean-depend:
|
||||
-rm -rf ./$(DEPDIR)
|
||||
|
||||
.cc.o:
|
||||
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
$(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
|
||||
|
||||
.cc.obj:
|
||||
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
$(CXXCOMPILE) -c -o $@ `cygpath -w $<`
|
||||
|
||||
.cc.lo:
|
||||
@AMDEP_TRUE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
$(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
|
||||
distclean-libtool:
|
||||
-rm -f libtool
|
||||
uninstall-info-am:
|
||||
gsmincludeHEADERS_INSTALL = $(INSTALL_HEADER)
|
||||
install-gsmincludeHEADERS: $(gsminclude_HEADERS)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(gsmincludedir)
|
||||
@list='$(gsminclude_HEADERS)'; for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " $(gsmincludeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(gsmincludedir)/$$f"; \
|
||||
$(gsmincludeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(gsmincludedir)/$$f; \
|
||||
done
|
||||
|
||||
uninstall-gsmincludeHEADERS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(gsminclude_HEADERS)'; for p in $$list; do \
|
||||
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||
echo " rm -f $(DESTDIR)$(gsmincludedir)/$$f"; \
|
||||
rm -f $(DESTDIR)$(gsmincludedir)/$$f; \
|
||||
done
|
||||
|
||||
ETAGS = etags
|
||||
ETAGSFLAGS =
|
||||
|
||||
tags: TAGS
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
mkid -fID $$unique
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|
||||
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$tags $$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& cd $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) $$here
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
top_distdir = ..
|
||||
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@list='$(DISTFILES)'; for file in $$list; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
dir="/$$dir"; \
|
||||
$(mkinstalldirs) "$(distdir)$$dir"; \
|
||||
else \
|
||||
dir=''; \
|
||||
fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
|
||||
fi; \
|
||||
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
|
||||
|
||||
installdirs:
|
||||
$(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(gsmincludedir)
|
||||
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
|
||||
mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
|
||||
distclean-am: clean-am distclean-compile distclean-depend \
|
||||
distclean-generic distclean-libtool distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am: install-gsmincludeHEADERS
|
||||
|
||||
install-exec-am: install-libLTLIBRARIES
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-man:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
||||
uninstall-am: uninstall-gsmincludeHEADERS uninstall-info-am \
|
||||
uninstall-libLTLIBRARIES
|
||||
|
||||
.PHONY: GTAGS all all-am check check-am clean clean-generic \
|
||||
clean-libLTLIBRARIES clean-libtool distclean distclean-compile \
|
||||
distclean-depend distclean-generic distclean-libtool \
|
||||
distclean-tags distdir dvi dvi-am info info-am install \
|
||||
install-am install-data install-data-am install-exec \
|
||||
install-exec-am install-gsmincludeHEADERS install-info \
|
||||
install-info-am install-libLTLIBRARIES install-man \
|
||||
install-strip installcheck installcheck-am installdirs \
|
||||
maintainer-clean maintainer-clean-generic mostlyclean \
|
||||
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
|
||||
tags uninstall uninstall-am uninstall-gsmincludeHEADERS \
|
||||
uninstall-info-am uninstall-libLTLIBRARIES
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
@ -0,0 +1,444 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_at.cc
|
||||
// *
|
||||
// * Purpose: Utility classes for AT command sequence handling
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 3.5.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <gsm_config.h>
|
||||
#endif
|
||||
#include <gsmlib/gsm_at.h>
|
||||
#include <gsmlib/gsm_nls.h>
|
||||
#include <gsmlib/gsm_util.h>
|
||||
#include <gsmlib/gsm_error.h>
|
||||
#include <gsmlib/gsm_event.h>
|
||||
#include <gsmlib/gsm_me_ta.h>
|
||||
#include <ctype.h>
|
||||
#include <strstream>
|
||||
|
||||
using namespace std;
|
||||
using namespace gsmlib;
|
||||
|
||||
// GsmAt members
|
||||
|
||||
bool GsmAt::matchResponse(string answer, string responseToMatch)
|
||||
{
|
||||
if (answer.substr(0, responseToMatch.length()) == responseToMatch)
|
||||
return true;
|
||||
else
|
||||
// some TAs omit the ':' at the end of the response
|
||||
if (_meTa.getCapabilities()._omitsColon &&
|
||||
responseToMatch[responseToMatch.length() - 1] == ':' &&
|
||||
answer.substr(0, responseToMatch.length() - 1) ==
|
||||
responseToMatch.substr(0, responseToMatch.length() - 1))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
string GsmAt::cutResponse(string answer, string responseToMatch)
|
||||
{
|
||||
if (answer.substr(0, responseToMatch.length()) == responseToMatch)
|
||||
return normalize(answer.substr(responseToMatch.length(),
|
||||
answer.length() -
|
||||
responseToMatch.length()));
|
||||
else
|
||||
// some TAs omit the ':' at the end of the response
|
||||
if (_meTa.getCapabilities()._omitsColon &&
|
||||
responseToMatch[responseToMatch.length() - 1] == ':' &&
|
||||
answer.substr(0, responseToMatch.length() - 1) ==
|
||||
responseToMatch.substr(0, responseToMatch.length() - 1))
|
||||
return normalize(answer.substr(responseToMatch.length() - 1,
|
||||
answer.length() -
|
||||
responseToMatch.length() + 1));
|
||||
assert(0);
|
||||
return "";
|
||||
}
|
||||
|
||||
void GsmAt::throwCmeException(string s) throw(GsmException)
|
||||
{
|
||||
if (matchResponse(s, "ERROR"))
|
||||
throw GsmException(_("unspecified ME/TA error"), ChatError);
|
||||
|
||||
bool meError = matchResponse(s, "+CME ERROR:");
|
||||
if (meError)
|
||||
s = cutResponse(s, "+CME ERROR:");
|
||||
else
|
||||
s = cutResponse(s, "+CMS ERROR:");
|
||||
istrstream is(s.c_str());
|
||||
int error;
|
||||
is >> error;
|
||||
throw GsmException(_("ME/TA error '") +
|
||||
(meError ? getMEErrorText(error) :
|
||||
getSMSErrorText(error)) +
|
||||
"' " +
|
||||
stringPrintf(_("(code %s)"), s.c_str()),
|
||||
ChatError, error);
|
||||
}
|
||||
|
||||
GsmAt::GsmAt(MeTa &meTa) :
|
||||
_meTa(meTa), _port(meTa.getPort()), _eventHandler(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
string GsmAt::chat(string atCommand, string response,
|
||||
bool ignoreErrors, bool acceptEmptyResponse)
|
||||
throw(GsmException)
|
||||
{
|
||||
string dummy;
|
||||
return chat(atCommand, response, dummy, ignoreErrors, false,
|
||||
acceptEmptyResponse);
|
||||
}
|
||||
|
||||
string GsmAt::chat(string atCommand, string response, string &pdu,
|
||||
bool ignoreErrors, bool expectPdu,
|
||||
bool acceptEmptyResponse) throw(GsmException)
|
||||
{
|
||||
string s;
|
||||
bool gotOk = false; // special handling for empty SMS entries
|
||||
|
||||
// send AT command
|
||||
putLine("AT" + atCommand);
|
||||
// and gobble up CR/LF (and possibly echoed characters if echo can't be
|
||||
// switched off)
|
||||
// Also, some mobiles (e.g., Sony Ericsson K800i) respond to commands
|
||||
// like "at+cmgf=0" with "+CMGF: 0" on success as well as the "OK"
|
||||
// status -- so gobble that (but not if that sort of response was expected)
|
||||
// FIXME: this is a gross hack, should be done via capabilities or sth
|
||||
#include <string>
|
||||
string::size_type loc = atCommand.find( "=", 1 );
|
||||
string expect;
|
||||
if (loc != string::npos) {
|
||||
expect = atCommand;
|
||||
expect.replace(loc, 1, " ");
|
||||
expect.insert(loc, ":");
|
||||
} else {
|
||||
expect = "";
|
||||
}
|
||||
do
|
||||
{
|
||||
s = normalize(getLine());
|
||||
}
|
||||
while (s.length() == 0 || s == "AT" + atCommand ||
|
||||
((response.length() == 0 || !matchResponse(s, response)) &&
|
||||
(expect.length() > 0 && matchResponse(s, expect))));
|
||||
|
||||
// handle errors
|
||||
if (matchResponse(s, "+CME ERROR:") || matchResponse(s, "+CMS ERROR:"))
|
||||
if (ignoreErrors)
|
||||
return "";
|
||||
else
|
||||
throwCmeException(s);
|
||||
if (matchResponse(s, "ERROR"))
|
||||
if (ignoreErrors)
|
||||
return "";
|
||||
else
|
||||
throw GsmException(_("ME/TA error '<unspecified>' (code not known)"),
|
||||
ChatError, -1);
|
||||
|
||||
// return if response is "OK" and caller says this is OK
|
||||
if (acceptEmptyResponse && s == "OK")
|
||||
return "";
|
||||
|
||||
// handle PDU if one is expected
|
||||
if (expectPdu)
|
||||
{
|
||||
string ps;
|
||||
do
|
||||
{
|
||||
ps = normalize(getLine());
|
||||
}
|
||||
while (ps.length() == 0 && ps != "OK");
|
||||
if (ps == "OK")
|
||||
gotOk = true;
|
||||
else
|
||||
{
|
||||
pdu = ps;
|
||||
// remove trailing zero added by some devices (e.g. Falcom A2-1)
|
||||
if (pdu.length() > 0 && pdu[pdu.length() - 1] == 0)
|
||||
pdu.erase(pdu.length() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// handle expected response
|
||||
if (response.length() == 0) // no response expected
|
||||
{
|
||||
if (s == "OK") return "";
|
||||
// else fall through to error
|
||||
}
|
||||
else
|
||||
{
|
||||
string result;
|
||||
// some TA/TEs don't prefix their response with the response string
|
||||
// as proscribed by the standard: just handle either case
|
||||
if (matchResponse(s, response))
|
||||
result = cutResponse(s, response);
|
||||
else
|
||||
result = s;
|
||||
|
||||
if (gotOk)
|
||||
return result;
|
||||
else
|
||||
{
|
||||
// get the final "OK"
|
||||
do
|
||||
{
|
||||
s = normalize(getLine());
|
||||
}
|
||||
while (s.length() == 0);
|
||||
|
||||
if (s == "OK") return result;
|
||||
// else fall through to error
|
||||
}
|
||||
}
|
||||
throw GsmException(
|
||||
stringPrintf(_("unexpected response '%s' when sending 'AT%s'"),
|
||||
s.c_str(), atCommand.c_str()),
|
||||
ChatError);
|
||||
}
|
||||
|
||||
vector<string> GsmAt::chatv(string atCommand, string response,
|
||||
bool ignoreErrors) throw(GsmException)
|
||||
{
|
||||
string s;
|
||||
vector<string> result;
|
||||
|
||||
// send AT command
|
||||
putLine("AT" + atCommand);
|
||||
// and gobble up CR/LF (and possibly echoed characters if echo can't be
|
||||
// switched off)
|
||||
do
|
||||
{
|
||||
s = normalize(getLine());
|
||||
}
|
||||
while (s.length() == 0 || s == "AT" + atCommand);
|
||||
|
||||
// handle errors
|
||||
if (matchResponse(s, "+CME ERROR:") || matchResponse(s, "+CMS ERROR:"))
|
||||
if (ignoreErrors)
|
||||
return result;
|
||||
else
|
||||
throwCmeException(s);
|
||||
if (matchResponse(s, "ERROR"))
|
||||
if (ignoreErrors)
|
||||
return result;
|
||||
else
|
||||
throw GsmException(_("ME/TA error '<unspecified>' (code not known)"),
|
||||
ChatError, -1);
|
||||
|
||||
// push all lines that are not empty
|
||||
// cut response prefix if it is there
|
||||
// stop when an OK line is read
|
||||
while (1)
|
||||
{
|
||||
if (s == "OK")
|
||||
return result;
|
||||
// some TA/TEs don't prefix their response with the response string
|
||||
// as proscribed by the standard: just handle either case
|
||||
if (response.length() != 0 && matchResponse(s, response))
|
||||
result.push_back(cutResponse(s, response));
|
||||
else
|
||||
result.push_back(s);
|
||||
// get next line
|
||||
do
|
||||
{
|
||||
s = normalize(getLine());
|
||||
}
|
||||
while (s.length() == 0);
|
||||
reportProgress();
|
||||
}
|
||||
|
||||
// never reached
|
||||
assert(0);
|
||||
return result;
|
||||
}
|
||||
|
||||
string GsmAt::normalize(string s)
|
||||
{
|
||||
size_t start = 0, end = s.length();
|
||||
bool changed = true;
|
||||
|
||||
while (start < end && changed)
|
||||
{
|
||||
changed = false;
|
||||
if (isspace(s[start]))
|
||||
{
|
||||
++start;
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
if (isspace(s[end - 1]))
|
||||
{
|
||||
--end;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return s.substr(start, end - start);
|
||||
}
|
||||
|
||||
string GsmAt::sendPdu(string atCommand, string response, string pdu,
|
||||
bool acceptEmptyResponse) throw(GsmException)
|
||||
{
|
||||
string s;
|
||||
bool errorCondition;
|
||||
bool retry = false;
|
||||
int tries = 5; // How many error conditions do we accept
|
||||
|
||||
int c;
|
||||
do
|
||||
{
|
||||
errorCondition = false;
|
||||
putLine("AT" + atCommand);
|
||||
do
|
||||
{
|
||||
retry = false;
|
||||
try
|
||||
{
|
||||
do
|
||||
{
|
||||
// read first of two bytes "> "
|
||||
c = readByte();
|
||||
}
|
||||
// there have been reports that some phones give spurious CRs
|
||||
// LF separates CDSI messages if there are more than one
|
||||
while (c == CR || c == LF);
|
||||
}
|
||||
catch (GsmException &e)
|
||||
{
|
||||
c = '-';
|
||||
errorCondition = true; // TA does not expect PDU anymore, retry
|
||||
}
|
||||
|
||||
if (c == '+' || c == 'E') // error or unsolicited result code
|
||||
{
|
||||
_port->putBack(c);
|
||||
s = normalize(getLine());
|
||||
errorCondition = (s != "");
|
||||
|
||||
retry = ! errorCondition;
|
||||
}
|
||||
}
|
||||
while (retry);
|
||||
}
|
||||
while (errorCondition && tries--);
|
||||
|
||||
if (! errorCondition)
|
||||
{
|
||||
|
||||
if (c != '>' || readByte() != ' ')
|
||||
throw GsmException(_("unexpected character in PDU handshake"),
|
||||
ChatError);
|
||||
|
||||
putLine(pdu + "\032", false); // write pdu followed by CTRL-Z
|
||||
|
||||
// some phones (Ericcson T68, T39) send spurious zero characters after
|
||||
// accepting the PDU
|
||||
c = readByte();
|
||||
if (c != 0)
|
||||
_port->putBack(c);
|
||||
|
||||
// loop while empty lines (maybe with a zero, Ericsson T39m)
|
||||
// or an echo of the pdu (with or without CTRL-Z)
|
||||
// is read
|
||||
do
|
||||
{
|
||||
s = normalize(getLine());
|
||||
}
|
||||
while (s.length() == 0 || s == pdu || s == (pdu + "\032") ||
|
||||
(s.length() == 1 && s[0] == 0));
|
||||
}
|
||||
|
||||
// handle errors
|
||||
if (matchResponse(s, "+CME ERROR:") || matchResponse(s, "+CMS ERROR:"))
|
||||
throwCmeException(s);
|
||||
if (matchResponse(s, "ERROR"))
|
||||
throw GsmException(_("ME/TA error '<unspecified>' (code not known)"),
|
||||
ChatError, -1);
|
||||
|
||||
// return if response is "OK" and caller says this is OK
|
||||
if (acceptEmptyResponse && s == "OK")
|
||||
return "";
|
||||
|
||||
if (matchResponse(s, response))
|
||||
{
|
||||
string result = cutResponse(s, response);
|
||||
// get the final "OK"
|
||||
do
|
||||
{
|
||||
s = normalize(getLine());
|
||||
}
|
||||
while (s.length() == 0);
|
||||
|
||||
if (s == "OK") return result;
|
||||
// else fall through to error
|
||||
}
|
||||
throw GsmException(
|
||||
stringPrintf(_("unexpected response '%s' when sending 'AT%s'"),
|
||||
s.c_str(), atCommand.c_str()),
|
||||
ChatError);
|
||||
}
|
||||
|
||||
string GsmAt::getLine() throw(GsmException)
|
||||
{
|
||||
if (_eventHandler == (GsmEvent*)NULL)
|
||||
return _port->getLine();
|
||||
else
|
||||
{
|
||||
bool eventOccurred;
|
||||
string result;
|
||||
do
|
||||
{
|
||||
eventOccurred = false;
|
||||
result = _port->getLine();
|
||||
string s = normalize(result);
|
||||
if (matchResponse(s, "+CMT:") ||
|
||||
matchResponse(s, "+CBM:") ||
|
||||
matchResponse(s, "+CDS:") ||
|
||||
matchResponse(s, "+CMTI:") ||
|
||||
matchResponse(s, "+CBMI:") ||
|
||||
matchResponse(s, "+CDSI:") ||
|
||||
matchResponse(s, "RING") ||
|
||||
matchResponse(s, "NO CARRIER") ||
|
||||
// hack: the +CLIP? sequence returns +CLIP: n,m
|
||||
// which is NOT an unsolicited result code
|
||||
(matchResponse(s, "+CLIP:") && s.length() > 10))
|
||||
{
|
||||
_eventHandler->dispatch(s, *this);
|
||||
eventOccurred = true;
|
||||
}
|
||||
}
|
||||
while (eventOccurred);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
void GsmAt::putLine(string line,
|
||||
bool carriageReturn) throw(GsmException)
|
||||
{
|
||||
_port->putLine(line, carriageReturn);
|
||||
// remove empty echo line
|
||||
if (carriageReturn)
|
||||
getLine();
|
||||
}
|
||||
|
||||
bool GsmAt::wait(GsmTime timeout) throw(GsmException)
|
||||
{
|
||||
return _port->wait(timeout);
|
||||
}
|
||||
|
||||
int GsmAt::readByte() throw(GsmException)
|
||||
{
|
||||
return _port->readByte();
|
||||
}
|
||||
|
||||
GsmEvent *GsmAt::setEventHandler(GsmEvent *newHandler)
|
||||
{
|
||||
GsmEvent *result = _eventHandler;
|
||||
_eventHandler = newHandler;
|
||||
return result;
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_at.h
|
||||
// *
|
||||
// * Purpose: Utility classes for AT command sequence handling
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 3.5.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifndef GSM_AT_H
|
||||
#define GSM_AT_H
|
||||
|
||||
#include <gsmlib/gsm_port.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gsmlib
|
||||
{
|
||||
// forward declarations
|
||||
|
||||
class GsmEvent;
|
||||
class MeTa;
|
||||
|
||||
// utiliy class to handle AT sequences
|
||||
|
||||
class GsmAt : public RefBase
|
||||
{
|
||||
protected:
|
||||
MeTa &_meTa;
|
||||
Ref<Port> _port;
|
||||
GsmEvent *_eventHandler;
|
||||
|
||||
// return true if response matches
|
||||
bool matchResponse(string answer, string responseToMatch);
|
||||
|
||||
// cut response and normalize
|
||||
string cutResponse(string answer, string responseToMatch);
|
||||
|
||||
// parse CME error contained in string and throw MeTaException
|
||||
void throwCmeException(string s) throw(GsmException);
|
||||
|
||||
public:
|
||||
GsmAt(MeTa &meTa);
|
||||
|
||||
// return MeTa object for this AT object
|
||||
MeTa &getMeTa() {return _meTa;}
|
||||
|
||||
// the following sequence functions recognize asynchronous messages
|
||||
// from the TA and return the appropriate event
|
||||
|
||||
// send AT command, wait for response response, returns response line
|
||||
// without response match
|
||||
// if response == "" only an OK is expected
|
||||
// white space at beginning or end are removed
|
||||
// +CME ERROR or ERROR raises exception (if ignoreErrors == true)
|
||||
// additionally, accept empty responses (just an OK)
|
||||
// if acceptEmptyResponse == true
|
||||
// in this case an empty string is returned
|
||||
string chat(string atCommand = "",
|
||||
string response = "",
|
||||
bool ignoreErrors = false,
|
||||
bool acceptEmptyResponse = false) throw(GsmException);
|
||||
|
||||
// same as chat() above but also get pdu if expectPdu == true
|
||||
string chat(string atCommand,
|
||||
string response,
|
||||
string &pdu,
|
||||
bool ignoreErrors = false,
|
||||
bool expectPdu = true,
|
||||
bool acceptEmptyResponse = false) throw(GsmException);
|
||||
|
||||
// same as above, but expect several response lines
|
||||
vector<string> chatv(string atCommand = "",
|
||||
string response = "",
|
||||
bool ignoreErrors = false)
|
||||
throw(GsmException);
|
||||
|
||||
// removes whitespace at beginning and end of string
|
||||
string normalize(string s);
|
||||
|
||||
// send pdu (wait for <CR><LF><greater_than><space> and send <CTRL-Z>
|
||||
// at the end
|
||||
// return text after response
|
||||
string sendPdu(string atCommand, string response, string pdu,
|
||||
bool acceptEmptyResponse = false) throw(GsmException);
|
||||
|
||||
// functions from class Port
|
||||
string getLine() throw(GsmException);
|
||||
void putLine(string line,
|
||||
bool carriageReturn = true) throw(GsmException);
|
||||
bool wait(GsmTime timeout) throw(GsmException);
|
||||
int readByte() throw(GsmException);
|
||||
|
||||
// set event handler class, return old one
|
||||
GsmEvent *setEventHandler(GsmEvent *newHandler);
|
||||
};
|
||||
};
|
||||
|
||||
#endif // GSM_AT_H
|
@ -0,0 +1,176 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_cb.cc
|
||||
// *
|
||||
// * Purpose: Cell Broadcast Message Implementation
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 4.8.2001
|
||||
// *************************************************************************
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <gsm_config.h>
|
||||
#endif
|
||||
#include <gsmlib/gsm_sysdep.h>
|
||||
#include <gsmlib/gsm_cb.h>
|
||||
#include <gsmlib/gsm_nls.h>
|
||||
#include <strstream>
|
||||
|
||||
using namespace std;
|
||||
using namespace gsmlib;
|
||||
|
||||
// local constants
|
||||
|
||||
static const string dashes =
|
||||
"---------------------------------------------------------------------------";
|
||||
|
||||
// CBDataCodingScheme members
|
||||
|
||||
CBDataCodingScheme::CBDataCodingScheme(unsigned char dcs) : _dcs(dcs)
|
||||
{
|
||||
if ((_dcs & 0xf0) <= 0x30) // bits 7..4 in the range 0000..0011
|
||||
if ((_dcs & 0x30) == 0)
|
||||
_language = (Language)_dcs;
|
||||
else
|
||||
_language = Unknown;
|
||||
}
|
||||
|
||||
string CBDataCodingScheme::toString() const
|
||||
{
|
||||
string result;
|
||||
if (compressed()) result += _("compressed ");
|
||||
switch (getLanguage())
|
||||
{
|
||||
case German:
|
||||
result += _("German");
|
||||
break;
|
||||
case English:
|
||||
result += _("English");
|
||||
break;
|
||||
case Italian:
|
||||
result += _("Italian");
|
||||
break;
|
||||
case French:
|
||||
result += _("French");
|
||||
break;
|
||||
case Spanish:
|
||||
result += _("Spanish");
|
||||
break;
|
||||
case Dutch:
|
||||
result += _("Dutch");
|
||||
break;
|
||||
case Swedish:
|
||||
result += _("Swedish");
|
||||
break;
|
||||
case Danish:
|
||||
result += _("Danish");
|
||||
break;
|
||||
case Portuguese:
|
||||
result += _("Portuguese");
|
||||
break;
|
||||
case Finnish:
|
||||
result += _("Finnish");
|
||||
break;
|
||||
case Norwegian:
|
||||
result += _("Norwegian");
|
||||
break;
|
||||
case Greek:
|
||||
result += _("Greek");
|
||||
break;
|
||||
case Turkish:
|
||||
result += _("Turkish");
|
||||
break;
|
||||
}
|
||||
result += " ";
|
||||
switch (getAlphabet())
|
||||
{
|
||||
case DCS_DEFAULT_ALPHABET:
|
||||
result += _("default alphabet");
|
||||
break;
|
||||
case DCS_EIGHT_BIT_ALPHABET:
|
||||
result += _("8-bit alphabet");
|
||||
break;
|
||||
case DCS_SIXTEEN_BIT_ALPHABET:
|
||||
result += _("16-bit alphabet");
|
||||
break;
|
||||
case DCS_RESERVED_ALPHABET:
|
||||
result += _("reserved alphabet");
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// CBMessage members
|
||||
|
||||
CBMessage::CBMessage(string pdu) throw(GsmException)
|
||||
{
|
||||
SMSDecoder d(pdu);
|
||||
_messageCode = d.getInteger(6) << 4;
|
||||
_geographicalScope = (GeographicalScope)d.get2Bits();
|
||||
_updateNumber = d.getInteger(4);
|
||||
_messageCode |= d.getInteger(4);
|
||||
_messageIdentifier = d.getInteger(8) << 8;
|
||||
_messageIdentifier |= d.getInteger(8);
|
||||
_dataCodingScheme = CBDataCodingScheme(d.getOctet());
|
||||
_totalPageNumber = d.getInteger(4);
|
||||
_currentPageNumber = d.getInteger(4);
|
||||
|
||||
// the values 82 and 93 come from ETSI GSM 03.41, section 9.3
|
||||
d.markSeptet();
|
||||
if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET)
|
||||
{
|
||||
_data = d.getString(93);
|
||||
_data = gsmToLatin1(_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char *s =
|
||||
(unsigned char*)alloca(sizeof(unsigned char) * 82);
|
||||
d.getOctets(s, 82);
|
||||
_data.assign((char*)s, (unsigned int)82);
|
||||
}
|
||||
}
|
||||
|
||||
string CBMessage::toString() const
|
||||
{
|
||||
ostrstream os;
|
||||
os << dashes << endl
|
||||
<< _("Message type: CB") << endl
|
||||
<< _("Geographical scope: ");
|
||||
switch (_geographicalScope)
|
||||
{
|
||||
case CellWide:
|
||||
os << "Cell wide" << endl;
|
||||
break;
|
||||
case PLMNWide:
|
||||
os << "PLMN wide" << endl;
|
||||
break;
|
||||
case LocationAreaWide:
|
||||
os << "Location area wide" << endl;
|
||||
break;
|
||||
case CellWide2:
|
||||
os << "Cell wide (2)" << endl;
|
||||
break;
|
||||
}
|
||||
// remove trailing \r characters for output
|
||||
string data = _data;
|
||||
string::iterator i;
|
||||
for (i = data.end(); i > data.begin() && *(i - 1) == '\r';
|
||||
--i);
|
||||
data.erase(i, data.end());
|
||||
|
||||
os << _("Message Code: ") << _messageCode << endl
|
||||
<< _("Update Number: ") << _updateNumber << endl
|
||||
<< _("Message Identifer: ") << _messageIdentifier << endl
|
||||
<< _("Data coding scheme: ") << _dataCodingScheme.toString() << endl
|
||||
<< _("Total page number: ") << _totalPageNumber << endl
|
||||
<< _("Current page number: ") << _currentPageNumber << endl
|
||||
<< _("Data: '") << data << "'" << endl
|
||||
<< dashes << endl << endl << ends;
|
||||
char *ss = os.str();
|
||||
string result(ss);
|
||||
delete[] ss;
|
||||
return result;
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_cb.h
|
||||
// *
|
||||
// * Purpose: Cell Broadcast Message Implementation
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 4.8.2001
|
||||
// *************************************************************************
|
||||
|
||||
#ifndef GSM_CB_H
|
||||
#define GSM_CB_H
|
||||
|
||||
#include <gsmlib/gsm_sms_codec.h>
|
||||
#include <gsmlib/gsm_util.h>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gsmlib
|
||||
{
|
||||
// representation of DataCodingScheme
|
||||
// The data coding scheme is described in detail in ETSI GSM 03.38, section 5
|
||||
// This class reuses the DCS_* constants from DataCodingScheme in
|
||||
// gsm_sms_codec
|
||||
|
||||
class CBDataCodingScheme
|
||||
{
|
||||
public:
|
||||
enum Language {German = 0, English = 1, Italian = 2, French = 3,
|
||||
Spanish = 4, Dutch = 5, Swedish = 6, Danish = 7,
|
||||
Portuguese = 8, Finnish = 9, Norwegian = 10, Greek = 11,
|
||||
Turkish = 12, Unknown = 1000};
|
||||
|
||||
private:
|
||||
unsigned char _dcs;
|
||||
Language _language;
|
||||
|
||||
public:
|
||||
// initialize with data coding scheme octet
|
||||
CBDataCodingScheme(unsigned char dcs);
|
||||
|
||||
// default constructor
|
||||
CBDataCodingScheme() : _dcs(DCS_DEFAULT_ALPHABET), _language(English) {}
|
||||
|
||||
// return language of CBM
|
||||
Language getLanguage() const {return _language;}
|
||||
|
||||
// return compression level (if language == Unknown)
|
||||
bool compressed() const {return (_dcs & DCS_COMPRESSED) == DCS_COMPRESSED;}
|
||||
|
||||
// return type of alphabet used
|
||||
// (DCS_DEFAULT_ALPHABET, DCS_EIGHT_BIT_ALPHABET, DCS_SIXTEEN_BIT_ALPHABET,
|
||||
// DCS_RESERVED_ALPHABET)
|
||||
unsigned char getAlphabet() const
|
||||
{return _language == Unknown ? _dcs & (3 << 2) : DCS_DEFAULT_ALPHABET;}
|
||||
|
||||
// create textual representation of CB data coding scheme
|
||||
string toString() const;
|
||||
};
|
||||
|
||||
// representation of Cell Broadcast message (CBM)
|
||||
// The CBM format is described in detail in ETSI GSM 03.41, section 9.3
|
||||
|
||||
class CBMessage : public RefBase
|
||||
{
|
||||
public:
|
||||
enum GeographicalScope {CellWide, PLMNWide, LocationAreaWide,
|
||||
CellWide2};
|
||||
|
||||
private:
|
||||
// fields parsed from the CB TPDU
|
||||
GeographicalScope _geographicalScope;
|
||||
int _messageCode;
|
||||
int _updateNumber;
|
||||
int _messageIdentifier;
|
||||
CBDataCodingScheme _dataCodingScheme;
|
||||
int _totalPageNumber;
|
||||
int _currentPageNumber;
|
||||
string _data;
|
||||
|
||||
public:
|
||||
// constructor with given pdu
|
||||
CBMessage(string pdu) throw(GsmException);
|
||||
|
||||
// accessor functions
|
||||
GeographicalScope getGeographicalScope() const {return _geographicalScope;}
|
||||
int getMessageCode() const {return _messageCode;}
|
||||
int getUpdateNumber() const {return _updateNumber;}
|
||||
int getMessageIdentifier() const {return _messageIdentifier;}
|
||||
CBDataCodingScheme getDataCodingScheme() const {return _dataCodingScheme;}
|
||||
int getTotalPageNumber() const {return _totalPageNumber;}
|
||||
int getCurrentPageNumber() const {return _currentPageNumber;}
|
||||
string getData() const {return _data;}
|
||||
|
||||
// create textual representation of CBM
|
||||
string toString() const;
|
||||
};
|
||||
|
||||
// some useful typdefs
|
||||
typedef Ref<CBMessage> CBMessageRef;
|
||||
};
|
||||
|
||||
#endif // GSM_CB_H
|
@ -0,0 +1,424 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_error.cc
|
||||
// *
|
||||
// * Purpose: Error codes and error handling functions
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 11.5.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <gsm_config.h>
|
||||
#endif
|
||||
#include <gsmlib/gsm_nls.h>
|
||||
#include <gsmlib/gsm_error.h>
|
||||
#include <gsmlib/gsm_util.h>
|
||||
#include <strstream>
|
||||
|
||||
using namespace std;
|
||||
using namespace gsmlib;
|
||||
|
||||
string gsmlib::getMEErrorText(const int errorCode) throw(GsmException)
|
||||
{
|
||||
switch (errorCode)
|
||||
{
|
||||
case ME_PHONE_FAILURE:
|
||||
return _("phone failure");
|
||||
break;
|
||||
case ME_NO_CONNECTION_TO_PHONE:
|
||||
return _("no connection to phone");
|
||||
break;
|
||||
case ME_PHONE_ADAPTOR_LINK_RESERVED:
|
||||
return _("phone adaptor link reserved");
|
||||
break;
|
||||
case ME_OPERATION_NOT_ALLOWED:
|
||||
return _("operation not allowed");
|
||||
break;
|
||||
case ME_OPERATION_NOT_SUPPORTED:
|
||||
return _("operation not supported");
|
||||
break;
|
||||
case ME_PH_SIM_PIN_REQUIRED:
|
||||
return _("ph SIM PIN required");
|
||||
break;
|
||||
case ME_SIM_NOT_INSERTED:
|
||||
return _("SIM not inserted");
|
||||
break;
|
||||
case ME_SIM_PIN_REQUIRED:
|
||||
return _("SIM PIN required");
|
||||
break;
|
||||
case ME_SIM_PUK_REQUIRED:
|
||||
return _("SIM PUK required");
|
||||
break;
|
||||
case ME_SIM_FAILURE:
|
||||
return _("SIM failure");
|
||||
break;
|
||||
case ME_SIM_BUSY:
|
||||
return _("SIM busy");
|
||||
break;
|
||||
case ME_SIM_WRONG:
|
||||
return _("SIM wrong");
|
||||
break;
|
||||
case ME_INCORRECT_PASSWORD:
|
||||
return _("incorrect password");
|
||||
break;
|
||||
case ME_SIM_PIN2_REQUIRED:
|
||||
return _("SIM PIN2 required");
|
||||
break;
|
||||
case ME_SIM_PUK2_REQUIRED:
|
||||
return _("SIM PUK2 required");
|
||||
break;
|
||||
case ME_MEMORY_FULL:
|
||||
return _("memory full");
|
||||
break;
|
||||
case ME_INVALID_INDEX:
|
||||
return _("invalid index");
|
||||
break;
|
||||
case ME_NOT_FOUND:
|
||||
return _("not found");
|
||||
break;
|
||||
case ME_MEMORY_FAILURE:
|
||||
return _("memory failure");
|
||||
break;
|
||||
case ME_TEXT_STRING_TOO_LONG:
|
||||
return _("text string too long");
|
||||
break;
|
||||
case ME_INVALID_CHARACTERS_IN_TEXT_STRING:
|
||||
return _("invalid characters in text string");
|
||||
break;
|
||||
case ME_DIAL_STRING_TOO_LONG:
|
||||
return _("dial string too long");
|
||||
break;
|
||||
case ME_INVALID_CHARACTERS_IN_DIAL_STRING:
|
||||
return _("invalid characters in dial string");
|
||||
break;
|
||||
case ME_NO_NETWORK_SERVICE:
|
||||
return _("no network service");
|
||||
break;
|
||||
case ME_NETWORK_TIMEOUT:
|
||||
return _("network timeout");
|
||||
break;
|
||||
case ME_UNKNOWN:
|
||||
return _("unknown");
|
||||
break;
|
||||
default:
|
||||
throw GsmException(stringPrintf(_("invalid ME error %d"), errorCode),
|
||||
OtherError);
|
||||
}
|
||||
}
|
||||
|
||||
string gsmlib::getSMSErrorText(const int errorCode) throw(GsmException)
|
||||
{
|
||||
switch (errorCode)
|
||||
{
|
||||
case SMS_UNASSIGNED_OR_UNALLOCATED_NUMBER:
|
||||
return _("Unassigned (unallocated) number");
|
||||
break;
|
||||
case SMS_OPERATOR_DETERMINED_BARRING:
|
||||
return _("Operator determined barring");
|
||||
break;
|
||||
case SMS_CALL_BARRED:
|
||||
return _("Call barred");
|
||||
break;
|
||||
case SMS_NETWORK_FAILURE:
|
||||
return _("Network failure");
|
||||
break;
|
||||
case SMS_SHORT_MESSAGE_TRANSFER_REJECTED:
|
||||
return _("Short message transfer rejected");
|
||||
break;
|
||||
case SMS_CONGESTION:
|
||||
case SMS_CONGESTION2:
|
||||
return _("Congestion");
|
||||
break;
|
||||
case SMS_DESTINATION_OUT_OF_SERVICE:
|
||||
return _("Destination out of service");
|
||||
break;
|
||||
case SMS_UNIDENTIFIED_SUBSCRIBER:
|
||||
return _("Unidentified subscriber");
|
||||
break;
|
||||
case SMS_FACILITY_REJECTED:
|
||||
return _("Facility rejected");
|
||||
break;
|
||||
case SMS_UNKNOWN_SUBSCRIBER:
|
||||
return _("Unknown subscriber");
|
||||
break;
|
||||
case SMS_NETWORK_OUT_OF_ORDER:
|
||||
return _("Network out of order");
|
||||
break;
|
||||
case SMS_TEMPORARY_FAILURE:
|
||||
return _("Temporary failure");
|
||||
break;
|
||||
case SMS_RESOURCES_UNAVAILABLE_UNSPECIFIED:
|
||||
return _("Resources unavailable, unspecified");
|
||||
break;
|
||||
case SMS_REQUESTED_FACILITY_NOT_SUBSCRIBED:
|
||||
return _("Requested facility not subscribed");
|
||||
break;
|
||||
case SMS_REQUESTED_FACILITY_NOT_IMPLEMENTED:
|
||||
return _("Requested facility not implemented");
|
||||
break;
|
||||
case SMS_INVALID_TRANSACTION_IDENTIFIER:
|
||||
return _("Invalid Transaction Identifier");
|
||||
break;
|
||||
case SMS_SEMANTICALLY_INCORRECT_MESSAGE:
|
||||
return _("Semantically incorrect message");
|
||||
break;
|
||||
case SMS_INVALID_MANDATORY_INFORMATION:
|
||||
return _("Invalid mandatory information");
|
||||
break;
|
||||
case SMS_MESSAGE_TYPE_NONEXISTENT_OR_NOT_IMPLEMENTED:
|
||||
return _("Message type non-existent or not implemented");
|
||||
break;
|
||||
case SMS_MESSAGE_NOT_COMPATIBLE_WITH_SHORT_MESSAGE_PROTOCOL_STATE:
|
||||
return _("Message not compatible with short message protocol state");
|
||||
break;
|
||||
case SMS_INFORMATION_ELEMENT_NONEXISTENT_OR_NOT_IMPLEMENTED:
|
||||
return _("Information element non-existent or not implemented");
|
||||
break;
|
||||
case SMS_UNSPECIFIED_PROTOCOL_ERROR:
|
||||
return _("Protocol error, unspecified");
|
||||
break;
|
||||
case SMS_UNSPECIFIED_INTERWORKING_ERROR:
|
||||
return _("Interworking, unspecified");
|
||||
break;
|
||||
case SMS_TELEMATIC_INTERWORKING_NOT_SUPPORTED:
|
||||
return _("Telematic interworking not supported");
|
||||
break;
|
||||
case SMS_SHORT_MESSAGE_TYPE_0_NOT_SUPPORTED:
|
||||
return _("Short message Type 0 not supported");
|
||||
break;
|
||||
case SMS_CANNOT_REPLACE_SHORT_MESSAGE:
|
||||
return _("Cannot replace short message");
|
||||
break;
|
||||
case SMS_UNSPECIFIED_TP_PID_ERROR:
|
||||
return _("Unspecified TP-PID error");
|
||||
break;
|
||||
case SMS_DATA_CODING_SCHEME_NOT_SUPPORTED:
|
||||
return _("Data coding scheme (alphabet) not supported");
|
||||
break;
|
||||
case SMS_MESSAGE_CLASS_NOT_SUPPORTED:
|
||||
return _("Message class not supported");
|
||||
break;
|
||||
case SMS_UNSPECIFIEC_TP_DCS_ERROR:
|
||||
return _("Unspecifiec TP-DCS error");
|
||||
break;
|
||||
case SMS_COMMAND_CANNOT_BE_ACTIONED:
|
||||
return _("Command cannot be actioned");
|
||||
break;
|
||||
case SMS_COMMAND_UNSUPPORTED:
|
||||
return _("Command unsupported");
|
||||
break;
|
||||
case SMS_UNSPECIFIED_TP_COMMAND_ERROR:
|
||||
return _("Unspecified TP-Command error");
|
||||
break;
|
||||
case SMS_TPDU_NOT_SUPPORTED:
|
||||
return _("TPDU not supported");
|
||||
break;
|
||||
case SMS_SC_BUSY:
|
||||
return _("SC busy");
|
||||
break;
|
||||
case SMS_NO_SC_SUBSCRIPTION:
|
||||
return _("No SC subscription");
|
||||
break;
|
||||
case SMS_SC_SYSTEM_FAILURE:
|
||||
return _("SC system failure");
|
||||
break;
|
||||
case SMS_INVALID_SME_ADDRESS:
|
||||
return _("Invalid SME address");
|
||||
break;
|
||||
case SMS_DESTINATION_SME_BARRED:
|
||||
return _("Destination SME barred");
|
||||
break;
|
||||
case SMS_SM_REJECTED_DUPLICATED_SM:
|
||||
return _("SM Rejected-Duplicated SM");
|
||||
break;
|
||||
case SMS_SIM_SMS_STORAGE_FULL:
|
||||
return _("SIM SMS storage full");
|
||||
break;
|
||||
case SMS_NO_SMS_STORAGE_CAPABILITY_IN_SIM:
|
||||
return _("No SMS storage capability in SIM");
|
||||
break;
|
||||
case SMS_ERROR_IN_MS:
|
||||
return _("Error in MS");
|
||||
break;
|
||||
case SMS_MEMORY_CAPACITY_EXCEED:
|
||||
return _("Memory Capacity Exceed");
|
||||
break;
|
||||
case SMS_UNSPECIFIED_ERROR_CAUSE:
|
||||
return _("Unspecified error cause");
|
||||
break;
|
||||
case SMS_ME_FAILURE:
|
||||
return _("ME failure");
|
||||
break;
|
||||
case SMS_SMS_SERVICE_OF_ME_RESERVED:
|
||||
return _("SMS service of ME reserved");
|
||||
break;
|
||||
case SMS_OPERATION_NOT_ALLOWED:
|
||||
return _("operation not allowed");
|
||||
break;
|
||||
case SMS_OPERATION_NOT_SUPPORTED:
|
||||
return _("operation not supported");
|
||||
break;
|
||||
case SMS_INVALID_PDU_MODE_PARAMETER:
|
||||
return _("invalid PDU mode parameter");
|
||||
break;
|
||||
case SMS_INVALID_TEXT_MODE_PARAMETER:
|
||||
return _("invalid text mode parameter");
|
||||
break;
|
||||
case SMS_SIM_NOT_INSERTED:
|
||||
return _("SIM not inserted");
|
||||
break;
|
||||
case SMS_SIM_PIN_REQUIRED:
|
||||
return _("SIM PIN required");
|
||||
break;
|
||||
case SMS_PH_SIM_PIN_REQUIRED:
|
||||
return _("PH-SIM PIN required");
|
||||
break;
|
||||
case SMS_SIM_FAILURE:
|
||||
return _("SIM failure");
|
||||
break;
|
||||
case SMS_SIM_BUSY:
|
||||
return _("SIM busy");
|
||||
break;
|
||||
case SMS_SIM_WRONG:
|
||||
return _("SIM wrong");
|
||||
break;
|
||||
case SMS_SIM_PUK_REQUIRED:
|
||||
return _("SIM PUK required");
|
||||
break;
|
||||
case SMS_SIM_PIN2_REQUIRED:
|
||||
return _("SIM PIN2 required");
|
||||
break;
|
||||
case SMS_SIM_PUK2_REQUIRED:
|
||||
return _("SIM PUK2 required");
|
||||
break;
|
||||
case SMS_MEMORY_FAILURE:
|
||||
return _("memory failure");
|
||||
break;
|
||||
case SMS_INVALID_MEMORY_INDEX:
|
||||
return _("invalid memory index");
|
||||
break;
|
||||
case SMS_MEMORY_FULL:
|
||||
return _("memory full");
|
||||
break;
|
||||
case SMS_SMSC_ADDRESS_UNKNOWN:
|
||||
return _("SMSC address unknown");
|
||||
break;
|
||||
case SMS_NO_NETWORK_SERVICE:
|
||||
return _("no network service");
|
||||
break;
|
||||
case SMS_NETWORK_TIMEOUT:
|
||||
return _("network timeout");
|
||||
break;
|
||||
case SMS_NO_CNMA_ACKNOWLEDGEMENT_EXPECTED:
|
||||
return _("no +CNMA acknowledgement expected");
|
||||
break;
|
||||
case SMS_UNKNOWN_ERROR:
|
||||
return _("unknown error");
|
||||
break;
|
||||
default:
|
||||
throw GsmException(stringPrintf(_("invalid SMS error %d"), errorCode),
|
||||
OtherError);
|
||||
}
|
||||
}
|
||||
|
||||
string gsmlib::getSMSStatusString(unsigned char status)
|
||||
{
|
||||
string result;
|
||||
if (status < SMS_STATUS_TEMPORARY_BIT)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case SMS_STATUS_RECEIVED:
|
||||
result = _("Short message received by the SME");
|
||||
break;
|
||||
case SMS_STATUS_FORWARDED:
|
||||
result = _("Short message forwarded by the SC to the SME but the SC "
|
||||
"is unable to confirm delivery");
|
||||
break;
|
||||
case SMS_STATUS_SM_REPLACES:
|
||||
result = _("Short message replaced by the SC");
|
||||
break;
|
||||
default:
|
||||
result = _("reserved");
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else if (status & SMS_STATUS_TEMPORARY_BIT)
|
||||
{
|
||||
switch (status & ~(SMS_STATUS_TEMPORARY_BIT | SMS_STATUS_PERMANENT_BIT))
|
||||
{
|
||||
case SMS_STATUS_CONGESTION:
|
||||
result = _("Congestion");
|
||||
break;
|
||||
case SMS_STATUS_SME_BUSY:
|
||||
result = _("SME busy");
|
||||
break;
|
||||
case SMS_STATUS_NO_RESPONSE_FROM_SME:
|
||||
result = _("No response from SME");
|
||||
break;
|
||||
case SMS_STATUS_SERVICE_REJECTED:
|
||||
result = _("Service rejected");
|
||||
break;
|
||||
case SMS_STATUS_QUALITY_OF_SERVICE_UNAVAILABLE:
|
||||
result = _("Quality of service not available");
|
||||
break;
|
||||
case SMS_STATUS_ERROR_IN_SME:
|
||||
result = _("Error in SME");
|
||||
break;
|
||||
default:
|
||||
result = _("reserved");
|
||||
break;
|
||||
}
|
||||
if (status & SMS_STATUS_PERMANENT_BIT)
|
||||
return result + _(" (Temporary error, SC is not making any "
|
||||
"more transfer attempts)");
|
||||
else
|
||||
return result + _(" (Temporary error, SC still trying to "
|
||||
"transfer SM)");
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (status & ~SMS_STATUS_PERMANENT_BIT)
|
||||
{
|
||||
case SMS_STATUS_REMOTE_PROCECURE_ERROR:
|
||||
result = _("Remote Procedure Error");
|
||||
break;
|
||||
case SMS_STATUS_INCOMPATIBLE_DESTINATION:
|
||||
result = _("Incompatible destination");
|
||||
break;
|
||||
case SMS_STATUS_CONNECTION_REJECTED_BY_SME:
|
||||
result = _("Connection rejected by SME");
|
||||
break;
|
||||
case SMS_STATUS_NOT_OBTAINABLE:
|
||||
result = _("Not obtainable");
|
||||
break;
|
||||
case SMS_STATUS_QUALITY_OF_SERVICE_UNAVAILABLE:
|
||||
result = _("Quality of service not available");
|
||||
break;
|
||||
case SMS_STATUS_NO_INTERWORKING_AVAILABLE:
|
||||
result = _("No interworking available");
|
||||
break;
|
||||
case SMS_STATUS_SM_VALIDITY_PERDIOD_EXPIRED:
|
||||
result = _("SM validity period expired");
|
||||
break;
|
||||
case SMS_STATUS_SM_DELETED_BY_ORIGINATING_SME:
|
||||
result = _("SM deleted by originating SME");
|
||||
break;
|
||||
case SMS_STATUS_SM_DELETED_BY_ADMINISTRATION:
|
||||
result = _("SM deleted by SC administration");
|
||||
break;
|
||||
case SMS_STATUS_SM_DOES_NOT_EXIST:
|
||||
result = _("SM does not exit");
|
||||
break;
|
||||
default:
|
||||
result = _("reserved");
|
||||
break;
|
||||
}
|
||||
return result + _(" (Permanent Error, SC is not making any "
|
||||
"more transfer attempts)");
|
||||
}
|
||||
}
|
@ -0,0 +1,209 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_error.h
|
||||
// *
|
||||
// * Purpose: Error codes and error handling functions
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 4.5.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifndef GSM_ERROR_H
|
||||
#define GSM_ERROR_H
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gsmlib
|
||||
{
|
||||
// different classes of GSM errors
|
||||
enum GsmErrorClass{OSError, // error caused by OS call (eg. file handling)
|
||||
ParserError, // error when parsing AT response
|
||||
ChatError, // error in chat sequence (ME/TA/SMS error)
|
||||
ParameterError, // gsmlib function called with bad params
|
||||
NotImplementedError, // feature not implemented
|
||||
MeTaCapabilityError, // non-existent capability in ME
|
||||
SMSFormatError, // SMS format error
|
||||
InterruptException, // gsmlib was interrupted()
|
||||
OtherError}; // all other errors
|
||||
|
||||
// all gsmlib exceptions
|
||||
|
||||
class GsmException : public runtime_error
|
||||
{
|
||||
private:
|
||||
GsmErrorClass _errorClass;
|
||||
int _errorCode;
|
||||
|
||||
public:
|
||||
GsmException(string errorText, GsmErrorClass errorClass) :
|
||||
runtime_error(errorText), _errorClass(errorClass), _errorCode(-1) {}
|
||||
|
||||
GsmException(string errorText, GsmErrorClass errorClass, int errorCode) :
|
||||
runtime_error(errorText), _errorClass(errorClass),
|
||||
_errorCode(errorCode) {}
|
||||
|
||||
int getErrorCode() const {return _errorCode;}
|
||||
|
||||
GsmErrorClass getErrorClass() const {return _errorClass;}
|
||||
};
|
||||
|
||||
// error codes returned by TA/ME (+CMEE)
|
||||
|
||||
const int ME_PHONE_FAILURE = 0;
|
||||
const int ME_NO_CONNECTION_TO_PHONE = 1;
|
||||
const int ME_PHONE_ADAPTOR_LINK_RESERVED = 2;
|
||||
const int ME_OPERATION_NOT_ALLOWED = 3;
|
||||
const int ME_OPERATION_NOT_SUPPORTED = 4;
|
||||
const int ME_PH_SIM_PIN_REQUIRED = 5;
|
||||
const int ME_SIM_NOT_INSERTED = 10;
|
||||
const int ME_SIM_PIN_REQUIRED = 11;
|
||||
const int ME_SIM_PUK_REQUIRED = 12;
|
||||
const int ME_SIM_FAILURE = 13;
|
||||
const int ME_SIM_BUSY = 14;
|
||||
const int ME_SIM_WRONG = 15;
|
||||
const int ME_INCORRECT_PASSWORD = 16;
|
||||
const int ME_SIM_PIN2_REQUIRED = 17;
|
||||
const int ME_SIM_PUK2_REQUIRED = 18;
|
||||
const int ME_MEMORY_FULL = 20;
|
||||
const int ME_INVALID_INDEX = 21;
|
||||
const int ME_NOT_FOUND = 22;
|
||||
const int ME_MEMORY_FAILURE = 23;
|
||||
const int ME_TEXT_STRING_TOO_LONG = 24;
|
||||
const int ME_INVALID_CHARACTERS_IN_TEXT_STRING = 25;
|
||||
const int ME_DIAL_STRING_TOO_LONG = 26;
|
||||
const int ME_INVALID_CHARACTERS_IN_DIAL_STRING = 27;
|
||||
const int ME_NO_NETWORK_SERVICE = 30;
|
||||
const int ME_NETWORK_TIMEOUT = 31;
|
||||
const int ME_UNKNOWN = 100;
|
||||
|
||||
// return descriptive text for the given error code
|
||||
// the text is already translated
|
||||
extern string getMEErrorText(const int errorCode) throw(GsmException);
|
||||
|
||||
// SMS error codes
|
||||
|
||||
// error codes from ETSI GSM 04.11, Annex E
|
||||
const int SMS_UNASSIGNED_OR_UNALLOCATED_NUMBER = 1;
|
||||
const int SMS_OPERATOR_DETERMINED_BARRING = 8;
|
||||
const int SMS_CALL_BARRED = 10;
|
||||
const int SMS_NETWORK_FAILURE = 17;
|
||||
const int SMS_SHORT_MESSAGE_TRANSFER_REJECTED = 21;
|
||||
const int SMS_CONGESTION = 22;
|
||||
const int SMS_DESTINATION_OUT_OF_SERVICE = 27;
|
||||
const int SMS_UNIDENTIFIED_SUBSCRIBER = 28;
|
||||
const int SMS_FACILITY_REJECTED = 29;
|
||||
const int SMS_UNKNOWN_SUBSCRIBER = 30;
|
||||
const int SMS_NETWORK_OUT_OF_ORDER = 38;
|
||||
const int SMS_TEMPORARY_FAILURE = 41;
|
||||
const int SMS_CONGESTION2 = 42;
|
||||
const int SMS_RESOURCES_UNAVAILABLE_UNSPECIFIED = 47;
|
||||
const int SMS_REQUESTED_FACILITY_NOT_SUBSCRIBED = 50;
|
||||
const int SMS_REQUESTED_FACILITY_NOT_IMPLEMENTED = 69;
|
||||
const int SMS_INVALID_TRANSACTION_IDENTIFIER = 81;
|
||||
const int SMS_SEMANTICALLY_INCORRECT_MESSAGE = 95;
|
||||
const int SMS_INVALID_MANDATORY_INFORMATION = 96;
|
||||
const int SMS_MESSAGE_TYPE_NONEXISTENT_OR_NOT_IMPLEMENTED = 97;
|
||||
const int SMS_MESSAGE_NOT_COMPATIBLE_WITH_SHORT_MESSAGE_PROTOCOL_STATE = 98;
|
||||
const int SMS_INFORMATION_ELEMENT_NONEXISTENT_OR_NOT_IMPLEMENTED = 99;
|
||||
const int SMS_UNSPECIFIED_PROTOCOL_ERROR = 111;
|
||||
const int SMS_UNSPECIFIED_INTERWORKING_ERROR = 127;
|
||||
|
||||
// error codes from ETSI GSM 03.40, section 9.2.3.22
|
||||
const int SMS_TELEMATIC_INTERWORKING_NOT_SUPPORTED = 0x80;
|
||||
const int SMS_SHORT_MESSAGE_TYPE_0_NOT_SUPPORTED = 0x81;
|
||||
const int SMS_CANNOT_REPLACE_SHORT_MESSAGE = 0x82;
|
||||
const int SMS_UNSPECIFIED_TP_PID_ERROR = 0x8f;
|
||||
const int SMS_DATA_CODING_SCHEME_NOT_SUPPORTED = 0x90;
|
||||
const int SMS_MESSAGE_CLASS_NOT_SUPPORTED = 0x91;
|
||||
const int SMS_UNSPECIFIEC_TP_DCS_ERROR = 0x9f;
|
||||
const int SMS_COMMAND_CANNOT_BE_ACTIONED = 0xa0;
|
||||
const int SMS_COMMAND_UNSUPPORTED = 0xa1;
|
||||
const int SMS_UNSPECIFIED_TP_COMMAND_ERROR = 0xaf;
|
||||
const int SMS_TPDU_NOT_SUPPORTED = 0xb0;
|
||||
const int SMS_SC_BUSY = 0xc0;
|
||||
const int SMS_NO_SC_SUBSCRIPTION = 0xc1;
|
||||
const int SMS_SC_SYSTEM_FAILURE = 0xc2;
|
||||
const int SMS_INVALID_SME_ADDRESS = 0xc3;
|
||||
const int SMS_DESTINATION_SME_BARRED = 0xc4;
|
||||
const int SMS_SM_REJECTED_DUPLICATED_SM = 0xc5;
|
||||
const int SMS_SIM_SMS_STORAGE_FULL = 0xd0;
|
||||
const int SMS_NO_SMS_STORAGE_CAPABILITY_IN_SIM = 0xd1;
|
||||
const int SMS_ERROR_IN_MS = 0xd2;
|
||||
const int SMS_MEMORY_CAPACITY_EXCEED = 0xd3;
|
||||
const int SMS_UNSPECIFIED_ERROR_CAUSE = 0xff;
|
||||
|
||||
// error codes from ETSI GSM 07.05, section 3.2.5
|
||||
const int SMS_ME_FAILURE = 300;
|
||||
const int SMS_SMS_SERVICE_OF_ME_RESERVED = 301;
|
||||
const int SMS_OPERATION_NOT_ALLOWED = 302;
|
||||
const int SMS_OPERATION_NOT_SUPPORTED = 303;
|
||||
const int SMS_INVALID_PDU_MODE_PARAMETER = 304;
|
||||
const int SMS_INVALID_TEXT_MODE_PARAMETER = 305;
|
||||
const int SMS_SIM_NOT_INSERTED = 310;
|
||||
const int SMS_SIM_PIN_REQUIRED = 311;
|
||||
const int SMS_PH_SIM_PIN_REQUIRED = 312;
|
||||
const int SMS_SIM_FAILURE = 313;
|
||||
const int SMS_SIM_BUSY = 314;
|
||||
const int SMS_SIM_WRONG = 315;
|
||||
const int SMS_SIM_PUK_REQUIRED = 316;
|
||||
const int SMS_SIM_PIN2_REQUIRED = 317;
|
||||
const int SMS_SIM_PUK2_REQUIRED = 318;
|
||||
const int SMS_MEMORY_FAILURE = 320;
|
||||
const int SMS_INVALID_MEMORY_INDEX = 321;
|
||||
const int SMS_MEMORY_FULL = 322;
|
||||
const int SMS_SMSC_ADDRESS_UNKNOWN = 330;
|
||||
const int SMS_NO_NETWORK_SERVICE = 331;
|
||||
const int SMS_NETWORK_TIMEOUT = 332;
|
||||
const int SMS_NO_CNMA_ACKNOWLEDGEMENT_EXPECTED = 340;
|
||||
const int SMS_UNKNOWN_ERROR = 500;
|
||||
|
||||
// return descriptive text for the given error code
|
||||
// the text is already translated
|
||||
extern string getSMSErrorText(const int errorCode) throw(GsmException);
|
||||
|
||||
// SMS status handling
|
||||
// success codes
|
||||
const int SMS_STATUS_RECEIVED = 0;
|
||||
const int SMS_STATUS_FORWARDED = 1;
|
||||
const int SMS_STATUS_SM_REPLACES = 2;
|
||||
|
||||
// if this bit is set, the error is only temporary and
|
||||
// the SC is still trying to transfer the SM
|
||||
const int SMS_STATUS_TEMPORARY_BIT = 32;
|
||||
|
||||
// if this bit is set, the error is only temporary and
|
||||
// the SC is still trying to transfer the SM
|
||||
const int SMS_STATUS_PERMANENT_BIT = 64;
|
||||
// both bits may be set at once
|
||||
|
||||
// temporary errors (both bits may be set)
|
||||
const int SMS_STATUS_CONGESTION = 0;
|
||||
const int SMS_STATUS_SME_BUSY = 1;
|
||||
const int SMS_STATUS_NO_RESPONSE_FROM_SME = 2;
|
||||
const int SMS_STATUS_SERVICE_REJECTED = 3;
|
||||
const int SMS_STATUS_QUALITY_OF_SERVICE_UNAVAILABLE = 4;
|
||||
const int SMS_STATUS_ERROR_IN_SME = 5;
|
||||
|
||||
// permanent errors (SMS_STATUS_PERMANENT_BIT is set)
|
||||
const int SMS_STATUS_REMOTE_PROCECURE_ERROR = 0;
|
||||
const int SMS_STATUS_INCOMPATIBLE_DESTINATION = 1;
|
||||
const int SMS_STATUS_CONNECTION_REJECTED_BY_SME = 2;
|
||||
const int SMS_STATUS_NOT_OBTAINABLE = 3;
|
||||
// const int SMS_STATUS_QUALITY_OF_SERVICE_UNAVAILABLE = 4;
|
||||
const int SMS_STATUS_NO_INTERWORKING_AVAILABLE = 5;
|
||||
const int SMS_STATUS_SM_VALIDITY_PERDIOD_EXPIRED = 6;
|
||||
const int SMS_STATUS_SM_DELETED_BY_ORIGINATING_SME = 7;
|
||||
const int SMS_STATUS_SM_DELETED_BY_ADMINISTRATION = 8;
|
||||
const int SMS_STATUS_SM_DOES_NOT_EXIST = 9;
|
||||
|
||||
// return text for SMS status code
|
||||
// the text is already translated
|
||||
string getSMSStatusString(unsigned char status);
|
||||
};
|
||||
|
||||
#endif // GSM_ERROR_H
|
@ -0,0 +1,174 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_event.cc
|
||||
// *
|
||||
// * Purpose: Event handler interface
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 7.6.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <gsm_config.h>
|
||||
#endif
|
||||
#include <gsmlib/gsm_nls.h>
|
||||
#include <gsmlib/gsm_event.h>
|
||||
#include <gsmlib/gsm_parser.h>
|
||||
#include <gsmlib/gsm_at.h>
|
||||
#include <gsmlib/gsm_me_ta.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace gsmlib;
|
||||
|
||||
// GsmEvent members
|
||||
|
||||
void GsmEvent::dispatch(string s, GsmAt &at) throw(GsmException)
|
||||
{
|
||||
SMSMessageType messageType;
|
||||
bool indication = false;
|
||||
if (s.substr(0, 5) == "+CMT:")
|
||||
messageType = NormalSMS;
|
||||
else if (s.substr(0, 5) == "+CBM:")
|
||||
messageType = CellBroadcastSMS;
|
||||
else if (s.substr(0, 5) == "+CDS:")
|
||||
{
|
||||
// workaround for phones that report CDS when they actually mean CDSI
|
||||
indication = at.getMeTa().getCapabilities()._CDSmeansCDSI;
|
||||
messageType = StatusReportSMS;
|
||||
}
|
||||
else if (s.substr(0, 6) == "+CMTI:")
|
||||
{
|
||||
indication = true;
|
||||
messageType = NormalSMS;
|
||||
}
|
||||
else if (s.substr(0, 6) == "+CBMI:")
|
||||
{
|
||||
indication = true;
|
||||
messageType = CellBroadcastSMS;
|
||||
}
|
||||
else if (s.substr(0, 6) == "+CDSI:")
|
||||
{
|
||||
indication = true;
|
||||
messageType = StatusReportSMS;
|
||||
}
|
||||
else if (s.substr(0, 4) == "RING")
|
||||
{
|
||||
ringIndication();
|
||||
return;
|
||||
}
|
||||
// handling NO CARRIER
|
||||
else if (s.substr(0, 10) == "NO CARRIER")
|
||||
{
|
||||
noAnswer();
|
||||
return;
|
||||
}
|
||||
|
||||
else if (s.substr(0, 6) == "+CLIP:")
|
||||
{
|
||||
// <number>,<type>[,<subaddr>,<satype>[,<alpha>]]
|
||||
s = s.substr(6);
|
||||
Parser p(s);
|
||||
string num = p.parseString();
|
||||
if (p.parseComma(true))
|
||||
{
|
||||
unsigned int numberFormat;
|
||||
if ((numberFormat = p.parseInt()) == InternationalNumberFormat)
|
||||
num = "+" + num;
|
||||
else if (numberFormat != UnknownNumberFormat)
|
||||
throw GsmException(stringPrintf(_("unexpected number format %d"),
|
||||
numberFormat), OtherError);
|
||||
}
|
||||
string subAddr;
|
||||
string alpha;
|
||||
if (p.parseComma(true))
|
||||
{
|
||||
subAddr = p.parseString(true);
|
||||
p.parseComma();
|
||||
p.parseInt(true); // FIXME subaddr type ignored
|
||||
|
||||
if (p.parseComma(true))
|
||||
alpha = p.parseString(true);
|
||||
}
|
||||
|
||||
// call the event handler
|
||||
callerLineID(num, subAddr, alpha);
|
||||
return;
|
||||
}
|
||||
else
|
||||
throw GsmException(stringPrintf(_("unexpected unsolicited event '%s'"),
|
||||
s.c_str()), OtherError);
|
||||
|
||||
if (indication)
|
||||
{
|
||||
// handle SMS storage indication
|
||||
s = s.substr(6);
|
||||
Parser p(s);
|
||||
string storeName = p.parseString();
|
||||
p.parseComma();
|
||||
unsigned int index = p.parseInt();
|
||||
SMSReceptionIndication(storeName, index - 1, messageType);
|
||||
}
|
||||
else
|
||||
if (messageType == CellBroadcastSMS)
|
||||
{
|
||||
// handle CB message
|
||||
string pdu = at.getLine();
|
||||
|
||||
CBMessageRef cb = new CBMessage(pdu);
|
||||
|
||||
// call the event handler
|
||||
CBReception(cb);
|
||||
}
|
||||
else
|
||||
{
|
||||
// handle SMS
|
||||
string pdu = at.getLine();
|
||||
|
||||
// add missing service centre address if required by ME
|
||||
if (! at.getMeTa().getCapabilities()._hasSMSSCAprefix)
|
||||
pdu = "00" + pdu;
|
||||
|
||||
SMSMessageRef sms = SMSMessage::decode(pdu);
|
||||
|
||||
// send acknowledgement if necessary
|
||||
if (at.getMeTa().getCapabilities()._sendAck)
|
||||
at.chat("+CNMA");
|
||||
|
||||
// call the event handler
|
||||
SMSReception(sms, messageType);
|
||||
}
|
||||
}
|
||||
|
||||
void GsmEvent::callerLineID(string number, string subAddr, string alpha)
|
||||
{
|
||||
// ignore event
|
||||
}
|
||||
|
||||
void GsmEvent::SMSReception(SMSMessageRef newMessage,
|
||||
SMSMessageType messageType)
|
||||
{
|
||||
// ignore event
|
||||
}
|
||||
|
||||
void GsmEvent::CBReception(CBMessageRef newMessage)
|
||||
{
|
||||
// ignore event
|
||||
}
|
||||
|
||||
void GsmEvent::SMSReceptionIndication(string storeName, unsigned int index,
|
||||
SMSMessageType messageType)
|
||||
{
|
||||
// ignore event
|
||||
}
|
||||
|
||||
void GsmEvent::ringIndication()
|
||||
{
|
||||
// ignore event
|
||||
}
|
||||
|
||||
void GsmEvent::noAnswer()
|
||||
{
|
||||
// ignore event
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_event.h
|
||||
// *
|
||||
// * Purpose: Event handler interface
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 7.6.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifndef GSM_EVENT_H
|
||||
#define GSM_EVENT_H
|
||||
|
||||
#include <gsmlib/gsm_sms.h>
|
||||
#include <gsmlib/gsm_cb.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gsmlib
|
||||
{
|
||||
// forward declarations
|
||||
|
||||
class GsmAt;
|
||||
|
||||
// event handler interface
|
||||
|
||||
class GsmEvent
|
||||
{
|
||||
private:
|
||||
// dispatch CMT/CBR/CDS/CLIP etc.
|
||||
void dispatch(string s, GsmAt &at) throw(GsmException);
|
||||
|
||||
public:
|
||||
// for SMSReception, type of SMS
|
||||
enum SMSMessageType {NormalSMS, CellBroadcastSMS, StatusReportSMS};
|
||||
|
||||
// caller line identification presentation
|
||||
// only called if setCLIPEvent(true) is set
|
||||
virtual void callerLineID(string number, string subAddr, string alpha);
|
||||
|
||||
// called if the string NO CARRIER is read
|
||||
virtual void noAnswer();
|
||||
|
||||
// SMS reception
|
||||
// only called if setSMSReceptionEvent(...true...) is set
|
||||
virtual void SMSReception(SMSMessageRef newMessage,
|
||||
SMSMessageType messageType);
|
||||
|
||||
// CB reception
|
||||
// only called if setSMSReceptionEvent(...true...) is set
|
||||
// storage of CBM in ME is not supported by the standard
|
||||
virtual void CBReception(CBMessageRef newMessage);
|
||||
|
||||
// SMS reception indication (called when SMS is not delivered to TE
|
||||
// but stored in ME memory)
|
||||
virtual void SMSReceptionIndication(string storeName, unsigned int index,
|
||||
SMSMessageType messageType);
|
||||
|
||||
// RING indication
|
||||
virtual void ringIndication();
|
||||
|
||||
friend class gsmlib::GsmAt;
|
||||
};
|
||||
};
|
||||
|
||||
#endif // GSM_EVENT_H
|
@ -0,0 +1,128 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_map_key.h
|
||||
// *
|
||||
// * Purpose: Common MapKey implementation for the multimaps in
|
||||
// * gsm_sorted_sms_store and gsm_sorted_phonebook
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 5.11.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifndef GSM_MAP_KEY_H
|
||||
#define GSM_MAP_KEY_H
|
||||
|
||||
#include <gsmlib/gsm_sms_codec.h>
|
||||
|
||||
namespace gsmlib
|
||||
{
|
||||
// sort order for MapKeys
|
||||
|
||||
enum SortOrder {ByText = 0, ByTelephone = 1, ByIndex = 2, ByDate = 3,
|
||||
ByType = 4, ByAddress = 5};
|
||||
|
||||
// wrapper for map key, can access Sortedtore to get sortOrder()
|
||||
|
||||
template <class SortedStore> class MapKey
|
||||
{
|
||||
public:
|
||||
SortedStore &_myStore; // my store
|
||||
// different type keys
|
||||
Address _addressKey;
|
||||
Timestamp _timeKey;
|
||||
int _intKey;
|
||||
string _strKey;
|
||||
|
||||
public:
|
||||
// constructors for the different sort keys
|
||||
MapKey(SortedStore &myStore, Address key) :
|
||||
_myStore(myStore), _addressKey(key) {}
|
||||
MapKey(SortedStore &myStore, Timestamp key) :
|
||||
_myStore(myStore), _timeKey(key) {}
|
||||
MapKey(SortedStore &myStore, int key) :
|
||||
_myStore(myStore), _intKey(key) {}
|
||||
MapKey(SortedStore &myStore, string key) :
|
||||
_myStore(myStore), _strKey(key) {}
|
||||
|
||||
/*
|
||||
friend
|
||||
bool operator<
|
||||
#ifndef WIN32
|
||||
<>
|
||||
#endif
|
||||
(const MapKey<SortedStore> &x,
|
||||
const MapKey<SortedStore> &y);
|
||||
friend
|
||||
bool operator==
|
||||
#ifndef WIN32
|
||||
<>
|
||||
#endif
|
||||
(const MapKey<SortedStore> &x,
|
||||
const MapKey<SortedStore> &y);
|
||||
*/
|
||||
};
|
||||
|
||||
// compare two keys
|
||||
template <class SortedStore>
|
||||
extern bool operator<(const MapKey<SortedStore> &x,
|
||||
const MapKey<SortedStore> &y);
|
||||
template <class SortedStore>
|
||||
extern bool operator==(const MapKey<SortedStore> &x,
|
||||
const MapKey<SortedStore> &y);
|
||||
|
||||
// MapKey members
|
||||
|
||||
template <class SortedStore>
|
||||
bool operator<(const MapKey<SortedStore> &x,
|
||||
const MapKey<SortedStore> &y)
|
||||
{
|
||||
assert(&x._myStore == &y._myStore);
|
||||
|
||||
switch (x._myStore.sortOrder())
|
||||
{
|
||||
case ByDate:
|
||||
return x._timeKey < y._timeKey;
|
||||
case ByAddress:
|
||||
return x._addressKey < y._addressKey;
|
||||
case ByIndex:
|
||||
case ByType:
|
||||
return x._intKey < y._intKey;
|
||||
case ByTelephone:
|
||||
return Address(x._strKey) < Address(y._strKey);
|
||||
case ByText:
|
||||
return x._strKey < y._strKey;
|
||||
default:
|
||||
assert(0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
template <class SortedStore>
|
||||
bool operator==(const MapKey<SortedStore> &x,
|
||||
const MapKey<SortedStore> &y)
|
||||
{
|
||||
assert(&x._myStore == &y._myStore);
|
||||
|
||||
switch (x._myStore.sortOrder())
|
||||
{
|
||||
case ByDate:
|
||||
return x._timeKey == y._timeKey;
|
||||
case ByAddress:
|
||||
return x._addressKey == y._addressKey;
|
||||
case ByIndex:
|
||||
case ByType:
|
||||
return x._intKey == y._intKey;
|
||||
case ByTelephone:
|
||||
return Address(x._strKey) == Address(y._strKey);
|
||||
case ByText:
|
||||
return x._strKey == y._strKey;
|
||||
default:
|
||||
assert(0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // GSM_MAP_KEY_H
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,402 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_me_ta.h
|
||||
// *
|
||||
// * Purpose: Mobile Equipment/Terminal Adapter and SMS functions
|
||||
// * (ETSI GSM 07.07 and 07.05)
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 3.5.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifndef GSM_ME_TA_H
|
||||
#define GSM_ME_TA_H
|
||||
|
||||
#include <gsmlib/gsm_error.h>
|
||||
#include <gsmlib/gsm_event.h>
|
||||
#include <gsmlib/gsm_phonebook.h>
|
||||
#include <gsmlib/gsm_sms_store.h>
|
||||
#include <gsmlib/gsm_util.h>
|
||||
#include <gsmlib/gsm_at.h>
|
||||
#include <gsmlib/gsm_sms.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gsmlib
|
||||
{
|
||||
// *** phone capability description (you could also call it phone quirks)
|
||||
|
||||
struct Capabilities
|
||||
{
|
||||
bool _hasSMSSCAprefix; // SMS have service centre address prefix
|
||||
int _cpmsParamCount; // number of SMS store parameters to
|
||||
// CPMS command
|
||||
bool _omitsColon; // omits trailing ':' in AT responses
|
||||
bool _veryShortCOPSanswer; // Falcom A2-1
|
||||
bool _wrongSMSStatusCode; // Motorola Timeport 260
|
||||
bool _CDSmeansCDSI; // Nokia Cellular Card Phone RPE-1 GSM900
|
||||
bool _sendAck; // send ack for directly routed SMS
|
||||
Capabilities(); // constructor, set default behaviours
|
||||
};
|
||||
|
||||
// *** auxiliary structs
|
||||
|
||||
// Static ME information (AT command sequences given in brackets)
|
||||
struct MEInfo
|
||||
{
|
||||
string _manufacturer; // (+CGMI)
|
||||
string _model; // (+CGMM)
|
||||
string _revision; // (+CGMR)
|
||||
string _serialNumber; // (+CGSN), IMEI
|
||||
};
|
||||
|
||||
// modes for network operation selection
|
||||
enum OPModes {AutomaticOPMode = 0, ManualOPMode = 1,
|
||||
DeregisterOPMode = 2, ManualAutomaticOPMode = 4};
|
||||
|
||||
// status codes or network operaton selection
|
||||
enum OPStatus {UnknownOPStatus = 0, AvailableOPStatus = 1,
|
||||
CurrentOPStatus = 2, ForbiddenOPStatus = 3};
|
||||
|
||||
// network operator info
|
||||
struct OPInfo
|
||||
{
|
||||
OPModes _mode;
|
||||
OPStatus _status;
|
||||
string _longName;
|
||||
string _shortName;
|
||||
int _numericName; // may be NOT_SET
|
||||
|
||||
OPInfo() : _status(UnknownOPStatus), _numericName(NOT_SET) {}
|
||||
};
|
||||
|
||||
// facility classes
|
||||
enum FacilityClass {VoiceFacility = 1, DataFacility = 2, FaxFacility = 4};
|
||||
const int ALL_FACILITIES = VoiceFacility | DataFacility | FaxFacility;
|
||||
|
||||
// struct to hold password info
|
||||
struct PWInfo
|
||||
{
|
||||
string _facility;
|
||||
int _maxPasswdLen;
|
||||
};
|
||||
|
||||
// call forward reasons
|
||||
// AllReasons encompasses 0..3
|
||||
// AllConditionalReasons encompasses 1..3
|
||||
enum ForwardReason {UnconditionalReason = 0, MobileBusyReason = 1,
|
||||
NoReplyReason = 2, NotReachableReason = 3,
|
||||
AllReasons = 4, AllConditionalReasons = 5, NoReason = 6};
|
||||
|
||||
// call forward modes
|
||||
enum ForwardMode {DisableMode = 0, EnableMode = 1,
|
||||
RegistrationMode = 3, ErasureMode = 4};
|
||||
|
||||
// call forward info
|
||||
struct ForwardInfo
|
||||
{
|
||||
bool _active; // status in the network
|
||||
FacilityClass _cl; // voice, fax, or data
|
||||
string _number; // telephone number
|
||||
string _subAddr; // subaddress
|
||||
int _time; // time in the range 1..30 (for NoReplyReason)
|
||||
ForwardReason _reason; // reason for the forwarding
|
||||
};
|
||||
|
||||
// SMS types
|
||||
typedef Ref<SMSStore> SMSStoreRef;
|
||||
typedef vector<SMSStoreRef> SMSStoreVector;
|
||||
|
||||
// this class allows access to all functions of a ME/TA as described
|
||||
// in sections 5-8 of ETSI GSM 07.07
|
||||
// Note: If the ME is changed (ie. disconnected an another one connected
|
||||
// to the TA), a new ME object must be created
|
||||
// (Mobile equipment = ME, terminal adapter = TA)
|
||||
class MeTa : public RefBase
|
||||
{
|
||||
protected:
|
||||
Ref<Port> _port; // port the ME/TA is connected to
|
||||
Ref<GsmAt> _at; // chat object for the port
|
||||
PhonebookVector _phonebookCache; // cache of all used phonebooks
|
||||
SMSStoreVector _smsStoreCache; // cache of all used phonebooks
|
||||
string _lastPhonebookName; // remember last phonebook set on ME/TA
|
||||
string _lastSMSStoreName; // remember last SMS store set on ME/TA
|
||||
Capabilities _capabilities; // ME/TA quirks
|
||||
GsmEvent _defaultEventHandler; // default event handler
|
||||
// see comments in MeTa::init()
|
||||
string _lastCharSet; // remember last character set
|
||||
|
||||
// init ME/TA to sensible defaults
|
||||
void init() throw(GsmException);
|
||||
|
||||
public:
|
||||
// initialize a new MeTa object given the port
|
||||
MeTa(Ref<Port> port) throw(GsmException);
|
||||
|
||||
// initialize a new MeTa object given the AT handler
|
||||
//MeTa(Ref<GsmAt> at) throw(GsmException);
|
||||
|
||||
// set the current phonebook in the ME
|
||||
// remember the last phonebook set for optimisation
|
||||
void setPhonebook(string phonebookName) throw(GsmException);
|
||||
|
||||
// set the current SMS store in the ME
|
||||
// set storeTypes to
|
||||
// 1 to set store for reading and deleting
|
||||
// 2 to set store for writing and sending (includes type 1)
|
||||
// 3 to preferred store for receiving SMS (includes types 1 and 2)
|
||||
// remember the last SMS store set for optimisation
|
||||
// if needResultCode is set this optimisation is not done
|
||||
string setSMSStore(string smsStore, int storeTypes,
|
||||
bool needResultCode = false)
|
||||
throw(GsmException);
|
||||
|
||||
// get current SMS store settings
|
||||
void getSMSStore(string &readDeleteStore,
|
||||
string &writeSendStore,
|
||||
string &receiveStore) throw(GsmException);
|
||||
|
||||
// get capabilities of this ME/TA
|
||||
Capabilities getCapabilities() const {return _capabilities;}
|
||||
|
||||
// return my port
|
||||
Ref<Port> getPort() {return _port;}
|
||||
|
||||
// return my at handler
|
||||
Ref<GsmAt> getAt() {return _at;}
|
||||
|
||||
// set event handler for unsolicited result codes
|
||||
GsmEvent *setEventHandler(GsmEvent *newHandler)
|
||||
{return _at->setEventHandler(newHandler);}
|
||||
|
||||
// wait for an event
|
||||
void waitEvent(GsmTime timeout) throw(GsmException);
|
||||
|
||||
// *** ETSI GSM 07.07 Section 5: "General Commands"
|
||||
|
||||
// return ME information
|
||||
MEInfo getMEInfo() throw(GsmException);
|
||||
|
||||
// return available character sets
|
||||
vector<string> getSupportedCharSets() throw(GsmException);// (+CSCS=?)
|
||||
|
||||
// return current character set (default: GSM)
|
||||
string getCurrentCharSet() throw(GsmException);// (+CSCS?)
|
||||
|
||||
// set character set to use
|
||||
void setCharSet(string charSetName) throw(GsmException);// (+CSCS=)
|
||||
|
||||
// *** ETSI GSM 07.07 Section 6: "Call control commands and methods"
|
||||
|
||||
// get extended error report
|
||||
string getExtendedErrorReport() throw(GsmException);// (+CEER)
|
||||
|
||||
// dial a number, CLI presentation as defined in network
|
||||
void dial(string number) throw(GsmException);// (ATD)
|
||||
|
||||
// answer
|
||||
void answer() throw(GsmException); // (ATA)
|
||||
|
||||
// hangup
|
||||
void hangup() throw(GsmException); // (ATH)
|
||||
|
||||
// set Personal Identification Number
|
||||
void setPIN(string number) throw(GsmException);// (+CPIN)
|
||||
|
||||
// get PIN Status
|
||||
string getPINStatus() throw(GsmException);// (+CPIN?)
|
||||
|
||||
// *** ETSI GSM 07.07 Section 7: "Network service related commands"
|
||||
|
||||
// return available network operators
|
||||
// this fills in all fields of OPInfo with the exception of _mode
|
||||
vector<OPInfo> getAvailableOPInfo() throw(GsmException); // (+COPS=?)
|
||||
|
||||
// return current network operators
|
||||
// this fills in all the fields of OPInfo with the exception of _status
|
||||
OPInfo getCurrentOPInfo() throw(GsmException);
|
||||
|
||||
// set network operator
|
||||
// caller must fill in ALL names it has read from previous calls
|
||||
// of getCurrentOPInfo() or getAvailableOPInfo()
|
||||
// (because ME/TA might not implement all names)
|
||||
void setCurrentOPInfo(OPModes mode,
|
||||
string longName = "",
|
||||
string shortName = "",
|
||||
int numericName = NOT_SET) throw(GsmException);
|
||||
|
||||
// get facility lock capabilities (+CLCK)
|
||||
vector<string> getFacilityLockCapabilities() throw(GsmException);
|
||||
|
||||
// query facility lock status for named facility
|
||||
bool getFacilityLockStatus(string facility, FacilityClass cl)
|
||||
throw(GsmException);
|
||||
|
||||
// lock facility
|
||||
void lockFacility(string facility, FacilityClass cl, string passwd = "")
|
||||
throw(GsmException);
|
||||
|
||||
// unlock facility
|
||||
void unlockFacility(string facility, FacilityClass cl, string passwd = "")
|
||||
throw(GsmException);
|
||||
|
||||
// return names of facility for which a password can be set
|
||||
// and the maximum length of the respective password
|
||||
vector<PWInfo> getPasswords() throw(GsmException);// (+CPWD=?)
|
||||
|
||||
// set password for the given facility
|
||||
void setPassword(string facility, string oldPasswd, string newPasswd)
|
||||
throw(GsmException);
|
||||
// (+CPWD=)
|
||||
|
||||
// get CLIP (caller line identification presentation) in the network
|
||||
bool getNetworkCLIP() throw(GsmException);// (+CLIP?)
|
||||
|
||||
// set CLIP presentation on or off
|
||||
// enables GsmEvent::callerLineID
|
||||
void setCLIPPresentation(bool enable) throw(GsmException);// (+CLIP=)
|
||||
|
||||
// returns if the above is enable
|
||||
bool getCLIPPresentation() throw(GsmException);// (+CLIP?)
|
||||
|
||||
// set call forwarding
|
||||
void setCallForwarding(ForwardReason reason,
|
||||
ForwardMode mode,
|
||||
string number,
|
||||
string subaddr,
|
||||
FacilityClass cl = (FacilityClass)ALL_FACILITIES,
|
||||
int forwardTime = NOT_SET)
|
||||
throw(GsmException); // (+CCFC=)
|
||||
|
||||
// get Information of currently set CF in the network
|
||||
// the caller must give the reason to query
|
||||
void getCallForwardInfo(ForwardReason reason,
|
||||
ForwardInfo &voice,
|
||||
ForwardInfo &fax,
|
||||
ForwardInfo &data)
|
||||
throw(GsmException); // (+CCFC=)
|
||||
|
||||
|
||||
// *** ETSI GSM 07.07 Section 8: "Mobile Equipment control
|
||||
// and status commands"
|
||||
|
||||
// return/set ME functionality level (+CFUN):
|
||||
// 0 Minimum functionality
|
||||
// 1 full functionality
|
||||
// 2 disable phone transmit RF circuits only
|
||||
// 3 disable phone receive RF circuits only
|
||||
// 4 disable phone both transmit and receive RF circuits
|
||||
// 5...127 implementation-defined
|
||||
int getFunctionalityLevel() throw(GsmException);
|
||||
void setFunctionalityLevel(int level) throw(GsmException);
|
||||
|
||||
// return battery charge status (+CBC):
|
||||
// 0 ME is powered by the battery
|
||||
// 1 ME has a battery connected, but is not powered by it
|
||||
// 2 ME does not have a battery connected
|
||||
// 3 Recognized power fault, calls inhibited
|
||||
int getBatteryChargeStatus() throw(GsmException);
|
||||
|
||||
// return battery charge (range 0..100) (+CBC)
|
||||
int getBatteryCharge() throw(GsmException);
|
||||
|
||||
// get signal strength indication (+CSQ):
|
||||
// 0 -113 dBm or less
|
||||
// 1 -111 dBm
|
||||
// 2...30 -109... -53 dBm
|
||||
// 31 -51 dBm or greater
|
||||
// 99 not known or not detectable
|
||||
int getSignalStrength() throw(GsmException);
|
||||
|
||||
// get channel bit error rate (+CSQ):
|
||||
// 0...7 as RXQUAL values in the table in GSM 05.08 [20] subclause 8.2.4
|
||||
// 99 not known or not detectable
|
||||
int getBitErrorRate() throw(GsmException);
|
||||
|
||||
// get available phone book memory storage strings (+CPBS=?)
|
||||
vector<string> getPhoneBookStrings() throw(GsmException);
|
||||
|
||||
// get phone book given the phone book memory storage string
|
||||
PhonebookRef getPhonebook(string phonebookString,
|
||||
bool preload = false) throw(GsmException);
|
||||
|
||||
|
||||
// *** ETSI GSM 07.05 SMS functions
|
||||
|
||||
// return service centre address (+CSCA?)
|
||||
string getServiceCentreAddress() throw(GsmException);
|
||||
|
||||
// set service centre address (+CSCA=)
|
||||
void setServiceCentreAddress(string sca) throw(GsmException);
|
||||
|
||||
// return names of available message stores (<mem1>, +CPMS=?)
|
||||
vector<string> getSMSStoreNames() throw(GsmException);
|
||||
|
||||
// return SMS store given the name
|
||||
SMSStoreRef getSMSStore(string storeName) throw(GsmException);
|
||||
|
||||
// send a single SMS message
|
||||
void sendSMS(Ref<SMSSubmitMessage> smsMessage) throw(GsmException);
|
||||
|
||||
// send one or several (concatenated) SMS messages
|
||||
// The SUBMIT message template must have all options set, only
|
||||
// the userData and the userDataHeader are changed.
|
||||
// If oneSMS is true, only one SMS is sent. Otherwise several SMSs
|
||||
// are sent. If concatenatedMessageId is != -1 this is used as the message
|
||||
// ID for concatenated SMS (for this a user data header as defined in
|
||||
// GSM GTS 3.40 is used, the old UDH in the template is overwritten).
|
||||
void sendSMSs(Ref<SMSSubmitMessage> smsTemplate, string text,
|
||||
bool oneSMS = false,
|
||||
int concatenatedMessageId = -1)
|
||||
throw(GsmException);
|
||||
|
||||
// set SMS service level
|
||||
// if set to 1 send commands return ACK PDU, 0 is the default
|
||||
void setMessageService(int serviceLevel) throw(GsmException);
|
||||
|
||||
// return SMS service level
|
||||
unsigned int getMessageService() throw(GsmException);
|
||||
|
||||
// return true if any of the thre message types GsmEvent::SMSMessageType
|
||||
// is routed directly to the TA and not stored in the ME
|
||||
void getSMSRoutingToTA(bool &smsRouted, // (+CNMI?)
|
||||
bool &cbsRouted,
|
||||
bool &statusReportsRouted) throw(GsmException);
|
||||
|
||||
// sets routing of SMS to TA to true for all supported SMSMessageTypes
|
||||
// if onlyReceptionIndication is set to true
|
||||
// only GsmEvent::SMSReceptionIndication is called
|
||||
// this has two reasons: GSM 07.05 section 3.4.1 does not recommend
|
||||
// direct routing of new SMS to the TA
|
||||
// I cannot test direct routing of SMS because it does not work with
|
||||
// my hardware
|
||||
void setSMSRoutingToTA(bool enableSMS, bool enableCBS,
|
||||
bool enableStatReport,
|
||||
bool onlyReceptionIndication = true)
|
||||
throw(GsmException);
|
||||
// (+CNMI=)
|
||||
|
||||
bool getCallWaitingLockStatus(FacilityClass cl)
|
||||
throw(GsmException);
|
||||
|
||||
void setCallWaitingLockStatus(FacilityClass cl,
|
||||
bool lock)throw(GsmException);
|
||||
|
||||
void setCLIRPresentation(bool enable) throw(GsmException);
|
||||
//(+CLIR)
|
||||
|
||||
// 0:according to the subscription of the CLIR service
|
||||
// 1:CLIR invocation
|
||||
// 2:CLIR suppression
|
||||
int getCLIRPresentation() throw(GsmException);
|
||||
|
||||
friend class Phonebook;
|
||||
friend class SMSStore;
|
||||
};
|
||||
};
|
||||
|
||||
#endif // GSM_ME_TA_H
|
@ -0,0 +1,32 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_nls.cc
|
||||
// *
|
||||
// * Purpose: Groups macros, initialization and includes
|
||||
// * for National Language Support (NLS)
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 3.11.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <gsm_config.h>
|
||||
#endif
|
||||
#include <gsmlib/gsm_nls.h>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
|
||||
using namespace gsmlib;
|
||||
|
||||
#ifdef HAVE_LOCALE_H
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
bool InitNLS::initialized = false;
|
||||
|
||||
#endif // ENABLE_NLS
|
@ -0,0 +1,71 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_nls.h
|
||||
// *
|
||||
// * Purpose: Groups macros, initialization and includes
|
||||
// * for National Language Support (NLS)
|
||||
// *
|
||||
// * Warning: Only include this header from gsmlib .cc-files
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 3.11.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifndef GSM_NLS_H
|
||||
#define GSM_NLS_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <gsm_config.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
|
||||
#ifdef HAVE_LIBINTL_H
|
||||
#include <libintl.h>
|
||||
#else
|
||||
#include "../intl/libintl.h"
|
||||
#endif
|
||||
#ifdef HAVE_LOCALE_H
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
#define _(String) dgettext(PACKAGE, String)
|
||||
|
||||
// this causes automatic NLS initialization if one file of the library
|
||||
// includes gsm_nls.h
|
||||
|
||||
namespace gsmlib
|
||||
{
|
||||
const class InitNLS
|
||||
{
|
||||
static bool initialized;
|
||||
|
||||
public:
|
||||
InitNLS()
|
||||
{
|
||||
if (! initialized) // do only once
|
||||
{
|
||||
setlocale(LC_ALL, "");
|
||||
#ifdef LOCAL_TRANSLATIONS
|
||||
bindtextdomain(PACKAGE, "../po");
|
||||
#else
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
#endif
|
||||
textdomain(PACKAGE);
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
} initNLS;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#define _(String) (String)
|
||||
|
||||
#endif // ENABLE_NLS
|
||||
|
||||
#define N_(String) (String)
|
||||
|
||||
#endif // GSM_NLS_H
|
@ -0,0 +1,381 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_parser.cc
|
||||
// *
|
||||
// * Purpose: Parser to parse MA/TA result strings
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 13.5.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <gsm_config.h>
|
||||
#endif
|
||||
#include <gsmlib/gsm_parser.h>
|
||||
#include <gsmlib/gsm_nls.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <strstream>
|
||||
|
||||
using namespace std;
|
||||
using namespace gsmlib;
|
||||
|
||||
// Parser members
|
||||
|
||||
int Parser::nextChar(bool skipWhiteSpace)
|
||||
{
|
||||
if (skipWhiteSpace)
|
||||
while (_i < _s.length() && isspace(_s[_i])) ++_i;
|
||||
|
||||
if (_i == _s.length())
|
||||
{
|
||||
_eos = true;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _s[_i++];
|
||||
}
|
||||
|
||||
bool Parser::checkEmptyParameter(bool allowNoParameter) throw(GsmException)
|
||||
{
|
||||
int c = nextChar();
|
||||
if (c == ',' || c == -1)
|
||||
if (allowNoParameter)
|
||||
{
|
||||
putBackChar();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
throwParseException(_("expected parameter"));
|
||||
|
||||
putBackChar();
|
||||
return false;
|
||||
}
|
||||
|
||||
string Parser::parseString2(bool stringWithQuotationMarks)
|
||||
throw(GsmException)
|
||||
{
|
||||
int c;
|
||||
string result;
|
||||
if (parseChar('"', true)) // OK, string starts and ends with quotation mark
|
||||
if (stringWithQuotationMarks)
|
||||
{
|
||||
// read till end of line
|
||||
while ((c = nextChar(false)) != -1)
|
||||
result += c;
|
||||
|
||||
// check for """ at end of line
|
||||
if (result.length() == 0 || result[result.length() - 1] != '"')
|
||||
throwParseException(_("expected '\"'"));
|
||||
|
||||
// remove """ at the end
|
||||
result.resize(result.length() - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// read till next """
|
||||
while ((c = nextChar(false)) != '"')
|
||||
if (c == -1)
|
||||
throwParseException();
|
||||
else
|
||||
result += c;
|
||||
}
|
||||
else // string ends with "," or EOL
|
||||
{
|
||||
c = nextChar(false);
|
||||
while (c != ',' && c != -1)
|
||||
{
|
||||
result += c;
|
||||
c = nextChar(false);
|
||||
}
|
||||
if (c == ',') putBackChar();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int Parser::parseInt2() throw(GsmException)
|
||||
{
|
||||
string s;
|
||||
int c;
|
||||
int result;
|
||||
|
||||
while (isdigit(c = nextChar())) s += c;
|
||||
|
||||
putBackChar();
|
||||
if (s.length() == 0)
|
||||
throwParseException(_("expected number"));
|
||||
|
||||
istrstream is(s.c_str());
|
||||
is >> result;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Parser::throwParseException(string message) throw(GsmException)
|
||||
{
|
||||
ostrstream os;
|
||||
if (message.length() == 0)
|
||||
throw GsmException(stringPrintf(_("unexpected end of string '%s'"),
|
||||
_s.c_str()), ParserError);
|
||||
else
|
||||
throw GsmException(message +
|
||||
stringPrintf(_(" (at position %d of string '%s')"), _i,
|
||||
_s.c_str()), ParserError);
|
||||
}
|
||||
|
||||
Parser::Parser(string s) : _i(0), _s(s), _eos(false)
|
||||
{
|
||||
}
|
||||
|
||||
bool Parser::parseChar(char c, bool allowNoChar) throw(GsmException)
|
||||
{
|
||||
if (nextChar() != c)
|
||||
if (allowNoChar)
|
||||
{
|
||||
putBackChar();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
throwParseException(stringPrintf(_("expected '%c'"), c));
|
||||
return true;
|
||||
}
|
||||
|
||||
vector<string> Parser::parseStringList(bool allowNoList)
|
||||
throw(GsmException)
|
||||
{
|
||||
// handle case of empty parameter
|
||||
vector<string> result;
|
||||
if (checkEmptyParameter(allowNoList)) return result;
|
||||
|
||||
parseChar('(');
|
||||
if (nextChar() != ')')
|
||||
{
|
||||
putBackChar();
|
||||
while (1)
|
||||
{
|
||||
result.push_back(parseString());
|
||||
int c = nextChar();
|
||||
if (c == ')')
|
||||
break;
|
||||
if (c == -1)
|
||||
throwParseException();
|
||||
if (c != ',')
|
||||
throwParseException(_("expected ')' or ','"));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
vector<bool> Parser::parseIntList(bool allowNoList)
|
||||
throw(GsmException)
|
||||
{
|
||||
// handle case of empty parameter
|
||||
bool isRange = false;
|
||||
vector<bool> result;
|
||||
int resultCapacity = 0;
|
||||
unsigned int saveI = _i;
|
||||
|
||||
if (checkEmptyParameter(allowNoList)) return result;
|
||||
|
||||
// check for the case of a integer list consisting of only one parameter
|
||||
// some TAs omit the parentheses in this case
|
||||
if (isdigit(nextChar()))
|
||||
{
|
||||
putBackChar();
|
||||
int num = parseInt();
|
||||
result.resize(num + 1, false);
|
||||
result[num] = true;
|
||||
return result;
|
||||
}
|
||||
putBackChar();
|
||||
|
||||
// run in two passes
|
||||
// pass 0: find capacity needed for result
|
||||
// pass 1: resize result and fill it in
|
||||
for (int pass = 0; pass < 2; ++pass)
|
||||
{
|
||||
if (pass == 1)
|
||||
{
|
||||
_i = saveI;
|
||||
result.resize(resultCapacity + 1, false);
|
||||
}
|
||||
|
||||
parseChar('(');
|
||||
if (nextChar() != ')')
|
||||
{
|
||||
putBackChar();
|
||||
int lastInt = -1;
|
||||
while (1)
|
||||
{
|
||||
int thisInt = parseInt();
|
||||
|
||||
if (isRange)
|
||||
{
|
||||
assert(lastInt != -1);
|
||||
if (lastInt <= thisInt)
|
||||
for (int i = lastInt; i < thisInt; ++i)
|
||||
{
|
||||
if (i > resultCapacity)
|
||||
resultCapacity = i;
|
||||
if (pass == 1)
|
||||
result[i] = true;
|
||||
}
|
||||
else
|
||||
for (int i = thisInt; i < lastInt; ++i)
|
||||
{
|
||||
if (i > resultCapacity)
|
||||
resultCapacity = i;
|
||||
if (pass == 1)
|
||||
result[i] = true;
|
||||
}
|
||||
isRange = false;
|
||||
}
|
||||
|
||||
if (thisInt > resultCapacity)
|
||||
resultCapacity = thisInt;
|
||||
if (pass == 1)
|
||||
result[thisInt] = true;
|
||||
lastInt = thisInt;
|
||||
|
||||
int c = nextChar();
|
||||
if (c == ')')
|
||||
break;
|
||||
|
||||
if (c == -1)
|
||||
throwParseException();
|
||||
|
||||
if (c != ',' && c != '-')
|
||||
throwParseException(_("expected ')', ',' or '-'"));
|
||||
|
||||
if (c == ',')
|
||||
isRange = false;
|
||||
else // is '-'
|
||||
if (isRange)
|
||||
throwParseException(_("range of the form a-b-c not allowed"));
|
||||
else
|
||||
isRange = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isRange)
|
||||
throwParseException(_("range of the form a- no allowed"));
|
||||
return result;
|
||||
}
|
||||
|
||||
vector<ParameterRange> Parser::parseParameterRangeList(bool allowNoList)
|
||||
throw(GsmException)
|
||||
{
|
||||
// handle case of empty parameter
|
||||
vector<ParameterRange> result;
|
||||
if (checkEmptyParameter(allowNoList)) return result;
|
||||
|
||||
result.push_back(parseParameterRange());
|
||||
while (parseComma(true))
|
||||
{
|
||||
result.push_back(parseParameterRange());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ParameterRange Parser::parseParameterRange(bool allowNoParameterRange)
|
||||
throw(GsmException)
|
||||
{
|
||||
// handle case of empty parameter
|
||||
ParameterRange result;
|
||||
if (checkEmptyParameter(allowNoParameterRange)) return result;
|
||||
|
||||
parseChar('(');
|
||||
result._parameter = parseString();
|
||||
parseComma();
|
||||
result._range = parseRange(false, true);
|
||||
parseChar(')');
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
IntRange Parser::parseRange(bool allowNoRange, bool allowNonRange)
|
||||
throw(GsmException)
|
||||
{
|
||||
// handle case of empty parameter
|
||||
IntRange result;
|
||||
if (checkEmptyParameter(allowNoRange)) return result;
|
||||
|
||||
parseChar('(');
|
||||
result._low = parseInt();
|
||||
// allow non-ranges is allowNonRange == true
|
||||
if (parseChar('-', allowNonRange))
|
||||
result._high = parseInt();
|
||||
parseChar(')');
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int Parser::parseInt(bool allowNoInt) throw(GsmException)
|
||||
{
|
||||
// handle case of empty parameter
|
||||
int result = NOT_SET;
|
||||
if (checkEmptyParameter(allowNoInt)) return result;
|
||||
|
||||
result = parseInt2();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
string Parser::parseString(bool allowNoString,
|
||||
bool stringWithQuotationMarks)
|
||||
throw(GsmException)
|
||||
{
|
||||
// handle case of empty parameter
|
||||
string result;
|
||||
if (checkEmptyParameter(allowNoString)) return result;
|
||||
|
||||
result = parseString2(stringWithQuotationMarks);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Parser::parseComma(bool allowNoComma) throw(GsmException)
|
||||
{
|
||||
if (nextChar() != ',')
|
||||
if(allowNoComma)
|
||||
{
|
||||
putBackChar();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
throwParseException(_("expected comma"));
|
||||
return true;
|
||||
}
|
||||
|
||||
string Parser::parseEol() throw(GsmException)
|
||||
{
|
||||
string result;
|
||||
int c;
|
||||
while ((c = nextChar()) != -1) result += c;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Parser::checkEol() throw(GsmException)
|
||||
{
|
||||
if (nextChar() != -1)
|
||||
{
|
||||
putBackChar();
|
||||
throwParseException(_("expected end of line"));
|
||||
}
|
||||
}
|
||||
|
||||
string Parser::getEol()
|
||||
{
|
||||
string result;
|
||||
int c;
|
||||
unsigned int saveI = _i;
|
||||
bool saveEos = _eos;
|
||||
while ((c = nextChar()) != -1) result += c;
|
||||
_i = saveI;
|
||||
_eos = saveEos;
|
||||
return result;
|
||||
}
|
@ -0,0 +1,125 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_parser.h
|
||||
// *
|
||||
// * Purpose: Parser to parse MA/TA result strings
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 13.5.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifndef GSM_PARSER_H
|
||||
#define GSM_PARSER_H
|
||||
|
||||
#include <gsmlib/gsm_util.h>
|
||||
#include <gsmlib/gsm_error.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gsmlib
|
||||
{
|
||||
class Parser : public RefBase
|
||||
{
|
||||
private:
|
||||
unsigned int _i; // index into _s, next character
|
||||
string _s; // string to parse
|
||||
bool _eos; // true if end-of-string reached in nextChar()
|
||||
|
||||
// return next character or -1 if end of string
|
||||
int nextChar(bool skipWhiteSpace = true);
|
||||
|
||||
// "puts back" a character
|
||||
void putBackChar() {if (! _eos) --_i;}
|
||||
|
||||
// check for empty parameter (ie. "," or end of string)
|
||||
// skips white space
|
||||
// returns true if no parameter
|
||||
// or throw an GsmException if allowNoParameter == false
|
||||
bool checkEmptyParameter(bool allowNoParameter) throw(GsmException);
|
||||
|
||||
// parse a string (like "string")
|
||||
// throw an exception if not well-formed
|
||||
string parseString2(bool stringWithQuotationMarks) throw(GsmException);
|
||||
|
||||
// parse a int (like 1234)
|
||||
// throw an exception if not well-formed
|
||||
int parseInt2() throw(GsmException);
|
||||
|
||||
// throw a parser exception
|
||||
void throwParseException(string message = "") throw(GsmException);
|
||||
|
||||
public:
|
||||
Parser(string s);
|
||||
|
||||
// the following functions skip white space
|
||||
// parse a character, if absent throw a GsmException
|
||||
// return false if allowNoChar == true and character not encountered
|
||||
bool parseChar(char c, bool allowNoChar = false) throw(GsmException);
|
||||
|
||||
// parse a list of the form "("ABC", DEF")"
|
||||
// the list can be empty (ie. == "" ) if allowNoList == true
|
||||
vector<string> parseStringList(bool allowNoList = false)
|
||||
throw(GsmException);
|
||||
|
||||
// parse a list of the form "(12, 14)" or "(1-4, 10)"
|
||||
// the result is returned as a bit vector where for each integer
|
||||
// in the list and/or range(s) a bit is set
|
||||
// the list can be empty (ie. == "") if allowNoList == true
|
||||
vector<bool> parseIntList(bool allowNoList = false)
|
||||
throw(GsmException);
|
||||
|
||||
// parse a list of parameter ranges (see below)
|
||||
// the list can be empty (ie. == "" ) if allowNoList == true
|
||||
vector<ParameterRange> parseParameterRangeList(bool allowNoList = false)
|
||||
throw(GsmException);
|
||||
|
||||
// parse a string plus its valid integer range of the
|
||||
// form "("string",(1-125))"
|
||||
// the parameter range may be absent if allowNoParameterRange == true
|
||||
ParameterRange parseParameterRange(bool allowNoParameterRange = false)
|
||||
throw(GsmException);
|
||||
|
||||
// parse an integer range of the form "(1-125)"
|
||||
// the range may be absent if allowNoRange == true
|
||||
// then IntRange::_high and _low are set to NOT_SET
|
||||
// the range may be short if allowNonRange == true
|
||||
// then IntRange::_high is set to NOT_SET
|
||||
IntRange parseRange(bool allowNoRange = false, bool allowNonRange = false)
|
||||
throw(GsmException);
|
||||
|
||||
// parse an integer of the form "1234"
|
||||
// allow absent int if allowNoInt == true
|
||||
// then it returns NOT_SET
|
||||
int parseInt(bool allowNoInt = false) throw(GsmException);
|
||||
|
||||
// parse a string of the form ""string""
|
||||
// allow absent string if allowNoString == true
|
||||
// then it returns ""
|
||||
// if stringWithQuotationMarks == true the string may contain """
|
||||
// the string is then parsed till the end of the line
|
||||
string parseString(bool allowNoString = false,
|
||||
bool stringWithQuotationMarks = false)
|
||||
throw(GsmException);
|
||||
|
||||
// parse a single ","
|
||||
// the comma may be absent if allowNoComma == true
|
||||
// returns true if there was a comma
|
||||
bool parseComma(bool allowNoComma = false) throw(GsmException);
|
||||
|
||||
// parse till end of line, return result without whitespace
|
||||
string parseEol() throw(GsmException);
|
||||
|
||||
// check that end of line is reached
|
||||
void checkEol() throw(GsmException);
|
||||
|
||||
// return string till end of line without whitespace
|
||||
// (does not change internal state)
|
||||
string getEol();
|
||||
};
|
||||
};
|
||||
|
||||
#endif // GSM_PARSER_H
|
@ -0,0 +1,585 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_phonebook.cc
|
||||
// *
|
||||
// * Purpose: Phonebook management functions
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 6.5.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <gsm_config.h>
|
||||
#endif
|
||||
#include <gsmlib/gsm_nls.h>
|
||||
#include <gsmlib/gsm_sysdep.h>
|
||||
#include <gsmlib/gsm_phonebook.h>
|
||||
#include <gsmlib/gsm_parser.h>
|
||||
#include <gsmlib/gsm_me_ta.h>
|
||||
#include <strstream>
|
||||
#include <iostream>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace gsmlib;
|
||||
|
||||
// PhonebookEntry members
|
||||
|
||||
PhonebookEntry::PhonebookEntry(const PhonebookEntryBase &e)
|
||||
throw(GsmException) : _cached(true), _myPhonebook(NULL)
|
||||
{
|
||||
set(e.telephone(), e.text(), e.index(), e.useIndex());
|
||||
}
|
||||
|
||||
void PhonebookEntry::set(string telephone, string text, int index,
|
||||
bool useIndex)
|
||||
throw(GsmException)
|
||||
{
|
||||
checkTextAndTelephone(text, telephone);
|
||||
|
||||
if (_myPhonebook != NULL)
|
||||
{
|
||||
if (text.length() > _myPhonebook->getMaxTextLen())
|
||||
throw GsmException(
|
||||
stringPrintf(_("length of text '%s' exceeds maximum text "
|
||||
"length (%d characters) of phonebook '%s'"),
|
||||
text.c_str(), _myPhonebook->getMaxTextLen(),
|
||||
_myPhonebook->name().c_str()),
|
||||
ParameterError);
|
||||
|
||||
if (telephone.length() > _myPhonebook->getMaxTelephoneLen())
|
||||
throw GsmException(
|
||||
stringPrintf(_("length of telephone number '%s' "
|
||||
"exceeds maximum telephone number "
|
||||
"length (%d characters) of phonebook '%s'"),
|
||||
telephone.c_str(), _myPhonebook->getMaxTelephoneLen(),
|
||||
_myPhonebook->name().c_str()),
|
||||
ParameterError);
|
||||
|
||||
_myPhonebook->writeEntry(_index, telephone, text);
|
||||
}
|
||||
else
|
||||
_index = index;
|
||||
|
||||
_useIndex = useIndex;
|
||||
_cached = true;
|
||||
_telephone = telephone;
|
||||
_text = text;
|
||||
_changed = true;
|
||||
}
|
||||
|
||||
string PhonebookEntry::text() const throw(GsmException)
|
||||
{
|
||||
if (! cached())
|
||||
{
|
||||
assert(_myPhonebook != NULL);
|
||||
// these operations are at least "logically const"
|
||||
PhonebookEntry *thisEntry = const_cast<PhonebookEntry*>(this);
|
||||
_myPhonebook->readEntry(_index, thisEntry->_telephone, thisEntry->_text);
|
||||
thisEntry->_cached = true;
|
||||
}
|
||||
return _text;
|
||||
}
|
||||
|
||||
string PhonebookEntry::telephone() const throw(GsmException)
|
||||
{
|
||||
if (! cached())
|
||||
{
|
||||
assert(_myPhonebook != NULL);
|
||||
// these operations are at least "logically const"
|
||||
PhonebookEntry *thisEntry = const_cast<PhonebookEntry*>(this);
|
||||
_myPhonebook->readEntry(_index, thisEntry->_telephone, thisEntry->_text);
|
||||
thisEntry->_cached = true;
|
||||
}
|
||||
return _telephone;
|
||||
}
|
||||
|
||||
bool PhonebookEntry::cached() const
|
||||
{
|
||||
if (_myPhonebook == NULL)
|
||||
return _cached;
|
||||
else
|
||||
return _cached && _myPhonebook->_useCache;
|
||||
}
|
||||
|
||||
PhonebookEntry::PhonebookEntry(const PhonebookEntry &e) throw(GsmException)
|
||||
{
|
||||
set(e._telephone, e._text, e._index, e._useIndex);
|
||||
}
|
||||
|
||||
PhonebookEntry &PhonebookEntry::operator=(const PhonebookEntry &e)
|
||||
throw(GsmException)
|
||||
{
|
||||
set(e._telephone, e._text, e._index, e._useIndex);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Phonebook members
|
||||
|
||||
int Phonebook::parsePhonebookEntry(string response,
|
||||
string &telephone, string &text)
|
||||
{
|
||||
// this is a workaround for a bug that occurs with my ME/TA combination
|
||||
// some texts are truncated and don't have a trailing "
|
||||
if (response.length() > 0 && response[response.length() - 1] != '"')
|
||||
response += '"';
|
||||
Parser p(response);
|
||||
|
||||
int index = p.parseInt();
|
||||
p.parseComma();
|
||||
|
||||
// handle case of empty entry
|
||||
if (p.getEol().substr(0, 5) == "EMPTY")
|
||||
{
|
||||
telephone = "";
|
||||
text = "";
|
||||
return index;
|
||||
}
|
||||
|
||||
telephone = p.parseString();
|
||||
p.parseComma();
|
||||
unsigned int numberFormat = p.parseInt();
|
||||
if (numberFormat != UnknownNumberFormat &&
|
||||
numberFormat != InternationalNumberFormat)
|
||||
cerr << "*** GSMLIB WARNING: Unexpected number format when reading from "
|
||||
<< "phonebook: " << numberFormat << " ***" << endl;
|
||||
p.parseComma();
|
||||
text = p.parseString(false, true);
|
||||
if (lowercase(_myMeTa.getCurrentCharSet()) == "gsm")
|
||||
text = gsmToLatin1(text);
|
||||
if (numberFormat == InternationalNumberFormat)
|
||||
{
|
||||
// skip leading "+" signs that may already exist
|
||||
while (telephone.length() > 0 && telephone[0] == '+')
|
||||
telephone = telephone.substr(1);
|
||||
telephone = "+" + telephone;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
void Phonebook::readEntry(int index, string &telephone, string &text)
|
||||
throw(GsmException)
|
||||
{
|
||||
// select phonebook
|
||||
_myMeTa.setPhonebook(_phonebookName);
|
||||
|
||||
// read entry
|
||||
string response = _at->chat("+CPBR=" + intToStr(index), "+CPBR:",
|
||||
false, // dont't ignore errors
|
||||
true); // but accept empty responses
|
||||
// (the latter is necessary for some mobile phones that return nothing
|
||||
// if the entry is empty)
|
||||
|
||||
if (response.length() == 0) // OK phone returned empty response
|
||||
{
|
||||
telephone = text = ""; // then the entry is empty as well
|
||||
}
|
||||
else
|
||||
parsePhonebookEntry(response, telephone, text);
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (debugLevel() >= 1)
|
||||
cerr << "*** Reading PB entry " << index << " number " << telephone
|
||||
<< " text " << text << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Phonebook::findEntry(string text, int &index, string &telephone)
|
||||
throw(GsmException)
|
||||
{
|
||||
// select phonebook
|
||||
_myMeTa.setPhonebook(_phonebookName);
|
||||
|
||||
// read entry
|
||||
string response = _at->chat("+CPBF=\"" + text + "\"", "+CPBF:",
|
||||
false, // dont't ignore errors
|
||||
true); // but accept empty responses
|
||||
// (the latter is necessary for some mobile phones that return nothing
|
||||
// if the entry is empty)
|
||||
|
||||
if (response.length() == 0) // OK phone returned empty response
|
||||
{
|
||||
telephone = ""; // then the entry is empty as well
|
||||
index = 0;
|
||||
}
|
||||
else
|
||||
index=parsePhonebookEntry(response, telephone, text);
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (debugLevel() >= 1)
|
||||
cerr << "*** Finding PB entry " << text << " number " << telephone
|
||||
<< " index " << index << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Phonebook::writeEntry(int index, string telephone, string text)
|
||||
throw(GsmException)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
if (debugLevel() >= 1)
|
||||
cerr << "*** Writing PB entry #" << index << " number '" << telephone
|
||||
<< "' text '" << text << "'" << endl;
|
||||
#endif
|
||||
// select phonebook
|
||||
_myMeTa.setPhonebook(_phonebookName);
|
||||
|
||||
// write entry
|
||||
string s;
|
||||
if (telephone == "" && text == "")
|
||||
{
|
||||
ostrstream os;
|
||||
os << "+CPBW=" << index;
|
||||
os << ends;
|
||||
char *ss = os.str();
|
||||
s = string(ss);
|
||||
delete[] ss;
|
||||
}
|
||||
else
|
||||
{
|
||||
int type;
|
||||
if (telephone.find('+') == string::npos)
|
||||
type = UnknownNumberFormat;
|
||||
else
|
||||
type = InternationalNumberFormat;
|
||||
string gsmText = text;
|
||||
if (lowercase(_myMeTa.getCurrentCharSet()) == "gsm")
|
||||
gsmText = latin1ToGsm(gsmText);
|
||||
ostrstream os;
|
||||
os << "+CPBW=" << index << ",\"" << telephone << "\"," << type
|
||||
<< ",\"";
|
||||
os << ends;
|
||||
char *ss = os.str();
|
||||
s = string(ss);
|
||||
delete[] ss;
|
||||
// this cannot be added with ostrstream because the gsmText can
|
||||
// contain a zero (GSM default alphabet for '@')
|
||||
s += gsmText + "\"";
|
||||
}
|
||||
_at->chat(s);
|
||||
}
|
||||
|
||||
Phonebook::iterator Phonebook::insertFirstEmpty(string telephone, string text)
|
||||
throw(GsmException)
|
||||
{
|
||||
for (int i = 0; i < _maxSize; i++)
|
||||
if (_phonebook[i].empty())
|
||||
{
|
||||
_phonebook[i].set(telephone, text);
|
||||
adjustSize(1);
|
||||
return begin() + i;
|
||||
}
|
||||
throw GsmException(_("phonebook full"), OtherError);
|
||||
}
|
||||
|
||||
Phonebook::iterator Phonebook::insert(const string telephone,
|
||||
const string text,
|
||||
const int index)
|
||||
{
|
||||
for (int i = 0; i < _maxSize; i++)
|
||||
if (_phonebook[i].index() == index)
|
||||
if (_phonebook[i].empty())
|
||||
{
|
||||
_phonebook[i].set(telephone, text);
|
||||
adjustSize(1);
|
||||
return begin() + i;
|
||||
}
|
||||
else
|
||||
throw GsmException(_("attempt to overwrite phonebook entry"),
|
||||
OtherError);
|
||||
return end();
|
||||
}
|
||||
|
||||
Phonebook::Phonebook(string phonebookName, Ref<GsmAt> at, MeTa &myMeTa,
|
||||
bool preload) throw(GsmException) :
|
||||
_phonebookName(phonebookName), _at(at), _myMeTa(myMeTa), _useCache(true)
|
||||
{
|
||||
// select phonebook
|
||||
_myMeTa.setPhonebook(_phonebookName);
|
||||
|
||||
// query size and maximum capacity of phonebook
|
||||
_size = -1; // -1 means not known yet
|
||||
_maxSize = -1;
|
||||
Parser q(_at->chat("+CPBS?", "+CPBS:"));
|
||||
string dummy = q.parseString();
|
||||
if (q.parseComma(true)) // this means that
|
||||
{ // used and total result is supported by ME
|
||||
_size = q.parseInt();
|
||||
q.parseComma();
|
||||
_maxSize = q.parseInt();
|
||||
}
|
||||
|
||||
// get basic phonebook info from ME
|
||||
Parser p(_at->chat("+CPBR=?", "+CPBR:"));
|
||||
|
||||
// get index of actually available entries in the phonebook
|
||||
vector<bool> availablePositions = p.parseIntList();
|
||||
p.parseComma();
|
||||
_maxNumberLength = p.parseInt();
|
||||
p.parseComma();
|
||||
_maxTextLength = p.parseInt();
|
||||
|
||||
// find out capacity of phonebook in ME
|
||||
// Note: The phonebook in the ME may be sparse, eg. the range of
|
||||
// allowed index numbers may be something like (3-4, 20-100, 120).
|
||||
// The standard allows this, even though it is unlikely to be
|
||||
// implemented like that by anyone.
|
||||
// In memory we store only phonebook entries that may actually be
|
||||
// used, ie. the phonebook in memory is not sparse.
|
||||
// Each entry has a member _index that corresponds to the index in the ME.
|
||||
if (_maxSize == -1)
|
||||
{
|
||||
_maxSize = 0;
|
||||
for (vector<bool>::iterator i = availablePositions.begin();
|
||||
i != availablePositions.end(); ++i)
|
||||
if (*i) ++_maxSize;
|
||||
}
|
||||
|
||||
// for use with preload below
|
||||
int *meToPhonebookIndexMap =
|
||||
(int*)alloca(sizeof(int) * (availablePositions.size() + 1));
|
||||
|
||||
// initialize phone book entries
|
||||
if (_maxSize == 0)
|
||||
_phonebook = NULL;
|
||||
else
|
||||
_phonebook = new PhonebookEntry[_maxSize];
|
||||
int nextAvailableIndex = 0;
|
||||
int i;
|
||||
for (i = 0; i < _maxSize; i++)
|
||||
{
|
||||
while (! availablePositions[nextAvailableIndex])
|
||||
nextAvailableIndex++;
|
||||
_phonebook[i]._index = nextAvailableIndex;
|
||||
_phonebook[i]._cached = false;
|
||||
_phonebook[i]._myPhonebook = this;
|
||||
meToPhonebookIndexMap[nextAvailableIndex++] = i;
|
||||
}
|
||||
|
||||
// find out first index number of phonebook
|
||||
int firstIndex = -1;
|
||||
for (i = 0; i < _maxSize; i++)
|
||||
if (availablePositions[i])
|
||||
{
|
||||
firstIndex = i;
|
||||
break;
|
||||
}
|
||||
|
||||
// preload phonebook
|
||||
// Note: this contains a workaround for the bug that
|
||||
// some MEs can not return the entire phonebook with one AT command
|
||||
// To detect this condition, _size must be known
|
||||
// also, this code only handles non-sparse phonebooks
|
||||
if (preload && _size != -1 &&
|
||||
(int)availablePositions.size() == _maxSize + firstIndex)
|
||||
{
|
||||
int entriesRead = 0;
|
||||
int startIndex = firstIndex;
|
||||
|
||||
while (entriesRead < _size)
|
||||
{
|
||||
reportProgress(0, _maxSize); // chatv also calls reportProgress()
|
||||
vector<string> responses =
|
||||
_at->chatv("+CPBR=" + intToStr(startIndex) +
|
||||
"," + intToStr(_maxSize + firstIndex - 1),
|
||||
"+CPBR:", true);
|
||||
|
||||
// this means that we have read nothing even though not all
|
||||
// entries have been retrieved (entriesRead < _size)
|
||||
// this could be due to a malfunction of the ME...
|
||||
// anyway, missing entries can be read later by readEntry()
|
||||
if (responses.size() == 0)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
if (debugLevel() >= 1)
|
||||
cerr << "*** error when preloading phonebook: "
|
||||
"not all entries returned" << endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
for (vector<string>::iterator i = responses.begin();
|
||||
i != responses.end(); ++i)
|
||||
{
|
||||
string telephone, text;
|
||||
int meIndex = parsePhonebookEntry(*i, telephone, text);
|
||||
_phonebook[meToPhonebookIndexMap[meIndex]]._cached = true;
|
||||
_phonebook[meToPhonebookIndexMap[meIndex]]._telephone = telephone;
|
||||
_phonebook[meToPhonebookIndexMap[meIndex]]._text = text;
|
||||
assert(_phonebook[meToPhonebookIndexMap[meIndex]]._index == meIndex);
|
||||
|
||||
++entriesRead;
|
||||
startIndex = meIndex + 1;
|
||||
#ifndef NDEBUG
|
||||
if (debugLevel() >= 1)
|
||||
cerr << "*** Preloading PB entry " << meIndex
|
||||
<< " number " << telephone
|
||||
<< " text " << text << endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Phonebook::iterator Phonebook::begin()
|
||||
{
|
||||
return &_phonebook[0];
|
||||
}
|
||||
|
||||
Phonebook::const_iterator Phonebook::begin() const
|
||||
{
|
||||
return &_phonebook[0];
|
||||
}
|
||||
|
||||
Phonebook::iterator Phonebook::end()
|
||||
{
|
||||
return &_phonebook[_maxSize];
|
||||
}
|
||||
|
||||
Phonebook::const_iterator Phonebook::end() const
|
||||
{
|
||||
return &_phonebook[_maxSize];
|
||||
}
|
||||
|
||||
Phonebook::reference Phonebook::operator[](int n)
|
||||
{
|
||||
return _phonebook[n];
|
||||
}
|
||||
|
||||
Phonebook::const_reference Phonebook::operator[](int n) const
|
||||
{
|
||||
return _phonebook[n];
|
||||
}
|
||||
|
||||
Phonebook::reference Phonebook::front()
|
||||
{
|
||||
return _phonebook[0];
|
||||
}
|
||||
|
||||
Phonebook::const_reference Phonebook::front() const
|
||||
{
|
||||
return _phonebook[0];
|
||||
}
|
||||
|
||||
Phonebook::reference Phonebook::back()
|
||||
{
|
||||
return _phonebook[_maxSize - 1];
|
||||
}
|
||||
|
||||
Phonebook::const_reference Phonebook::back() const
|
||||
{
|
||||
return _phonebook[_maxSize - 1];
|
||||
}
|
||||
|
||||
int Phonebook::size() const throw(GsmException)
|
||||
{
|
||||
if (_size != -1)
|
||||
return _size;
|
||||
else
|
||||
{
|
||||
int result = 0;
|
||||
for (int i = 0; i < _maxSize; i++)
|
||||
if (! _phonebook[i].empty())
|
||||
result++;
|
||||
Phonebook *thisPhonebook = const_cast<Phonebook*>(this);
|
||||
thisPhonebook->_size = result;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
Phonebook::iterator Phonebook::insert(iterator position,
|
||||
const PhonebookEntry& x)
|
||||
throw(GsmException)
|
||||
{
|
||||
if (x.useIndex() && x.index() != -1)
|
||||
return insert(x.telephone(), x.text(), x.index());
|
||||
else
|
||||
return insertFirstEmpty(x.telephone(), x.text());
|
||||
}
|
||||
|
||||
void Phonebook::insert (iterator pos, int n, const PhonebookEntry& x)
|
||||
throw(GsmException)
|
||||
{
|
||||
for (int i = 0; i < n; i++)
|
||||
if (x.useIndex() && x.index() != -1)
|
||||
insert(x.telephone(), x.text(), x.index());
|
||||
else
|
||||
insertFirstEmpty(x.telephone(), x.text());
|
||||
}
|
||||
|
||||
void Phonebook::insert (iterator pos, long n, const PhonebookEntry& x)
|
||||
throw(GsmException)
|
||||
{
|
||||
for (long i = 0; i < n; i++)
|
||||
if (x.useIndex() && x.index() != -1)
|
||||
insert(x.telephone(), x.text(), x.index());
|
||||
else
|
||||
insertFirstEmpty(x.telephone(), x.text());
|
||||
}
|
||||
|
||||
Phonebook::iterator Phonebook::erase(iterator position)
|
||||
throw(GsmException)
|
||||
{
|
||||
if (! position->empty())
|
||||
{
|
||||
position->set("", "");
|
||||
adjustSize(-1);
|
||||
}
|
||||
return position + 1;
|
||||
}
|
||||
|
||||
Phonebook::iterator Phonebook::erase(iterator first, iterator last)
|
||||
throw(GsmException)
|
||||
{
|
||||
iterator i;
|
||||
for (i = first; i != last; ++i)
|
||||
erase(i);
|
||||
return i;
|
||||
}
|
||||
|
||||
void Phonebook::clear() throw(GsmException)
|
||||
{
|
||||
for (iterator i = begin(); i != end(); ++i)
|
||||
erase(i);
|
||||
}
|
||||
|
||||
Phonebook::iterator Phonebook::find(string text) throw(GsmException)
|
||||
{
|
||||
int index;
|
||||
string telephone;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < _maxSize; i++)
|
||||
if (_phonebook[i].text() == text)
|
||||
return begin() + i;
|
||||
|
||||
findEntry(text, index, telephone);
|
||||
|
||||
for (i = 0; i < _maxSize; i++)
|
||||
if (_phonebook[i].index() == index)
|
||||
if (_phonebook[i].cached())
|
||||
{
|
||||
// if entry was already (= cached) and is now different
|
||||
// the SIM card or it's contents were changed
|
||||
if (_phonebook[i]._telephone != telephone ||
|
||||
_phonebook[i]._text != text)
|
||||
throw GsmException(_("SIM card changed while accessing phonebook"),
|
||||
OtherError);
|
||||
}
|
||||
else
|
||||
{
|
||||
_phonebook[i]._cached = true;
|
||||
_phonebook[i]._telephone = telephone;
|
||||
_phonebook[i]._text = text;
|
||||
return begin() + i;
|
||||
}
|
||||
return end();
|
||||
}
|
||||
|
||||
Phonebook::~Phonebook()
|
||||
{
|
||||
delete []_phonebook;
|
||||
}
|
@ -0,0 +1,195 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_phonebook.h
|
||||
// *
|
||||
// * Purpose: Phonebook management functions
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 4.5.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifndef GSM_PHONEBOOK_H
|
||||
#define GSM_PHONEBOOK_H
|
||||
|
||||
#include <gsmlib/gsm_sorted_phonebook_base.h>
|
||||
#include <gsmlib/gsm_at.h>
|
||||
#include <gsmlib/gsm_util.h>
|
||||
#include <string>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gsmlib
|
||||
{
|
||||
// forward declarations
|
||||
class Phonebook;
|
||||
|
||||
// a single entry in the phonebook that corresponds to an ME entry
|
||||
|
||||
class PhonebookEntry : public PhonebookEntryBase
|
||||
{
|
||||
private:
|
||||
// this constructor is only used by Phonebook
|
||||
PhonebookEntry() {}
|
||||
bool _cached; // true, if this entry corresponds to info
|
||||
// in the ME
|
||||
Phonebook *_myPhonebook;
|
||||
|
||||
public:
|
||||
PhonebookEntry(string telephone, string text) :
|
||||
PhonebookEntryBase(telephone, text),
|
||||
_cached(true), _myPhonebook(NULL) {}
|
||||
PhonebookEntry(const PhonebookEntryBase &e) throw(GsmException);
|
||||
|
||||
// accessor functions, inherited from PhonebookEntryBase
|
||||
// set() does not use the index argument
|
||||
void set(string telephone, string text, int index = -1,
|
||||
bool useIndex = false)
|
||||
throw(GsmException);
|
||||
string text() const throw(GsmException);
|
||||
string telephone() const throw(GsmException);
|
||||
|
||||
// return true if entry is cached (and caching is enabled)
|
||||
bool cached() const;
|
||||
|
||||
PhonebookEntry(const PhonebookEntry &e) throw(GsmException);
|
||||
PhonebookEntry &operator=(const PhonebookEntry &e) throw(GsmException);
|
||||
|
||||
virtual ~PhonebookEntry() {}
|
||||
|
||||
friend class Phonebook;
|
||||
};
|
||||
|
||||
// this class corresponds to a phonebook in the ME
|
||||
// all functions directly update storage in the ME
|
||||
// if the ME is exchanged, the storage may become corrupted because
|
||||
// of internal buffering in the Phonebook class
|
||||
|
||||
class Phonebook : public RefBase, public NoCopy
|
||||
{
|
||||
public:
|
||||
// iterator defs
|
||||
typedef PhonebookEntry *iterator;
|
||||
typedef const PhonebookEntry *const_iterator;
|
||||
typedef PhonebookEntry &reference;
|
||||
typedef const PhonebookEntry &const_reference;
|
||||
|
||||
private:
|
||||
PhonebookEntry *_phonebook; // array of size _maxSize of entries
|
||||
int _maxSize; // maximum size of pb (-1 == not known yet)
|
||||
int _size; // current size of pb (-1 == not known yet)
|
||||
string _phonebookName; // name of the phonebook, 2-byte like "ME"
|
||||
unsigned int _maxNumberLength; // maximum length of telephone number
|
||||
unsigned int _maxTextLength; // maximum length of descriptive text
|
||||
Ref<GsmAt> _at; // my GsmAt class
|
||||
vector<int> _positionMap; // maps in-memory index to ME index
|
||||
MeTa &_myMeTa; // the MeTa object that created this Phonebook
|
||||
bool _useCache; // true if entries should be cached
|
||||
|
||||
// helper function, parse phonebook response returned by ME/TA
|
||||
// returns index of entry
|
||||
int parsePhonebookEntry(string response, string &telephone, string &text);
|
||||
|
||||
// internal access functions
|
||||
// read/write/find entry from/to ME
|
||||
void readEntry(int index, string &telephone, string &text)
|
||||
throw(GsmException);
|
||||
void writeEntry(int index, string telephone, string text)
|
||||
throw(GsmException);
|
||||
void findEntry(string text, int &index, string &telephone)
|
||||
throw(GsmException);
|
||||
|
||||
// adjust size only if it was set once
|
||||
void adjustSize(int sizeAdjust)
|
||||
{
|
||||
if (_size != -1) _size += sizeAdjust;
|
||||
}
|
||||
|
||||
// insert into first empty position and return position where inserted
|
||||
iterator insertFirstEmpty(const string telephone, const string text)
|
||||
throw(GsmException);
|
||||
|
||||
// insert into specified index position
|
||||
iterator insert(const string telephone, const string text,
|
||||
const int index);
|
||||
|
||||
// used my class MeTa
|
||||
// load phonebook name phonebookName, use AT handler at
|
||||
// preload entire phonebook if preload == true
|
||||
Phonebook(string phonebookName, Ref<GsmAt> at,
|
||||
MeTa &myMeTa, bool preload = false) throw(GsmException);
|
||||
|
||||
public:
|
||||
// set cache mode on or off
|
||||
void setCaching(bool useCache) {_useCache = useCache;}
|
||||
|
||||
// return name of this phonebook (2-character string)
|
||||
string name() const {return _phonebookName;}
|
||||
|
||||
// return maximum telephone number length
|
||||
unsigned int getMaxTelephoneLen() const {return _maxNumberLength;}
|
||||
|
||||
// return maximum entry description length
|
||||
unsigned int getMaxTextLen() const { return _maxTextLength;}
|
||||
|
||||
// phonebook traversal commands
|
||||
// these are suitable to use stdc++ lib algorithms and iterators
|
||||
// ME have fixed storage space implemented as memory slots
|
||||
// that may either be empty or used
|
||||
|
||||
// traversal commands
|
||||
iterator begin();
|
||||
const_iterator begin() const;
|
||||
iterator end();
|
||||
const_iterator end() const;
|
||||
reference front();
|
||||
const_reference front() const;
|
||||
reference back();
|
||||
const_reference back() const;
|
||||
reference operator[](int n);
|
||||
const_reference operator[](int n) const;
|
||||
|
||||
// the size macros return the number of used entries
|
||||
int size() const throw(GsmException);
|
||||
int max_size() const {return _maxSize;}
|
||||
int capacity() const {return _maxSize;}
|
||||
bool empty() const throw(GsmException) {return size() == 0;}
|
||||
|
||||
// insert iterators insert into the first empty cell regardless of position
|
||||
// - existing iterators are not invalidated after an insert operation
|
||||
// - return position where it was actually inserted (may be != position)
|
||||
// - insert only writes to available positions
|
||||
// - throw an exception if size() == max_size() (ie. not empty slots)
|
||||
iterator insert(iterator position, const PhonebookEntry& x)
|
||||
throw(GsmException);
|
||||
|
||||
// insert n times, same procedure as above
|
||||
void insert(iterator pos, int n, const PhonebookEntry& x)
|
||||
throw(GsmException);
|
||||
void insert(iterator pos, long n, const PhonebookEntry& x)
|
||||
throw(GsmException);
|
||||
|
||||
// erase operators set used slots to "empty"
|
||||
iterator erase(iterator position) throw(GsmException);
|
||||
iterator erase(iterator first, iterator last) throw(GsmException);
|
||||
void clear() throw(GsmException);
|
||||
|
||||
// finds an entry given the text
|
||||
iterator find(string text) throw(GsmException);
|
||||
|
||||
// destructor
|
||||
virtual ~Phonebook();
|
||||
|
||||
friend class PhonebookEntry;
|
||||
friend class MeTa;
|
||||
};
|
||||
|
||||
// useful phonebook types
|
||||
typedef Ref<Phonebook> PhonebookRef;
|
||||
typedef vector<PhonebookRef> PhonebookVector;
|
||||
};
|
||||
|
||||
#endif // GSM_PHONEBOOK_H
|
@ -0,0 +1,58 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_port.h
|
||||
// *
|
||||
// * Purpose: Abstract port definition
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 3.5.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifndef GSM_PORT_H
|
||||
#define GSM_PORT_H
|
||||
|
||||
#include <gsmlib/gsm_error.h>
|
||||
#include <gsmlib/gsm_util.h>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gsmlib
|
||||
{
|
||||
// TA defaults
|
||||
const int TIMEOUT_SECS = 60;
|
||||
const char DEFAULT_INIT_STRING[] = "E0";
|
||||
const int DEFAULT_BAUD_RATE = 38400;
|
||||
|
||||
class Port : public RefBase
|
||||
{
|
||||
public:
|
||||
// read line from port(including eol characters)
|
||||
virtual string getLine() throw(GsmException) =0;
|
||||
|
||||
// write line to port
|
||||
virtual void putLine(string line,
|
||||
bool carriageReturn = true) throw(GsmException) =0;
|
||||
|
||||
// wait for new data to become available, return after timeout
|
||||
// if timeout == 0, wait forever
|
||||
// return true if data available
|
||||
virtual bool wait(GsmTime timeout) throw(GsmException) =0;
|
||||
|
||||
// put back one byte that can be read by a subsequent call to readByte()
|
||||
virtual void putBack(unsigned char c) =0;
|
||||
|
||||
// read a single byte, return -1 if error or file closed
|
||||
virtual int readByte() throw(GsmException) =0;
|
||||
|
||||
// set timeout for the readByte(), getLine(), and putLine() functions
|
||||
// (globally for ALL ports)
|
||||
virtual void setTimeOut(unsigned int timeout) =0;
|
||||
|
||||
virtual ~Port() {}
|
||||
};
|
||||
};
|
||||
|
||||
#endif // GSM_PORT_H
|
@ -0,0 +1,863 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_sms.cc
|
||||
// *
|
||||
// * Purpose: SMS functions
|
||||
// * (ETSI GSM 07.05)
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 16.5.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <gsm_config.h>
|
||||
#endif
|
||||
#include <gsmlib/gsm_nls.h>
|
||||
#include <gsmlib/gsm_sysdep.h>
|
||||
#include <gsmlib/gsm_sms.h>
|
||||
#include <gsmlib/gsm_util.h>
|
||||
#include <gsmlib/gsm_parser.h>
|
||||
#include <gsmlib/gsm_me_ta.h>
|
||||
#include <strstream>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
using namespace gsmlib;
|
||||
|
||||
// local constants
|
||||
|
||||
static const string dashes =
|
||||
"---------------------------------------------------------------------------";
|
||||
|
||||
// SMSMessage members
|
||||
|
||||
Ref<SMSMessage> SMSMessage::decode(string pdu,
|
||||
bool SCtoMEdirection,
|
||||
GsmAt *at) throw(GsmException)
|
||||
{
|
||||
Ref<SMSMessage> result;
|
||||
SMSDecoder d(pdu);
|
||||
d.getAddress(true);
|
||||
MessageType messageTypeIndicator = (MessageType)d.get2Bits(); // bits 0..1
|
||||
if (SCtoMEdirection)
|
||||
// TPDUs from SC to ME
|
||||
switch (messageTypeIndicator)
|
||||
{
|
||||
case SMS_DELIVER:
|
||||
result = new SMSDeliverMessage(pdu);
|
||||
break;
|
||||
|
||||
case SMS_STATUS_REPORT:
|
||||
result = new SMSStatusReportMessage(pdu);
|
||||
break;
|
||||
|
||||
case SMS_SUBMIT_REPORT:
|
||||
// observed with Motorola Timeport 260, the SCtoMEdirection can
|
||||
// be wrong in this case
|
||||
if (at != NULL && at->getMeTa().getCapabilities()._wrongSMSStatusCode)
|
||||
result = new SMSSubmitMessage(pdu);
|
||||
else
|
||||
result = new SMSSubmitReportMessage(pdu);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw GsmException(_("unhandled SMS TPDU type"), OtherError);
|
||||
}
|
||||
else
|
||||
// TPDUs from ME to SC
|
||||
switch (messageTypeIndicator)
|
||||
{
|
||||
case SMS_SUBMIT:
|
||||
result = new SMSSubmitMessage(pdu);
|
||||
break;
|
||||
|
||||
case SMS_DELIVER_REPORT:
|
||||
result = new SMSDeliverReportMessage(pdu);
|
||||
break;
|
||||
|
||||
case SMS_COMMAND:
|
||||
result = new SMSCommandMessage(pdu);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw GsmException(_("unhandled SMS TPDU type"), OtherError);
|
||||
}
|
||||
result->_at = at;
|
||||
return result;
|
||||
}
|
||||
|
||||
Ref<SMSMessage> SMSMessage::decode(istream& s) throw(gsmlib::GsmException)
|
||||
{
|
||||
string pdu;
|
||||
unsigned char ScToMe;
|
||||
|
||||
s >> ScToMe;
|
||||
s >> pdu;
|
||||
|
||||
return decode(pdu,ScToMe=='S');
|
||||
}
|
||||
|
||||
unsigned char SMSMessage::send(Ref<SMSMessage> &ackPdu)
|
||||
throw(GsmException)
|
||||
{
|
||||
if (_messageTypeIndicator != SMS_SUBMIT &&
|
||||
_messageTypeIndicator != SMS_COMMAND)
|
||||
throw GsmException(_("can only send SMS-SUBMIT and SMS-COMMAND TPDUs"),
|
||||
ParameterError);
|
||||
|
||||
if (_at.isnull())
|
||||
throw GsmException(_("no device given for sending SMS"), ParameterError);
|
||||
|
||||
string pdu = encode();
|
||||
Parser p(_at->sendPdu("+CMGS=" +
|
||||
intToStr(pdu.length() / 2 - getSCAddressLen()),
|
||||
"+CMGS:", pdu));
|
||||
unsigned char messageReference = p.parseInt();
|
||||
|
||||
if (p.parseComma(true))
|
||||
{
|
||||
string pdu = p.parseEol();
|
||||
|
||||
// add missing service centre address if required by ME
|
||||
if (! _at->getMeTa().getCapabilities()._hasSMSSCAprefix)
|
||||
pdu = "00" + pdu;
|
||||
|
||||
ackPdu = SMSMessage::decode(pdu);
|
||||
}
|
||||
else
|
||||
ackPdu = SMSMessageRef();
|
||||
|
||||
return messageReference;
|
||||
}
|
||||
|
||||
unsigned char SMSMessage::send() throw(GsmException)
|
||||
{
|
||||
SMSMessageRef mref;
|
||||
return send(mref);
|
||||
}
|
||||
|
||||
unsigned int SMSMessage::getSCAddressLen()
|
||||
{
|
||||
SMSEncoder e;
|
||||
e.setAddress(_serviceCentreAddress, true);
|
||||
return e.getLength();
|
||||
}
|
||||
|
||||
unsigned char SMSMessage::userDataLength() const
|
||||
{
|
||||
unsigned int udhl = _userDataHeader.length();
|
||||
if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET)
|
||||
return _userData.length() + (udhl ? ((1 + udhl) * 8 + 6) / 7 : 0);
|
||||
else
|
||||
return _userData.length() + (udhl ? (1 + udhl) : 0);
|
||||
}
|
||||
|
||||
ostream& SMSMessage::operator<<(ostream& s)
|
||||
{
|
||||
unsigned char ScToMe;
|
||||
|
||||
if (dynamic_cast<SMSDeliverMessage*>(this) ||
|
||||
dynamic_cast<SMSStatusReportMessage*>(this) ||
|
||||
dynamic_cast<SMSSubmitReportMessage*>(this))
|
||||
{
|
||||
ScToMe = 'S';
|
||||
}
|
||||
else if (dynamic_cast<SMSSubmitMessage*>(this) ||
|
||||
dynamic_cast<SMSCommandMessage*>(this) ||
|
||||
dynamic_cast<SMSDeliverReportMessage*>(this))
|
||||
{
|
||||
ScToMe = 'M';
|
||||
}
|
||||
else
|
||||
{
|
||||
throw GsmException(_("unhandled SMS TPDU type"), OtherError);
|
||||
}
|
||||
|
||||
s << ScToMe;
|
||||
return s << encode();
|
||||
}
|
||||
|
||||
// SMSMessage::SMSMessage(SMSMessage &m)
|
||||
// {
|
||||
// _at = m._at;
|
||||
|
||||
// }
|
||||
|
||||
// SMSMessage &SMSMessage::operator=(SMSMessage &m)
|
||||
// {
|
||||
// }
|
||||
|
||||
SMSMessage::~SMSMessage() {}
|
||||
|
||||
// SMSDeliverMessage members
|
||||
|
||||
void SMSDeliverMessage::init()
|
||||
{
|
||||
_messageTypeIndicator = SMS_DELIVER;
|
||||
_moreMessagesToSend = false;
|
||||
_replyPath = false;
|
||||
_statusReportIndication = false;
|
||||
_protocolIdentifier = 0;
|
||||
}
|
||||
|
||||
SMSDeliverMessage::SMSDeliverMessage()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
SMSDeliverMessage::SMSDeliverMessage(string pdu) throw(GsmException)
|
||||
{
|
||||
SMSDecoder d(pdu);
|
||||
_serviceCentreAddress = d.getAddress(true);
|
||||
_messageTypeIndicator = (MessageType)d.get2Bits(); // bits 0..1
|
||||
assert(_messageTypeIndicator == SMS_DELIVER);
|
||||
_moreMessagesToSend = d.getBit(); // bit 2
|
||||
d.getBit(); // bit 3
|
||||
d.getBit(); // bit 4
|
||||
_statusReportIndication = d.getBit(); // bit 5
|
||||
bool userDataHeaderIndicator = d.getBit(); // bit 6
|
||||
_replyPath = d.getBit(); // bit 7
|
||||
_originatingAddress = d.getAddress();
|
||||
_protocolIdentifier = d.getOctet();
|
||||
_dataCodingScheme = d.getOctet();
|
||||
_serviceCentreTimestamp = d.getTimestamp();
|
||||
unsigned char userDataLength = d.getOctet();
|
||||
d.markSeptet();
|
||||
|
||||
if (userDataHeaderIndicator)
|
||||
{
|
||||
_userDataHeader.decode(d);
|
||||
if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET)
|
||||
userDataLength -= ((_userDataHeader.length() + 1) * 8 + 6) / 7;
|
||||
else
|
||||
userDataLength -= ((string)_userDataHeader).length() + 1;
|
||||
}
|
||||
else
|
||||
_userDataHeader = UserDataHeader();
|
||||
|
||||
if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET)
|
||||
{ // userDataLength is length in septets
|
||||
_userData = d.getString(userDataLength);
|
||||
_userData = gsmToLatin1(_userData);
|
||||
}
|
||||
else
|
||||
{ // userDataLength is length in octets
|
||||
unsigned char *s =
|
||||
(unsigned char*)alloca(sizeof(unsigned char) * userDataLength);
|
||||
d.getOctets(s, userDataLength);
|
||||
_userData.assign((char*)s, (unsigned int)userDataLength);
|
||||
}
|
||||
}
|
||||
|
||||
string SMSDeliverMessage::encode()
|
||||
{
|
||||
SMSEncoder e;
|
||||
e.setAddress(_serviceCentreAddress, true);
|
||||
e.set2Bits(_messageTypeIndicator); // bits 0..1
|
||||
e.setBit(_moreMessagesToSend); // bit 2
|
||||
e.setBit(); // bit 3
|
||||
e.setBit(); // bit 4
|
||||
e.setBit(_statusReportIndication); // bit 5
|
||||
e.setBit(_userDataHeader.length() != 0); // bit 6
|
||||
e.setBit(_replyPath); // bit 7
|
||||
e.setAddress(_originatingAddress);
|
||||
e.setOctet(_protocolIdentifier);
|
||||
e.setOctet(_dataCodingScheme);
|
||||
e.setTimestamp(_serviceCentreTimestamp);
|
||||
e.setOctet(userDataLength());
|
||||
e.markSeptet();
|
||||
if (_userDataHeader.length()) _userDataHeader.encode(e);
|
||||
if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET)
|
||||
e.setString(latin1ToGsm(_userData));
|
||||
else
|
||||
e.setOctets((unsigned char*)_userData.data(), _userData.length());
|
||||
return e.getHexString();
|
||||
}
|
||||
|
||||
string SMSDeliverMessage::toString() const
|
||||
{
|
||||
ostrstream os;
|
||||
os << dashes << endl
|
||||
<< _("Message type: SMS-DELIVER") << endl
|
||||
<< _("SC address: '") << _serviceCentreAddress._number << "'" << endl
|
||||
<< _("More messages to send: ") << _moreMessagesToSend << endl
|
||||
<< _("Reply path: ") << _replyPath << endl
|
||||
<< _("User data header indicator: ")
|
||||
<< (_userDataHeader.length()!=0) << endl
|
||||
<< _("Status report indication: ") << _statusReportIndication << endl
|
||||
<< _("Originating address: '") << _originatingAddress._number
|
||||
<< "'" << endl
|
||||
<< _("Protocol identifier: 0x") << hex
|
||||
<< (unsigned int)_protocolIdentifier << dec << endl
|
||||
<< _("Data coding scheme: ") << _dataCodingScheme.toString() << endl
|
||||
<< _("SC timestamp: ") << _serviceCentreTimestamp.toString() << endl
|
||||
<< _("User data length: ") << (int)userDataLength() << endl
|
||||
<< _("User data header: 0x")
|
||||
<< bufToHex((unsigned char*)
|
||||
((string)_userDataHeader).data(),
|
||||
((string)_userDataHeader).length())
|
||||
<< endl
|
||||
<< _("User data: '") << _userData << "'" << endl
|
||||
<< dashes << endl << endl
|
||||
<< ends;
|
||||
char *ss = os.str();
|
||||
string result(ss);
|
||||
delete[] ss;
|
||||
return result;
|
||||
}
|
||||
|
||||
Address SMSDeliverMessage::address() const
|
||||
{
|
||||
return _originatingAddress;
|
||||
}
|
||||
|
||||
Ref<SMSMessage> SMSDeliverMessage::clone()
|
||||
{
|
||||
Ref<SMSMessage> result = new SMSDeliverMessage(*this);
|
||||
return result;
|
||||
}
|
||||
|
||||
// SMSSubmitMessage members
|
||||
|
||||
void SMSSubmitMessage::init()
|
||||
{
|
||||
// set everything to sensible default values
|
||||
_messageTypeIndicator = SMS_SUBMIT;
|
||||
_validityPeriodFormat = TimePeriod::Relative;
|
||||
_validityPeriod._format = TimePeriod::Relative;
|
||||
_validityPeriod._relativeTime = 168; // 2 days
|
||||
_statusReportRequest = false;
|
||||
_replyPath = false;
|
||||
_rejectDuplicates = true;
|
||||
_messageReference = 0;
|
||||
_protocolIdentifier = 0;
|
||||
}
|
||||
|
||||
SMSSubmitMessage::SMSSubmitMessage()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
SMSSubmitMessage::SMSSubmitMessage(string pdu) throw(GsmException)
|
||||
{
|
||||
SMSDecoder d(pdu);
|
||||
_serviceCentreAddress = d.getAddress(true);
|
||||
_messageTypeIndicator = (MessageType)d.get2Bits(); // bits 0..1
|
||||
assert(_messageTypeIndicator == SMS_SUBMIT);
|
||||
_rejectDuplicates = d.getBit(); // bit 2
|
||||
_validityPeriodFormat = (TimePeriod::Format)d.get2Bits(); // bits 3..4
|
||||
_statusReportRequest = d.getBit(); // bit 5
|
||||
bool userDataHeaderIndicator = d.getBit(); // bit 6
|
||||
_replyPath = d.getBit(); // bit 7
|
||||
_messageReference = d.getOctet();
|
||||
_destinationAddress = d.getAddress();
|
||||
_protocolIdentifier = d.getOctet();
|
||||
_dataCodingScheme = d.getOctet();
|
||||
if (_validityPeriodFormat != TimePeriod::NotPresent)
|
||||
_validityPeriod = d.getTimePeriod(_validityPeriodFormat);
|
||||
unsigned char userDataLength = d.getOctet();
|
||||
d.markSeptet();
|
||||
|
||||
if (userDataHeaderIndicator)
|
||||
{
|
||||
_userDataHeader.decode(d);
|
||||
if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET)
|
||||
userDataLength -= ((_userDataHeader.length() + 1) * 8 + 6) / 7;
|
||||
else
|
||||
userDataLength -= ((string)_userDataHeader).length() + 1;
|
||||
}
|
||||
else
|
||||
_userDataHeader = UserDataHeader();
|
||||
|
||||
if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET)
|
||||
{ // userDataLength is length in septets
|
||||
_userData = d.getString(userDataLength);
|
||||
_userData = gsmToLatin1(_userData);
|
||||
}
|
||||
else
|
||||
{ // _userDataLength is length in octets
|
||||
unsigned char *s =
|
||||
(unsigned char*)alloca(sizeof(unsigned char) * userDataLength);
|
||||
d.getOctets(s, userDataLength);
|
||||
_userData.assign((char*)s, userDataLength);
|
||||
}
|
||||
}
|
||||
|
||||
SMSSubmitMessage::SMSSubmitMessage(string text, string number)
|
||||
{
|
||||
init();
|
||||
_destinationAddress = Address(number);
|
||||
_userData = text;
|
||||
}
|
||||
|
||||
string SMSSubmitMessage::encode()
|
||||
{
|
||||
SMSEncoder e;
|
||||
e.setAddress(_serviceCentreAddress, true);
|
||||
e.set2Bits(_messageTypeIndicator); // bits 0..1
|
||||
e.setBit(_rejectDuplicates); // bit 2
|
||||
e.set2Bits(_validityPeriodFormat); // bits 3..4
|
||||
e.setBit(_statusReportRequest); // bit 5
|
||||
bool userDataHeaderIndicator = _userDataHeader.length() != 0;
|
||||
e.setBit(userDataHeaderIndicator); // bit 6
|
||||
e.setBit(_replyPath); // bit 7
|
||||
e.setOctet(_messageReference);
|
||||
e.setAddress(_destinationAddress);
|
||||
e.setOctet(_protocolIdentifier);
|
||||
e.setOctet(_dataCodingScheme);
|
||||
e.setTimePeriod(_validityPeriod);
|
||||
e.setOctet(userDataLength());
|
||||
e.markSeptet();
|
||||
if (userDataHeaderIndicator) _userDataHeader.encode(e);
|
||||
if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET)
|
||||
e.setString(latin1ToGsm(_userData));
|
||||
else
|
||||
e.setOctets((unsigned char*)_userData.data(), _userData.length());
|
||||
return e.getHexString();
|
||||
}
|
||||
|
||||
string SMSSubmitMessage::toString() const
|
||||
{
|
||||
ostrstream os;
|
||||
os << dashes << endl
|
||||
<< _("Message type: SMS-SUBMIT") << endl
|
||||
<< _("SC address: '") << _serviceCentreAddress._number << "'" << endl
|
||||
<< _("Reject duplicates: ") << _rejectDuplicates << endl
|
||||
<< _("Validity period format: ");
|
||||
switch (_validityPeriodFormat)
|
||||
{
|
||||
case TimePeriod::NotPresent:
|
||||
os << _("not present");
|
||||
break;
|
||||
case TimePeriod::Relative:
|
||||
os << _("relative");
|
||||
break;
|
||||
case TimePeriod::Absolute:
|
||||
os << _("absolute");
|
||||
break;
|
||||
default:
|
||||
os << _("unknown");
|
||||
break;
|
||||
}
|
||||
os << endl
|
||||
<< _("Reply path: ") << _replyPath << endl
|
||||
<< _("User data header indicator: ")
|
||||
<< (_userDataHeader.length()!=0) << endl
|
||||
<< _("Status report request: ") << _statusReportRequest << endl
|
||||
<< _("Message reference: ") << (unsigned int)_messageReference << endl
|
||||
<< _("Destination address: '") << _destinationAddress._number
|
||||
<< "'" << endl
|
||||
<< _("Protocol identifier: 0x") << hex
|
||||
<< (unsigned int)_protocolIdentifier << dec << endl
|
||||
<< _("Data coding scheme: ") << _dataCodingScheme.toString() << endl
|
||||
<< _("Validity period: ") << _validityPeriod.toString() << endl
|
||||
<< _("User data length: ") << (int)userDataLength() << endl
|
||||
<< _("User data header: 0x") << bufToHex((unsigned char*)
|
||||
((string)_userDataHeader).data(),
|
||||
_userDataHeader.length())
|
||||
<< endl
|
||||
<< _("User data: '") << _userData << "'" << endl
|
||||
<< dashes << endl << endl
|
||||
<< ends;
|
||||
char *ss = os.str();
|
||||
string result(ss);
|
||||
delete[] ss;
|
||||
return result;
|
||||
}
|
||||
|
||||
Address SMSSubmitMessage::address() const
|
||||
{
|
||||
return _destinationAddress;
|
||||
}
|
||||
|
||||
Ref<SMSMessage> SMSSubmitMessage::clone()
|
||||
{
|
||||
Ref<SMSMessage> result = new SMSSubmitMessage(*this);
|
||||
return result;
|
||||
}
|
||||
|
||||
// SMSStatusReportMessage members
|
||||
|
||||
void SMSStatusReportMessage::init()
|
||||
{
|
||||
_messageTypeIndicator = SMS_STATUS_REPORT;
|
||||
_moreMessagesToSend = false;
|
||||
_statusReportQualifier = false;
|
||||
_messageReference = 0;
|
||||
_status = SMS_STATUS_RECEIVED;
|
||||
}
|
||||
|
||||
SMSStatusReportMessage::SMSStatusReportMessage(string pdu) throw(GsmException)
|
||||
{
|
||||
SMSDecoder d(pdu);
|
||||
_serviceCentreAddress = d.getAddress(true);
|
||||
_messageTypeIndicator = (MessageType)d.get2Bits(); // bits 0..1
|
||||
assert(_messageTypeIndicator == SMS_STATUS_REPORT);
|
||||
_moreMessagesToSend = d.getBit(); // bit 2
|
||||
d.getBit(); // bit 3
|
||||
d.getBit(); // bit 4
|
||||
_statusReportQualifier = d.getBit(); // bit 5
|
||||
_messageReference = d.getOctet();
|
||||
_recipientAddress = d.getAddress();
|
||||
_serviceCentreTimestamp = d.getTimestamp();
|
||||
_dischargeTime = d.getTimestamp();
|
||||
_status = d.getOctet();
|
||||
}
|
||||
|
||||
string SMSStatusReportMessage::encode()
|
||||
{
|
||||
SMSEncoder e;
|
||||
e.setAddress(_serviceCentreAddress, true);
|
||||
e.set2Bits(_messageTypeIndicator); // bits 0..1
|
||||
e.setBit(_moreMessagesToSend); // bit 2
|
||||
e.setBit(); // bit 3
|
||||
e.setBit(); // bit 4
|
||||
e.setBit(_statusReportQualifier); // bit 5
|
||||
e.setOctet(_messageReference);
|
||||
e.setAddress(_recipientAddress);
|
||||
e.setTimestamp(_serviceCentreTimestamp);
|
||||
e.setTimestamp(_dischargeTime);
|
||||
e.setOctet(_status);
|
||||
return e.getHexString();
|
||||
}
|
||||
|
||||
string SMSStatusReportMessage::toString() const
|
||||
{
|
||||
ostrstream os;
|
||||
os << dashes << endl
|
||||
<< _("Message type: SMS-STATUS-REPORT") << endl
|
||||
<< _("SC address: '") << _serviceCentreAddress._number << "'" << endl
|
||||
<< _("More messages to send: ") << _moreMessagesToSend << endl
|
||||
<< _("Status report qualifier: ") << _statusReportQualifier << endl
|
||||
<< _("Message reference: ") << (unsigned int)_messageReference << endl
|
||||
<< _("Recipient address: '") << _recipientAddress._number << "'" << endl
|
||||
<< _("SC timestamp: ") << _serviceCentreTimestamp.toString() << endl
|
||||
<< _("Discharge time: ") << _dischargeTime.toString() << endl
|
||||
<< _("Status: 0x") << hex << (unsigned int)_status << dec
|
||||
<< " '" << getSMSStatusString(_status) << "'" << endl
|
||||
<< dashes << endl << endl
|
||||
<< ends;
|
||||
char *ss = os.str();
|
||||
string result(ss);
|
||||
delete[] ss;
|
||||
return result;
|
||||
}
|
||||
|
||||
Address SMSStatusReportMessage::address() const
|
||||
{
|
||||
return _recipientAddress;
|
||||
}
|
||||
|
||||
Ref<SMSMessage> SMSStatusReportMessage::clone()
|
||||
{
|
||||
Ref<SMSMessage> result = new SMSStatusReportMessage(*this);
|
||||
return result;
|
||||
}
|
||||
|
||||
// SMSCommandMessage members
|
||||
|
||||
void SMSCommandMessage::init()
|
||||
{
|
||||
_messageTypeIndicator = SMS_COMMAND;
|
||||
_messageReference = 0;
|
||||
_statusReportRequest = true;
|
||||
_protocolIdentifier = 0;
|
||||
_commandType = EnquireSM;
|
||||
_messageNumber = 0;
|
||||
_commandDataLength = 0;
|
||||
}
|
||||
|
||||
SMSCommandMessage::SMSCommandMessage(string pdu) throw(GsmException)
|
||||
{
|
||||
SMSDecoder d(pdu);
|
||||
_serviceCentreAddress = d.getAddress(true);
|
||||
_messageTypeIndicator = (MessageType)d.get2Bits(); // bits 0..1
|
||||
assert(_messageTypeIndicator == SMS_COMMAND);
|
||||
d.getBit(); // bit 2
|
||||
d.getBit(); // bit 3
|
||||
d.getBit(); // bit 4
|
||||
_statusReportRequest = d.getBit(); // bit 5
|
||||
_messageReference = d.getOctet();
|
||||
_protocolIdentifier = d.getOctet();
|
||||
_commandType = d.getOctet();
|
||||
_messageNumber = d.getOctet();
|
||||
_destinationAddress = d.getAddress();
|
||||
_commandDataLength = d.getOctet();
|
||||
unsigned char *s =
|
||||
(unsigned char*)alloca(sizeof(unsigned char) * _commandDataLength);
|
||||
d.getOctets(s, _commandDataLength);
|
||||
}
|
||||
|
||||
string SMSCommandMessage::encode()
|
||||
{
|
||||
SMSEncoder e;
|
||||
e.setAddress(_serviceCentreAddress, true);
|
||||
e.set2Bits(_messageTypeIndicator); // bits 0..1
|
||||
e.setBit(); // bit 2
|
||||
e.setBit(); // bit 3
|
||||
e.setBit(); // bit 4
|
||||
e.setBit(_statusReportRequest); // bit 5
|
||||
e.setOctet(_messageReference);
|
||||
e.setOctet(_protocolIdentifier);
|
||||
e.setOctet(_commandType);
|
||||
e.setOctet(_messageNumber);
|
||||
e.setAddress(_destinationAddress);
|
||||
e.setOctet(_commandData.length());
|
||||
e.setOctets((const unsigned char*)_commandData.data(),
|
||||
(short unsigned int)_commandData.length());
|
||||
return e.getHexString();
|
||||
}
|
||||
|
||||
string SMSCommandMessage::toString() const
|
||||
{
|
||||
ostrstream os;
|
||||
os << dashes << endl
|
||||
<< _("Message type: SMS-COMMAND") << endl
|
||||
<< _("SC address: '") << _serviceCentreAddress._number << "'" << endl
|
||||
<< _("Message reference: ") << (unsigned int)_messageReference << endl
|
||||
<< _("Status report request: ") << _statusReportRequest << endl
|
||||
<< _("Protocol identifier: 0x") << hex
|
||||
<< (unsigned int)_protocolIdentifier << dec << endl
|
||||
<< _("Command type: 0x") << hex << (unsigned int)_commandType
|
||||
<< dec << endl
|
||||
<< _("Message number: ") << (unsigned int)_messageNumber << endl
|
||||
<< _("Destination address: '") << _destinationAddress._number
|
||||
<< "'" << endl
|
||||
<< _("Command data length: ") << (unsigned int)_commandDataLength << endl
|
||||
<< _("Command data: '") << _commandData << "'" << endl
|
||||
<< dashes << endl << endl
|
||||
<< ends;
|
||||
char *ss = os.str();
|
||||
string result(ss);
|
||||
delete[] ss;
|
||||
return result;
|
||||
}
|
||||
|
||||
Address SMSCommandMessage::address() const
|
||||
{
|
||||
return _destinationAddress;
|
||||
}
|
||||
|
||||
Ref<SMSMessage> SMSCommandMessage::clone()
|
||||
{
|
||||
Ref<SMSMessage> result = new SMSCommandMessage(*this);
|
||||
return result;
|
||||
}
|
||||
|
||||
// SMSDeliverReportMessage members
|
||||
|
||||
void SMSDeliverReportMessage::init()
|
||||
{
|
||||
_messageTypeIndicator = SMS_DELIVER_REPORT;
|
||||
_protocolIdentifierPresent = false;
|
||||
_dataCodingSchemePresent = false;
|
||||
_userDataLengthPresent = false;
|
||||
}
|
||||
|
||||
SMSDeliverReportMessage::SMSDeliverReportMessage(string pdu)
|
||||
throw(GsmException)
|
||||
{
|
||||
SMSDecoder d(pdu);
|
||||
_serviceCentreAddress = d.getAddress(true);
|
||||
_messageTypeIndicator = (MessageType)d.get2Bits(); // bits 0..1
|
||||
assert(_messageTypeIndicator == SMS_DELIVER_REPORT);
|
||||
d.alignOctet(); // skip to parameter indicator
|
||||
_protocolIdentifierPresent = d.getBit(); // bit 0
|
||||
_dataCodingSchemePresent = d.getBit(); // bit 1
|
||||
_userDataLengthPresent = d.getBit(); // bit 2
|
||||
if (_protocolIdentifierPresent)
|
||||
_protocolIdentifier = d.getOctet();
|
||||
if (_dataCodingSchemePresent)
|
||||
_dataCodingScheme = d.getOctet();
|
||||
if (_userDataLengthPresent)
|
||||
{
|
||||
unsigned char userDataLength = d.getOctet();
|
||||
d.markSeptet();
|
||||
if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET)
|
||||
{
|
||||
_userData = d.getString(userDataLength);
|
||||
_userData = gsmToLatin1(_userData);
|
||||
}
|
||||
else
|
||||
{ // userDataLength is length in octets
|
||||
unsigned char *s =
|
||||
(unsigned char*)alloca(sizeof(unsigned char) * userDataLength);
|
||||
d.getOctets(s, userDataLength);
|
||||
_userData.assign((char*)s, userDataLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string SMSDeliverReportMessage::encode()
|
||||
{
|
||||
SMSEncoder e;
|
||||
e.setAddress(_serviceCentreAddress, true);
|
||||
e.set2Bits(_messageTypeIndicator); // bits 0..1
|
||||
e.alignOctet(); // skip to parameter indicator
|
||||
e.setBit(_protocolIdentifierPresent); // bit 0
|
||||
e.setBit(_dataCodingSchemePresent); // bit 1
|
||||
e.setBit(_userDataLengthPresent); // bit 2
|
||||
if (_protocolIdentifierPresent)
|
||||
e.setOctet(_protocolIdentifier);
|
||||
if (_dataCodingSchemePresent)
|
||||
e.setOctet(_dataCodingScheme);
|
||||
if (_userDataLengthPresent)
|
||||
{
|
||||
unsigned char userDataLength = _userData.length();
|
||||
e.setOctet(userDataLength);
|
||||
if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET)
|
||||
e.setString(latin1ToGsm(_userData));
|
||||
else
|
||||
e.setOctets((unsigned char*)_userData.data(), userDataLength);
|
||||
}
|
||||
return e.getHexString();
|
||||
}
|
||||
|
||||
string SMSDeliverReportMessage::toString() const
|
||||
{
|
||||
ostrstream os;
|
||||
os << dashes << endl
|
||||
<< _("Message type: SMS-DELIVER-REPORT") << endl
|
||||
<< _("SC address: '") << _serviceCentreAddress._number << "'" << endl
|
||||
<< _("Protocol identifier present: ") << _protocolIdentifierPresent
|
||||
<< endl
|
||||
<< _("Data coding scheme present: ") << _dataCodingSchemePresent << endl
|
||||
<< _("User data length present: ") << _userDataLengthPresent << endl;
|
||||
if (_protocolIdentifierPresent)
|
||||
os << _("Protocol identifier: 0x") << hex
|
||||
<< (unsigned int)_protocolIdentifier
|
||||
<< dec << endl;
|
||||
if (_dataCodingSchemePresent)
|
||||
os << _("Data coding scheme: ") << _dataCodingScheme.toString() << endl;
|
||||
if (_userDataLengthPresent)
|
||||
os << _("User data length: ") << (int)userDataLength() << endl
|
||||
<< _("User data: '") << _userData << "'" << endl;
|
||||
os << dashes << endl << endl
|
||||
<< ends;
|
||||
char *ss = os.str();
|
||||
string result(ss);
|
||||
delete[] ss;
|
||||
return result;
|
||||
}
|
||||
|
||||
Address SMSDeliverReportMessage::address() const
|
||||
{
|
||||
assert(0); // not address, should not be in SMS store
|
||||
return Address();
|
||||
}
|
||||
|
||||
Ref<SMSMessage> SMSDeliverReportMessage::clone()
|
||||
{
|
||||
Ref<SMSMessage> result = new SMSDeliverReportMessage(*this);
|
||||
return result;
|
||||
}
|
||||
|
||||
// SMSSubmitReportMessage members
|
||||
|
||||
void SMSSubmitReportMessage::init()
|
||||
{
|
||||
_messageTypeIndicator = SMS_SUBMIT_REPORT;
|
||||
_protocolIdentifierPresent = false;
|
||||
_dataCodingSchemePresent = false;
|
||||
_userDataLengthPresent = false;
|
||||
}
|
||||
|
||||
SMSSubmitReportMessage::SMSSubmitReportMessage(string pdu) throw(GsmException)
|
||||
{
|
||||
SMSDecoder d(pdu);
|
||||
_serviceCentreAddress = d.getAddress(true);
|
||||
_messageTypeIndicator = (MessageType)d.get2Bits(); // bits 0..1
|
||||
assert(_messageTypeIndicator == SMS_SUBMIT_REPORT);
|
||||
_serviceCentreTimestamp = d.getTimestamp();
|
||||
_protocolIdentifierPresent = d.getBit(); // bit 0
|
||||
_dataCodingSchemePresent = d.getBit(); // bit 1
|
||||
_userDataLengthPresent = d.getBit(); // bit 2
|
||||
if (_protocolIdentifierPresent)
|
||||
_protocolIdentifier = d.getOctet();
|
||||
if (_dataCodingSchemePresent)
|
||||
_dataCodingScheme = d.getOctet();
|
||||
if (_userDataLengthPresent)
|
||||
{
|
||||
unsigned char userDataLength = d.getOctet();
|
||||
d.markSeptet();
|
||||
if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET)
|
||||
{
|
||||
_userData = d.getString(userDataLength);
|
||||
_userData = gsmToLatin1(_userData);
|
||||
}
|
||||
else
|
||||
{ // _userDataLength is length in octets
|
||||
unsigned char *s =
|
||||
(unsigned char*)alloca(sizeof(unsigned char) * userDataLength);
|
||||
d.getOctets(s, userDataLength);
|
||||
_userData.assign((char*)s, userDataLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string SMSSubmitReportMessage::encode()
|
||||
{
|
||||
SMSEncoder e;
|
||||
e.setAddress(_serviceCentreAddress, true);
|
||||
e.set2Bits(_messageTypeIndicator); // bits 0..1
|
||||
e.setTimestamp(_serviceCentreTimestamp);
|
||||
e.setBit(_protocolIdentifierPresent); // bit 0
|
||||
e.setBit(_dataCodingSchemePresent); // bit 1
|
||||
e.setBit(_userDataLengthPresent); // bit 2
|
||||
if (_protocolIdentifierPresent)
|
||||
e.setOctet(_protocolIdentifier);
|
||||
if (_dataCodingSchemePresent)
|
||||
e.setOctet(_dataCodingScheme);
|
||||
if (_userDataLengthPresent)
|
||||
{
|
||||
e.setOctet(userDataLength());
|
||||
if (_dataCodingScheme.getAlphabet() == DCS_DEFAULT_ALPHABET)
|
||||
e.setString(latin1ToGsm(_userData));
|
||||
else
|
||||
e.setOctets((unsigned char*)_userData.data(), _userData.length());
|
||||
}
|
||||
return e.getHexString();
|
||||
}
|
||||
|
||||
string SMSSubmitReportMessage::toString() const
|
||||
{
|
||||
ostrstream os;
|
||||
os << dashes << endl
|
||||
<< _("Message type: SMS-SUBMIT-REPORT") << endl
|
||||
<< _("SC address: '") << _serviceCentreAddress._number << "'" << endl
|
||||
<< _("SC timestamp: ") << _serviceCentreTimestamp.toString() << endl
|
||||
<< _("Protocol identifier present: ") << _protocolIdentifierPresent
|
||||
<< endl
|
||||
<< _("Data coding scheme present: ") << _dataCodingSchemePresent << endl
|
||||
<< _("User data length present: ") << _userDataLengthPresent << endl;
|
||||
if (_protocolIdentifierPresent)
|
||||
os << _("Protocol identifier: 0x") << hex
|
||||
<< (unsigned int)_protocolIdentifier
|
||||
<< dec << endl;
|
||||
if (_dataCodingSchemePresent)
|
||||
os << _("Data coding scheme: ") << _dataCodingScheme.toString() << endl;
|
||||
if (_userDataLengthPresent)
|
||||
os << _("User data length: ") << (int)userDataLength() << endl
|
||||
<< _("User data: '") << _userData << "'" << endl;
|
||||
os << dashes << endl << endl
|
||||
<< ends;
|
||||
char *ss = os.str();
|
||||
string result(ss);
|
||||
delete[] ss;
|
||||
return result;
|
||||
}
|
||||
|
||||
Address SMSSubmitReportMessage::address() const
|
||||
{
|
||||
assert(0); // not address, should not be in SMS store
|
||||
return Address();
|
||||
}
|
||||
|
||||
Ref<SMSMessage> SMSSubmitReportMessage::clone()
|
||||
{
|
||||
Ref<SMSMessage> result = new SMSSubmitReportMessage(*this);
|
||||
return result;
|
||||
}
|
||||
|
@ -0,0 +1,480 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_sms.h
|
||||
// *
|
||||
// * Purpose: SMS functions
|
||||
// * (ETSI GSM 07.05)
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 16.5.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifndef GSM_SMS_H
|
||||
#define GSM_SMS_H
|
||||
|
||||
#include <gsmlib/gsm_sms_codec.h>
|
||||
#include <gsmlib/gsm_error.h>
|
||||
#include <gsmlib/gsm_util.h>
|
||||
#include <gsmlib/gsm_at.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gsmlib
|
||||
{
|
||||
// forward declarations
|
||||
class SMSStore;
|
||||
class SMSMessage;
|
||||
|
||||
// this class represents a single SMS message
|
||||
class SMSMessage : public RefBase
|
||||
{
|
||||
private:
|
||||
Ref<GsmAt> _at; // connection to the device
|
||||
|
||||
public:
|
||||
// possible values for message type indicator
|
||||
enum MessageType {SMS_DELIVER = 0, SMS_DELIVER_REPORT = 0,
|
||||
SMS_STATUS_REPORT = 2, SMS_COMMAND = 2,
|
||||
SMS_SUBMIT = 1, SMS_SUBMIT_REPORT = 1};
|
||||
|
||||
protected:
|
||||
// fields of the different TPDUs
|
||||
// all PDUs
|
||||
string _userData;
|
||||
UserDataHeader _userDataHeader;
|
||||
Address _serviceCentreAddress;
|
||||
MessageType _messageTypeIndicator;// 2 bits
|
||||
DataCodingScheme _dataCodingScheme;
|
||||
|
||||
public:
|
||||
// decode hexadecimal pdu string
|
||||
// return SMSMessage of the appropriate type
|
||||
// differentiate between SMS transfer directions SC to ME, ME to SC
|
||||
// also give GsmAt object for send()
|
||||
static Ref<SMSMessage> decode(string pdu,
|
||||
bool SCtoMEdirection = true,
|
||||
GsmAt *at = NULL)
|
||||
throw(GsmException);
|
||||
|
||||
static Ref<SMSMessage> decode(istream& s) throw(GsmException);
|
||||
|
||||
// encode pdu, return hexadecimal pdu string
|
||||
virtual string encode() = 0;
|
||||
|
||||
// send this PDU
|
||||
// returns message reference and ACK-PDU (if requested)
|
||||
// only applicate to SMS-SUBMIT and SMS-COMMAND
|
||||
unsigned char send(Ref<SMSMessage> &ackPdu) throw(GsmException);
|
||||
|
||||
// same as above, but ACK-PDU is discarded
|
||||
unsigned char send() throw(GsmException);
|
||||
|
||||
// create textual representation of SMS
|
||||
virtual string toString() const = 0;
|
||||
|
||||
// return deep copy of this message
|
||||
virtual Ref<SMSMessage> clone() = 0;
|
||||
|
||||
// return length of SC address when encoded
|
||||
unsigned int getSCAddressLen();
|
||||
|
||||
// accessor functions
|
||||
MessageType messageType() const {return _messageTypeIndicator;}
|
||||
Address serviceCentreAddress() const {return _serviceCentreAddress;}
|
||||
|
||||
// provided for sorting messages by timestamp
|
||||
virtual Timestamp serviceCentreTimestamp() const {return Timestamp();}
|
||||
|
||||
// return recipient, destination etc. address (for sorting by address)
|
||||
virtual Address address() const = 0;
|
||||
|
||||
virtual void setUserData(string x) {_userData = x;}
|
||||
virtual string userData() const {return _userData;}
|
||||
|
||||
// return the size of user data (including user data header)
|
||||
unsigned char userDataLength() const;
|
||||
|
||||
// accessor functions
|
||||
virtual void setUserDataHeader(UserDataHeader x) {_userDataHeader = x;}
|
||||
virtual UserDataHeader userDataHeader() const {return _userDataHeader;}
|
||||
|
||||
virtual DataCodingScheme dataCodingScheme() const
|
||||
{return _dataCodingScheme;}
|
||||
virtual void setDataCodingScheme(DataCodingScheme x)
|
||||
{_dataCodingScheme = x;}
|
||||
|
||||
void setServiceCentreAddress(Address &x) {_serviceCentreAddress = x;}
|
||||
void setAt(Ref<GsmAt> at) {_at = at;}
|
||||
|
||||
virtual ~SMSMessage();
|
||||
|
||||
// print ASCII hex representation of message
|
||||
ostream& operator<<(ostream& s);
|
||||
|
||||
// copy constructor and assignment
|
||||
// SMSMessage(SMSMessage &m);
|
||||
// SMSMessage &operator=(SMSMessage &m);
|
||||
|
||||
friend class SMSStore;
|
||||
};
|
||||
|
||||
// SMS-DELIVER TPDU
|
||||
class SMSDeliverMessage : public SMSMessage
|
||||
{
|
||||
private:
|
||||
// SMS-DELIVER PDU members (see GSM 03.40 section 9.2.2.1)
|
||||
bool _moreMessagesToSend;
|
||||
bool _replyPath;
|
||||
bool _statusReportIndication;
|
||||
Address _originatingAddress;
|
||||
unsigned char _protocolIdentifier; // octet
|
||||
Timestamp _serviceCentreTimestamp;
|
||||
|
||||
// initialize members to sensible values
|
||||
void init();
|
||||
|
||||
public:
|
||||
// constructor, sets sensible default values
|
||||
SMSDeliverMessage();
|
||||
|
||||
// constructor with given pdu
|
||||
SMSDeliverMessage(string pdu) throw(GsmException);
|
||||
|
||||
// encode pdu, return hexadecimal pdu string
|
||||
virtual string encode();
|
||||
|
||||
// create textual representation of SMS
|
||||
virtual string toString() const;
|
||||
|
||||
// inherited from SMSMessage
|
||||
Address address() const;
|
||||
Ref<SMSMessage> clone();
|
||||
|
||||
// accessor functions
|
||||
bool moreMessagesToSend() const {return _moreMessagesToSend;}
|
||||
bool replyPath() const {return _replyPath;}
|
||||
bool statusReportIndication() const {return _statusReportIndication;}
|
||||
Address originatingAddress() const {return _originatingAddress;}
|
||||
unsigned char protocolIdentifier() const {return _protocolIdentifier;}
|
||||
Timestamp serviceCentreTimestamp() const {return _serviceCentreTimestamp;}
|
||||
|
||||
void setMoreMessagesToSend(bool x) {_moreMessagesToSend = x;}
|
||||
void setReplyPath(bool x) {_replyPath = x;}
|
||||
void setStatusReportIndication(bool x) {_statusReportIndication = x;}
|
||||
void setOriginatingAddress(Address &x) {_originatingAddress = x;}
|
||||
void setProtocolIdentifier(unsigned char x) {_protocolIdentifier = x;}
|
||||
void setServiceCentreTimestamp(Timestamp &x) {_serviceCentreTimestamp = x;}
|
||||
|
||||
virtual ~SMSDeliverMessage() {}
|
||||
};
|
||||
|
||||
// SMS-SUBMIT TPDU
|
||||
class SMSSubmitMessage : public SMSMessage
|
||||
{
|
||||
private:
|
||||
// SMS-SUBMIT PDU (see GSM 03.40 section 9.2.2.2)
|
||||
bool _rejectDuplicates;
|
||||
TimePeriod::Format _validityPeriodFormat; // 2 bits
|
||||
bool _replyPath;
|
||||
bool _statusReportRequest;
|
||||
unsigned char _messageReference; // integer
|
||||
Address _destinationAddress;
|
||||
unsigned char _protocolIdentifier;
|
||||
TimePeriod _validityPeriod;
|
||||
|
||||
// initialize members to sensible values
|
||||
void init();
|
||||
|
||||
public:
|
||||
// constructor, sets sensible default values
|
||||
SMSSubmitMessage();
|
||||
|
||||
// constructor with given pdu
|
||||
SMSSubmitMessage(string pdu) throw(GsmException);
|
||||
|
||||
// convenience constructor
|
||||
// given the text and recipient telephone number
|
||||
SMSSubmitMessage(string text, string number);
|
||||
|
||||
// encode pdu, return hexadecimal pdu string
|
||||
virtual string encode();
|
||||
|
||||
// create textual representation of SMS
|
||||
virtual string toString() const;
|
||||
|
||||
// inherited from SMSMessage
|
||||
Address address() const;
|
||||
Ref<SMSMessage> clone();
|
||||
|
||||
// accessor functions
|
||||
bool rejectDuplicates() const {return _rejectDuplicates;}
|
||||
TimePeriod::Format validityPeriodFormat() const
|
||||
{return _validityPeriodFormat;}
|
||||
bool replyPath() const {return _replyPath;}
|
||||
bool statusReportRequest() const {return _statusReportRequest;}
|
||||
unsigned char messageReference() const {return _messageReference;}
|
||||
Address destinationAddress() const {return _destinationAddress;}
|
||||
unsigned char protocolIdentifier() const {return _protocolIdentifier;}
|
||||
TimePeriod validityPeriod() const {return _validityPeriod;}
|
||||
|
||||
void setRejectDuplicates(bool x) {_rejectDuplicates = x;}
|
||||
void setValidityPeriodFormat(TimePeriod::Format &x)
|
||||
{_validityPeriodFormat = x;}
|
||||
void setReplyPath(bool x) {_replyPath = x;}
|
||||
void setStatusReportRequest(bool x) {_statusReportRequest = x;}
|
||||
void setMessageReference(unsigned char x) {_messageReference = x;}
|
||||
void setDestinationAddress(Address &x) {_destinationAddress = x;}
|
||||
void setProtocolIdentifier(unsigned char x) {_protocolIdentifier = x;}
|
||||
void setValidityPeriod(TimePeriod &x) {_validityPeriod = x;}
|
||||
|
||||
virtual ~SMSSubmitMessage() {}
|
||||
};
|
||||
|
||||
// SMS-STATUS-REPORT TPDU
|
||||
class SMSStatusReportMessage : public SMSMessage
|
||||
{
|
||||
private:
|
||||
// SMS-STATUS-REPORT PDU (see GSM 03.40 section 9.2.2.3)
|
||||
bool _moreMessagesToSend;
|
||||
bool _statusReportQualifier;
|
||||
unsigned char _messageReference;
|
||||
Address _recipientAddress;
|
||||
Timestamp _serviceCentreTimestamp;
|
||||
Timestamp _dischargeTime;
|
||||
unsigned char _status; // octet
|
||||
|
||||
// initialize members to sensible values
|
||||
void init();
|
||||
|
||||
public:
|
||||
// constructor, sets sensible default values
|
||||
SMSStatusReportMessage() {init();}
|
||||
|
||||
// constructor with given pdu
|
||||
SMSStatusReportMessage(string pdu) throw(GsmException);
|
||||
|
||||
// encode pdu, return hexadecimal pdu string
|
||||
virtual string encode();
|
||||
|
||||
// create textual representation of SMS
|
||||
virtual string toString() const;
|
||||
|
||||
// inherited from SMSMessage
|
||||
Address address() const;
|
||||
Ref<SMSMessage> clone();
|
||||
|
||||
// accessor functions
|
||||
bool moreMessagesToSend() const {return _moreMessagesToSend;}
|
||||
bool statusReportQualifier() const {return _statusReportQualifier;}
|
||||
unsigned char messageReference() const {return _messageReference;}
|
||||
Address recipientAddress() const {return _recipientAddress;}
|
||||
Timestamp serviceCentreTimestamp() const {return _serviceCentreTimestamp;}
|
||||
Timestamp dischargeTime() const {return _dischargeTime;}
|
||||
unsigned char status() const {return _status;}
|
||||
|
||||
void setMoreMessagesToSend(bool x) {_moreMessagesToSend = x;}
|
||||
void setStatusReportQualifier(bool x) {_statusReportQualifier = x;}
|
||||
void setMessageReference(unsigned char x) {_messageReference = x;}
|
||||
void setRecipientAddress(Address x) {_recipientAddress = x;}
|
||||
void setServiceCentreTimestamp(Timestamp x) {_serviceCentreTimestamp = x;}
|
||||
void setDischargeTime(Timestamp x) {_serviceCentreTimestamp = x;}
|
||||
void setStatus(unsigned char x) {_status = x;}
|
||||
|
||||
virtual ~SMSStatusReportMessage() {}
|
||||
};
|
||||
|
||||
// SMS-COMMAND TPDU
|
||||
class SMSCommandMessage : public SMSMessage
|
||||
{
|
||||
public:
|
||||
// command types, other values are reserved or SC-specific
|
||||
enum CommandType {EnquireSM = 0, CancelStatusReportRequest = 1,
|
||||
DeleteSubmittedSM = 2, EnalbeStatusReportRequest = 3};
|
||||
|
||||
private:
|
||||
// SMS-COMMAND PDU (see GSM 03.40 section 9.2.2.4)
|
||||
unsigned char _messageReference;
|
||||
bool _statusReportRequest;
|
||||
unsigned char _protocolIdentifier;
|
||||
unsigned char _commandType;
|
||||
unsigned char _messageNumber;
|
||||
Address _destinationAddress;
|
||||
unsigned char _commandDataLength;
|
||||
string _commandData;
|
||||
|
||||
// initialize members to sensible values
|
||||
void init();
|
||||
|
||||
public:
|
||||
// constructor, sets sensible default values
|
||||
SMSCommandMessage() {init();}
|
||||
|
||||
// constructor with given pdu
|
||||
SMSCommandMessage(string pdu) throw(GsmException);
|
||||
|
||||
// encode pdu, return hexadecimal pdu string
|
||||
virtual string encode();
|
||||
|
||||
// create textual representation of SMS
|
||||
virtual string toString() const;
|
||||
|
||||
// inherited from SMSMessage
|
||||
Address address() const;
|
||||
Ref<SMSMessage> clone();
|
||||
|
||||
// accessor functions
|
||||
unsigned char messageReference() const {return _messageReference;}
|
||||
bool statusReportRequest() const {return _statusReportRequest;}
|
||||
unsigned char protocolIdentifier() const {return _protocolIdentifier;}
|
||||
unsigned char commandType() const {return _commandType;}
|
||||
unsigned char messageNumber() const {return _messageNumber;}
|
||||
Address destinationAddress() const {return _destinationAddress;}
|
||||
unsigned char commandDataLength() const {return _commandDataLength;}
|
||||
string commandData() const {return _commandData;}
|
||||
|
||||
void setMessageReference(unsigned char x) {_messageReference = x;}
|
||||
void setStatusReportRequest(bool x) {_statusReportRequest = x;}
|
||||
void setProtocolIdentifier(unsigned char x) {_protocolIdentifier = x;}
|
||||
void setCommandType(unsigned char x) {_commandType = x;}
|
||||
void setMessageNumber(unsigned char x) {_messageNumber = x;}
|
||||
void setDestinationAddress(Address &x) {_destinationAddress = x;}
|
||||
void setCommandDataLength(unsigned char x) {_commandDataLength = x;}
|
||||
void setCommandData(string x) {_commandData = x;}
|
||||
|
||||
virtual ~SMSCommandMessage() {}
|
||||
};
|
||||
|
||||
// SMS-DELIVER-REPORT TPDU for RP-ACK
|
||||
class SMSDeliverReportMessage : public SMSMessage
|
||||
{
|
||||
private:
|
||||
// SMS-DELIVER-REPORT PDU (see GSM 03.40 section 9.2.2.1a (II))
|
||||
bool _protocolIdentifierPresent; // parameter indicator
|
||||
bool _dataCodingSchemePresent;
|
||||
bool _userDataLengthPresent;
|
||||
unsigned char _protocolIdentifier;
|
||||
|
||||
// initialize members to sensible values
|
||||
void init();
|
||||
|
||||
public:
|
||||
// constructor, sets sensible default values
|
||||
SMSDeliverReportMessage() {init();}
|
||||
|
||||
// constructor with given pdu
|
||||
SMSDeliverReportMessage(string pdu) throw(GsmException);
|
||||
|
||||
// encode pdu, return hexadecimal pdu string
|
||||
virtual string encode();
|
||||
|
||||
// create textual representation of SMS
|
||||
virtual string toString() const;
|
||||
|
||||
// inherited from SMSMessage
|
||||
Address address() const;
|
||||
Ref<SMSMessage> clone();
|
||||
|
||||
// accessor functions
|
||||
bool protocolIdentifierPresent() const {return _protocolIdentifierPresent;}
|
||||
bool dataCodingSchemePresent() const {return _dataCodingSchemePresent;}
|
||||
bool userDataLengthPresent() const {return _userDataLengthPresent;}
|
||||
unsigned char protocolIdentifier() const
|
||||
{assert(_protocolIdentifierPresent); return _protocolIdentifier;}
|
||||
DataCodingScheme dataCodingScheme() const
|
||||
{assert(_dataCodingSchemePresent); return _dataCodingScheme;}
|
||||
UserDataHeader userDataHeader() const
|
||||
{assert(_userDataLengthPresent); return _userDataHeader;}
|
||||
string userData() const
|
||||
{assert(_userDataLengthPresent); return _userData;}
|
||||
|
||||
void setProtocolIdentifier(unsigned char x)
|
||||
{_protocolIdentifierPresent = true; _protocolIdentifier = x;}
|
||||
void setDataCodingScheme(DataCodingScheme x)
|
||||
{_dataCodingSchemePresent = true; _dataCodingScheme = x;}
|
||||
void setUserDataHeader(UserDataHeader x)
|
||||
{
|
||||
_userDataLengthPresent = true;
|
||||
_userDataHeader = x;
|
||||
}
|
||||
void setUserData(string x)
|
||||
{
|
||||
_userDataLengthPresent = true;
|
||||
_userData = x;
|
||||
}
|
||||
|
||||
virtual ~SMSDeliverReportMessage() {}
|
||||
};
|
||||
|
||||
// SMS-SUBMIT-REPORT TPDU for RP-ACK
|
||||
class SMSSubmitReportMessage : public SMSMessage
|
||||
{
|
||||
private:
|
||||
// SMS-SUBMIT-REPORT PDU (see GSM 03.40 section 9.2.2.2a (II))
|
||||
Timestamp _serviceCentreTimestamp;
|
||||
bool _protocolIdentifierPresent; // parameter indicator
|
||||
bool _dataCodingSchemePresent;
|
||||
bool _userDataLengthPresent;
|
||||
unsigned char _protocolIdentifier;
|
||||
DataCodingScheme _dataCodingScheme;
|
||||
|
||||
// initialize members to sensible values
|
||||
void init();
|
||||
|
||||
public:
|
||||
// constructor, sets sensible default values
|
||||
SMSSubmitReportMessage() {init();}
|
||||
|
||||
// constructor with given pdu
|
||||
SMSSubmitReportMessage(string pdu) throw(GsmException);
|
||||
|
||||
// encode pdu, return hexadecimal pdu string
|
||||
virtual string encode();
|
||||
|
||||
// create textual representation of SMS
|
||||
virtual string toString() const;
|
||||
|
||||
// inherited from SMSMessage
|
||||
Address address() const;
|
||||
Ref<SMSMessage> clone();
|
||||
|
||||
// accessor functions
|
||||
Timestamp serviceCentreTimestamp() const {return _serviceCentreTimestamp;}
|
||||
bool protocolIdentifierPresent() const {return _protocolIdentifierPresent;}
|
||||
bool dataCodingSchemePresent() const {return _dataCodingSchemePresent;}
|
||||
bool userDataLengthPresent() const {return _userDataLengthPresent;}
|
||||
unsigned char protocolIdentifier() const
|
||||
{assert(_protocolIdentifierPresent); return _protocolIdentifier;}
|
||||
DataCodingScheme dataCodingScheme() const
|
||||
{assert(_dataCodingSchemePresent); return _dataCodingScheme;}
|
||||
UserDataHeader userDataHeader() const
|
||||
{assert(_userDataLengthPresent); return _userDataHeader;}
|
||||
string userData() const
|
||||
{assert(_userDataLengthPresent); return _userData;}
|
||||
|
||||
void setServiceCentreTimestamp(Timestamp &x) {_serviceCentreTimestamp = x;}
|
||||
void setProtocolIdentifier(unsigned char x)
|
||||
{_protocolIdentifierPresent = true; _protocolIdentifier = x;}
|
||||
void setDataCodingScheme(DataCodingScheme x)
|
||||
{_dataCodingSchemePresent = true; _dataCodingScheme = x;}
|
||||
void setUserDataHeader(UserDataHeader x)
|
||||
{
|
||||
_userDataLengthPresent = true;
|
||||
_userDataHeader = x;
|
||||
}
|
||||
void setUserData(string x)
|
||||
{
|
||||
_userDataLengthPresent = true;
|
||||
_userData = x;
|
||||
}
|
||||
virtual ~SMSSubmitReportMessage() {}
|
||||
};
|
||||
|
||||
// some useful typdefs
|
||||
typedef Ref<SMSMessage> SMSMessageRef;
|
||||
};
|
||||
|
||||
#endif // GSM_SMS_H
|
@ -0,0 +1,702 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_sms_codec.cc
|
||||
// *
|
||||
// * Purpose: Coder and Encoder for SMS TPDUs
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 17.5.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <gsm_config.h>
|
||||
#endif
|
||||
#include <gsmlib/gsm_nls.h>
|
||||
#include <gsmlib/gsm_sysdep.h>
|
||||
#include <gsmlib/gsm_sms_codec.h>
|
||||
#include <gsmlib/gsm_util.h>
|
||||
#include <time.h>
|
||||
#include <strstream>
|
||||
#include <iomanip>
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
#include <climits>
|
||||
#include <string>
|
||||
using namespace std;
|
||||
using namespace gsmlib;
|
||||
|
||||
// Address members
|
||||
|
||||
Address::Address(string number) : _plan(ISDN_Telephone)
|
||||
{
|
||||
number = removeWhiteSpace(number);
|
||||
if (number.length() > 0 && number[0] == '+')
|
||||
{
|
||||
_type = International;
|
||||
_number = number.substr(1, number.length() - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
_type = Unknown;
|
||||
_number = number;
|
||||
}
|
||||
}
|
||||
|
||||
string Address::toString() const
|
||||
{
|
||||
if (_type == International)
|
||||
return "+" + _number;
|
||||
else
|
||||
return _number;
|
||||
}
|
||||
|
||||
bool gsmlib::operator<(const Address &x, const Address &y)
|
||||
{
|
||||
// normalize numbers according to the following two rules:
|
||||
// - prepend "+" if international number
|
||||
// - append 0s to the shorter number so that both numbers have equal length
|
||||
string xnumber = x._number;
|
||||
string ynumber = y._number;
|
||||
static string twenty0s = "00000000000000000000";
|
||||
|
||||
if (x._type == Address::International) xnumber = "+" + xnumber;
|
||||
if (y._type == Address::International) ynumber = "+" + ynumber;
|
||||
|
||||
while (xnumber.length() != ynumber.length())
|
||||
if (xnumber.length() < ynumber.length())
|
||||
{
|
||||
int diff = ynumber.length() - xnumber.length();
|
||||
xnumber += twenty0s.substr(0, (diff > 20 ? 20 : diff));
|
||||
}
|
||||
else
|
||||
{
|
||||
int diff = xnumber.length() - ynumber.length();
|
||||
ynumber += twenty0s.substr(0, (diff > 20 ? 20 : diff));
|
||||
}
|
||||
|
||||
return xnumber < ynumber;
|
||||
}
|
||||
|
||||
bool gsmlib::operator==(const Address &x, const Address &y)
|
||||
{
|
||||
return x._number == y._number && x._plan == y._plan;
|
||||
}
|
||||
|
||||
// Timestamp members
|
||||
|
||||
bool Timestamp::empty() const
|
||||
{
|
||||
return _year == 0 && _month == 0 && _day == 0 && _hour == 0 &&
|
||||
_minute == 0 && _seconds == 0 && _timeZoneMinutes == 0;
|
||||
}
|
||||
|
||||
string Timestamp::toString(bool appendTimeZone) const
|
||||
{
|
||||
short timeZoneMinutes = _timeZoneMinutes;
|
||||
short timeZoneHours = timeZoneMinutes / 60;
|
||||
timeZoneMinutes %= 60;
|
||||
|
||||
// format date and time in a locale-specific way
|
||||
struct tm t;
|
||||
t.tm_sec = _seconds;
|
||||
t.tm_min = _minute;
|
||||
t.tm_hour = _hour;
|
||||
t.tm_mon = _month - 1;
|
||||
// year 2000 heuristics, SMSs cannot be older than start of GSM network
|
||||
t.tm_year = _year < 80 ? _year + 100 : _year;
|
||||
t.tm_mday = _day;
|
||||
t.tm_isdst = -1;
|
||||
t.tm_yday = 0;
|
||||
t.tm_wday = 0;
|
||||
|
||||
#ifdef BROKEN_STRFTIME
|
||||
char formattedTime[1024];
|
||||
strftime(formattedTime, 1024, "%x %X", &t);
|
||||
#else
|
||||
int formattedTimeSize = strftime(NULL, INT_MAX, "%x %X", &t) + 1;
|
||||
char *formattedTime = (char*)alloca(sizeof(char) * formattedTimeSize);
|
||||
strftime(formattedTime, formattedTimeSize, "%x %X", &t);
|
||||
#endif
|
||||
|
||||
if (! appendTimeZone)
|
||||
return formattedTime;
|
||||
|
||||
ostrstream os;
|
||||
os << formattedTime << " (" << (_negativeTimeZone ? '-' : '+')
|
||||
<< setfill('0') << setw(2) << timeZoneHours
|
||||
<< setw(2) << timeZoneMinutes << ')' << ends;
|
||||
char *ss = os.str();
|
||||
string result(ss);
|
||||
delete[] ss;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool gsmlib::operator<(const Timestamp &x, const Timestamp &y)
|
||||
{
|
||||
// we don't take time zone info into account because
|
||||
// - it's more complicated to compute
|
||||
// - it might confuse the user for whom it's also too complicated
|
||||
if (x._year < y._year)
|
||||
return true;
|
||||
else if (x._year > y._year)
|
||||
return false;
|
||||
|
||||
if (x._month < y._month)
|
||||
return true;
|
||||
else if (x._month > y._month)
|
||||
return false;
|
||||
|
||||
if (x._day < y._day)
|
||||
return true;
|
||||
else if (x._day > y._day)
|
||||
return false;
|
||||
|
||||
if (x._hour < y._hour)
|
||||
return true;
|
||||
else if (x._hour > y._hour)
|
||||
return false;
|
||||
|
||||
if (x._minute < y._minute)
|
||||
return true;
|
||||
else if (x._minute > y._minute)
|
||||
return false;
|
||||
|
||||
return x._seconds < y._seconds;
|
||||
}
|
||||
|
||||
bool gsmlib::operator==(const Timestamp &x, const Timestamp &y)
|
||||
{
|
||||
// we don't take time zone info in order to be consistent with operator<
|
||||
return x._year == y._year && x._month == y._month && x._day == y._day &&
|
||||
x._hour == y._hour && x._minute == y._minute && x._seconds == y._seconds;
|
||||
}
|
||||
|
||||
// TimePeriod members
|
||||
|
||||
string TimePeriod::toString() const
|
||||
{
|
||||
switch (_format)
|
||||
{
|
||||
case NotPresent:
|
||||
return _("not present");
|
||||
case Relative:
|
||||
{
|
||||
ostrstream os;
|
||||
if (_relativeTime <= 143)
|
||||
os << ((int)_relativeTime + 1) * 5 << _(" minutes");
|
||||
else if (_relativeTime <= 167)
|
||||
os << 12 * 60 + ((int)_relativeTime - 143) * 30 << _(" minutes");
|
||||
else if (_relativeTime <= 196)
|
||||
os << (int)_relativeTime - 166 << _(" days");
|
||||
else if (_relativeTime <= 143)
|
||||
os << (int)_relativeTime - 192 << _(" weeks");
|
||||
os << ends;
|
||||
char *ss = os.str();
|
||||
string result(ss);
|
||||
delete[] ss;
|
||||
return result;
|
||||
}
|
||||
case Absolute:
|
||||
return _absoluteTime.toString();
|
||||
default:
|
||||
return _("unknown");
|
||||
}
|
||||
}
|
||||
|
||||
// DataCodingScheme members
|
||||
|
||||
string DataCodingScheme::toString() const
|
||||
{
|
||||
string result;
|
||||
if (compressed()) result += _("compressed ");
|
||||
if (messageWaitingIndication())
|
||||
switch (getMessageWaitingType())
|
||||
{
|
||||
case DCS_VOICEMAIL_MESSAGE_WAITING:
|
||||
result += _("voicemail message waiting");
|
||||
break;
|
||||
case DCS_FAX_MESSAGE_WAITING:
|
||||
result += _("fax message waiting");
|
||||
break;
|
||||
case DCS_ELECTRONIC_MAIL_MESSAGE_WAITING:
|
||||
result += _("electronic mail message waiting");
|
||||
break;
|
||||
case DCS_OTHER_MESSAGE_WAITING:
|
||||
result += _("other message waiting");
|
||||
break;
|
||||
}
|
||||
else
|
||||
switch (getAlphabet())
|
||||
{
|
||||
case DCS_DEFAULT_ALPHABET:
|
||||
result += _("default alphabet");
|
||||
break;
|
||||
case DCS_EIGHT_BIT_ALPHABET:
|
||||
result += _("8-bit alphabet");
|
||||
break;
|
||||
case DCS_SIXTEEN_BIT_ALPHABET:
|
||||
result += _("16-bit alphabet");
|
||||
break;
|
||||
case DCS_RESERVED_ALPHABET:
|
||||
result += _("reserved alphabet");
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// SMSDecoder members
|
||||
|
||||
SMSDecoder::SMSDecoder(string pdu) : _bi(0), _septetStart(NULL)
|
||||
{
|
||||
_p = new unsigned char[pdu.length() / 2];
|
||||
_op = _p;
|
||||
if (! hexToBuf(pdu, _p))
|
||||
throw GsmException(_("bad hexadecimal PDU format"), SMSFormatError);
|
||||
_maxop = _op + pdu.length() / 2;
|
||||
}
|
||||
|
||||
void SMSDecoder::alignOctet()
|
||||
{
|
||||
if (_bi != 0)
|
||||
{
|
||||
_bi = 0;
|
||||
++_op;
|
||||
}
|
||||
}
|
||||
|
||||
void SMSDecoder::alignSeptet()
|
||||
{
|
||||
assert(_septetStart != NULL);
|
||||
while (((_op - _septetStart) * 8 + _bi) % 7 != 0) getBit();
|
||||
}
|
||||
|
||||
unsigned char SMSDecoder::get2Bits()
|
||||
{
|
||||
unsigned char result = getBit();
|
||||
return result | (getBit() << 1);
|
||||
}
|
||||
|
||||
unsigned char SMSDecoder::getOctet()
|
||||
{
|
||||
alignOctet();
|
||||
if (_op >= _maxop)
|
||||
throw GsmException(_("premature end of PDU"), SMSFormatError);
|
||||
return *_op++;
|
||||
}
|
||||
|
||||
void SMSDecoder::getOctets(unsigned char* octets, unsigned short length)
|
||||
{
|
||||
alignOctet();
|
||||
for (unsigned short i = 0; i < length; ++i)
|
||||
{
|
||||
if (_op >= _maxop)
|
||||
throw GsmException(_("premature end of PDU"), SMSFormatError);
|
||||
*octets++ = *_op++;
|
||||
}
|
||||
}
|
||||
|
||||
string SMSDecoder::getSemiOctets(unsigned short length)
|
||||
{
|
||||
string result;
|
||||
result.reserve(length);
|
||||
alignOctet();
|
||||
for (unsigned short i = 0; i < length; ++i)
|
||||
{
|
||||
if (_bi == 0)
|
||||
{
|
||||
if (_op >= _maxop)
|
||||
throw GsmException(_("premature end of PDU"), SMSFormatError);
|
||||
// bits 0..3 are most significant
|
||||
result += '0' + (*_op & 0xf);
|
||||
_bi = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_op >= _maxop)
|
||||
throw GsmException(_("premature end of PDU"), SMSFormatError);
|
||||
// bits 4..7 are least significant, skip 0xf digit
|
||||
if ((*_op & 0xf0) != 0xf0)
|
||||
result += '0' + (*_op >> 4);
|
||||
_bi = 0;
|
||||
++_op;
|
||||
}
|
||||
}
|
||||
alignOctet();
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned long SMSDecoder::getSemiOctetsInteger(unsigned short length)
|
||||
{
|
||||
unsigned long result = 0;
|
||||
alignOctet();
|
||||
for (unsigned short i = 0; i < length; ++i)
|
||||
{
|
||||
if (_bi == 0)
|
||||
{
|
||||
if (_op >= _maxop)
|
||||
throw GsmException(_("premature end of PDU"), SMSFormatError);
|
||||
// bits 0..3 are most significant
|
||||
result = result * 10 + (*_op & 0xf);
|
||||
_bi = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_op >= _maxop)
|
||||
throw GsmException(_("premature end of PDU"), SMSFormatError);
|
||||
// bits 4..7 are least significant, skip 0xf digit
|
||||
if ((*_op & 0xf0) != 0xf0)
|
||||
result = result * 10 + (*_op >> 4);
|
||||
_bi = 0;
|
||||
++_op;
|
||||
}
|
||||
}
|
||||
alignOctet();
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned long SMSDecoder::getTimeZone(bool &negativeTimeZone)
|
||||
{
|
||||
unsigned long result = 0;
|
||||
alignOctet();
|
||||
for (unsigned short i = 0; i < 2; ++i)
|
||||
{
|
||||
if (_bi == 0)
|
||||
{
|
||||
if (_op >= _maxop)
|
||||
throw GsmException(_("premature end of PDU"), SMSFormatError);
|
||||
// bits 0..3 are most significant
|
||||
if (i == 0)
|
||||
{ // get sign
|
||||
result = result * 10 + (*_op & 0x7);
|
||||
negativeTimeZone = (*_op & 0x8 == 0);
|
||||
}
|
||||
else
|
||||
result = result * 10 + (*_op & 0xf);
|
||||
_bi = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_op >= _maxop)
|
||||
throw GsmException(_("premature end of PDU"), SMSFormatError);
|
||||
// bits 4..7 are least significant
|
||||
result = result * 10 + (*_op >> 4);
|
||||
_bi = 0;
|
||||
++_op;
|
||||
}
|
||||
}
|
||||
alignOctet();
|
||||
return result * 15; // compute minutes
|
||||
}
|
||||
|
||||
unsigned long SMSDecoder::getInteger(unsigned short length)
|
||||
{
|
||||
unsigned long result = 0;
|
||||
for (unsigned short i = 0; i < length; ++i)
|
||||
result |= (getBit() << i);
|
||||
return result;
|
||||
}
|
||||
|
||||
string SMSDecoder::getString(unsigned short length)
|
||||
{
|
||||
string result;
|
||||
alignSeptet();
|
||||
for (unsigned short i = 0; i < length; ++i)
|
||||
{
|
||||
unsigned char c = 0;
|
||||
for (unsigned short j = 0; j < 7; ++j)
|
||||
c |= getBit() << j;
|
||||
result += c;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Address SMSDecoder::getAddress(bool scAddressFormat)
|
||||
{
|
||||
Address result;
|
||||
alignOctet();
|
||||
|
||||
unsigned char addressLength = getOctet();
|
||||
if (addressLength == 0 && scAddressFormat)
|
||||
return result; // special case for SUBMIT-PDUs
|
||||
|
||||
// parse Type-of-Address
|
||||
result._plan = (Address::NumberingPlan)getInteger(4);
|
||||
result._type = (Address::Type)getInteger(3);
|
||||
|
||||
// get address
|
||||
if (result._type == Address::Alphanumeric)
|
||||
{
|
||||
markSeptet();
|
||||
// addressLength is number of semi-octets
|
||||
// (addressLength / 2) * 8 is number of available bits
|
||||
// divided by 7 is number of 7-bit characters
|
||||
result._number = gsmToLatin1(getString(addressLength * 4 / 7));
|
||||
alignOctet();
|
||||
}
|
||||
else
|
||||
result._number = getSemiOctets(scAddressFormat ?
|
||||
(addressLength - 1) * 2 : addressLength);
|
||||
return result;
|
||||
}
|
||||
|
||||
Timestamp SMSDecoder::getTimestamp()
|
||||
{
|
||||
Timestamp result;
|
||||
|
||||
result._year = getSemiOctetsInteger(2);
|
||||
result._month = getSemiOctetsInteger(2);
|
||||
result._day = getSemiOctetsInteger(2);
|
||||
result._hour = getSemiOctetsInteger(2);
|
||||
result._minute = getSemiOctetsInteger(2);
|
||||
result._seconds = getSemiOctetsInteger(2);
|
||||
result._timeZoneMinutes = getTimeZone(result._negativeTimeZone);
|
||||
return result;
|
||||
}
|
||||
|
||||
TimePeriod SMSDecoder::getTimePeriod(TimePeriod::Format format)
|
||||
{
|
||||
TimePeriod result;
|
||||
result._format = format;
|
||||
switch (format)
|
||||
{
|
||||
case TimePeriod::NotPresent:
|
||||
break;
|
||||
case TimePeriod::Relative:
|
||||
result._relativeTime = getOctet();
|
||||
break;
|
||||
case TimePeriod::Absolute:
|
||||
result._absoluteTime = getTimestamp();
|
||||
break;
|
||||
default:
|
||||
throw GsmException(_("unknown time period format"), SMSFormatError);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
SMSDecoder::~SMSDecoder()
|
||||
{
|
||||
delete _p;
|
||||
}
|
||||
|
||||
// SMSEncoder members
|
||||
|
||||
SMSEncoder::SMSEncoder() : _bi(0), _op(_p)
|
||||
{
|
||||
memset((void*)_p, 0, sizeof(_p));
|
||||
}
|
||||
|
||||
void SMSEncoder::alignOctet()
|
||||
{
|
||||
if (_bi != 0)
|
||||
{
|
||||
_bi = 0;
|
||||
++_op;
|
||||
}
|
||||
}
|
||||
|
||||
void SMSEncoder::alignSeptet()
|
||||
{
|
||||
while (((_op - _septetStart) * 8 + _bi) % 7 != 0) setBit();
|
||||
}
|
||||
|
||||
void SMSEncoder::set2Bits(unsigned char twoBits)
|
||||
{
|
||||
setBit(twoBits & 1);
|
||||
setBit((twoBits & 2) == 2);
|
||||
}
|
||||
|
||||
void SMSEncoder::setOctet(unsigned char octet)
|
||||
{
|
||||
alignOctet();
|
||||
*_op++ = octet;
|
||||
}
|
||||
|
||||
void SMSEncoder::setOctets(const unsigned char* octets, unsigned short length)
|
||||
{
|
||||
alignOctet();
|
||||
for (unsigned short i = 0; i < length; ++i)
|
||||
*_op++ = octets[i];
|
||||
}
|
||||
|
||||
void SMSEncoder::setSemiOctets(string semiOctets)
|
||||
{
|
||||
alignOctet();
|
||||
for (unsigned int i = 0; i < semiOctets.length(); ++i)
|
||||
{
|
||||
if (_bi == 0)
|
||||
{
|
||||
*_op = semiOctets[i] - '0';
|
||||
_bi = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
*_op++ |= (semiOctets[i] - '0') << 4;
|
||||
_bi = 0;
|
||||
}
|
||||
}
|
||||
if (_bi == 4)
|
||||
*_op++ |= 0xf0;
|
||||
_bi = 0;
|
||||
}
|
||||
|
||||
void SMSEncoder::setSemiOctetsInteger(unsigned long intValue,
|
||||
unsigned short length)
|
||||
{
|
||||
ostrstream os;
|
||||
os << intValue << ends;
|
||||
char *ss = os.str();
|
||||
string s(ss);
|
||||
delete[] ss;
|
||||
assert(s.length() <= length);
|
||||
while (s.length() < length) s = '0' + s;
|
||||
setSemiOctets(s);
|
||||
}
|
||||
|
||||
void SMSEncoder::setTimeZone(bool negativeTimeZone, unsigned long timeZone)
|
||||
{
|
||||
setSemiOctetsInteger(timeZone / 15, 2);
|
||||
if (!negativeTimeZone)
|
||||
*(_op - 1) |= 8;
|
||||
}
|
||||
|
||||
void SMSEncoder::setInteger(unsigned long intvalue, unsigned short length)
|
||||
{
|
||||
for (unsigned short i = 0; i < length; ++i)
|
||||
setBit((intvalue & (1 << i)) != 0);
|
||||
}
|
||||
|
||||
void SMSEncoder::setString(string stringValue)
|
||||
{
|
||||
alignSeptet();
|
||||
for (unsigned int i = 0; i < stringValue.length(); ++i)
|
||||
{
|
||||
unsigned char c = stringValue[i];
|
||||
for (unsigned short j = 0; j < 7; ++j)
|
||||
setBit(((1 << j) & c) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
void SMSEncoder::setAddress(Address &address, bool scAddressFormat)
|
||||
{
|
||||
alignOctet();
|
||||
if (scAddressFormat)
|
||||
{
|
||||
unsigned int numberLen = address._number.length();
|
||||
if (numberLen == 0)
|
||||
{
|
||||
setOctet(0); // special case: use default SC address
|
||||
return; // (set by +CSCA=)
|
||||
}
|
||||
setOctet(numberLen / 2 + numberLen % 2 + 1);
|
||||
// not supported for SCA format
|
||||
assert(address._type != Address::Alphanumeric);
|
||||
}
|
||||
else
|
||||
if (address._type == Address::Alphanumeric)
|
||||
// address in GSM default encoding, see also comment in getAddress()
|
||||
setOctet((address._number.length() * 7 + 6) / 8 * 2);
|
||||
else
|
||||
setOctet(address._number.length());
|
||||
|
||||
setInteger(address._plan, 4);
|
||||
setInteger(address._type, 3);
|
||||
setBit(1);
|
||||
|
||||
if (address._number.length() > 0)
|
||||
if (address._type == Address::Alphanumeric)
|
||||
{
|
||||
markSeptet();
|
||||
setString(latin1ToGsm(address._number));
|
||||
}
|
||||
else
|
||||
setSemiOctets(address._number);
|
||||
alignOctet();
|
||||
}
|
||||
|
||||
void SMSEncoder::setTimestamp(Timestamp timestamp)
|
||||
{
|
||||
setSemiOctetsInteger(timestamp._year, 2);
|
||||
setSemiOctetsInteger(timestamp._month, 2);
|
||||
setSemiOctetsInteger(timestamp._day, 2);
|
||||
setSemiOctetsInteger(timestamp._hour, 2);
|
||||
setSemiOctetsInteger(timestamp._minute, 2);
|
||||
setSemiOctetsInteger(timestamp._seconds, 2);
|
||||
setTimeZone(timestamp._negativeTimeZone, timestamp._timeZoneMinutes);
|
||||
}
|
||||
|
||||
void SMSEncoder::setTimePeriod(TimePeriod period)
|
||||
{
|
||||
switch (period._format)
|
||||
{
|
||||
case TimePeriod::NotPresent:
|
||||
break;
|
||||
case TimePeriod::Relative:
|
||||
setOctet(period._relativeTime);
|
||||
break;
|
||||
case TimePeriod::Absolute:
|
||||
setTimestamp(period._absoluteTime);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
string SMSEncoder::getHexString()
|
||||
{
|
||||
short bi = _bi;
|
||||
unsigned char *op = _op;
|
||||
alignOctet();
|
||||
string result = bufToHex(_p, _op - _p);
|
||||
_bi = bi;
|
||||
_op = op;
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned int SMSEncoder::getLength()
|
||||
{
|
||||
short bi = _bi;
|
||||
unsigned char *op = _op;
|
||||
alignOctet();
|
||||
unsigned int result = _op - _p;
|
||||
_bi = bi;
|
||||
_op = op;
|
||||
return result;
|
||||
}
|
||||
|
||||
// UserDataHeader members
|
||||
|
||||
void UserDataHeader::encode(SMSEncoder &e)
|
||||
{
|
||||
e.setOctet(_udh.length());
|
||||
e.setOctets((unsigned char*)_udh.data(), _udh.length());
|
||||
}
|
||||
|
||||
void UserDataHeader::decode(SMSDecoder &d)
|
||||
{
|
||||
unsigned char udhLen = d.getOctet();
|
||||
unsigned char *s =
|
||||
(unsigned char*)alloca(sizeof(unsigned char) * udhLen);
|
||||
d.getOctets(s, udhLen);
|
||||
string ss((char*)s, (unsigned int)udhLen);
|
||||
_udh = ss;
|
||||
}
|
||||
|
||||
string UserDataHeader::getIE(unsigned char id)
|
||||
{
|
||||
int udhl, pos = 0;
|
||||
|
||||
udhl = _udh.length();
|
||||
while (pos < udhl)
|
||||
{
|
||||
unsigned char iei = _udh[pos++];
|
||||
unsigned char ieidl = _udh[pos++];
|
||||
if (iei == id) return _udh.substr(pos, ieidl);
|
||||
pos += ieidl;
|
||||
}
|
||||
return "";
|
||||
}
|
@ -0,0 +1,329 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_sms_codec.h
|
||||
// *
|
||||
// * Purpose: Coder and Encoder for SMS TPDUs
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 16.5.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifndef GSM_SMS_CODEC_H
|
||||
#define GSM_SMS_CODEC_H
|
||||
|
||||
#include <string>
|
||||
#include <assert.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gsmlib
|
||||
{
|
||||
// this struct represents a telephone number
|
||||
// usually _type == Unknown or International
|
||||
// and _number == ISDN_Telephone
|
||||
struct Address
|
||||
{
|
||||
enum Type {Unknown = 0, International = 1, National = 2,
|
||||
NetworkSpecific = 3, Subscriber = 4,
|
||||
Alphanumeric = 5, Abbreviated = 6, Reserved = 7};
|
||||
enum NumberingPlan {UnknownPlan = 0, ISDN_Telephone = 1,
|
||||
Data = 3, Telex = 4, NationalPlan = 8,
|
||||
PrivatePlan = 9, Ermes = 10, ReservedPlan = 15};
|
||||
Type _type;
|
||||
NumberingPlan _plan;
|
||||
string _number;
|
||||
|
||||
Address() : _type(Unknown), _plan(UnknownPlan) {}
|
||||
// the constructor sets _type and _plan to defaults
|
||||
// _plan == ISDN_Telephone
|
||||
// _type == International if number starts with "+"
|
||||
// _type == unknown otherwise
|
||||
// number must be of the form "+123456" or "123456"
|
||||
Address(string number);
|
||||
|
||||
// return string representation
|
||||
string toString() const;
|
||||
|
||||
friend bool operator<(const Address &x, const Address &y);
|
||||
friend bool operator==(const Address &x, const Address &y);
|
||||
};
|
||||
|
||||
// compare two addresses
|
||||
extern bool operator<(const Address &x, const Address &y);
|
||||
extern bool operator==(const Address &x, const Address &y);
|
||||
|
||||
// representation of a SMS timestamp
|
||||
struct Timestamp
|
||||
{
|
||||
short _year, _month, _day, _hour, _minute, _seconds, _timeZoneMinutes;
|
||||
bool _negativeTimeZone;
|
||||
|
||||
Timestamp() : _year(0), _month(0), _day(0), _hour(0),
|
||||
_minute(0), _seconds(0), _timeZoneMinutes(0), _negativeTimeZone(false) {}
|
||||
|
||||
// return true if the time stamp is empty (ie. contains only zeroes)
|
||||
bool empty() const;
|
||||
|
||||
// return string representation
|
||||
string toString(bool appendTimeZone = true) const;
|
||||
|
||||
friend bool operator<(const Timestamp &x, const Timestamp &y);
|
||||
friend bool operator==(const Timestamp &x, const Timestamp &y);
|
||||
};
|
||||
|
||||
// compare two timestamps
|
||||
extern bool operator<(const Timestamp &x, const Timestamp &y);
|
||||
extern bool operator==(const Timestamp &x, const Timestamp &y);
|
||||
|
||||
// representation of time period
|
||||
struct TimePeriod
|
||||
{
|
||||
// possible values for validity period format
|
||||
enum Format {NotPresent = 0, Relative = 2, Absolute = 3};
|
||||
Format _format;
|
||||
Timestamp _absoluteTime;
|
||||
unsigned char _relativeTime;
|
||||
|
||||
TimePeriod() : _format(NotPresent), _relativeTime(0) {}
|
||||
|
||||
// return string representation (already translated)
|
||||
string toString() const;
|
||||
};
|
||||
|
||||
// representation of DataCodingScheme
|
||||
// the data coding scheme is described in detail in ETSI GSM 03.38, section 4
|
||||
const unsigned char DCS_COMPRESSED = 0x20; // bit 5
|
||||
|
||||
const unsigned char DCS_DEFAULT_ALPHABET = 0 << 2; // bit 2..3 == 0
|
||||
const unsigned char DCS_EIGHT_BIT_ALPHABET = 1 << 2; // bit 2..3 == 01
|
||||
const unsigned char DCS_SIXTEEN_BIT_ALPHABET = 2 << 2; // bit 2..3 == 10
|
||||
const unsigned char DCS_RESERVED_ALPHABET = 3 << 2; // bit 2..3 == 11
|
||||
|
||||
const unsigned char DCS_MESSAGE_WAITING_INDICATION = 0xc0; // bit 7..6 == 11
|
||||
const unsigned char DCS_VOICEMAIL_MESSAGE_WAITING = 0;
|
||||
const unsigned char DCS_FAX_MESSAGE_WAITING = 1;
|
||||
const unsigned char DCS_ELECTRONIC_MAIL_MESSAGE_WAITING = 2;
|
||||
const unsigned char DCS_OTHER_MESSAGE_WAITING = 3;
|
||||
|
||||
class DataCodingScheme
|
||||
{
|
||||
private:
|
||||
unsigned char _dcs;
|
||||
|
||||
public:
|
||||
// initialize with data coding scheme octet
|
||||
DataCodingScheme(unsigned char dcs) : _dcs(dcs) {}
|
||||
|
||||
// set to default values (no message waiting, no message class indication,
|
||||
// default 7-bit alphabet)
|
||||
DataCodingScheme() : _dcs(DCS_DEFAULT_ALPHABET) {}
|
||||
|
||||
// return type of alphabet used (if messageWaitingIndication == false)
|
||||
unsigned char getAlphabet() const {return _dcs & (3 << 2);}
|
||||
|
||||
// return true if message compressed
|
||||
// (if messageWaitingIndication == false)
|
||||
bool compressed() const {return _dcs & DCS_COMPRESSED == DCS_COMPRESSED;}
|
||||
|
||||
// return true if message waiting indication
|
||||
bool messageWaitingIndication() const
|
||||
{return _dcs & DCS_MESSAGE_WAITING_INDICATION ==
|
||||
DCS_MESSAGE_WAITING_INDICATION;}
|
||||
|
||||
// return type of waiting message (if messageWaitingIndication == true)
|
||||
unsigned char getMessageWaitingType() const {return _dcs & 3;}
|
||||
|
||||
// return string representation (already translated)
|
||||
string toString() const;
|
||||
|
||||
operator unsigned char() const {return _dcs;}
|
||||
};
|
||||
|
||||
// utility class facilitate SMS TPDU decoding
|
||||
class SMSDecoder
|
||||
{
|
||||
private:
|
||||
unsigned char *_p; // buffer to hold pdu
|
||||
short _bi; // bit index (0..7)
|
||||
unsigned char *_op; // current octet pointer
|
||||
unsigned char *_septetStart; // start of septet string
|
||||
|
||||
unsigned char *_maxop; // pointer to last byte after _p
|
||||
|
||||
public:
|
||||
// initialize with a hexadecimal octet string containing SMS TPDU
|
||||
SMSDecoder(string pdu);
|
||||
|
||||
// align to octet border
|
||||
void alignOctet();
|
||||
|
||||
// remember starting point of septets (important for alignSeptet())
|
||||
void markSeptet() {alignOctet(); _septetStart = _op;}
|
||||
|
||||
// align to septet border
|
||||
void alignSeptet();
|
||||
|
||||
// get single bit
|
||||
bool getBit()
|
||||
{
|
||||
assert(_op < _maxop);
|
||||
bool result = ((*_op >> _bi) & 1);
|
||||
if (_bi == 7)
|
||||
{
|
||||
_bi = 0;
|
||||
++_op;
|
||||
}
|
||||
else
|
||||
++_bi;
|
||||
return result;
|
||||
}
|
||||
|
||||
// get two bits
|
||||
unsigned char get2Bits();
|
||||
|
||||
// get one octet
|
||||
unsigned char getOctet();
|
||||
|
||||
// get string of octets of specified length
|
||||
void getOctets(unsigned char* octets, unsigned short length);
|
||||
|
||||
// get length semi-octets (bcd-coded number) as ASCII string of numbers
|
||||
string getSemiOctets(unsigned short length);
|
||||
|
||||
// get length semi-octets (bcd-coded number) as integer
|
||||
unsigned long getSemiOctetsInteger(unsigned short length);
|
||||
|
||||
// get time zone (in minutes) and time zone sign
|
||||
unsigned long getTimeZone(bool &negativeTimeZone);
|
||||
|
||||
// get integer with length number of bits
|
||||
unsigned long getInteger(unsigned short length);
|
||||
|
||||
// get length number of alphanumeric 7-bit characters
|
||||
// markSeptet() must be called before this function
|
||||
string getString(unsigned short length);
|
||||
|
||||
// get address/telephone number
|
||||
// service centre address has special format
|
||||
Address getAddress(bool scAddressFormat = false);
|
||||
|
||||
// get Timestamp
|
||||
Timestamp getTimestamp();
|
||||
|
||||
// get TimePeriod of given format
|
||||
TimePeriod getTimePeriod(TimePeriod::Format format);
|
||||
|
||||
// destructor
|
||||
~SMSDecoder();
|
||||
};
|
||||
|
||||
// utility class for SMS TPDU encoding
|
||||
class SMSEncoder
|
||||
{
|
||||
private:
|
||||
unsigned char _p[2000]; // buffer to hold pdu (2000 should be enough)
|
||||
short _bi; // bit index (0..7)
|
||||
unsigned char *_op; // current octet pointer
|
||||
unsigned char *_septetStart; // start of septet string
|
||||
|
||||
public:
|
||||
// constructor
|
||||
SMSEncoder();
|
||||
|
||||
// align to octet border
|
||||
void alignOctet();
|
||||
|
||||
// remember starting point of septets (important for alignSeptet())
|
||||
void markSeptet() {alignOctet(); _septetStart = _op;}
|
||||
|
||||
// align to septet border
|
||||
void alignSeptet();
|
||||
|
||||
// set single bit
|
||||
void setBit(bool bit = false)
|
||||
{
|
||||
if (bit)
|
||||
*_op |= (1 << _bi);
|
||||
if (_bi == 7)
|
||||
{
|
||||
_bi = 0;
|
||||
++_op;
|
||||
}
|
||||
else
|
||||
++_bi;
|
||||
}
|
||||
|
||||
// set two bits
|
||||
void set2Bits(unsigned char twoBits);
|
||||
|
||||
// set one octet
|
||||
void setOctet(unsigned char octet);
|
||||
|
||||
// set string of octets of specified length
|
||||
void setOctets(const unsigned char* octets, unsigned short length);
|
||||
|
||||
// set semi-octets semiOctets (given as ASCII string of numbers)
|
||||
void setSemiOctets(string semiOctets);
|
||||
|
||||
// set semi-octets (given as integer)
|
||||
void setSemiOctetsInteger(unsigned long intValue, unsigned short length);
|
||||
|
||||
// set time zone (in minutes) and time zone sign
|
||||
void setTimeZone(bool negativeTimeZone, unsigned long timeZone);
|
||||
|
||||
// set integer with length number of bits
|
||||
void setInteger(unsigned long intvalue, unsigned short length);
|
||||
|
||||
// set alphanumeric 7-bit characters
|
||||
void setString(string stringValue);
|
||||
|
||||
// set address/telephone number
|
||||
// service centre address has special format
|
||||
void setAddress(Address &address, bool scAddressFormat = false);
|
||||
|
||||
// set Timestamp
|
||||
void setTimestamp(Timestamp timestamp);
|
||||
|
||||
// set TimePeriod
|
||||
void setTimePeriod(TimePeriod period);
|
||||
|
||||
// return constructed TPDU as hex-encoded string
|
||||
string getHexString();
|
||||
|
||||
// return current length of TPDU
|
||||
unsigned int getLength();
|
||||
};
|
||||
|
||||
// class to handle user data header
|
||||
class UserDataHeader
|
||||
{
|
||||
private:
|
||||
string _udh;
|
||||
|
||||
public:
|
||||
// empty user data header
|
||||
UserDataHeader() {}
|
||||
|
||||
// initialize with user data header
|
||||
UserDataHeader (string udh) : _udh(udh) {}
|
||||
|
||||
// encode header
|
||||
void encode(SMSEncoder &e);
|
||||
|
||||
// decode header
|
||||
void decode(SMSDecoder &d);
|
||||
|
||||
// return a given information element, if present, or an empty string
|
||||
string getIE(unsigned char id);
|
||||
|
||||
// return the size of the header
|
||||
unsigned int length() const {return _udh.length();}
|
||||
|
||||
// return user data header as octet string
|
||||
operator string() const {return _udh;}
|
||||
};
|
||||
};
|
||||
|
||||
#endif // GSM_SMS_CODEC_H
|
@ -0,0 +1,489 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_sms_store.cc
|
||||
// *
|
||||
// * Purpose: SMS functions, SMS store
|
||||
// * (ETSI GSM 07.05)
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 20.5.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <gsm_config.h>
|
||||
#endif
|
||||
#include <gsmlib/gsm_sms_store.h>
|
||||
#include <gsmlib/gsm_parser.h>
|
||||
#include <gsmlib/gsm_me_ta.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace gsmlib;
|
||||
|
||||
// SMSStoreEntry members
|
||||
|
||||
SMSStoreEntry::SMSStoreEntry() :
|
||||
_status(Unknown), _cached(false), _mySMSStore(NULL), _index(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SMSMessageRef SMSStoreEntry::message() const throw(GsmException)
|
||||
{
|
||||
if (! cached())
|
||||
{
|
||||
assert(_mySMSStore != NULL);
|
||||
// these operations are at least "logically const"
|
||||
SMSStoreEntry *thisEntry = const_cast<SMSStoreEntry*>(this);
|
||||
_mySMSStore->readEntry(_index, thisEntry->_message, thisEntry->_status);
|
||||
thisEntry->_cached = true;
|
||||
}
|
||||
return _message;
|
||||
}
|
||||
|
||||
CBMessageRef SMSStoreEntry::cbMessage() const throw(GsmException)
|
||||
{
|
||||
assert(_mySMSStore != NULL);
|
||||
|
||||
// these operations are at least "logically const"
|
||||
SMSStoreEntry *thisEntry = const_cast<SMSStoreEntry*>(this);
|
||||
// don't cache CB message for now
|
||||
thisEntry->_cached = false;
|
||||
|
||||
CBMessageRef result;
|
||||
_mySMSStore->readEntry(_index, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
SMSStoreEntry::SMSMemoryStatus SMSStoreEntry::status() const
|
||||
throw(GsmException)
|
||||
{
|
||||
if (! cached())
|
||||
{
|
||||
assert(_mySMSStore != NULL);
|
||||
// these operations are at least "logically const"
|
||||
SMSStoreEntry *thisEntry = const_cast<SMSStoreEntry*>(this);
|
||||
_mySMSStore->readEntry(_index, thisEntry->_message, thisEntry->_status);
|
||||
thisEntry->_cached = true;
|
||||
}
|
||||
return _status;
|
||||
}
|
||||
|
||||
bool SMSStoreEntry::empty() const throw(GsmException)
|
||||
{
|
||||
return message().isnull();
|
||||
}
|
||||
|
||||
unsigned char SMSStoreEntry::send(Ref<SMSMessage> &ackPdu)
|
||||
throw(GsmException)
|
||||
{
|
||||
return _mySMSStore->send(_index, ackPdu);
|
||||
}
|
||||
|
||||
unsigned char SMSStoreEntry::send() throw(GsmException)
|
||||
{
|
||||
SMSMessageRef mref;
|
||||
return send(mref);
|
||||
}
|
||||
|
||||
bool SMSStoreEntry::cached() const
|
||||
{
|
||||
if (_mySMSStore == NULL)
|
||||
return _cached;
|
||||
else
|
||||
return _cached && _mySMSStore->_useCache;
|
||||
}
|
||||
|
||||
Ref<SMSStoreEntry> SMSStoreEntry::clone()
|
||||
{
|
||||
Ref<SMSStoreEntry> result = new SMSStoreEntry(_message->clone());
|
||||
result->_status = _status;
|
||||
result->_index = _index;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool SMSStoreEntry::operator==(const SMSStoreEntry &e) const
|
||||
{
|
||||
if (_message.isnull() || e._message.isnull())
|
||||
return _message.isnull() && e._message.isnull();
|
||||
else
|
||||
return _message->encode() == e._message->encode();
|
||||
}
|
||||
|
||||
SMSStoreEntry::SMSStoreEntry(const SMSStoreEntry &e)
|
||||
{
|
||||
_message = e._message;
|
||||
_status = e._status;
|
||||
_cached = e._cached;
|
||||
_mySMSStore = e._mySMSStore;
|
||||
_index = e._index;
|
||||
}
|
||||
|
||||
SMSStoreEntry &SMSStoreEntry::operator=(const SMSStoreEntry &e)
|
||||
{
|
||||
_message = e._message;
|
||||
_status = e._status;
|
||||
_cached = e._cached;
|
||||
_mySMSStore = e._mySMSStore;
|
||||
_index = e._index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// iterator members
|
||||
|
||||
SMSStoreEntry &SMSStoreIterator::operator*()
|
||||
{
|
||||
return (*_store)[_index];
|
||||
}
|
||||
|
||||
SMSStoreEntry *SMSStoreIterator::operator->()
|
||||
{
|
||||
return &(*_store)[_index];
|
||||
}
|
||||
|
||||
SMSStoreIterator::operator SMSStoreEntry*()
|
||||
{
|
||||
return &(*_store)[_index];
|
||||
}
|
||||
|
||||
SMSStoreIterator &SMSStoreIterator::operator=(const SMSStoreIterator &i)
|
||||
{
|
||||
_index = i._index;
|
||||
_store = i._store;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const SMSStoreEntry &SMSStoreConstIterator::operator*()
|
||||
{
|
||||
return (*_store)[_index];
|
||||
}
|
||||
|
||||
const SMSStoreEntry *SMSStoreConstIterator::operator->()
|
||||
{
|
||||
return &(*_store)[_index];
|
||||
}
|
||||
|
||||
// SMSStore members
|
||||
|
||||
void SMSStore::readEntry(int index, SMSMessageRef &message,
|
||||
SMSStoreEntry::SMSMemoryStatus &status)
|
||||
throw(GsmException)
|
||||
{
|
||||
// select SMS store
|
||||
_meTa.setSMSStore(_storeName, 1);
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (debugLevel() >= 1)
|
||||
cerr << "*** Reading SMS entry " << index << endl;
|
||||
#endif // NDEBUG
|
||||
|
||||
string pdu;
|
||||
Ref<Parser> p;
|
||||
try
|
||||
{
|
||||
p = new Parser(_at->chat("+CMGR=" + intToStr(index + 1), "+CMGR:",
|
||||
pdu, false, true, true));
|
||||
}
|
||||
catch (GsmException &ge)
|
||||
{
|
||||
if (ge.getErrorCode() != SMS_INVALID_MEMORY_INDEX)
|
||||
throw ge;
|
||||
else
|
||||
{
|
||||
message = SMSMessageRef();
|
||||
status = SMSStoreEntry::Unknown;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (pdu.length() == 0)
|
||||
{
|
||||
message = SMSMessageRef();
|
||||
status = SMSStoreEntry::Unknown;
|
||||
}
|
||||
else
|
||||
{
|
||||
// add missing service centre address if required by ME
|
||||
if (! _at->getMeTa().getCapabilities()._hasSMSSCAprefix)
|
||||
pdu = "00" + pdu;
|
||||
|
||||
status = (SMSStoreEntry::SMSMemoryStatus)p->parseInt();
|
||||
|
||||
// ignore the rest of the line
|
||||
message = SMSMessageRef(
|
||||
SMSMessage::decode(pdu,
|
||||
!(status == SMSStoreEntry::StoredUnsent ||
|
||||
status == SMSStoreEntry::StoredSent),
|
||||
_at.getptr()));
|
||||
}
|
||||
}
|
||||
|
||||
void SMSStore::readEntry(int index, CBMessageRef &message)
|
||||
throw(GsmException)
|
||||
{
|
||||
// select SMS store
|
||||
_meTa.setSMSStore(_storeName, 1);
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (debugLevel() >= 1)
|
||||
cerr << "*** Reading CB entry " << index << endl;
|
||||
#endif // NDEBUG
|
||||
|
||||
string pdu;
|
||||
Ref<Parser> p;
|
||||
try
|
||||
{
|
||||
// this is just one row splitted in two part
|
||||
// (msvc6 fail with internal compiler error)
|
||||
string s = _at->chat("+CMGR=" + intToStr(index + 1), "+CMGR:",
|
||||
pdu, false, true, true);
|
||||
p = new Parser(s);
|
||||
}
|
||||
catch (GsmException &ge)
|
||||
{
|
||||
if (ge.getErrorCode() != SMS_INVALID_MEMORY_INDEX)
|
||||
throw ge;
|
||||
else
|
||||
{
|
||||
message = CBMessageRef();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (pdu.length() == 0)
|
||||
message = CBMessageRef();
|
||||
else
|
||||
message = CBMessageRef(new CBMessage(pdu));
|
||||
}
|
||||
|
||||
void SMSStore::writeEntry(int &index, SMSMessageRef message)
|
||||
throw(GsmException)
|
||||
{
|
||||
// select SMS store
|
||||
_meTa.setSMSStore(_storeName, 2);
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (debugLevel() >= 1)
|
||||
cerr << "*** Writing SMS entry " << index << endl;
|
||||
#endif
|
||||
|
||||
// compute length of pdu
|
||||
string pdu = message->encode();
|
||||
|
||||
// set message status to "RECEIVED READ" for SMS_DELIVER, SMS_STATUS_REPORT
|
||||
string statusString;
|
||||
|
||||
// Normally the ",1" sets the message status to "REC READ" (received read)
|
||||
// which is appropriate for all non-submit messages
|
||||
// Motorola Timeport 260 does not like this code, though
|
||||
// DELIVER messages are magically recognized anyway
|
||||
if (message->messageType() != SMSMessage::SMS_SUBMIT &&
|
||||
! _at->getMeTa().getCapabilities()._wrongSMSStatusCode)
|
||||
statusString = ",1";
|
||||
|
||||
Parser p(_at->sendPdu("+CMGW=" +
|
||||
intToStr(pdu.length() / 2 -
|
||||
message->getSCAddressLen()) + statusString,
|
||||
"+CMGW:", pdu));
|
||||
index = p.parseInt() - 1;
|
||||
}
|
||||
|
||||
void SMSStore::eraseEntry(int index) throw(GsmException)
|
||||
{
|
||||
// Select SMS store
|
||||
_meTa.setSMSStore(_storeName, 1);
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (debugLevel() >= 1)
|
||||
cerr << "*** Erasing SMS entry " << index << endl;
|
||||
#endif
|
||||
|
||||
_at->chat("+CMGD=" + intToStr(index + 1));
|
||||
}
|
||||
|
||||
unsigned char SMSStore::send(int index, Ref<SMSMessage> &ackPdu)
|
||||
throw(GsmException)
|
||||
{
|
||||
Parser p(_at->chat("+CMSS=" + intToStr(index + 1), "+CMSS:"));
|
||||
unsigned char messageReference = p.parseInt();
|
||||
|
||||
if (p.parseComma(true))
|
||||
{
|
||||
string pdu = p.parseEol();
|
||||
|
||||
// add missing service centre address if required by ME
|
||||
if (! _at->getMeTa().getCapabilities()._hasSMSSCAprefix)
|
||||
pdu = "00" + pdu;
|
||||
|
||||
ackPdu = SMSMessage::decode(pdu);
|
||||
}
|
||||
else
|
||||
ackPdu = SMSMessageRef();
|
||||
|
||||
return messageReference;
|
||||
}
|
||||
|
||||
int SMSStore::doInsert(SMSMessageRef message)
|
||||
throw(GsmException)
|
||||
{
|
||||
int index;
|
||||
writeEntry(index, message);
|
||||
// it is safer to force reading back the SMS from the ME
|
||||
resizeStore(index + 1);
|
||||
_store[index]->_cached = false;
|
||||
return index;
|
||||
}
|
||||
|
||||
SMSStore::SMSStore(string storeName, Ref<GsmAt> at, MeTa &meTa)
|
||||
throw(GsmException) :
|
||||
_storeName(storeName), _at(at), _meTa(meTa), _useCache(true)
|
||||
{
|
||||
// select SMS store
|
||||
Parser p(_meTa.setSMSStore(_storeName, true, true));
|
||||
|
||||
p.parseInt(); // skip number of used mems
|
||||
p.parseComma();
|
||||
|
||||
resizeStore(p.parseInt()); // ignore rest of line
|
||||
}
|
||||
|
||||
void SMSStore::resizeStore(int newSize)
|
||||
{
|
||||
int oldSize = _store.size();
|
||||
if (newSize > oldSize)
|
||||
{
|
||||
// cout << "*** Resizing from " << oldSize << " to " << newSize << endl;
|
||||
_store.resize(newSize);
|
||||
|
||||
// initialize store entries
|
||||
for (int i = oldSize; i < newSize; i++)
|
||||
{
|
||||
_store[i] = new SMSStoreEntry();
|
||||
_store[i]->_index = i;
|
||||
_store[i]->_cached = false;
|
||||
_store[i]->_mySMSStore = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SMSStore::iterator SMSStore::begin()
|
||||
{
|
||||
return SMSStoreIterator(0, this);
|
||||
}
|
||||
|
||||
SMSStore::const_iterator SMSStore::begin() const
|
||||
{
|
||||
return SMSStoreConstIterator(0, this);
|
||||
}
|
||||
|
||||
SMSStore::iterator SMSStore::end()
|
||||
{
|
||||
return SMSStoreIterator(_store.size(), this);
|
||||
}
|
||||
|
||||
SMSStore::const_iterator SMSStore::end() const
|
||||
{
|
||||
return SMSStoreConstIterator(_store.size(), this);
|
||||
}
|
||||
|
||||
SMSStore::reference SMSStore::operator[](int n)
|
||||
{
|
||||
resizeStore(n + 1);
|
||||
return *_store[n];
|
||||
}
|
||||
|
||||
SMSStore::const_reference SMSStore::operator[](int n) const
|
||||
{
|
||||
const_cast<SMSStore*>(this)->resizeStore(n + 1);
|
||||
return *_store[n];
|
||||
}
|
||||
|
||||
SMSStore::reference SMSStore::front()
|
||||
{
|
||||
return *_store[0];
|
||||
}
|
||||
|
||||
SMSStore::const_reference SMSStore::front() const
|
||||
{
|
||||
return *_store[0];
|
||||
}
|
||||
|
||||
SMSStore::reference SMSStore::back()
|
||||
{
|
||||
return *_store.back();
|
||||
}
|
||||
|
||||
SMSStore::const_reference SMSStore::back() const
|
||||
{
|
||||
return *_store.back();
|
||||
}
|
||||
|
||||
int SMSStore::size() const throw(GsmException)
|
||||
{
|
||||
// select SMS store
|
||||
Parser p(_meTa.setSMSStore(_storeName, 1, true));
|
||||
|
||||
return p.parseInt();
|
||||
}
|
||||
|
||||
SMSStore::iterator SMSStore::insert(iterator position,
|
||||
const SMSStoreEntry& x)
|
||||
throw(GsmException)
|
||||
{
|
||||
int index = doInsert(x.message());
|
||||
return SMSStoreIterator(index, this);
|
||||
}
|
||||
|
||||
SMSStore::iterator SMSStore::insert(const SMSStoreEntry& x)
|
||||
throw(GsmException)
|
||||
{
|
||||
int index = doInsert(x.message());
|
||||
return SMSStoreIterator(index, this);
|
||||
}
|
||||
|
||||
void SMSStore::insert (iterator pos, int n, const SMSStoreEntry& x)
|
||||
throw(GsmException)
|
||||
{
|
||||
for (int i = 0; i < n; i++)
|
||||
doInsert(x.message());
|
||||
}
|
||||
|
||||
void SMSStore::insert (iterator pos, long n, const SMSStoreEntry& x)
|
||||
throw(GsmException)
|
||||
{
|
||||
for (long i = 0; i < n; i++)
|
||||
doInsert(x.message());
|
||||
}
|
||||
|
||||
SMSStore::iterator SMSStore::erase(iterator position)
|
||||
throw(GsmException)
|
||||
{
|
||||
eraseEntry(position->_index);
|
||||
position->_cached = false;
|
||||
return position + 1;
|
||||
}
|
||||
|
||||
SMSStore::iterator SMSStore::erase(iterator first, iterator last)
|
||||
throw(GsmException)
|
||||
{
|
||||
iterator i(0, this);
|
||||
for (i = first; i != last; ++i)
|
||||
erase(i);
|
||||
return i;
|
||||
}
|
||||
|
||||
void SMSStore::clear() throw(GsmException)
|
||||
{
|
||||
for (iterator i = begin(); i != end(); ++i)
|
||||
erase(i);
|
||||
}
|
||||
|
||||
SMSStore::~SMSStore()
|
||||
{
|
||||
for (vector<SMSStoreEntry*>::iterator i = _store.begin();
|
||||
i != _store.end(); ++i)
|
||||
delete *i;
|
||||
}
|
||||
|
@ -0,0 +1,295 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_sms_store.h
|
||||
// *
|
||||
// * Purpose: SMS functions, SMS store
|
||||
// * (ETSI GSM 07.05)
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 20.5.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifndef GSM_SMS_STORE_H
|
||||
#define GSM_SMS_STORE_H
|
||||
|
||||
#include <string>
|
||||
#include <iterator>
|
||||
#include <gsmlib/gsm_at.h>
|
||||
#include <gsmlib/gsm_util.h>
|
||||
#include <gsmlib/gsm_sms.h>
|
||||
#include <gsmlib/gsm_cb.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gsmlib
|
||||
{
|
||||
// forward declarations
|
||||
class SMSStore;
|
||||
class MeTa;
|
||||
|
||||
// a single entry in the SMS store
|
||||
|
||||
class SMSStoreEntry : public RefBase
|
||||
{
|
||||
public:
|
||||
// status in ME memory
|
||||
enum SMSMemoryStatus {ReceivedUnread = 0, ReceivedRead = 1,
|
||||
StoredUnsent = 2, StoredSent = 3,
|
||||
All = 4, Unknown = 5};
|
||||
|
||||
private:
|
||||
SMSMessageRef _message;
|
||||
SMSMemoryStatus _status;
|
||||
bool _cached;
|
||||
SMSStore *_mySMSStore;
|
||||
int _index;
|
||||
|
||||
public:
|
||||
// this constructor is only used by SMSStore
|
||||
SMSStoreEntry();
|
||||
|
||||
// create new entry given a SMS message
|
||||
SMSStoreEntry(SMSMessageRef message) :
|
||||
_message(message), _status(Unknown), _cached(true), _mySMSStore(NULL),
|
||||
_index(0) {}
|
||||
|
||||
// create new entry given a SMS message and an index
|
||||
// only to be used for file-based stores (see gsm_sorted_sms_store)
|
||||
SMSStoreEntry(SMSMessageRef message, int index) :
|
||||
_message(message), _status(Unknown), _cached(true), _mySMSStore(NULL),
|
||||
_index(index) {}
|
||||
|
||||
// clear cached flag
|
||||
void clearCached() { _cached = false; }
|
||||
|
||||
// return SMS message stored in the entry
|
||||
SMSMessageRef message() const throw(GsmException);
|
||||
|
||||
// return CB message stored in the entry
|
||||
CBMessageRef cbMessage() const throw(GsmException);
|
||||
|
||||
// return message status in store
|
||||
SMSMemoryStatus status() const throw(GsmException);
|
||||
|
||||
// return true if empty, ie. no SMS in this entry
|
||||
bool empty() const throw(GsmException);
|
||||
|
||||
// send this PDU from store
|
||||
// returns message reference and ACK-PDU (if requested)
|
||||
// only applicate to SMS-SUBMIT and SMS-COMMAND
|
||||
unsigned char send(Ref<SMSMessage> &ackPdu) throw(GsmException);
|
||||
|
||||
// same as above, but ACK-PDU is discarded
|
||||
unsigned char send() throw(GsmException);
|
||||
|
||||
// return index (guaranteed to be unique,
|
||||
// can be used for identification in store)
|
||||
int index() const {return _index;}
|
||||
|
||||
// return true if entry is cached (and caching is enabled)
|
||||
bool cached() const;
|
||||
|
||||
// return deep copy of this entry
|
||||
Ref<SMSStoreEntry> clone();
|
||||
|
||||
// equality operator
|
||||
bool operator==(const SMSStoreEntry &e) const;
|
||||
|
||||
// return store reference
|
||||
SMSStore *getStore() {return _mySMSStore;}
|
||||
|
||||
// copy constructor and assignment
|
||||
SMSStoreEntry(const SMSStoreEntry &e);
|
||||
SMSStoreEntry &operator=(const SMSStoreEntry &e);
|
||||
|
||||
friend class SMSStore;
|
||||
};
|
||||
|
||||
// iterator for the SMSStore class
|
||||
|
||||
#if __GNUC__ == 2 && __GNUC_MINOR__ == 95
|
||||
class SMSStoreIterator : public random_access_iterator<SMSStoreEntry,
|
||||
int>
|
||||
#else
|
||||
class SMSStoreIterator : public iterator<random_access_iterator_tag,
|
||||
SMSStoreEntry, int>
|
||||
#endif
|
||||
{
|
||||
int _index;
|
||||
SMSStore *_store;
|
||||
|
||||
SMSStoreIterator(int index, SMSStore *store) :
|
||||
_index(index), _store(store) {}
|
||||
|
||||
public:
|
||||
SMSStoreIterator(SMSStoreEntry *entry) :
|
||||
_index(entry->index()), _store(entry->getStore()) {}
|
||||
|
||||
SMSStoreEntry &operator*();
|
||||
SMSStoreEntry *operator->();
|
||||
SMSStoreIterator &operator+(int i)
|
||||
{_index += i; return *this;}
|
||||
operator SMSStoreEntry*();
|
||||
SMSStoreIterator &operator=(const SMSStoreIterator &i);
|
||||
SMSStoreIterator &operator++()
|
||||
{++_index; return *this;}
|
||||
SMSStoreIterator &operator--()
|
||||
{--_index; return *this;}
|
||||
SMSStoreIterator &operator++(int i)
|
||||
{_index += i; return *this;}
|
||||
SMSStoreIterator &operator--(int i)
|
||||
{_index -= i; return *this;}
|
||||
bool operator<(SMSStoreIterator &i)
|
||||
{return _index < i._index;}
|
||||
bool operator==(const SMSStoreIterator &i) const
|
||||
{return _index == i._index;}
|
||||
bool operator!=(const SMSStoreIterator &i) const
|
||||
{return _index != i._index;}
|
||||
|
||||
friend class SMSStore;
|
||||
};
|
||||
|
||||
#if __GNUC__ == 2 && __GNUC_MINOR__ == 95
|
||||
class SMSStoreConstIterator : public random_access_iterator<SMSStoreEntry,
|
||||
int>
|
||||
#else
|
||||
class SMSStoreConstIterator : public iterator<random_access_iterator_tag,
|
||||
SMSStoreEntry, int>
|
||||
#endif
|
||||
{
|
||||
int _index;
|
||||
const SMSStore *_store;
|
||||
|
||||
SMSStoreConstIterator(int index, const SMSStore *store) :
|
||||
_index(index), _store(store) {}
|
||||
|
||||
public:
|
||||
const SMSStoreEntry &operator*();
|
||||
const SMSStoreEntry *operator->();
|
||||
SMSStoreConstIterator &operator++()
|
||||
{++_index; return *this;}
|
||||
SMSStoreConstIterator &operator--()
|
||||
{--_index; return *this;}
|
||||
SMSStoreConstIterator &operator++(int i)
|
||||
{_index += i; return *this;}
|
||||
SMSStoreConstIterator &operator--(int i)
|
||||
{_index -= i; return *this;}
|
||||
bool operator<(SMSStoreConstIterator &i)
|
||||
{return _index < i._index;}
|
||||
bool operator==(const SMSStoreConstIterator &i) const
|
||||
{return _index == i._index;}
|
||||
|
||||
friend class SMSStore;
|
||||
};
|
||||
|
||||
// this class corresponds to a SMS store in the ME
|
||||
// all functions directly update storage in the ME
|
||||
// if the ME is exchanged, the storage may become corrupted because
|
||||
// of internal buffering in the SMSStore class
|
||||
|
||||
class SMSStore : public RefBase, public NoCopy
|
||||
{
|
||||
private:
|
||||
vector<SMSStoreEntry*> _store; // vector of store entries
|
||||
string _storeName; // name of the store, 2-byte like "SM"
|
||||
Ref<GsmAt> _at; // my GsmAt class
|
||||
MeTa &_meTa; // my MeTa class
|
||||
bool _useCache; // true if entries should be cached
|
||||
|
||||
// internal access functions
|
||||
// read/write entry from/to ME
|
||||
void readEntry(int index, SMSMessageRef &message,
|
||||
SMSStoreEntry::SMSMemoryStatus &status) throw(GsmException);
|
||||
void readEntry(int index, CBMessageRef &message) throw(GsmException);
|
||||
void writeEntry(int &index, SMSMessageRef message)
|
||||
throw(GsmException);
|
||||
// erase entry
|
||||
void eraseEntry(int index) throw(GsmException);
|
||||
// send PDU index from store
|
||||
// returns message reference and ACK-PDU (if requested)
|
||||
// only applicate to SMS-SUBMIT and SMS-COMMAND
|
||||
unsigned char send(int index, Ref<SMSMessage> &ackPdu) throw(GsmException);
|
||||
|
||||
|
||||
// do the actual insertion, return index of new element
|
||||
int doInsert(SMSMessageRef message) throw(GsmException);
|
||||
|
||||
// used by class MeTa
|
||||
SMSStore(string storeName, Ref<GsmAt> at, MeTa &meTa) throw(GsmException);
|
||||
|
||||
// resize store entry vector if necessary
|
||||
void resizeStore(int newSize);
|
||||
|
||||
public:
|
||||
// iterator defs
|
||||
typedef SMSStoreIterator iterator;
|
||||
typedef SMSStoreConstIterator const_iterator;
|
||||
typedef SMSStoreEntry &reference;
|
||||
typedef const SMSStoreEntry &const_reference;
|
||||
|
||||
// set cache mode on or off
|
||||
void setCaching(bool useCache) {_useCache = useCache;}
|
||||
|
||||
// return name of this store (2-character string)
|
||||
string name() const {return _storeName;}
|
||||
|
||||
// SMS store traversal commands
|
||||
// these are suitable to use stdc++ lib algorithms and iterators
|
||||
// ME have fixed storage space implemented as memory slots
|
||||
// that may either be empty or used
|
||||
|
||||
// traversal commands
|
||||
iterator begin();
|
||||
const_iterator begin() const;
|
||||
iterator end();
|
||||
const_iterator end() const;
|
||||
reference front();
|
||||
const_reference front() const;
|
||||
reference back();
|
||||
const_reference back() const;
|
||||
reference operator[](int n);
|
||||
const_reference operator[](int n) const;
|
||||
|
||||
// The size macros return the number of used entries
|
||||
// Warning: indices may be _larger_ than size() because of this
|
||||
// (perhaps this should be changed, because it is unexpected behavior)
|
||||
|
||||
int size() const throw(GsmException);
|
||||
int max_size() const {return _store.size();}
|
||||
int capacity() const {return _store.size();}
|
||||
bool empty() const throw(GsmException) {return size() == 0;}
|
||||
|
||||
// insert iterators insert into the first empty cell regardless of position
|
||||
// existing iterators may be invalidated after an insert operation
|
||||
// return position
|
||||
// insert only writes to available positions
|
||||
// warning: insert fails silently if size() == max_size()
|
||||
iterator insert(iterator position, const SMSStoreEntry& x)
|
||||
throw(GsmException);
|
||||
iterator insert(const SMSStoreEntry& x) throw(GsmException);
|
||||
|
||||
// insert n times, same procedure as above
|
||||
void insert (iterator pos, int n, const SMSStoreEntry& x)
|
||||
throw(GsmException);
|
||||
void insert (iterator pos, long n, const SMSStoreEntry& x)
|
||||
throw(GsmException);
|
||||
|
||||
// erase operators set used slots to "empty"
|
||||
iterator erase(iterator position) throw(GsmException);
|
||||
iterator erase(iterator first, iterator last) throw(GsmException);
|
||||
void clear() throw(GsmException);
|
||||
|
||||
// destructor
|
||||
~SMSStore();
|
||||
|
||||
friend class SMSStoreEntry;
|
||||
friend class MeTa;
|
||||
};
|
||||
|
||||
typedef Ref<SMSStore> SMSStoreRef;
|
||||
|
||||
};
|
||||
|
||||
#endif // GSM_SMS_STORE_H
|
@ -0,0 +1,503 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_sorted_phonebook.cc
|
||||
// *
|
||||
// * Purpose: Alphabetically sorted phonebook
|
||||
// * (residing in files or in the ME)
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 25.6.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <gsm_config.h>
|
||||
#endif
|
||||
#include <gsmlib/gsm_util.h>
|
||||
#include <gsmlib/gsm_sorted_phonebook.h>
|
||||
#include <gsmlib/gsm_nls.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <limits.h>
|
||||
#include <cstring>
|
||||
|
||||
const int MAX_LINE_SIZE = 1000;
|
||||
|
||||
using namespace std;
|
||||
using namespace gsmlib;
|
||||
|
||||
string SortedPhonebook::escapeString(string s)
|
||||
{
|
||||
string result;
|
||||
|
||||
for (const char *pp = s.c_str(); *pp != 0; ++pp)
|
||||
{
|
||||
if (*pp == CR)
|
||||
result += "\\r";
|
||||
else if (*pp == LF)
|
||||
result += "\\n";
|
||||
else if (*pp == '\\')
|
||||
result += "\\\\";
|
||||
else if (*pp == '|')
|
||||
result += "\\|";
|
||||
else
|
||||
result += *pp;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
string SortedPhonebook::unescapeString(char *line, unsigned int &pos)
|
||||
{
|
||||
string result;
|
||||
bool escaped = false;
|
||||
|
||||
while (! (line[pos] == '|' && ! escaped) && line[pos] != 0 &&
|
||||
line[pos] != CR && line[pos] != LF)
|
||||
{
|
||||
if (escaped)
|
||||
{
|
||||
escaped = false;
|
||||
if (line[pos] == 'r')
|
||||
result += CR;
|
||||
else if (line[pos] == 'n')
|
||||
result += LF;
|
||||
else if (line[pos] == '\\')
|
||||
result += '\\';
|
||||
else if (line[pos] == '|')
|
||||
result += '|';
|
||||
else
|
||||
result += line[pos];
|
||||
}
|
||||
else
|
||||
if (line[pos] == '\\')
|
||||
escaped = true;
|
||||
else
|
||||
result += line[pos];
|
||||
|
||||
++pos;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void SortedPhonebook::readPhonebookFile(istream &pbs, string filename)
|
||||
throw(GsmException)
|
||||
{
|
||||
// read entries
|
||||
while (! pbs.eof())
|
||||
{
|
||||
char line[MAX_LINE_SIZE];
|
||||
pbs.getline(line, MAX_LINE_SIZE);
|
||||
|
||||
if (strlen(line) == 0)
|
||||
continue; // skip empty lines
|
||||
|
||||
if (pbs.bad())
|
||||
throw GsmException(stringPrintf(_("error reading from file '%s"),
|
||||
filename.c_str()),
|
||||
OSError);
|
||||
|
||||
// convert line to newEntry (line format : [index] '|' text '|' number
|
||||
string text, telephone;
|
||||
unsigned int pos = 0;
|
||||
|
||||
// parse index
|
||||
string indexS = unescapeString(line, pos);
|
||||
int index = -1;
|
||||
if (indexS.length() == 0)
|
||||
{
|
||||
if (_useIndices)
|
||||
throw GsmException(stringPrintf(_("entry '%s' lacks index"), line),
|
||||
ParserError);
|
||||
}
|
||||
else
|
||||
{
|
||||
index = checkNumber(indexS);
|
||||
_useIndices = true;
|
||||
}
|
||||
if (line[pos++] != '|')
|
||||
throw GsmException(stringPrintf(_("line '%s' has invalid format"), line),
|
||||
ParserError);
|
||||
|
||||
// parse text
|
||||
text = unescapeString(line, pos);
|
||||
if (line[pos++] != '|')
|
||||
throw GsmException(stringPrintf(_("line '%s' has invalid format"), line),
|
||||
ParserError);
|
||||
|
||||
// parse telephone number
|
||||
telephone = unescapeString(line, pos);
|
||||
|
||||
insert(PhonebookEntryBase(telephone, text, index));
|
||||
}
|
||||
}
|
||||
|
||||
void SortedPhonebook::sync(bool fromDestructor) throw(GsmException)
|
||||
{
|
||||
// if not in file it already is stored in ME/TA
|
||||
if (! _fromFile) return;
|
||||
|
||||
// if writing to stdout and not called from destructor ignore
|
||||
// (avoids writing to stdout multiple times)
|
||||
if (_filename == "" && ! fromDestructor) return;
|
||||
|
||||
// find out if any of the entries have been updated
|
||||
if (! _changed) // only look if we're not writing the file anyway
|
||||
for (iterator i = begin(); i != end(); i++)
|
||||
if (i->changed())
|
||||
{
|
||||
_changed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (_changed)
|
||||
{
|
||||
checkReadonly();
|
||||
// create backup file - but only once
|
||||
if (! _madeBackupFile && _filename != "") // don't make backup of stdout
|
||||
{
|
||||
renameToBackupFile(_filename);
|
||||
_madeBackupFile = true;
|
||||
}
|
||||
|
||||
// open stream
|
||||
ostream *pbs = NULL;
|
||||
try
|
||||
{
|
||||
if (_filename == "")
|
||||
pbs = &cout;
|
||||
else
|
||||
pbs = new ofstream(_filename.c_str());
|
||||
|
||||
if (pbs->bad())
|
||||
throw GsmException(
|
||||
stringPrintf(_("error opening file '%s' for writing"),
|
||||
(_filename == "" ? _("<STDOUT>") :
|
||||
_filename.c_str())),
|
||||
OSError);
|
||||
|
||||
// and write the entries
|
||||
for (PhonebookMap::iterator i = _sortedPhonebook.begin();
|
||||
i != _sortedPhonebook.end(); ++i)
|
||||
{
|
||||
// convert entry to output line
|
||||
string line =
|
||||
(_useIndices ? intToStr(i->second->index()) : "") + "|" +
|
||||
escapeString(i->second->text()) + "|" +
|
||||
escapeString(i->second->telephone());
|
||||
|
||||
// write out the line
|
||||
*pbs << line << endl;
|
||||
if (pbs->bad())
|
||||
throw GsmException(
|
||||
stringPrintf(_("error writing to file '%s'"),
|
||||
(_filename == "" ? _("<STDOUT>") :
|
||||
_filename.c_str())),
|
||||
OSError);
|
||||
}
|
||||
}
|
||||
catch(GsmException &e)
|
||||
{
|
||||
if (pbs != &cout) delete pbs;
|
||||
throw;
|
||||
}
|
||||
// close file
|
||||
if (pbs != &cout) delete pbs;
|
||||
|
||||
// reset all changed states
|
||||
_changed = false;
|
||||
for (iterator j = begin(); j != end(); j++)
|
||||
j->resetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void SortedPhonebook::checkReadonly() throw(GsmException)
|
||||
{
|
||||
if (_readonly) throw GsmException(
|
||||
_("attempt to change phonebook read from <STDIN>"),
|
||||
ParameterError);
|
||||
}
|
||||
|
||||
SortedPhonebook::SortedPhonebook(string filename, bool useIndices)
|
||||
throw(GsmException) :
|
||||
_changed(false), _fromFile(true), _madeBackupFile(false),
|
||||
_sortOrder(ByIndex), _useIndices(useIndices), _readonly(false),
|
||||
_filename(filename)
|
||||
{
|
||||
// open the file
|
||||
ifstream pbs(filename.c_str());
|
||||
if (pbs.bad())
|
||||
throw GsmException(stringPrintf(_("cannot open file '%s'"),
|
||||
filename.c_str()),
|
||||
OSError);
|
||||
// and read the file
|
||||
readPhonebookFile(pbs, filename);
|
||||
}
|
||||
|
||||
SortedPhonebook::SortedPhonebook(bool fromStdin, bool useIndices)
|
||||
throw(GsmException) :
|
||||
_changed(false), _fromFile(true), _madeBackupFile(false),
|
||||
_sortOrder(ByIndex), _useIndices(useIndices), _readonly(fromStdin)
|
||||
// _filename is "" - this means stdout
|
||||
{
|
||||
// read from stdin
|
||||
if (fromStdin)
|
||||
readPhonebookFile(cin, (string)_("<STDIN>"));
|
||||
}
|
||||
|
||||
SortedPhonebook::SortedPhonebook(PhonebookRef mePhonebook)
|
||||
throw(GsmException) :
|
||||
_changed(false), _fromFile(false), _madeBackupFile(false),
|
||||
_sortOrder(ByIndex), _readonly(false), _mePhonebook(mePhonebook)
|
||||
{
|
||||
int entriesRead = 0;
|
||||
reportProgress(0, _mePhonebook->end() - _mePhonebook->begin());
|
||||
|
||||
for (Phonebook::iterator i = _mePhonebook->begin();
|
||||
i != _mePhonebook->end(); ++i)
|
||||
{
|
||||
if (! i->empty())
|
||||
{
|
||||
_sortedPhonebook.insert(
|
||||
PhonebookMap::value_type(PhoneMapKey(*this, lowercase(i->text())), i));
|
||||
++entriesRead;
|
||||
if (entriesRead == _mePhonebook->size())
|
||||
return; // ready
|
||||
}
|
||||
reportProgress(i - _mePhonebook->begin());
|
||||
}
|
||||
}
|
||||
|
||||
void SortedPhonebook::setSortOrder(SortOrder newOrder)
|
||||
{
|
||||
if (newOrder == _sortOrder) return; // nothing to do
|
||||
|
||||
PhonebookMap savedPhonebook = _sortedPhonebook; // save phonebook
|
||||
_sortedPhonebook = PhonebookMap(); // empty old phonebook
|
||||
_sortOrder = newOrder;
|
||||
|
||||
// re-insert entries
|
||||
switch (newOrder)
|
||||
{
|
||||
case ByTelephone:
|
||||
{
|
||||
for (PhonebookMap::iterator i = savedPhonebook.begin();
|
||||
i != savedPhonebook.end(); ++i)
|
||||
_sortedPhonebook.
|
||||
insert(PhonebookMap::value_type(
|
||||
PhoneMapKey(*this, lowercase(i->second->telephone())), i->second));
|
||||
break;
|
||||
}
|
||||
case ByText:
|
||||
{
|
||||
for (PhonebookMap::iterator i = savedPhonebook.begin();
|
||||
i != savedPhonebook.end(); ++i)
|
||||
_sortedPhonebook.
|
||||
insert(PhonebookMap::value_type(
|
||||
PhoneMapKey(*this, lowercase(i->second->text())), i->second));
|
||||
break;
|
||||
}
|
||||
case ByIndex:
|
||||
{
|
||||
for (PhonebookMap::iterator i = savedPhonebook.begin();
|
||||
i != savedPhonebook.end(); ++i)
|
||||
_sortedPhonebook.
|
||||
insert(PhonebookMap::value_type(
|
||||
PhoneMapKey(*this, i->second->index()), i->second));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int SortedPhonebook::getMaxTelephoneLen() const
|
||||
{
|
||||
if (_fromFile)
|
||||
return UINT_MAX;
|
||||
else
|
||||
return _mePhonebook->getMaxTelephoneLen();
|
||||
}
|
||||
|
||||
unsigned int SortedPhonebook::getMaxTextLen() const
|
||||
{
|
||||
if (_fromFile)
|
||||
return UINT_MAX;
|
||||
else
|
||||
return _mePhonebook->getMaxTextLen();
|
||||
}
|
||||
|
||||
int SortedPhonebook::max_size() const
|
||||
{
|
||||
if (_fromFile)
|
||||
return _sortedPhonebook.max_size();
|
||||
else
|
||||
return _mePhonebook->max_size();
|
||||
}
|
||||
|
||||
int SortedPhonebook::capacity() const
|
||||
{
|
||||
if (_fromFile)
|
||||
return _sortedPhonebook.max_size();
|
||||
else
|
||||
return _mePhonebook->capacity();
|
||||
}
|
||||
|
||||
SortedPhonebook::iterator
|
||||
SortedPhonebook::insert(const PhonebookEntryBase& x) throw(GsmException)
|
||||
{
|
||||
checkReadonly();
|
||||
_changed = true;
|
||||
PhonebookEntryBase *newEntry;
|
||||
|
||||
if (_fromFile)
|
||||
if (_useIndices)
|
||||
{
|
||||
if (x.index() != -1) // check that index is unique
|
||||
{
|
||||
for (PhonebookMap::iterator i = _sortedPhonebook.begin();
|
||||
i != _sortedPhonebook.end(); ++i)
|
||||
if (i->second->index() == x.index())
|
||||
throw GsmException(_("indices must be unique in phonebook"),
|
||||
ParameterError);
|
||||
newEntry = new PhonebookEntryBase(x);
|
||||
}
|
||||
else // set index
|
||||
{
|
||||
SortOrder saveSortOrder = _sortOrder;
|
||||
setSortOrder(ByIndex);
|
||||
int index = 0;
|
||||
for (PhonebookMap::iterator i = _sortedPhonebook.begin();
|
||||
i != _sortedPhonebook.end(); ++i, ++index)
|
||||
if (i->second->index() != index)
|
||||
break;
|
||||
setSortOrder(saveSortOrder);
|
||||
newEntry = new PhonebookEntryBase();
|
||||
newEntry->set(x.telephone(), x.text(), index, true);
|
||||
}
|
||||
}
|
||||
else // index info in x is ignored
|
||||
newEntry = new PhonebookEntryBase(x);
|
||||
else
|
||||
{
|
||||
PhonebookEntry newMEEntry(x);
|
||||
newEntry = _mePhonebook->insert((PhonebookEntry*)NULL, newMEEntry);
|
||||
}
|
||||
switch (_sortOrder)
|
||||
{
|
||||
case ByTelephone:
|
||||
return
|
||||
_sortedPhonebook.
|
||||
insert(PhonebookMap::value_type(
|
||||
PhoneMapKey(*this, lowercase(newEntry->telephone())), newEntry));
|
||||
case ByText:
|
||||
return
|
||||
_sortedPhonebook.
|
||||
insert(PhonebookMap::value_type(
|
||||
PhoneMapKey(*this, lowercase(newEntry->text())), newEntry));
|
||||
case ByIndex:
|
||||
return
|
||||
_sortedPhonebook.
|
||||
insert(PhonebookMap::value_type(
|
||||
PhoneMapKey(*this, newEntry->index()), newEntry));
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
return SortedPhonebook::iterator();
|
||||
}
|
||||
|
||||
SortedPhonebook::iterator
|
||||
SortedPhonebook::insert(iterator position, const PhonebookEntryBase& x)
|
||||
throw(GsmException)
|
||||
{
|
||||
return insert(x);
|
||||
}
|
||||
|
||||
SortedPhonebook::size_type SortedPhonebook::erase(string &key)
|
||||
throw(GsmException)
|
||||
{
|
||||
// deallocate memory or remove from underlying ME phonebook
|
||||
for (PhonebookMap::iterator i =
|
||||
_sortedPhonebook.find(PhoneMapKey(*this, lowercase(key)));
|
||||
i != _sortedPhonebook.end() &&
|
||||
i->first == PhoneMapKey(*this, lowercase(key));
|
||||
++i)
|
||||
{
|
||||
checkReadonly();
|
||||
_changed = true;
|
||||
if (_fromFile)
|
||||
delete i->second;
|
||||
else
|
||||
_mePhonebook->erase((Phonebook::iterator)i->second);
|
||||
}
|
||||
|
||||
return _sortedPhonebook.erase(PhoneMapKey(*this, lowercase(key)));
|
||||
}
|
||||
|
||||
SortedPhonebook::size_type SortedPhonebook::erase(int key)
|
||||
throw(GsmException)
|
||||
{
|
||||
// deallocate memory or remove from underlying ME phonebook
|
||||
for (PhonebookMap::iterator i =
|
||||
_sortedPhonebook.find(PhoneMapKey(*this, key));
|
||||
i != _sortedPhonebook.end() && i->first == PhoneMapKey(*this, key);
|
||||
++i)
|
||||
{
|
||||
checkReadonly();
|
||||
_changed = true;
|
||||
if (_fromFile)
|
||||
delete i->second;
|
||||
else
|
||||
_mePhonebook->erase((Phonebook::iterator)i->second);
|
||||
}
|
||||
|
||||
return _sortedPhonebook.erase(PhoneMapKey(*this, key));
|
||||
}
|
||||
|
||||
void SortedPhonebook::erase(iterator position)
|
||||
throw(GsmException)
|
||||
{
|
||||
checkReadonly();
|
||||
_changed = true;
|
||||
// deallocate memory or remove from underlying ME phonebook
|
||||
if (_fromFile)
|
||||
delete ((PhonebookMap::iterator)position)->second;
|
||||
else
|
||||
_mePhonebook->erase((Phonebook::iterator)
|
||||
((PhonebookMap::iterator)position)->second);
|
||||
_sortedPhonebook.erase(position);
|
||||
}
|
||||
|
||||
void SortedPhonebook::erase(iterator first, iterator last)
|
||||
throw(GsmException)
|
||||
{
|
||||
checkReadonly();
|
||||
_changed = true;
|
||||
for (PhonebookMap::iterator i = first; i != last; ++i)
|
||||
if (_fromFile)
|
||||
delete i->second;
|
||||
else
|
||||
_mePhonebook->erase((Phonebook::iterator)i->second);
|
||||
_sortedPhonebook.erase(first, last);
|
||||
}
|
||||
|
||||
void SortedPhonebook::clear() throw(GsmException)
|
||||
{
|
||||
checkReadonly();
|
||||
_changed = true;
|
||||
for (iterator i = begin(); i != end(); i++)
|
||||
erase(i);
|
||||
}
|
||||
|
||||
SortedPhonebook::~SortedPhonebook()
|
||||
{
|
||||
if (_fromFile)
|
||||
{
|
||||
sync(true);
|
||||
for (PhonebookMap::iterator i = _sortedPhonebook.begin();
|
||||
i != _sortedPhonebook.end(); ++i)
|
||||
delete i->second;
|
||||
}
|
||||
}
|
@ -0,0 +1,159 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_sorted_phonebook.h
|
||||
// *
|
||||
// * Purpose: Alphabetically sorted phonebook
|
||||
// * (residing in files or in the ME)
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 25.6.1999
|
||||
// *************************************************************************
|
||||
|
||||
#ifndef GSM_SORTED_PHONEBOOK_H
|
||||
#define GSM_SORTED_PHONEBOOK_H
|
||||
|
||||
#include <gsmlib/gsm_sorted_phonebook_base.h>
|
||||
#include <gsmlib/gsm_phonebook.h>
|
||||
#include <gsmlib/gsm_util.h>
|
||||
#include <gsmlib/gsm_map_key.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace gsmlib
|
||||
{
|
||||
|
||||
// The class SortedPhonebook makes the phonebook more manageable:
|
||||
// - empty slots in the ME phonebook are hidden by the API
|
||||
// - the class transparently handles phonebooks that reside in files
|
||||
|
||||
class SortedPhonebook : public SortedPhonebookBase
|
||||
{
|
||||
private:
|
||||
bool _changed; // true if file has changed after last save
|
||||
bool _fromFile; // true if phonebook read from file
|
||||
bool _madeBackupFile; // true if backup file was created
|
||||
SortOrder _sortOrder; // sort order for the phonebook
|
||||
bool _useIndices; // if phonebook from file: input file had
|
||||
// indices; will write indices, too
|
||||
bool _readonly; // =true if read from stdin
|
||||
string _filename; // name of the file if phonebook from file
|
||||
PhonebookMap _sortedPhonebook; // phonebook from file
|
||||
PhonebookRef _mePhonebook; // phonebook if from ME
|
||||
|
||||
// convert CR and LF in string to "\r" and "\n" respectively
|
||||
string escapeString(string s);
|
||||
|
||||
// convert "\r" and "\n" to CR and LF respectively
|
||||
// start parsing with pos, stop when CR, LF, 0, or '|' is encountered
|
||||
string unescapeString(char *line, unsigned int &pos);
|
||||
|
||||
// initial read of phonebook file
|
||||
void readPhonebookFile(istream &pbs, string filename) throw(GsmException);
|
||||
|
||||
// synchronize SortedPhonebook with file (no action if in ME)
|
||||
void sync(bool fromDestructor) throw(GsmException);
|
||||
|
||||
// throw an exception if _readonly is set
|
||||
void checkReadonly() throw(GsmException);
|
||||
|
||||
public:
|
||||
// iterator defs
|
||||
typedef SortedPhonebookIterator iterator;
|
||||
typedef PhonebookMap::size_type size_type;
|
||||
|
||||
// constructor for file-based phonebook
|
||||
// expect indices in file if useIndices == true
|
||||
// read from file
|
||||
SortedPhonebook(string filename, bool useIndices)
|
||||
throw(GsmException);
|
||||
// read from stdin or start empty and write to stdout
|
||||
SortedPhonebook(bool fromStdin, bool useIndices)
|
||||
throw(GsmException);
|
||||
|
||||
// constructor for ME-based phonebook
|
||||
SortedPhonebook(PhonebookRef mePhonebook) throw(GsmException);
|
||||
|
||||
// return maximum telephone number length
|
||||
unsigned int getMaxTelephoneLen() const;
|
||||
|
||||
// return maximum entry description length
|
||||
unsigned int getMaxTextLen() const;
|
||||
|
||||
// handle sorting
|
||||
void setSortOrder(SortOrder newOrder);
|
||||
SortOrder sortOrder() const {return _sortOrder;}
|
||||
|
||||
// phonebook traversal commands
|
||||
// these are suitable to use stdc++ lib algorithms and iterators
|
||||
// ME have fixed storage space implemented as memory slots
|
||||
// that may either be empty or used
|
||||
|
||||
// traversal commands
|
||||
iterator begin() {return _sortedPhonebook.begin();}
|
||||
iterator end() {return _sortedPhonebook.end();}
|
||||
|
||||
// the size macros return the number of used entries
|
||||
int size() const {return _sortedPhonebook.size();}
|
||||
int max_size() const;
|
||||
int capacity() const;
|
||||
bool empty() const throw(GsmException) {return size() == 0;}
|
||||
|
||||
// existing iterators remain valid after an insert or erase operation
|
||||
// note: inserting many entries in indexed mode is inefficient
|
||||
// if the sort order is not set to indexed before
|
||||
|
||||
// return position
|
||||
// insert only writes to available positions
|
||||
// warning: insert fails silently if size() == max_size()
|
||||
iterator insert(const PhonebookEntryBase& x) throw(GsmException);
|
||||
iterator insert(iterator position, const PhonebookEntryBase& x)
|
||||
throw(GsmException);
|
||||
|
||||
PhonebookMap::size_type count(string &key)
|
||||
{return _sortedPhonebook.count(PhoneMapKey(*this, lowercase(key)));}
|
||||
iterator find(string &key)
|
||||
{return _sortedPhonebook.find(PhoneMapKey(*this, lowercase(key)));}
|
||||
iterator lower_bound(string &key)
|
||||
{return _sortedPhonebook.lower_bound(PhoneMapKey(*this,
|
||||
lowercase(key)));}
|
||||
iterator upper_bound(string &key)
|
||||
{return _sortedPhonebook.upper_bound(PhoneMapKey(*this,
|
||||
lowercase(key)));}
|
||||
pair<iterator, iterator> equal_range(string &key)
|
||||
{return _sortedPhonebook.equal_range(PhoneMapKey(*this,
|
||||
lowercase(key)));}
|
||||
|
||||
PhonebookMap::size_type count(int key)
|
||||
{return _sortedPhonebook.count(PhoneMapKey(*this, key));}
|
||||
iterator find(int key)
|
||||
{return _sortedPhonebook.find(PhoneMapKey(*this, key));}
|
||||
iterator lower_bound(int key)
|
||||
{return _sortedPhonebook.lower_bound(PhoneMapKey(*this, key));}
|
||||
iterator upper_bound(int key)
|
||||
{return _sortedPhonebook.upper_bound(PhoneMapKey(*this, key));}
|
||||
pair<iterator, iterator> equal_range(int key)
|
||||
{return _sortedPhonebook.equal_range(PhoneMapKey(*this, key));}
|
||||
|
||||
size_type erase(string &key) throw(GsmException);
|
||||
size_type erase(int key) throw(GsmException);
|
||||
void erase(iterator position) throw(GsmException);
|
||||
void erase(iterator first, iterator last) throw(GsmException);
|
||||
void clear() throw(GsmException);
|
||||
|
||||
// synchronize SortedPhonebook with file (no action if in ME)
|
||||
void sync() throw(GsmException) {sync(false);}
|
||||
|
||||
// destructor
|
||||
// writes back change to file if phonebook is in file
|
||||
virtual ~SortedPhonebook();
|
||||
};
|
||||
|
||||
// typedef Ref<SortedPhonebook> SortedPhonebookRef;
|
||||
};
|
||||
|
||||
#endif // GSM_SORTED_PHONEBOOK_H
|
@ -0,0 +1,115 @@
|
||||
// *************************************************************************
|
||||
// * GSM TA/ME library
|
||||
// *
|
||||
// * File: gsm_sorted_phonebook_base.cc
|
||||
// *
|
||||
// * Purpose: Virtual base class for alphabetically sorted phonebook
|
||||
// * The infrastructure in this module allows custom backends for
|
||||
// * storing phonebook entries to be integrated into gsmlib
|
||||
// * (eg. LDAP- or RDBMS-based phonebook stores).
|
||||
// *
|
||||
// * Author: Peter Hofmann (software@pxh.de)
|
||||
// *
|
||||
// * Created: 5.6.2000
|
||||
// *************************************************************************
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <gsm_config.h>
|
||||
#endif
|
||||
#include <gsmlib/gsm_sorted_phonebook_base.h>
|
||||
#include <gsmlib/gsm_error.h>
|
||||
#include <gsmlib/gsm_util.h>
|
||||
#include <gsmlib/gsm_nls.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace gsmlib;
|
||||
|
||||
// PhonebookEntryBase members
|
||||
|
||||
void PhonebookEntryBase::set(string telephone, string text, int index,
|
||||
bool useIndex)
|
||||
throw(GsmException)
|
||||
{
|
||||
checkTextAndTelephone(text, telephone);
|
||||
|
||||
_changed = true;
|
||||
_telephone = telephone;
|
||||
_text = text;
|
||||
_useIndex = useIndex;
|
||||
if (index != -1)
|
||||
_index = index;
|
||||
}
|
||||
|
||||
bool PhonebookEntryBase::operator==(const PhonebookEntryBase &e) const
|
||||
{
|
||||
assert(! ((_useIndex || e._useIndex) &&
|
||||
(_index == -1 || e._index == -1)));
|
||||
return _telephone == e._telephone && _text == e._text &&
|
||||
(! (_useIndex || e._useIndex) || _index == e._index);
|
||||
}
|
||||
|
||||
string PhonebookEntryBase::text() const throw(GsmException)
|
||||
{
|
||||
return _text;
|
||||
}
|
||||
|
||||
string PhonebookEntryBase::telephone() const throw(GsmException)
|
||||
{
|
||||
return _telephone;
|
||||
}
|
||||
|
||||
bool PhonebookEntryBase::empty() const throw(GsmException)
|
||||
{
|
||||
return (text() == "") && (telephone() == "");
|
||||
}
|
||||
|
||||
Ref<PhonebookEntryBase> PhonebookEntryBase::clone()
|
||||
{
|
||||
Ref<PhonebookEntryBase> result = new PhonebookEntryBase(*this);
|
||||
return result;
|
||||
}
|
||||
|
||||
PhonebookEntryBase::PhonebookEntryBase(const PhonebookEntryBase &e)
|
||||
throw(GsmException)
|
||||
{
|
||||
set(e._telephone, e._text, e._index, e._useIndex);
|
||||
}
|
||||
|
||||
PhonebookEntryBase &PhonebookEntryBase::operator=(const PhonebookEntryBase &e)
|
||||
throw(GsmException)
|
||||
{
|
||||
set(e._telephone, e._text, e._index, e._useIndex);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// CustomPhonebookRegistry members
|
||||
|
||||
map<string, CustomPhonebookFactory*>
|
||||
*CustomPhonebookRegistry::_factoryList = NULL;
|
||||
|
||||
void CustomPhonebookRegistry::
|
||||
registerCustomPhonebookFactory(string backendName,
|
||||
CustomPhonebookFactory *factory)
|
||||
throw(GsmException)
|
||||
{
|
||||
if (_factoryList == NULL)
|
||||
_factoryList = new map<string, CustomPhonebookFactory*>;
|
||||
backendName = lowercase(backendName);
|
||||
if (_factoryList->find(backendName) != _factoryList->end())
|
||||
throw GsmException(stringPrintf(_("backend '%s' already registered"),
|
||||
backendName.c_str()), ParameterError);
|
||||
}
|
||||
|
||||
SortedPhonebookRef CustomPhonebookRegistry::
|
||||
createPhonebook(string backendName, string source) throw(GsmException)
|
||||
{
|
||||
if (_factoryList == NULL)
|
||||
_factoryList = new map<string, CustomPhonebookFactory*>;
|
||||
backendName = lowercase(backendName);
|
||||
if (_factoryList->find(backendName) == _factoryList->end())
|
||||
throw GsmException(stringPrintf(_("backend '%s' not registered"),
|
||||
backendName.c_str()), ParameterError);
|
||||
return (*_factoryList)[backendName]->createPhonebook(source);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user