mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
synced 2025-11-02 13:03:33 +00:00
Compare commits
100 Commits
openbsc/0.
...
on-waves/0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2727909dba | ||
|
|
ad9856ec15 | ||
|
|
9d53a8ad2a | ||
|
|
058956e8ee | ||
|
|
a34bb9167f | ||
|
|
b8ac7ffd7c | ||
|
|
b13cf829da | ||
|
|
fdc64f6806 | ||
|
|
ab46372e2a | ||
|
|
ff0a562f9a | ||
|
|
556008d724 | ||
|
|
0094f84f30 | ||
|
|
86069143ff | ||
|
|
44f0be88a3 | ||
|
|
5d88b372d7 | ||
|
|
71c7bf5907 | ||
|
|
869033148c | ||
|
|
bc0f7c0988 | ||
|
|
7d06063cfb | ||
|
|
4e42b637fd | ||
|
|
f44de9942b | ||
|
|
3a110ae60b | ||
|
|
bb84adc465 | ||
|
|
8d123ea3c0 | ||
|
|
88ca894df7 | ||
|
|
42b0d6b494 | ||
|
|
82d8b0457b | ||
|
|
433d6ee1a2 | ||
|
|
203a6eddf8 | ||
|
|
56ef6249e3 | ||
|
|
b2a96b1be7 | ||
|
|
d4c29c1574 | ||
|
|
3d947e6d67 | ||
|
|
b62c9a19cf | ||
|
|
ff5957568f | ||
|
|
7d2e1ca4be | ||
|
|
7ce2e0c8b0 | ||
|
|
78d442420b | ||
|
|
8cd2709ebf | ||
|
|
41a1780102 | ||
|
|
2f84715984 | ||
|
|
7253154fc5 | ||
|
|
6c1c76683f | ||
|
|
a92fe9a4ca | ||
|
|
e83a3f584e | ||
|
|
118ddebc36 | ||
|
|
bb53004d47 | ||
|
|
6af20842cb | ||
|
|
cc41cb07e7 | ||
|
|
d6fb23523a | ||
|
|
2aa0b45cc0 | ||
|
|
619df61ad2 | ||
|
|
893ea65f38 | ||
|
|
64b811f113 | ||
|
|
91fc9bf862 | ||
|
|
111a58dd37 | ||
|
|
d1a2563a74 | ||
|
|
7d3ef919ce | ||
|
|
cba98d87d6 | ||
|
|
5c18ad0829 | ||
|
|
0d9ed87d5c | ||
|
|
ec7be0c969 | ||
|
|
9be3347601 | ||
|
|
3eef7b7d81 | ||
|
|
9de4a6daa9 | ||
|
|
851ace9f33 | ||
|
|
d1dd069b48 | ||
|
|
401db32ca2 | ||
|
|
17e03d21d2 | ||
|
|
26a9bff201 | ||
|
|
80fb260a60 | ||
|
|
55a0716da7 | ||
|
|
c88fb75616 | ||
|
|
d55a4dc326 | ||
|
|
a4e6f2e6e1 | ||
|
|
7f71d99cc3 | ||
|
|
b92167cf80 | ||
|
|
4b6a6dbe7e | ||
|
|
763e8c7766 | ||
|
|
823ff16088 | ||
|
|
6f93c6a1e0 | ||
|
|
f97e48b0de | ||
|
|
761600b0fd | ||
|
|
8549462bc6 | ||
|
|
436e5c6308 | ||
|
|
f8b9d844c1 | ||
|
|
58ec07d580 | ||
|
|
71465c21f4 | ||
|
|
16d0a833f8 | ||
|
|
ea72b62cac | ||
|
|
49a84ec6e9 | ||
|
|
42c636b6c8 | ||
|
|
a0a55f555e | ||
|
|
23ed00e410 | ||
|
|
3fe910b9f1 | ||
|
|
097bdeb77d | ||
|
|
1b85de02e0 | ||
|
|
2281d1835f | ||
|
|
fb4433a129 | ||
|
|
d954dcf9e1 |
22
libosmocore/.gitignore
vendored
22
libosmocore/.gitignore
vendored
@@ -1,22 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
.deps
|
||||
.libs
|
||||
*.o
|
||||
*.lo
|
||||
*.la
|
||||
*.pc
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
config.h*
|
||||
config.sub
|
||||
config.log
|
||||
config.status
|
||||
config.guess
|
||||
configure
|
||||
depcomp
|
||||
missing
|
||||
ltmain.sh
|
||||
install-sh
|
||||
stamp-h1
|
||||
libtool
|
||||
@@ -1,339 +0,0 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. 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 program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
@@ -1,7 +0,0 @@
|
||||
AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6
|
||||
|
||||
INCLUDES = $(all_includes) -I$(top_srcdir)/include
|
||||
SUBDIRS = include src tests
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = libosmocore.pc
|
||||
@@ -1,52 +0,0 @@
|
||||
AC_INIT
|
||||
|
||||
AM_INIT_AUTOMAKE(libosmocore, 0.0alpha1)
|
||||
|
||||
dnl kernel style compile messages
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
dnl checks for programs
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_RANLIB
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
dnl checks for header files
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(execinfo.h sys/select.h)
|
||||
|
||||
# The following test is taken from WebKit's webkit.m4
|
||||
saved_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -fvisibility=hidden "
|
||||
AC_MSG_CHECKING([if ${CC} supports -fvisibility=hidden])
|
||||
AC_COMPILE_IFELSE([char foo;],
|
||||
[ AC_MSG_RESULT([yes])
|
||||
SYMBOL_VISIBILITY="-fvisibility=hidden"],
|
||||
AC_MSG_RESULT([no]))
|
||||
CFLAGS="$saved_CFLAGS"
|
||||
AC_SUBST(SYMBOL_VISIBILITY)
|
||||
|
||||
dnl Generate the output
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
AC_ARG_ENABLE(talloc,
|
||||
[ --disable-talloc Disable building talloc memory allocator ],
|
||||
[enable_talloc=0], [enable_talloc=1])
|
||||
AM_CONDITIONAL(ENABLE_TALLOC, test "x$enable_talloc" = "x1")
|
||||
|
||||
AC_ARG_ENABLE(tests,
|
||||
[ --disable-tests Disable building test programs ],
|
||||
[enable_tests=0], [enable_tests=1])
|
||||
AM_CONDITIONAL(ENABLE_TESTS, test "x$enable_tests" = "x1")
|
||||
|
||||
AC_OUTPUT(
|
||||
libosmocore.pc
|
||||
include/osmocore/Makefile
|
||||
include/osmocore/protocol/Makefile
|
||||
include/Makefile
|
||||
src/Makefile
|
||||
tests/Makefile
|
||||
tests/timer/Makefile
|
||||
tests/sms/Makefile
|
||||
Makefile)
|
||||
@@ -1 +0,0 @@
|
||||
SUBDIRS = osmocore
|
||||
@@ -1,12 +0,0 @@
|
||||
osmocore_HEADERS = signal.h linuxlist.h timer.h select.h msgb.h \
|
||||
tlv.h bitvec.h comp128.h statistics.h gsm_utils.h utils.h \
|
||||
gsmtap.h write_queue.h rsl.h gsm48.h rxlev_stat.h mncc.h \
|
||||
gsm48_ie.h
|
||||
|
||||
if ENABLE_TALLOC
|
||||
osmocore_HEADERS += talloc.h
|
||||
endif
|
||||
|
||||
osmocoredir = $(includedir)/osmocore
|
||||
|
||||
SUBDIRS = protocol
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* COMP128 header
|
||||
*
|
||||
* See comp128.c for details
|
||||
*/
|
||||
|
||||
#ifndef __COMP128_H__
|
||||
#define __COMP128_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Performs the COMP128 algorithm (used as A3/A8)
|
||||
* ki : uint8_t [16]
|
||||
* srand : uint8_t [16]
|
||||
* sres : uint8_t [4]
|
||||
* kc : uint8_t [8]
|
||||
*/
|
||||
void comp128(uint8_t *ki, uint8_t *srand, uint8_t *sres, uint8_t *kc);
|
||||
|
||||
#endif /* __COMP128_H__ */
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#ifndef _OSMOCORE_GSM48_H
|
||||
|
||||
#include <osmocore/tlv.h>
|
||||
#include <osmocore/protocol/gsm_04_08.h>
|
||||
#include <osmocore/gsm48_ie.h>
|
||||
|
||||
extern const struct tlv_definition gsm48_att_tlvdef;
|
||||
extern const char *cc_state_names[32];
|
||||
extern const char *gsm48_cc_msg_names[0x40];
|
||||
const char *rr_cause_name(uint8_t cause);
|
||||
|
||||
void gsm48_generate_lai(struct gsm48_loc_area_id *lai48, uint16_t mcc,
|
||||
uint16_t mnc, uint16_t lac);
|
||||
int gsm48_generate_mid_from_tmsi(uint8_t *buf, uint32_t tmsi);
|
||||
int gsm48_generate_mid_from_imsi(uint8_t *buf, const char *imsi);
|
||||
|
||||
#endif
|
||||
@@ -1,107 +0,0 @@
|
||||
#ifndef _OSMOCORE_GSM48_IE_H
|
||||
#define _OSMOCORE_GSM48_IE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/tlv.h>
|
||||
#include <osmocore/mncc.h>
|
||||
#include <osmocore/protocol/gsm_04_08.h>
|
||||
|
||||
/* decode a 'called/calling/connect party BCD number' as in 10.5.4.7 */
|
||||
int gsm48_decode_bcd_number(char *output, int output_len,
|
||||
const uint8_t *bcd_lv, int h_len);
|
||||
|
||||
/* convert a ASCII phone number to 'called/calling/connect party BCD number' */
|
||||
int gsm48_encode_bcd_number(uint8_t *bcd_lv, uint8_t max_len,
|
||||
int h_len, const char *input);
|
||||
/* decode 'bearer capability' */
|
||||
int gsm48_decode_bearer_cap(struct gsm_mncc_bearer_cap *bcap,
|
||||
const uint8_t *lv);
|
||||
/* encode 'bearer capability' */
|
||||
int gsm48_encode_bearer_cap(struct msgb *msg, int lv_only,
|
||||
const struct gsm_mncc_bearer_cap *bcap);
|
||||
/* decode 'call control cap' */
|
||||
int gsm48_decode_cccap(struct gsm_mncc_cccap *ccap, const uint8_t *lv);
|
||||
/* encode 'call control cap' */
|
||||
int gsm48_encode_cccap(struct msgb *msg,
|
||||
const struct gsm_mncc_cccap *ccap);
|
||||
/* decode 'called party BCD number' */
|
||||
int gsm48_decode_called(struct gsm_mncc_number *called,
|
||||
const uint8_t *lv);
|
||||
/* encode 'called party BCD number' */
|
||||
int gsm48_encode_called(struct msgb *msg,
|
||||
const struct gsm_mncc_number *called);
|
||||
/* decode callerid of various IEs */
|
||||
int gsm48_decode_callerid(struct gsm_mncc_number *callerid,
|
||||
const uint8_t *lv);
|
||||
/* encode callerid of various IEs */
|
||||
int gsm48_encode_callerid(struct msgb *msg, int ie, int max_len,
|
||||
const struct gsm_mncc_number *callerid);
|
||||
/* decode 'cause' */
|
||||
int gsm48_decode_cause(struct gsm_mncc_cause *cause,
|
||||
const uint8_t *lv);
|
||||
/* encode 'cause' */
|
||||
int gsm48_encode_cause(struct msgb *msg, int lv_only,
|
||||
const struct gsm_mncc_cause *cause);
|
||||
/* decode 'calling number' */
|
||||
int gsm48_decode_calling(struct gsm_mncc_number *calling,
|
||||
const uint8_t *lv);
|
||||
/* encode 'calling number' */
|
||||
int gsm48_encode_calling(struct msgb *msg,
|
||||
const struct gsm_mncc_number *calling);
|
||||
/* decode 'connected number' */
|
||||
int gsm48_decode_connected(struct gsm_mncc_number *connected,
|
||||
const uint8_t *lv);
|
||||
/* encode 'connected number' */
|
||||
int gsm48_encode_connected(struct msgb *msg,
|
||||
const struct gsm_mncc_number *connected);
|
||||
/* decode 'redirecting number' */
|
||||
int gsm48_decode_redirecting(struct gsm_mncc_number *redirecting,
|
||||
const uint8_t *lv);
|
||||
/* encode 'redirecting number' */
|
||||
int gsm48_encode_redirecting(struct msgb *msg,
|
||||
const struct gsm_mncc_number *redirecting);
|
||||
/* decode 'facility' */
|
||||
int gsm48_decode_facility(struct gsm_mncc_facility *facility,
|
||||
const uint8_t *lv);
|
||||
/* encode 'facility' */
|
||||
int gsm48_encode_facility(struct msgb *msg, int lv_only,
|
||||
const struct gsm_mncc_facility *facility);
|
||||
/* decode 'notify' */
|
||||
int gsm48_decode_notify(int *notify, const uint8_t *v);
|
||||
/* encode 'notify' */
|
||||
int gsm48_encode_notify(struct msgb *msg, int notify);
|
||||
/* decode 'signal' */
|
||||
int gsm48_decode_signal(int *signal, const uint8_t *v);
|
||||
/* encode 'signal' */
|
||||
int gsm48_encode_signal(struct msgb *msg, int signal);
|
||||
/* decode 'keypad' */
|
||||
int gsm48_decode_keypad(int *keypad, const uint8_t *lv);
|
||||
/* encode 'keypad' */
|
||||
int gsm48_encode_keypad(struct msgb *msg, int keypad);
|
||||
/* decode 'progress' */
|
||||
int gsm48_decode_progress(struct gsm_mncc_progress *progress,
|
||||
const uint8_t *lv);
|
||||
/* encode 'progress' */
|
||||
int gsm48_encode_progress(struct msgb *msg, int lv_only,
|
||||
const struct gsm_mncc_progress *p);
|
||||
/* decode 'user-user' */
|
||||
int gsm48_decode_useruser(struct gsm_mncc_useruser *uu,
|
||||
const uint8_t *lv);
|
||||
/* encode 'useruser' */
|
||||
int gsm48_encode_useruser(struct msgb *msg, int lv_only,
|
||||
const struct gsm_mncc_useruser *uu);
|
||||
/* decode 'ss version' */
|
||||
int gsm48_decode_ssversion(struct gsm_mncc_ssversion *ssv,
|
||||
const uint8_t *lv);
|
||||
/* encode 'ss version' */
|
||||
int gsm48_encode_ssversion(struct msgb *msg,
|
||||
const struct gsm_mncc_ssversion *ssv);
|
||||
/* decode 'more data' does not require a function, because it has no value */
|
||||
/* encode 'more data' */
|
||||
int gsm48_encode_more(struct msgb *msg);
|
||||
|
||||
#endif
|
||||
@@ -1,84 +0,0 @@
|
||||
/* GSM utility functions, e.g. coding and decoding */
|
||||
/*
|
||||
* (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
|
||||
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GSM_UTILS_H
|
||||
#define GSM_UTILS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct gsm_time {
|
||||
uint32_t fn; /* FN count */
|
||||
uint16_t t1; /* FN div (26*51) */
|
||||
uint8_t t2; /* FN modulo 26 */
|
||||
uint8_t t3; /* FN modulo 51 */
|
||||
uint8_t tc;
|
||||
};
|
||||
|
||||
enum gsm_band {
|
||||
GSM_BAND_850 = 1,
|
||||
GSM_BAND_900 = 2,
|
||||
GSM_BAND_1800 = 4,
|
||||
GSM_BAND_1900 = 8,
|
||||
GSM_BAND_450 = 0x10,
|
||||
GSM_BAND_480 = 0x20,
|
||||
GSM_BAND_750 = 0x40,
|
||||
GSM_BAND_810 = 0x80,
|
||||
};
|
||||
|
||||
const char *gsm_band_name(enum gsm_band band);
|
||||
enum gsm_band gsm_band_parse(const char *mhz);
|
||||
|
||||
int gsm_7bit_decode(char *decoded, const uint8_t *user_data, uint8_t length);
|
||||
int gsm_7bit_encode(uint8_t *result, const char *data);
|
||||
|
||||
int ms_pwr_ctl_lvl(enum gsm_band band, unsigned int dbm);
|
||||
int ms_pwr_dbm(enum gsm_band band, uint8_t lvl);
|
||||
|
||||
/* According to TS 08.05 Chapter 8.1.4 */
|
||||
int rxlev2dbm(uint8_t rxlev);
|
||||
uint8_t dbm2rxlev(int dbm);
|
||||
|
||||
/* According to GSM 04.08 Chapter 10.5.2.29 */
|
||||
static inline int rach_max_trans_val2raw(int val) { return (val >> 1) & 3; }
|
||||
static inline int rach_max_trans_raw2val(int raw) {
|
||||
const int tbl[4] = { 1, 2, 4, 7 };
|
||||
return tbl[raw & 3];
|
||||
}
|
||||
|
||||
#define ARFCN_PCS 0x8000
|
||||
#define ARFCN_UPLINK 0x4000
|
||||
|
||||
enum gsm_band gsm_arfcn2band(uint16_t arfcn);
|
||||
|
||||
/* Convert an ARFCN to the frequency in MHz * 10 */
|
||||
uint16_t gsm_arfcn2freq10(uint16_t arfcn, int uplink);
|
||||
|
||||
/* Convert from frame number to GSM time */
|
||||
void gsm_fn2gsmtime(struct gsm_time *time, uint32_t fn);
|
||||
|
||||
/* Convert from GSM time to frame number */
|
||||
uint32_t gsm_gsmtime2fn(struct gsm_time *time);
|
||||
|
||||
void generate_backtrace();
|
||||
#endif
|
||||
@@ -1,72 +0,0 @@
|
||||
#ifndef _GSMTAP_H
|
||||
#define _GSMTAP_H
|
||||
|
||||
/* gsmtap header, pseudo-header in front of the actua GSM payload */
|
||||
|
||||
/* GSMTAP is a generic header format for GSM protocol captures,
|
||||
* it uses the IANA-assigned UDP port number 4729 and carries
|
||||
* payload in various formats of GSM interfaces such as Um MAC
|
||||
* blocks or Um bursts.
|
||||
*
|
||||
* Example programs generating GSMTAP data are airprobe
|
||||
* (http://airprobe.org/) or OsmocomBB (http://bb.osmocom.org/)
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define GSMTAP_VERSION 0x02
|
||||
|
||||
#define GSMTAP_TYPE_UM 0x01
|
||||
#define GSMTAP_TYPE_ABIS 0x02
|
||||
#define GSMTAP_TYPE_UM_BURST 0x03 /* raw burst bits */
|
||||
|
||||
#define GSMTAP_BURST_UNKNOWN 0x00
|
||||
#define GSMTAP_BURST_FCCH 0x01
|
||||
#define GSMTAP_BURST_PARTIAL_SCH 0x02
|
||||
#define GSMTAP_BURST_SCH 0x03
|
||||
#define GSMTAP_BURST_CTS_SCH 0x04
|
||||
#define GSMTAP_BURST_COMPACT_SCH 0x05
|
||||
#define GSMTAP_BURST_NORMAL 0x06
|
||||
#define GSMTAP_BURST_DUMMY 0x07
|
||||
#define GSMTAP_BURST_ACCESS 0x08
|
||||
#define GSMTAP_BURST_NONE 0x09
|
||||
|
||||
#define GSMTAP_CHANNEL_UNKNOWN 0x00
|
||||
#define GSMTAP_CHANNEL_BCCH 0x01
|
||||
#define GSMTAP_CHANNEL_CCCH 0x02
|
||||
#define GSMTAP_CHANNEL_RACH 0x03
|
||||
#define GSMTAP_CHANNEL_AGCH 0x04
|
||||
#define GSMTAP_CHANNEL_PCH 0x05
|
||||
#define GSMTAP_CHANNEL_SDCCH 0x06
|
||||
#define GSMTAP_CHANNEL_SDCCH4 0x07
|
||||
#define GSMTAP_CHANNEL_SDCCH8 0x08
|
||||
#define GSMTAP_CHANNEL_TCH_F 0x09
|
||||
#define GSMTAP_CHANNEL_TCH_H 0x0a
|
||||
#define GSMTAP_CHANNEL_ACCH 0x80
|
||||
|
||||
#define GSMTAP_ARFCN_F_PCS 0x8000
|
||||
#define GSMTAP_ARFCN_F_UPLINK 0x4000
|
||||
#define GSMTAP_ARFCN_MASK 0x3fff
|
||||
|
||||
#define GSMTAP_UDP_PORT 4729
|
||||
|
||||
struct gsmtap_hdr {
|
||||
uint8_t version; /* version, set to 0x01 currently */
|
||||
uint8_t hdr_len; /* length in number of 32bit words */
|
||||
uint8_t type; /* see GSMTAP_TYPE_* */
|
||||
uint8_t timeslot; /* timeslot (0..7 on Um) */
|
||||
|
||||
uint16_t arfcn; /* ARFCN (frequency) */
|
||||
int8_t signal_dbm; /* signal level in dBm */
|
||||
int8_t snr_db; /* signal/noise ratio in dB */
|
||||
|
||||
uint32_t frame_number; /* GSM Frame Number (FN) */
|
||||
|
||||
uint8_t sub_type; /* Type of burst/channel, see above */
|
||||
uint8_t antenna_nr; /* Antenna Number */
|
||||
uint8_t sub_slot; /* sub-slot within timeslot */
|
||||
uint8_t res; /* reserved for future use (RFU) */
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
#endif /* _GSMTAP_H */
|
||||
@@ -1,71 +0,0 @@
|
||||
#ifndef _OSMOCORE_MNCC_H
|
||||
#define _OSMOCORE_MNCC_H
|
||||
|
||||
#define GSM_MAX_FACILITY 128
|
||||
#define GSM_MAX_SSVERSION 128
|
||||
#define GSM_MAX_USERUSER 128
|
||||
|
||||
/* Expanded fields from GSM TS 04.08, Table 10.5.102 */
|
||||
struct gsm_mncc_bearer_cap {
|
||||
int transfer; /* Information Transfer Capability */
|
||||
int mode; /* Transfer Mode */
|
||||
int coding; /* Coding Standard */
|
||||
int radio; /* Radio Channel Requirement */
|
||||
int speech_ctm; /* CTM text telephony indication */
|
||||
int speech_ver[8]; /* Speech version indication */
|
||||
};
|
||||
|
||||
struct gsm_mncc_number {
|
||||
int type;
|
||||
int plan;
|
||||
int present;
|
||||
int screen;
|
||||
char number[33];
|
||||
};
|
||||
|
||||
struct gsm_mncc_cause {
|
||||
int location;
|
||||
int coding;
|
||||
int rec;
|
||||
int rec_val;
|
||||
int value;
|
||||
int diag_len;
|
||||
char diag[32];
|
||||
};
|
||||
|
||||
struct gsm_mncc_useruser {
|
||||
int proto;
|
||||
char info[GSM_MAX_USERUSER + 1]; /* + termination char */
|
||||
};
|
||||
|
||||
struct gsm_mncc_progress {
|
||||
int coding;
|
||||
int location;
|
||||
int descr;
|
||||
};
|
||||
|
||||
struct gsm_mncc_facility {
|
||||
int len;
|
||||
char info[GSM_MAX_FACILITY];
|
||||
};
|
||||
|
||||
struct gsm_mncc_ssversion {
|
||||
int len;
|
||||
char info[GSM_MAX_SSVERSION];
|
||||
};
|
||||
|
||||
struct gsm_mncc_cccap {
|
||||
int dtmf;
|
||||
int pcp;
|
||||
};
|
||||
|
||||
enum {
|
||||
GSM_MNCC_BCAP_SPEECH = 0,
|
||||
GSM_MNCC_BCAP_UNR_DIG = 1,
|
||||
GSM_MNCC_BCAP_AUDIO = 2,
|
||||
GSM_MNCC_BCAP_FAX_G3 = 3,
|
||||
GSM_MNCC_BCAP_OTHER_ITC = 5,
|
||||
GSM_MNCC_BCAP_RESERVED = 7,
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,3 +0,0 @@
|
||||
osmocore_proto_HEADERS = gsm_04_08.h gsm_04_11.h gsm_04_80.h gsm_08_58.h gsm_12_21.h
|
||||
|
||||
osmocore_protodir = $(includedir)/osmocore/protocol
|
||||
@@ -1,743 +0,0 @@
|
||||
#ifndef PROTO_GSM_04_08_H
|
||||
#define PROTO_GSM_04_08_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* GSM TS 04.08 definitions */
|
||||
struct gsm_lchan;
|
||||
|
||||
struct gsm48_classmark1 {
|
||||
uint8_t spare:1,
|
||||
rev_level:2,
|
||||
es_ind:1,
|
||||
a5_1:1,
|
||||
pwr_lev:3;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Chapter 10.5.2.5 */
|
||||
struct gsm48_chan_desc {
|
||||
uint8_t chan_nr;
|
||||
union {
|
||||
struct {
|
||||
uint8_t maio_high:4,
|
||||
h:1,
|
||||
tsc:3;
|
||||
uint8_t hsn:6,
|
||||
maio_low:2;
|
||||
} h1;
|
||||
struct {
|
||||
uint8_t arfcn_high:2,
|
||||
spare:2,
|
||||
h:1,
|
||||
tsc:3;
|
||||
uint8_t arfcn_low;
|
||||
} h0;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Chapter 10.5.2.21aa */
|
||||
struct gsm48_multi_rate_conf {
|
||||
uint8_t smod : 2,
|
||||
spare: 1,
|
||||
icmi : 1,
|
||||
nscb : 1,
|
||||
ver : 3;
|
||||
uint8_t m4_75 : 1,
|
||||
m5_15 : 1,
|
||||
m5_90 : 1,
|
||||
m6_70 : 1,
|
||||
m7_40 : 1,
|
||||
m7_95 : 1,
|
||||
m10_2 : 1,
|
||||
m12_2 : 1;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Chapter 10.5.2.30 */
|
||||
struct gsm48_req_ref {
|
||||
uint8_t ra;
|
||||
uint8_t t3_high:3,
|
||||
t1_:5;
|
||||
uint8_t t2:5,
|
||||
t3_low:3;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/*
|
||||
* Chapter 9.1.5/9.1.6
|
||||
*
|
||||
* For 9.1.6 the chan_desc has the meaning of 10.5.2.5a
|
||||
*/
|
||||
struct gsm48_chan_mode_modify {
|
||||
struct gsm48_chan_desc chan_desc;
|
||||
uint8_t mode;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
enum gsm48_chan_mode {
|
||||
GSM48_CMODE_SIGN = 0x00,
|
||||
GSM48_CMODE_SPEECH_V1 = 0x01,
|
||||
GSM48_CMODE_SPEECH_EFR = 0x21,
|
||||
GSM48_CMODE_SPEECH_AMR = 0x41,
|
||||
GSM48_CMODE_DATA_14k5 = 0x0f,
|
||||
GSM48_CMODE_DATA_12k0 = 0x03,
|
||||
GSM48_CMODE_DATA_6k0 = 0x0b,
|
||||
GSM48_CMODE_DATA_3k6 = 0x23,
|
||||
};
|
||||
|
||||
/* Chapter 9.1.2 */
|
||||
struct gsm48_ass_cmd {
|
||||
/* Semantic is from 10.5.2.5a */
|
||||
struct gsm48_chan_desc chan_desc;
|
||||
uint8_t power_command;
|
||||
uint8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Chapter 10.5.2.2 */
|
||||
struct gsm48_cell_desc {
|
||||
uint8_t bcc:3,
|
||||
ncc:3,
|
||||
arfcn_hi:2;
|
||||
uint8_t arfcn_lo;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Chapter 9.1.15 */
|
||||
struct gsm48_ho_cmd {
|
||||
struct gsm48_cell_desc cell_desc;
|
||||
struct gsm48_chan_desc chan_desc;
|
||||
uint8_t ho_ref;
|
||||
uint8_t power_command;
|
||||
uint8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Chapter 9.1.18 */
|
||||
struct gsm48_imm_ass {
|
||||
uint8_t l2_plen;
|
||||
uint8_t proto_discr;
|
||||
uint8_t msg_type;
|
||||
uint8_t page_mode;
|
||||
struct gsm48_chan_desc chan_desc;
|
||||
struct gsm48_req_ref req_ref;
|
||||
uint8_t timing_advance;
|
||||
uint8_t mob_alloc_len;
|
||||
uint8_t mob_alloc[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Chapter 10.5.1.3 */
|
||||
struct gsm48_loc_area_id {
|
||||
uint8_t digits[3]; /* BCD! */
|
||||
uint16_t lac;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.2.2 */
|
||||
struct gsm48_auth_req {
|
||||
uint8_t key_seq:4,
|
||||
spare:4;
|
||||
uint8_t rand[16];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.2.15 */
|
||||
struct gsm48_loc_upd_req {
|
||||
uint8_t type:4,
|
||||
key_seq:4;
|
||||
struct gsm48_loc_area_id lai;
|
||||
struct gsm48_classmark1 classmark1;
|
||||
uint8_t mi_len;
|
||||
uint8_t mi[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 10.1 */
|
||||
struct gsm48_hdr {
|
||||
uint8_t proto_discr;
|
||||
uint8_t msg_type;
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.3x System information Type header */
|
||||
struct gsm48_system_information_type_header {
|
||||
uint8_t l2_plen;
|
||||
uint8_t rr_protocol_discriminator :4,
|
||||
skip_indicator:4;
|
||||
uint8_t system_information;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct gsm48_rach_control {
|
||||
uint8_t re :1,
|
||||
cell_bar :1,
|
||||
tx_integer :4,
|
||||
max_trans :2;
|
||||
uint8_t t2;
|
||||
uint8_t t3;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 10.5.2.4 Cell Selection Parameters */
|
||||
struct gsm48_cell_sel_par {
|
||||
uint8_t ms_txpwr_max_ccch:5, /* GSM 05.08 MS-TXPWR-MAX-CCCH */
|
||||
cell_resel_hyst:3; /* GSM 05.08 CELL-RESELECT-HYSTERESIS */
|
||||
uint8_t rxlev_acc_min:6, /* GSM 05.08 RXLEV-ACCESS-MIN */
|
||||
neci:1,
|
||||
acs:1;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 10.5.2.11 Control Channel Description , Figure 10.5.33 */
|
||||
struct gsm48_control_channel_descr {
|
||||
uint8_t ccch_conf :3,
|
||||
bs_ag_blks_res :3,
|
||||
att :1,
|
||||
spare1 :1;
|
||||
uint8_t bs_pa_mfrms : 3,
|
||||
spare2 :5;
|
||||
uint8_t t3212;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct gsm48_cell_options {
|
||||
uint8_t radio_link_timeout:4,
|
||||
dtx:2,
|
||||
pwrc:1,
|
||||
spare:1;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.2.9 CM service request */
|
||||
struct gsm48_service_request {
|
||||
uint8_t cm_service_type : 4,
|
||||
cipher_key_seq : 4;
|
||||
/* length + 3 bytes */
|
||||
uint32_t classmark;
|
||||
uint8_t mi_len;
|
||||
uint8_t mi[0];
|
||||
/* optional priority level */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.31 System information Type 1 */
|
||||
struct gsm48_system_information_type_1 {
|
||||
struct gsm48_system_information_type_header header;
|
||||
uint8_t cell_channel_description[16];
|
||||
struct gsm48_rach_control rach_control;
|
||||
uint8_t rest_octets[0]; /* NCH position on the CCCH */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.32 System information Type 2 */
|
||||
struct gsm48_system_information_type_2 {
|
||||
struct gsm48_system_information_type_header header;
|
||||
uint8_t bcch_frequency_list[16];
|
||||
uint8_t ncc_permitted;
|
||||
struct gsm48_rach_control rach_control;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.35 System information Type 3 */
|
||||
struct gsm48_system_information_type_3 {
|
||||
struct gsm48_system_information_type_header header;
|
||||
uint16_t cell_identity;
|
||||
struct gsm48_loc_area_id lai;
|
||||
struct gsm48_control_channel_descr control_channel_desc;
|
||||
struct gsm48_cell_options cell_options;
|
||||
struct gsm48_cell_sel_par cell_sel_par;
|
||||
struct gsm48_rach_control rach_control;
|
||||
uint8_t rest_octets[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.36 System information Type 4 */
|
||||
struct gsm48_system_information_type_4 {
|
||||
struct gsm48_system_information_type_header header;
|
||||
struct gsm48_loc_area_id lai;
|
||||
struct gsm48_cell_sel_par cell_sel_par;
|
||||
struct gsm48_rach_control rach_control;
|
||||
/* optional CBCH conditional CBCH... followed by
|
||||
mandantory SI 4 Reset Octets
|
||||
*/
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.37 System information Type 5 */
|
||||
struct gsm48_system_information_type_5 {
|
||||
uint8_t rr_protocol_discriminator :4,
|
||||
skip_indicator:4;
|
||||
uint8_t system_information;
|
||||
uint8_t bcch_frequency_list[16];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.40 System information Type 6 */
|
||||
struct gsm48_system_information_type_6 {
|
||||
uint8_t rr_protocol_discriminator :4,
|
||||
skip_indicator:4;
|
||||
uint8_t system_information;
|
||||
uint16_t cell_identity;
|
||||
struct gsm48_loc_area_id lai;
|
||||
struct gsm48_cell_options cell_options;
|
||||
uint8_t ncc_permitted;
|
||||
uint8_t rest_octets[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.43a System Information type 13 */
|
||||
struct gsm48_system_information_type_13 {
|
||||
struct gsm48_system_information_type_header header;
|
||||
uint8_t rest_octets[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.2.12 IMSI Detach Indication */
|
||||
struct gsm48_imsi_detach_ind {
|
||||
struct gsm48_classmark1 classmark1;
|
||||
uint8_t mi_len;
|
||||
uint8_t mi[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 10.2 + GSM 04.07 12.2.3.1.1 */
|
||||
#define GSM48_PDISC_GROUP_CC 0x00
|
||||
#define GSM48_PDISC_BCAST_CC 0x01
|
||||
#define GSM48_PDISC_PDSS1 0x02
|
||||
#define GSM48_PDISC_CC 0x03
|
||||
#define GSM48_PDISC_PDSS2 0x04
|
||||
#define GSM48_PDISC_MM 0x05
|
||||
#define GSM48_PDISC_RR 0x06
|
||||
#define GSM48_PDISC_MM_GPRS 0x08
|
||||
#define GSM48_PDISC_SMS 0x09
|
||||
#define GSM48_PDISC_SM_GPRS 0x0a
|
||||
#define GSM48_PDISC_NC_SS 0x0b
|
||||
#define GSM48_PDISC_LOC 0x0c
|
||||
#define GSM48_PDISC_MASK 0x0f
|
||||
#define GSM48_PDISC_USSD 0x11
|
||||
|
||||
/* Section 10.4 */
|
||||
#define GSM48_MT_RR_INIT_REQ 0x3c
|
||||
#define GSM48_MT_RR_ADD_ASS 0x3b
|
||||
#define GSM48_MT_RR_IMM_ASS 0x3f
|
||||
#define GSM48_MT_RR_IMM_ASS_EXT 0x39
|
||||
#define GSM48_MT_RR_IMM_ASS_REJ 0x3a
|
||||
|
||||
#define GSM48_MT_RR_CIPH_M_CMD 0x35
|
||||
#define GSM48_MT_RR_CIPH_M_COMPL 0x32
|
||||
|
||||
#define GSM48_MT_RR_CFG_CHG_CMD 0x30
|
||||
#define GSM48_MT_RR_CFG_CHG_ACK 0x31
|
||||
#define GSM48_MT_RR_CFG_CHG_REJ 0x33
|
||||
|
||||
#define GSM48_MT_RR_ASS_CMD 0x2e
|
||||
#define GSM48_MT_RR_ASS_COMPL 0x29
|
||||
#define GSM48_MT_RR_ASS_FAIL 0x2f
|
||||
#define GSM48_MT_RR_HANDO_CMD 0x2b
|
||||
#define GSM48_MT_RR_HANDO_COMPL 0x2c
|
||||
#define GSM48_MT_RR_HANDO_FAIL 0x28
|
||||
#define GSM48_MT_RR_HANDO_INFO 0x2d
|
||||
|
||||
#define GSM48_MT_RR_CELL_CHG_ORDER 0x08
|
||||
#define GSM48_MT_RR_PDCH_ASS_CMD 0x23
|
||||
|
||||
#define GSM48_MT_RR_CHAN_REL 0x0d
|
||||
#define GSM48_MT_RR_PART_REL 0x0a
|
||||
#define GSM48_MT_RR_PART_REL_COMP 0x0f
|
||||
|
||||
#define GSM48_MT_RR_PAG_REQ_1 0x21
|
||||
#define GSM48_MT_RR_PAG_REQ_2 0x22
|
||||
#define GSM48_MT_RR_PAG_REQ_3 0x24
|
||||
#define GSM48_MT_RR_PAG_RESP 0x27
|
||||
#define GSM48_MT_RR_NOTIF_NCH 0x20
|
||||
#define GSM48_MT_RR_NOTIF_FACCH 0x25
|
||||
#define GSM48_MT_RR_NOTIF_RESP 0x26
|
||||
|
||||
#define GSM48_MT_RR_SYSINFO_8 0x18
|
||||
#define GSM48_MT_RR_SYSINFO_1 0x19
|
||||
#define GSM48_MT_RR_SYSINFO_2 0x1a
|
||||
#define GSM48_MT_RR_SYSINFO_3 0x1b
|
||||
#define GSM48_MT_RR_SYSINFO_4 0x1c
|
||||
#define GSM48_MT_RR_SYSINFO_5 0x1d
|
||||
#define GSM48_MT_RR_SYSINFO_6 0x1e
|
||||
#define GSM48_MT_RR_SYSINFO_7 0x1f
|
||||
|
||||
#define GSM48_MT_RR_SYSINFO_2bis 0x02
|
||||
#define GSM48_MT_RR_SYSINFO_2ter 0x03
|
||||
#define GSM48_MT_RR_SYSINFO_5bis 0x05
|
||||
#define GSM48_MT_RR_SYSINFO_5ter 0x06
|
||||
#define GSM48_MT_RR_SYSINFO_9 0x04
|
||||
#define GSM48_MT_RR_SYSINFO_13 0x00
|
||||
|
||||
#define GSM48_MT_RR_SYSINFO_16 0x3d
|
||||
#define GSM48_MT_RR_SYSINFO_17 0x3e
|
||||
|
||||
#define GSM48_MT_RR_CHAN_MODE_MODIF 0x10
|
||||
#define GSM48_MT_RR_STATUS 0x12
|
||||
#define GSM48_MT_RR_CHAN_MODE_MODIF_ACK 0x17
|
||||
#define GSM48_MT_RR_FREQ_REDEF 0x14
|
||||
#define GSM48_MT_RR_MEAS_REP 0x15
|
||||
#define GSM48_MT_RR_CLSM_CHG 0x16
|
||||
#define GSM48_MT_RR_CLSM_ENQ 0x13
|
||||
#define GSM48_MT_RR_EXT_MEAS_REP 0x36
|
||||
#define GSM48_MT_RR_EXT_MEAS_REP_ORD 0x37
|
||||
#define GSM48_MT_RR_GPRS_SUSP_REQ 0x34
|
||||
|
||||
#define GSM48_MT_RR_VGCS_UPL_GRANT 0x08
|
||||
#define GSM48_MT_RR_UPLINK_RELEASE 0x0e
|
||||
#define GSM48_MT_RR_UPLINK_FREE 0x0c
|
||||
#define GSM48_MT_RR_UPLINK_BUSY 0x2a
|
||||
#define GSM48_MT_RR_TALKER_IND 0x11
|
||||
|
||||
#define GSM48_MT_RR_APP_INFO 0x38
|
||||
|
||||
/* Table 10.2/3GPP TS 04.08 */
|
||||
#define GSM48_MT_MM_IMSI_DETACH_IND 0x01
|
||||
#define GSM48_MT_MM_LOC_UPD_ACCEPT 0x02
|
||||
#define GSM48_MT_MM_LOC_UPD_REJECT 0x04
|
||||
#define GSM48_MT_MM_LOC_UPD_REQUEST 0x08
|
||||
|
||||
#define GSM48_MT_MM_AUTH_REJ 0x11
|
||||
#define GSM48_MT_MM_AUTH_REQ 0x12
|
||||
#define GSM48_MT_MM_AUTH_RESP 0x14
|
||||
#define GSM48_MT_MM_ID_REQ 0x18
|
||||
#define GSM48_MT_MM_ID_RESP 0x19
|
||||
#define GSM48_MT_MM_TMSI_REALL_CMD 0x1a
|
||||
#define GSM48_MT_MM_TMSI_REALL_COMPL 0x1b
|
||||
|
||||
#define GSM48_MT_MM_CM_SERV_ACC 0x21
|
||||
#define GSM48_MT_MM_CM_SERV_REJ 0x22
|
||||
#define GSM48_MT_MM_CM_SERV_ABORT 0x23
|
||||
#define GSM48_MT_MM_CM_SERV_REQ 0x24
|
||||
#define GSM48_MT_MM_CM_SERV_PROMPT 0x25
|
||||
#define GSM48_MT_MM_CM_REEST_REQ 0x28
|
||||
#define GSM48_MT_MM_ABORT 0x29
|
||||
|
||||
#define GSM48_MT_MM_NULL 0x30
|
||||
#define GSM48_MT_MM_STATUS 0x31
|
||||
#define GSM48_MT_MM_INFO 0x32
|
||||
|
||||
/* Table 10.3/3GPP TS 04.08 */
|
||||
#define GSM48_MT_CC_ALERTING 0x01
|
||||
#define GSM48_MT_CC_CALL_CONF 0x08
|
||||
#define GSM48_MT_CC_CALL_PROC 0x02
|
||||
#define GSM48_MT_CC_CONNECT 0x07
|
||||
#define GSM48_MT_CC_CONNECT_ACK 0x0f
|
||||
#define GSM48_MT_CC_EMERG_SETUP 0x0e
|
||||
#define GSM48_MT_CC_PROGRESS 0x03
|
||||
#define GSM48_MT_CC_ESTAB 0x04
|
||||
#define GSM48_MT_CC_ESTAB_CONF 0x06
|
||||
#define GSM48_MT_CC_RECALL 0x0b
|
||||
#define GSM48_MT_CC_START_CC 0x09
|
||||
#define GSM48_MT_CC_SETUP 0x05
|
||||
|
||||
#define GSM48_MT_CC_MODIFY 0x17
|
||||
#define GSM48_MT_CC_MODIFY_COMPL 0x1f
|
||||
#define GSM48_MT_CC_MODIFY_REJECT 0x13
|
||||
#define GSM48_MT_CC_USER_INFO 0x10
|
||||
#define GSM48_MT_CC_HOLD 0x18
|
||||
#define GSM48_MT_CC_HOLD_ACK 0x19
|
||||
#define GSM48_MT_CC_HOLD_REJ 0x1a
|
||||
#define GSM48_MT_CC_RETR 0x1c
|
||||
#define GSM48_MT_CC_RETR_ACK 0x1d
|
||||
#define GSM48_MT_CC_RETR_REJ 0x1e
|
||||
|
||||
#define GSM48_MT_CC_DISCONNECT 0x25
|
||||
#define GSM48_MT_CC_RELEASE 0x2d
|
||||
#define GSM48_MT_CC_RELEASE_COMPL 0x2a
|
||||
|
||||
#define GSM48_MT_CC_CONG_CTRL 0x39
|
||||
#define GSM48_MT_CC_NOTIFY 0x3e
|
||||
#define GSM48_MT_CC_STATUS 0x3d
|
||||
#define GSM48_MT_CC_STATUS_ENQ 0x34
|
||||
#define GSM48_MT_CC_START_DTMF 0x35
|
||||
#define GSM48_MT_CC_STOP_DTMF 0x31
|
||||
#define GSM48_MT_CC_STOP_DTMF_ACK 0x32
|
||||
#define GSM48_MT_CC_START_DTMF_ACK 0x36
|
||||
#define GSM48_MT_CC_START_DTMF_REJ 0x37
|
||||
#define GSM48_MT_CC_FACILITY 0x3a
|
||||
|
||||
/* FIXME: Table 10.4 / 10.4a (GPRS) */
|
||||
|
||||
/* Section 10.5.2.26, Table 10.5.64 */
|
||||
#define GSM48_PM_MASK 0x03
|
||||
#define GSM48_PM_NORMAL 0x00
|
||||
#define GSM48_PM_EXTENDED 0x01
|
||||
#define GSM48_PM_REORG 0x02
|
||||
#define GSM48_PM_SAME 0x03
|
||||
|
||||
/* Chapter 10.5.3.5 / Table 10.5.93 */
|
||||
#define GSM48_LUPD_NORMAL 0x0
|
||||
#define GSM48_LUPD_PERIODIC 0x1
|
||||
#define GSM48_LUPD_IMSI_ATT 0x2
|
||||
#define GSM48_LUPD_RESERVED 0x3
|
||||
|
||||
/* Table 10.5.4 */
|
||||
#define GSM_MI_TYPE_MASK 0x07
|
||||
#define GSM_MI_TYPE_NONE 0x00
|
||||
#define GSM_MI_TYPE_IMSI 0x01
|
||||
#define GSM_MI_TYPE_IMEI 0x02
|
||||
#define GSM_MI_TYPE_IMEISV 0x03
|
||||
#define GSM_MI_TYPE_TMSI 0x04
|
||||
#define GSM_MI_ODD 0x08
|
||||
|
||||
#define GSM48_IE_MUL_RATE_CFG 0x03 /* 10.5.2.21aa */
|
||||
#define GSM48_IE_MOBILE_ID 0x17
|
||||
#define GSM48_IE_NAME_LONG 0x43 /* 10.5.3.5a */
|
||||
#define GSM48_IE_NAME_SHORT 0x45 /* 10.5.3.5a */
|
||||
#define GSM48_IE_UTC 0x46 /* 10.5.3.8 */
|
||||
#define GSM48_IE_NET_TIME_TZ 0x47 /* 10.5.3.9 */
|
||||
#define GSM48_IE_LSA_IDENT 0x48 /* 10.5.3.11 */
|
||||
|
||||
#define GSM48_IE_BEARER_CAP 0x04 /* 10.5.4.5 */
|
||||
#define GSM48_IE_CAUSE 0x08 /* 10.5.4.11 */
|
||||
#define GSM48_IE_CC_CAP 0x15 /* 10.5.4.5a */
|
||||
#define GSM48_IE_ALERT 0x19 /* 10.5.4.26 */
|
||||
#define GSM48_IE_FACILITY 0x1c /* 10.5.4.15 */
|
||||
#define GSM48_IE_PROGR_IND 0x1e /* 10.5.4.21 */
|
||||
#define GSM48_IE_AUX_STATUS 0x24 /* 10.5.4.4 */
|
||||
#define GSM48_IE_NOTIFY 0x27 /* 10.5.4.20 */
|
||||
#define GSM48_IE_KPD_FACILITY 0x2c /* 10.5.4.17 */
|
||||
#define GSM48_IE_SIGNAL 0x34 /* 10.5.4.23 */
|
||||
#define GSM48_IE_CONN_BCD 0x4c /* 10.5.4.13 */
|
||||
#define GSM48_IE_CONN_SUB 0x4d /* 10.5.4.14 */
|
||||
#define GSM48_IE_CALLING_BCD 0x5c /* 10.5.4.9 */
|
||||
#define GSM48_IE_CALLING_SUB 0x5d /* 10.5.4.10 */
|
||||
#define GSM48_IE_CALLED_BCD 0x5e /* 10.5.4.7 */
|
||||
#define GSM48_IE_CALLED_SUB 0x6d /* 10.5.4.8 */
|
||||
#define GSM48_IE_REDIR_BCD 0x74 /* 10.5.4.21a */
|
||||
#define GSM48_IE_REDIR_SUB 0x75 /* 10.5.4.21b */
|
||||
#define GSM48_IE_LOWL_COMPAT 0x7c /* 10.5.4.18 */
|
||||
#define GSM48_IE_HIGHL_COMPAT 0x7d /* 10.5.4.16 */
|
||||
#define GSM48_IE_USER_USER 0x7e /* 10.5.4.25 */
|
||||
#define GSM48_IE_SS_VERS 0x7f /* 10.5.4.24 */
|
||||
#define GSM48_IE_MORE_DATA 0xa0 /* 10.5.4.19 */
|
||||
#define GSM48_IE_CLIR_SUPP 0xa1 /* 10.5.4.11a */
|
||||
#define GSM48_IE_CLIR_INVOC 0xa2 /* 10.5.4.11b */
|
||||
#define GSM48_IE_REV_C_SETUP 0xa3 /* 10.5.4.22a */
|
||||
#define GSM48_IE_REPEAT_CIR 0xd1 /* 10.5.4.22 */
|
||||
#define GSM48_IE_REPEAT_SEQ 0xd3 /* 10.5.4.22 */
|
||||
|
||||
/* Section 10.5.4.11 / Table 10.5.122 */
|
||||
#define GSM48_CAUSE_CS_GSM 0x60
|
||||
|
||||
/* Section 9.1.2 / Table 9.3 */
|
||||
#define GSM48_IE_FRQLIST_AFTER 0x05
|
||||
#define GSM48_IE_CELL_CH_DESC 0x62
|
||||
#define GSM48_IE_MSLOT_DESC 0x10
|
||||
#define GSM48_IE_CHANMODE_1 0x63
|
||||
#define GSM48_IE_CHANMODE_2 0x11
|
||||
#define GSM48_IE_CHANMODE_3 0x13
|
||||
#define GSM48_IE_CHANMODE_4 0x14
|
||||
#define GSM48_IE_CHANMODE_5 0x15
|
||||
#define GSM48_IE_CHANMODE_6 0x16
|
||||
#define GSM48_IE_CHANMODE_7 0x17
|
||||
#define GSM48_IE_CHANMODE_8 0x18
|
||||
#define GSM48_IE_CHANDESC_2 0x64
|
||||
/* FIXME */
|
||||
|
||||
/* Section 10.5.4.23 / Table 10.5.130 */
|
||||
enum gsm48_signal_val {
|
||||
GSM48_SIGNAL_DIALTONE = 0x00,
|
||||
GSM48_SIGNAL_RINGBACK = 0x01,
|
||||
GSM48_SIGNAL_INTERCEPT = 0x02,
|
||||
GSM48_SIGNAL_NET_CONG = 0x03,
|
||||
GSM48_SIGNAL_BUSY = 0x04,
|
||||
GSM48_SIGNAL_CONFIRM = 0x05,
|
||||
GSM48_SIGNAL_ANSWER = 0x06,
|
||||
GSM48_SIGNAL_CALL_WAIT = 0x07,
|
||||
GSM48_SIGNAL_OFF_HOOK = 0x08,
|
||||
GSM48_SIGNAL_OFF = 0x3f,
|
||||
GSM48_SIGNAL_ALERT_OFF = 0x4f,
|
||||
};
|
||||
|
||||
enum gsm48_cause_loc {
|
||||
GSM48_CAUSE_LOC_USER = 0x00,
|
||||
GSM48_CAUSE_LOC_PRN_S_LU = 0x01,
|
||||
GSM48_CAUSE_LOC_PUN_S_LU = 0x02,
|
||||
GSM48_CAUSE_LOC_TRANS_NET = 0x03,
|
||||
GSM48_CAUSE_LOC_PUN_S_RU = 0x04,
|
||||
GSM48_CAUSE_LOC_PRN_S_RU = 0x05,
|
||||
/* not defined */
|
||||
GSM48_CAUSE_LOC_INN_NET = 0x07,
|
||||
GSM48_CAUSE_LOC_NET_BEYOND = 0x0a,
|
||||
};
|
||||
|
||||
/* Section 10.5.2.31 RR Cause / Table 10.5.70 */
|
||||
enum gsm48_rr_cause {
|
||||
GSM48_RR_CAUSE_NORMAL = 0x00,
|
||||
GSM48_RR_CAUSE_ABNORMAL_UNSPEC = 0x01,
|
||||
GSM48_RR_CAUSE_ABNORMAL_UNACCT = 0x02,
|
||||
GSM48_RR_CAUSE_ABNORMAL_TIMER = 0x03,
|
||||
GSM48_RR_CAUSE_ABNORMAL_NOACT = 0x04,
|
||||
GSM48_RR_CAUSE_PREMPTIVE_REL = 0x05,
|
||||
GSM48_RR_CAUSE_HNDOVER_IMP = 0x06,
|
||||
GSM48_RR_CAUSE_CHAN_MODE_UNACCT = 0x07,
|
||||
GSM48_RR_CAUSE_FREQ_NOT_IMPL = 0x08,
|
||||
GSM48_RR_CAUSE_CALL_CLEARED = 0x41,
|
||||
GSM48_RR_CAUSE_SEMANT_INCORR = 0x5f,
|
||||
GSM48_RR_CAUSE_INVALID_MAND_INF = 0x60,
|
||||
GSM48_RR_CAUSE_MSG_TYPE_N = 0x61,
|
||||
GSM48_RR_CAUSE_MSG_TYPE_N_COMPAT= 0x62,
|
||||
GSM48_RR_CAUSE_COND_IE_ERROR = 0x64,
|
||||
GSM48_RR_CAUSE_NO_CELL_ALLOC_A = 0x65,
|
||||
GSM48_RR_CAUSE_PROT_ERROR_UNSPC = 0x6f,
|
||||
};
|
||||
|
||||
/* Section 10.5.4.11 CC Cause / Table 10.5.123 */
|
||||
enum gsm48_cc_cause {
|
||||
GSM48_CC_CAUSE_UNASSIGNED_NR = 1,
|
||||
GSM48_CC_CAUSE_NO_ROUTE = 3,
|
||||
GSM48_CC_CAUSE_CHAN_UNACCEPT = 6,
|
||||
GSM48_CC_CAUSE_OP_DET_BARRING = 8,
|
||||
GSM48_CC_CAUSE_NORM_CALL_CLEAR = 16,
|
||||
GSM48_CC_CAUSE_USER_BUSY = 17,
|
||||
GSM48_CC_CAUSE_USER_NOTRESPOND = 18,
|
||||
GSM48_CC_CAUSE_USER_ALERTING_NA = 19,
|
||||
GSM48_CC_CAUSE_CALL_REJECTED = 21,
|
||||
GSM48_CC_CAUSE_NUMBER_CHANGED = 22,
|
||||
GSM48_CC_CAUSE_PRE_EMPTION = 25,
|
||||
GSM48_CC_CAUSE_NONSE_USER_CLR = 26,
|
||||
GSM48_CC_CAUSE_DEST_OOO = 27,
|
||||
GSM48_CC_CAUSE_INV_NR_FORMAT = 28,
|
||||
GSM48_CC_CAUSE_FACILITY_REJ = 29,
|
||||
GSM48_CC_CAUSE_RESP_STATUS_INQ = 30,
|
||||
GSM48_CC_CAUSE_NORMAL_UNSPEC = 31,
|
||||
GSM48_CC_CAUSE_NO_CIRCUIT_CHAN = 34,
|
||||
GSM48_CC_CAUSE_NETWORK_OOO = 38,
|
||||
GSM48_CC_CAUSE_TEMP_FAILURE = 41,
|
||||
GSM48_CC_CAUSE_SWITCH_CONG = 42,
|
||||
GSM48_CC_CAUSE_ACC_INF_DISCARD = 43,
|
||||
GSM48_CC_CAUSE_REQ_CHAN_UNAVAIL = 44,
|
||||
GSM48_CC_CAUSE_RESOURCE_UNAVAIL = 47,
|
||||
GSM48_CC_CAUSE_QOS_UNAVAIL = 49,
|
||||
GSM48_CC_CAUSE_REQ_FAC_NOT_SUBSC= 50,
|
||||
GSM48_CC_CAUSE_INC_BARRED_CUG = 55,
|
||||
GSM48_CC_CAUSE_BEARER_CAP_UNAUTH= 57,
|
||||
GSM48_CC_CAUSE_BEARER_CA_UNAVAIL= 58,
|
||||
GSM48_CC_CAUSE_SERV_OPT_UNAVAIL = 63,
|
||||
GSM48_CC_CAUSE_BEARERSERV_UNIMPL= 65,
|
||||
GSM48_CC_CAUSE_ACM_GE_ACM_MAX = 68,
|
||||
GSM48_CC_CAUSE_REQ_FAC_NOTIMPL = 69,
|
||||
GSM48_CC_CAUSE_RESTR_BCAP_AVAIL = 70,
|
||||
GSM48_CC_CAUSE_SERV_OPT_UNIMPL = 79,
|
||||
GSM48_CC_CAUSE_INVAL_TRANS_ID = 81,
|
||||
GSM48_CC_CAUSE_USER_NOT_IN_CUG = 87,
|
||||
GSM48_CC_CAUSE_INCOMPAT_DEST = 88,
|
||||
GSM48_CC_CAUSE_INVAL_TRANS_NET = 91,
|
||||
GSM48_CC_CAUSE_SEMANTIC_INCORR = 95,
|
||||
GSM48_CC_CAUSE_INVAL_MAND_INF = 96,
|
||||
GSM48_CC_CAUSE_MSGTYPE_NOTEXIST = 97,
|
||||
GSM48_CC_CAUSE_MSGTYPE_INCOMPAT = 98,
|
||||
GSM48_CC_CAUSE_IE_NOTEXIST = 99,
|
||||
GSM48_CC_CAUSE_COND_IE_ERR = 100,
|
||||
GSM48_CC_CAUSE_MSG_INCOMP_STATE = 101,
|
||||
GSM48_CC_CAUSE_RECOVERY_TIMER = 102,
|
||||
GSM48_CC_CAUSE_PROTO_ERR = 111,
|
||||
GSM48_CC_CAUSE_INTERWORKING = 127,
|
||||
};
|
||||
|
||||
/* Annex G, GSM specific cause values for mobility management */
|
||||
enum gsm48_reject_value {
|
||||
GSM48_REJECT_IMSI_UNKNOWN_IN_HLR = 2,
|
||||
GSM48_REJECT_ILLEGAL_MS = 3,
|
||||
GSM48_REJECT_IMSI_UNKNOWN_IN_VLR = 4,
|
||||
GSM48_REJECT_IMEI_NOT_ACCEPTED = 5,
|
||||
GSM48_REJECT_ILLEGAL_ME = 6,
|
||||
GSM48_REJECT_PLMN_NOT_ALLOWED = 11,
|
||||
GSM48_REJECT_LOC_NOT_ALLOWED = 12,
|
||||
GSM48_REJECT_ROAMING_NOT_ALLOWED = 13,
|
||||
GSM48_REJECT_NETWORK_FAILURE = 17,
|
||||
GSM48_REJECT_CONGESTION = 22,
|
||||
GSM48_REJECT_SRV_OPT_NOT_SUPPORTED = 32,
|
||||
GSM48_REJECT_RQD_SRV_OPT_NOT_SUPPORTED = 33,
|
||||
GSM48_REJECT_SRV_OPT_TMP_OUT_OF_ORDER = 34,
|
||||
GSM48_REJECT_CALL_CAN_NOT_BE_IDENTIFIED = 38,
|
||||
GSM48_REJECT_INCORRECT_MESSAGE = 95,
|
||||
GSM48_REJECT_INVALID_MANDANTORY_INF = 96,
|
||||
GSM48_REJECT_MSG_TYPE_NOT_IMPLEMENTED = 97,
|
||||
GSM48_REJECT_MSG_TYPE_NOT_COMPATIBLE = 98,
|
||||
GSM48_REJECT_INF_ELEME_NOT_IMPLEMENTED = 99,
|
||||
GSM48_REJECT_CONDTIONAL_IE_ERROR = 100,
|
||||
GSM48_REJECT_MSG_NOT_COMPATIBLE = 101,
|
||||
GSM48_REJECT_PROTOCOL_ERROR = 111,
|
||||
|
||||
/* according to G.6 Additional cause codes for GMM */
|
||||
GSM48_REJECT_GPRS_NOT_ALLOWED = 7,
|
||||
GSM48_REJECT_SERVICES_NOT_ALLOWED = 8,
|
||||
GSM48_REJECT_MS_IDENTITY_NOT_DERVIVABLE = 9,
|
||||
GSM48_REJECT_IMPLICITLY_DETACHED = 10,
|
||||
GSM48_REJECT_GPRS_NOT_ALLOWED_IN_PLMN = 14,
|
||||
GSM48_REJECT_MSC_TMP_NOT_REACHABLE = 16,
|
||||
};
|
||||
|
||||
enum chreq_type {
|
||||
CHREQ_T_EMERG_CALL,
|
||||
CHREQ_T_CALL_REEST_TCH_F,
|
||||
CHREQ_T_CALL_REEST_TCH_H,
|
||||
CHREQ_T_CALL_REEST_TCH_H_DBL,
|
||||
CHREQ_T_SDCCH,
|
||||
CHREQ_T_TCH_F,
|
||||
CHREQ_T_VOICE_CALL_TCH_H,
|
||||
CHREQ_T_DATA_CALL_TCH_H,
|
||||
CHREQ_T_LOCATION_UPD,
|
||||
CHREQ_T_PAG_R_ANY_NECI0,
|
||||
CHREQ_T_PAG_R_ANY_NECI1,
|
||||
CHREQ_T_PAG_R_TCH_F,
|
||||
CHREQ_T_PAG_R_TCH_FH,
|
||||
CHREQ_T_LMU,
|
||||
CHREQ_T_RESERVED_SDCCH,
|
||||
CHREQ_T_RESERVED_IGNORE,
|
||||
};
|
||||
|
||||
/* Chapter 11.3 */
|
||||
#define GSM48_T301 180, 0
|
||||
#define GSM48_T303 30, 0
|
||||
#define GSM48_T305 30, 0
|
||||
#define GSM48_T306 30, 0
|
||||
#define GSM48_T308 10, 0
|
||||
#define GSM48_T310 180, 0
|
||||
#define GSM48_T313 30, 0
|
||||
#define GSM48_T323 30, 0
|
||||
#define GSM48_T331 30, 0
|
||||
#define GSM48_T333 30, 0
|
||||
#define GSM48_T334 25, 0 /* min 15 */
|
||||
#define GSM48_T338 30, 0
|
||||
|
||||
/* Chapter 5.1.2.2 */
|
||||
#define GSM_CSTATE_NULL 0
|
||||
#define GSM_CSTATE_INITIATED 1
|
||||
#define GSM_CSTATE_MO_CALL_PROC 3
|
||||
#define GSM_CSTATE_CALL_DELIVERED 4
|
||||
#define GSM_CSTATE_CALL_PRESENT 6
|
||||
#define GSM_CSTATE_CALL_RECEIVED 7
|
||||
#define GSM_CSTATE_CONNECT_REQUEST 8
|
||||
#define GSM_CSTATE_MO_TERM_CALL_CONF 9
|
||||
#define GSM_CSTATE_ACTIVE 10
|
||||
#define GSM_CSTATE_DISCONNECT_REQ 12
|
||||
#define GSM_CSTATE_DISCONNECT_IND 12
|
||||
#define GSM_CSTATE_RELEASE_REQ 19
|
||||
#define GSM_CSTATE_MO_ORIG_MODIFY 26
|
||||
#define GSM_CSTATE_MO_TERM_MODIFY 27
|
||||
#define GSM_CSTATE_CONNECT_IND 28
|
||||
|
||||
#define SBIT(a) (1 << a)
|
||||
#define ALL_STATES 0xffffffff
|
||||
|
||||
/* Table 10.5.3/3GPP TS 04.08: Location Area Identification information element */
|
||||
#define GSM_LAC_RESERVED_DETACHED 0x0
|
||||
#define GSM_LAC_RESERVED_ALL_BTS 0xfffe
|
||||
|
||||
/* GSM 04.08 Bearer Capability: Information Transfer Capability */
|
||||
enum gsm48_bcap_itcap {
|
||||
GSM48_BCAP_ITCAP_SPEECH = 0,
|
||||
GSM48_BCAP_ITCAP_UNR_DIG_INF = 1,
|
||||
GSM48_BCAP_ITCAP_3k1_AUDIO = 2,
|
||||
GSM48_BCAP_ITCAP_FAX_G3 = 3,
|
||||
GSM48_BCAP_ITCAP_OTHER = 5,
|
||||
GSM48_BCAP_ITCAP_RESERVED = 7,
|
||||
};
|
||||
|
||||
/* GSM 04.08 Bearer Capability: Transfer Mode */
|
||||
enum gsm48_bcap_tmod {
|
||||
GSM48_BCAP_TMOD_CIRCUIT = 0,
|
||||
GSM48_BCAP_TMOD_PACKET = 1,
|
||||
};
|
||||
|
||||
/* GSM 04.08 Bearer Capability: Coding Standard */
|
||||
enum gsm48_bcap_coding {
|
||||
GSM48_BCAP_CODING_GSM_STD = 0,
|
||||
};
|
||||
|
||||
/* GSM 04.08 Bearer Capability: Radio Channel Requirements */
|
||||
enum gsm48_bcap_rrq {
|
||||
GSM48_BCAP_RRQ_FR_ONLY = 1,
|
||||
GSM48_BCAP_RRQ_DUAL_HR = 2,
|
||||
GSM48_BCAP_RRQ_DUAL_FR = 3,
|
||||
};
|
||||
|
||||
|
||||
#define GSM48_TMSI_LEN 5
|
||||
#define GSM48_MID_TMSI_LEN (GSM48_TMSI_LEN + 2)
|
||||
#define GSM48_MI_SIZE 32
|
||||
|
||||
|
||||
#endif /* PROTO_GSM_04_08_H */
|
||||
@@ -1,188 +0,0 @@
|
||||
#ifndef PROTO_GSM_04_11_H
|
||||
#define PROTO_GSM_04_11_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* GSM TS 04.11 definitions */
|
||||
|
||||
/* Chapter 5.2.3: SMC-CS states at the network side */
|
||||
enum gsm411_cp_state {
|
||||
GSM411_CPS_IDLE = 0,
|
||||
GSM411_CPS_MM_CONN_PENDING = 1, /* only MT ! */
|
||||
GSM411_CPS_WAIT_CP_ACK = 2,
|
||||
GSM411_CPS_MM_ESTABLISHED = 3,
|
||||
};
|
||||
|
||||
/* Chapter 6.2.2: SMR states at the network side */
|
||||
enum gsm411_rp_state {
|
||||
GSM411_RPS_IDLE = 0,
|
||||
GSM411_RPS_WAIT_FOR_RP_ACK = 1,
|
||||
GSM411_RPS_WAIT_TO_TX_RP_ACK = 3,
|
||||
};
|
||||
|
||||
/* Chapter 8.1.2 (refers to GSM 04.07 Chapter 11.2.3.1.1 */
|
||||
#define GSM411_PDISC_SMS 0x09
|
||||
|
||||
/* Chapter 8.1.3 */
|
||||
#define GSM411_MT_CP_DATA 0x01
|
||||
#define GSM411_MT_CP_ACK 0x04
|
||||
#define GSM411_MT_CP_ERROR 0x10
|
||||
|
||||
enum gsm411_cp_ie {
|
||||
GSM411_CP_IE_USER_DATA = 0x01, /* 8.1.4.1 */
|
||||
GSM411_CP_IE_CAUSE = 0x02, /* 8.1.4.2. */
|
||||
};
|
||||
|
||||
/* Section 8.1.4.2 / Table 8.2 */
|
||||
enum gsm411_cp_cause {
|
||||
GSM411_CP_CAUSE_NET_FAIL = 17,
|
||||
GSM411_CP_CAUSE_CONGESTION = 22,
|
||||
GSM411_CP_CAUSE_INV_TRANS_ID = 81,
|
||||
GSM411_CP_CAUSE_SEMANT_INC_MSG = 95,
|
||||
GSM411_CP_CAUSE_INV_MAND_INF = 96,
|
||||
GSM411_CP_CAUSE_MSGTYPE_NOTEXIST= 97,
|
||||
GSM411_CP_CAUSE_MSG_INCOMP_STATE= 98,
|
||||
GSM411_CP_CAUSE_IE_NOTEXIST = 99,
|
||||
GSM411_CP_CAUSE_PROTOCOL_ERR = 111,
|
||||
};
|
||||
|
||||
/* Chapter 8.2.2 */
|
||||
#define GSM411_MT_RP_DATA_MO 0x00
|
||||
#define GSM411_MT_RP_DATA_MT 0x01
|
||||
#define GSM411_MT_RP_ACK_MO 0x02
|
||||
#define GSM411_MT_RP_ACK_MT 0x03
|
||||
#define GSM411_MT_RP_ERROR_MO 0x04
|
||||
#define GSM411_MT_RP_ERROR_MT 0x05
|
||||
#define GSM411_MT_RP_SMMA_MO 0x06
|
||||
|
||||
enum gsm411_rp_ie {
|
||||
GSM411_IE_RP_USER_DATA = 0x41, /* 8.2.5.3 */
|
||||
GSM411_IE_RP_CAUSE = 0x42, /* 8.2.5.4 */
|
||||
};
|
||||
|
||||
/* Chapter 8.2.5.4 Table 8.4 */
|
||||
enum gsm411_rp_cause {
|
||||
/* valid only for MO */
|
||||
GSM411_RP_CAUSE_MO_NUM_UNASSIGNED = 1,
|
||||
GSM411_RP_CAUSE_MO_OP_DET_BARR = 8,
|
||||
GSM411_RP_CAUSE_MO_CALL_BARRED = 10,
|
||||
GSM411_RP_CAUSE_MO_SMS_REJECTED = 21,
|
||||
GSM411_RP_CAUSE_MO_DEST_OUT_OF_ORDER = 27,
|
||||
GSM411_RP_CAUSE_MO_UNIDENTIFIED_SUBSCR = 28,
|
||||
GSM411_RP_CAUSE_MO_FACILITY_REJ = 29,
|
||||
GSM411_RP_CAUSE_MO_UNKNOWN_SUBSCR = 30,
|
||||
GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER = 38,
|
||||
GSM411_RP_CAUSE_MO_TEMP_FAIL = 41,
|
||||
GSM411_RP_CAUSE_MO_CONGESTION = 42,
|
||||
GSM411_RP_CAUSE_MO_RES_UNAVAIL = 47,
|
||||
GSM411_RP_CAUSE_MO_REQ_FAC_NOTSUBSCR = 50,
|
||||
GSM411_RP_CAUSE_MO_REQ_FAC_NOTIMPL = 69,
|
||||
GSM411_RP_CAUSE_MO_INTERWORKING = 127,
|
||||
/* valid only for MT */
|
||||
GSM411_RP_CAUSE_MT_MEM_EXCEEDED = 22,
|
||||
/* valid for both directions */
|
||||
GSM411_RP_CAUSE_INV_TRANS_REF = 81,
|
||||
GSM411_RP_CAUSE_SEMANT_INC_MSG = 95,
|
||||
GSM411_RP_CAUSE_INV_MAND_INF = 96,
|
||||
GSM411_RP_CAUSE_MSGTYPE_NOTEXIST = 97,
|
||||
GSM411_RP_CAUSE_MSG_INCOMP_STATE = 98,
|
||||
GSM411_RP_CAUSE_IE_NOTEXIST = 99,
|
||||
GSM411_RP_CAUSE_PROTOCOL_ERR = 111,
|
||||
};
|
||||
|
||||
/* Chapter 10: Timers */
|
||||
#define GSM411_TMR_TR1M 40, 0 /* 35 < x < 45 seconds */
|
||||
#define GSM411_TMR_TRAM 30, 0 /* 25 < x < 35 seconds */
|
||||
#define GSM411_TMR_TR2M 15, 0 /* 12 < x < 20 seconds */
|
||||
|
||||
#define GSM411_TMR_TC1A 30, 0
|
||||
|
||||
/* Chapter 8.2.1 */
|
||||
struct gsm411_rp_hdr {
|
||||
uint8_t len;
|
||||
uint8_t msg_type;
|
||||
uint8_t msg_ref;
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* our own enum, not related to on-air protocol */
|
||||
enum sms_alphabet {
|
||||
DCS_NONE,
|
||||
DCS_7BIT_DEFAULT,
|
||||
DCS_UCS2,
|
||||
DCS_8BIT_DATA,
|
||||
};
|
||||
|
||||
/* GSM 03.40 / Chapter 9.2.3.1: TP-Message-Type-Indicator */
|
||||
#define GSM340_SMS_DELIVER_SC2MS 0x00
|
||||
#define GSM340_SMS_DELIVER_REP_MS2SC 0x00
|
||||
#define GSM340_SMS_STATUS_REP_SC2MS 0x02
|
||||
#define GSM340_SMS_COMMAND_MS2SC 0x02
|
||||
#define GSM340_SMS_SUBMIT_MS2SC 0x01
|
||||
#define GSM340_SMS_SUBMIT_REP_SC2MS 0x01
|
||||
#define GSM340_SMS_RESSERVED 0x03
|
||||
|
||||
/* GSM 03.40 / Chapter 9.2.3.2: TP-More-Messages-to-Send */
|
||||
#define GSM340_TP_MMS_MORE 0
|
||||
#define GSM340_TP_MMS_NO_MORE 1
|
||||
|
||||
/* GSM 03.40 / Chapter 9.2.3.3: TP-Validity-Period-Format */
|
||||
#define GSM340_TP_VPF_NONE 0
|
||||
#define GSM340_TP_VPF_RELATIVE 2
|
||||
#define GSM340_TP_VPF_ENHANCED 1
|
||||
#define GSM340_TP_VPF_ABSOLUTE 3
|
||||
|
||||
/* GSM 03.40 / Chapter 9.2.3.4: TP-Status-Report-Indication */
|
||||
#define GSM340_TP_SRI_NONE 0
|
||||
#define GSM340_TP_SRI_PRESENT 1
|
||||
|
||||
/* GSM 03.40 / Chapter 9.2.3.5: TP-Status-Report-Request */
|
||||
#define GSM340_TP_SRR_NONE 0
|
||||
#define GSM340_TP_SRR_REQUESTED 1
|
||||
|
||||
/* GSM 03.40 / Chapter 9.2.3.9: TP-Protocol-Identifier */
|
||||
/* telematic interworking (001 or 111 in bits 7-5) */
|
||||
#define GSM340_TP_PID_IMPLICIT 0x00
|
||||
#define GSM340_TP_PID_TELEX 0x01
|
||||
#define GSM340_TP_PID_FAX_G3 0x02
|
||||
#define GSM340_TP_PID_FAX_G4 0x03
|
||||
#define GSM340_TP_PID_VOICE 0x04
|
||||
#define GSM430_TP_PID_ERMES 0x05
|
||||
#define GSM430_TP_PID_NATIONAL_PAGING 0x06
|
||||
#define GSM430_TP_PID_VIDEOTEX 0x07
|
||||
#define GSM430_TP_PID_TELETEX_UNSPEC 0x08
|
||||
#define GSM430_TP_PID_TELETEX_PSPDN 0x09
|
||||
#define GSM430_TP_PID_TELETEX_CSPDN 0x0a
|
||||
#define GSM430_TP_PID_TELETEX_PSTN 0x0b
|
||||
#define GSM430_TP_PID_TELETEX_ISDN 0x0c
|
||||
#define GSM430_TP_PID_TELETEX_UCI 0x0d
|
||||
#define GSM430_TP_PID_MSG_HANDLING 0x10
|
||||
#define GSM430_TP_PID_MSG_X400 0x11
|
||||
#define GSM430_TP_PID_EMAIL 0x12
|
||||
#define GSM430_TP_PID_GSM_MS 0x1f
|
||||
/* if bit 7 = 0 and bit 6 = 1 */
|
||||
#define GSM430_TP_PID_SMS_TYPE_0 0
|
||||
#define GSM430_TP_PID_SMS_TYPE_1 1
|
||||
#define GSM430_TP_PID_SMS_TYPE_2 2
|
||||
#define GSM430_TP_PID_SMS_TYPE_3 3
|
||||
#define GSM430_TP_PID_SMS_TYPE_4 4
|
||||
#define GSM430_TP_PID_SMS_TYPE_5 5
|
||||
#define GSM430_TP_PID_SMS_TYPE_6 6
|
||||
#define GSM430_TP_PID_SMS_TYPE_7 7
|
||||
#define GSM430_TP_PID_RETURN_CALL_MSG 0x1f
|
||||
#define GSM430_TP_PID_ME_DATA_DNLOAD 0x3d
|
||||
#define GSM430_TP_PID_ME_DE_PERSONAL 0x3e
|
||||
#define GSM430_TP_PID_ME_SIM_DNLOAD 0x3f
|
||||
|
||||
/* GSM 03.38 Chapter 4: SMS Data Coding Scheme */
|
||||
#define GSM338_DCS_00_
|
||||
|
||||
#define GSM338_DCS_1110_7BIT (0 << 2)
|
||||
#define GSM338_DCS_1111_7BIT (0 << 2)
|
||||
#define GSM338_DCS_1111_8BIT_DATA (1 << 2)
|
||||
#define GSM338_DCS_1111_CLASS0 0
|
||||
#define GSM338_DCS_1111_CLASS1_ME 1
|
||||
#define GSM338_DCS_1111_CLASS2_SIM 2
|
||||
#define GSM338_DCS_1111_CLASS3_TE 3 /* See TS 07.05 */
|
||||
|
||||
#endif /* PROTO_GSM_04_11_H */
|
||||
@@ -1,126 +0,0 @@
|
||||
#ifndef PROTO_GSM_04_80_H
|
||||
#define PROTO_GSM_04_80_H
|
||||
|
||||
/* GSM TS 04.80 definitions (Supplementary Services Specification, Formats and Coding) */
|
||||
|
||||
/* Section 3.4 */
|
||||
#define GSM0480_MTYPE_RELEASE_COMPLETE 0x2A
|
||||
#define GSM0480_MTYPE_FACILITY 0x3A
|
||||
#define GSM0480_MTYPE_REGISTER 0x3B
|
||||
|
||||
/* Section 3.5 */
|
||||
#define GSM0480_IE_FACILITY 0x1C
|
||||
#define GSM0480_IE_SS_VERSION 0x7F
|
||||
|
||||
/* Section 3.6.2 */
|
||||
#define GSM0480_CTYPE_INVOKE 0xA1
|
||||
#define GSM0480_CTYPE_RETURN_RESULT 0xA2
|
||||
#define GSM0480_CTYPE_RETURN_ERROR 0xA3
|
||||
#define GSM0480_CTYPE_REJECT 0xA4
|
||||
|
||||
/* Section 3.6.3 */
|
||||
#define GSM0480_COMPIDTAG_INVOKE_ID 0x02
|
||||
#define GSM0480_COMPIDTAG_LINKED_ID 0x80
|
||||
|
||||
/* Section 3.6.4 */
|
||||
#define GSM0480_OPERATION_CODE 0x02
|
||||
|
||||
/* Section 3.6.5 */
|
||||
#define GSM_0480_SEQUENCE_TAG 0x30
|
||||
#define GSM_0480_SET_TAG 0x31
|
||||
|
||||
/* Section 3.6.6 */
|
||||
#define GSM_0480_ERROR_CODE_TAG 0x02
|
||||
|
||||
/* Section 3.6.7 */
|
||||
/* Table 3.13 */
|
||||
#define GSM_0480_PROBLEM_CODE_TAG_GENERAL 0x80
|
||||
#define GSM_0480_PROBLEM_CODE_TAG_INVOKE 0x81
|
||||
#define GSM_0480_PROBLEM_CODE_TAG_RETURN_RESULT 0x82
|
||||
#define GSM_0480_PROBLEM_CODE_TAG_RETURN_ERROR 0x83
|
||||
|
||||
/* Table 3.14 */
|
||||
#define GSM_0480_GEN_PROB_CODE_UNRECOGNISED 0x00
|
||||
#define GSM_0480_GEN_PROB_CODE_MISTYPED 0x01
|
||||
#define GSM_0480_GEN_PROB_CODE_BAD_STRUCTURE 0x02
|
||||
|
||||
/* Table 3.15 */
|
||||
#define GSM_0480_INVOKE_PROB_CODE_DUPLICATE_INVOKE_ID 0x00
|
||||
#define GSM_0480_INVOKE_PROB_CODE_UNRECOGNISED_OPERATION 0x01
|
||||
#define GSM_0480_INVOKE_PROB_CODE_MISTYPED_PARAMETER 0x02
|
||||
#define GSM_0480_INVOKE_PROB_CODE_RESOURCE_LIMITATION 0x03
|
||||
#define GSM_0480_INVOKE_PROB_CODE_INITIATING_RELEASE 0x04
|
||||
#define GSM_0480_INVOKE_PROB_CODE_UNRECOGNISED_LINKED_ID 0x05
|
||||
#define GSM_0480_INVOKE_PROB_CODE_UNEXPECTED_LINKED_RESPONSE 0x06
|
||||
#define GSM_0480_INVOKE_PROB_CODE_UNEXPECTED_LINKED_OPERATION 0x07
|
||||
|
||||
/* Table 3.16 */
|
||||
#define GSM_0480_RESULT_PROB_CODE_UNRECOGNISED_INVOKE_ID 0x00
|
||||
#define GSM_0480_RESULT_PROB_CODE_RETURN_RESULT_UNEXPECTED 0x01
|
||||
#define GSM_0480_RESULT_PROB_CODE_MISTYPED_PARAMETER 0x02
|
||||
|
||||
/* Table 3.17 */
|
||||
#define GSM_0480_ERROR_PROB_CODE_UNRECOGNISED_INVOKE_ID 0x00
|
||||
#define GSM_0480_ERROR_PROB_CODE_RETURN_ERROR_UNEXPECTED 0x01
|
||||
#define GSM_0480_ERROR_PROB_CODE_UNRECOGNISED_ERROR 0x02
|
||||
#define GSM_0480_ERROR_PROB_CODE_UNEXPECTED_ERROR 0x03
|
||||
#define GSM_0480_ERROR_PROB_CODE_MISTYPED_PARAMETER 0x04
|
||||
|
||||
/* Section 4.5 */
|
||||
#define GSM0480_OP_CODE_REGISTER_SS 0x0A
|
||||
#define GSM0480_OP_CODE_ERASE_SS 0x0B
|
||||
#define GSM0480_OP_CODE_ACTIVATE_SS 0x0C
|
||||
#define GSM0480_OP_CODE_DEACTIVATE_SS 0x0D
|
||||
#define GSM0480_OP_CODE_INTERROGATE_SS 0x0E
|
||||
#define GSM0480_OP_CODE_NOTIFY_SS 0x10
|
||||
#define GSM0480_OP_CODE_REGISTER_PASSWORD 0x11
|
||||
#define GSM0480_OP_CODE_GET_PASSWORD 0x12
|
||||
#define GSM0480_OP_CODE_PROCESS_USS_DATA 0x13
|
||||
#define GSM0480_OP_CODE_FORWARD_CHECK_SS_IND 0x26
|
||||
#define GSM0480_OP_CODE_PROCESS_USS_REQ 0x3B
|
||||
#define GSM0480_OP_CODE_USS_REQUEST 0x3C
|
||||
#define GSM0480_OP_CODE_USS_NOTIFY 0x3D
|
||||
#define GSM0480_OP_CODE_FORWARD_CUG_INFO 0x78
|
||||
#define GSM0480_OP_CODE_SPLIT_MPTY 0x79
|
||||
#define GSM0480_OP_CODE_RETRIEVE_MPTY 0x7A
|
||||
#define GSM0480_OP_CODE_HOLD_MPTY 0x7B
|
||||
#define GSM0480_OP_CODE_BUILD_MPTY 0x7C
|
||||
#define GSM0480_OP_CODE_FORWARD_CHARGE_ADVICE 0x7D
|
||||
|
||||
#define GSM0480_ERR_CODE_UNKNOWN_SUBSCRIBER 0x01
|
||||
#define GSM0480_ERR_CODE_ILLEGAL_SUBSCRIBER 0x09
|
||||
#define GSM0480_ERR_CODE_BEARER_SERVICE_NOT_PROVISIONED 0x0A
|
||||
#define GSM0480_ERR_CODE_TELESERVICE_NOT_PROVISIONED 0x0B
|
||||
#define GSM0480_ERR_CODE_ILLEGAL_EQUIPMENT 0x0C
|
||||
#define GSM0480_ERR_CODE_CALL_BARRED 0x0D
|
||||
#define GSM0480_ERR_CODE_ILLEGAL_SS_OPERATION 0x10
|
||||
#define GSM0480_ERR_CODE_SS_ERROR_STATUS 0x11
|
||||
#define GSM0480_ERR_CODE_SS_NOT_AVAILABLE 0x12
|
||||
#define GSM0480_ERR_CODE_SS_SUBSCRIPTION_VIOLATION 0x13
|
||||
#define GSM0480_ERR_CODE_SS_INCOMPATIBILITY 0x14
|
||||
#define GSM0480_ERR_CODE_FACILITY_NOT_SUPPORTED 0x15
|
||||
#define GSM0480_ERR_CODE_ABSENT_SUBSCRIBER 0x1B
|
||||
#define GSM0480_ERR_CODE_SYSTEM_FAILURE 0x22
|
||||
#define GSM0480_ERR_CODE_DATA_MISSING 0x23
|
||||
#define GSM0480_ERR_CODE_UNEXPECTED_DATA_VALUE 0x24
|
||||
#define GSM0480_ERR_CODE_PW_REGISTRATION_FAILURE 0x25
|
||||
#define GSM0480_ERR_CODE_NEGATIVE_PW_CHECK 0x26
|
||||
#define GSM0480_ERR_CODE_NUM_PW_ATTEMPTS_VIOLATION 0x2B
|
||||
#define GSM0480_ERR_CODE_UNKNOWN_ALPHABET 0x47
|
||||
#define GSM0480_ERR_CODE_USSD_BUSY 0x48
|
||||
#define GSM0480_ERR_CODE_MAX_MPTY_PARTICIPANTS 0x7E
|
||||
#define GSM0480_ERR_CODE_RESOURCES_NOT_AVAILABLE 0x7F
|
||||
|
||||
/* ASN.1 type-tags */
|
||||
#define ASN1_BOOLEAN_TAG 0x01
|
||||
#define ASN1_INTEGER_TAG 0x02
|
||||
#define ASN1_BIT_STRING_TAG 0x03
|
||||
#define ASN1_OCTET_STRING_TAG 0x04
|
||||
#define ASN1_NULL_TYPE_TAG 0x05
|
||||
#define ASN1_OBJECT_ID_TAG 0x06
|
||||
#define ASN1_UTF8_STRING_TAG 0x0C
|
||||
#define ASN1_PRINTABLE_STRING_TAG 0x13
|
||||
#define ASN1_IA5_STRING_TAG 0x16
|
||||
#define ASN1_UNICODE_STRING_TAG 0x1E
|
||||
|
||||
#endif /* PROTO_GSM_04_80_H */
|
||||
@@ -1,512 +0,0 @@
|
||||
#ifndef PROTO_GSM_08_58_H
|
||||
#define PROTO_GSM_08_58_H
|
||||
|
||||
/* GSM Radio Signalling Link messages on the A-bis interface
|
||||
* 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */
|
||||
|
||||
/* (C) 2008 by Harald Welte <laforge@gnumonks.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct abis_rsl_common_hdr {
|
||||
uint8_t msg_discr;
|
||||
uint8_t msg_type;
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Chapter 8.3 */
|
||||
struct abis_rsl_rll_hdr {
|
||||
struct abis_rsl_common_hdr c;
|
||||
uint8_t ie_chan;
|
||||
uint8_t chan_nr;
|
||||
uint8_t ie_link_id;
|
||||
uint8_t link_id;
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Chapter 8.3 and 8.4 */
|
||||
struct abis_rsl_dchan_hdr {
|
||||
struct abis_rsl_common_hdr c;
|
||||
uint8_t ie_chan;
|
||||
uint8_t chan_nr;
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/* Chapter 9.1 */
|
||||
#define ABIS_RSL_MDISC_RLL 0x02
|
||||
#define ABIS_RSL_MDISC_DED_CHAN 0x08
|
||||
#define ABIS_RSL_MDISC_COM_CHAN 0x0c
|
||||
#define ABIS_RSL_MDISC_TRX 0x10
|
||||
#define ABIS_RSL_MDISC_LOC 0x20
|
||||
#define ABIS_RSL_MDISC_IPACCESS 0x7e
|
||||
#define ABIS_RSL_MDISC_TRANSP 0x01
|
||||
|
||||
#define ABIS_RSL_MDISC_IS_TRANSP(x) (x & 0x01)
|
||||
|
||||
/* Chapter 9.1 */
|
||||
enum abis_rsl_msgtype {
|
||||
/* Radio Link Layer Management */
|
||||
RSL_MT_DATA_REQ = 0x01,
|
||||
RSL_MT_DATA_IND,
|
||||
RSL_MT_ERROR_IND,
|
||||
RSL_MT_EST_REQ,
|
||||
RSL_MT_EST_CONF,
|
||||
RSL_MT_EST_IND,
|
||||
RSL_MT_REL_REQ,
|
||||
RSL_MT_REL_CONF,
|
||||
RSL_MT_REL_IND,
|
||||
RSL_MT_UNIT_DATA_REQ,
|
||||
RSL_MT_UNIT_DATA_IND, /* 0x0b */
|
||||
|
||||
/* Common Channel Management / TRX Management */
|
||||
RSL_MT_BCCH_INFO = 0x11,
|
||||
RSL_MT_CCCH_LOAD_IND,
|
||||
RSL_MT_CHAN_RQD,
|
||||
RSL_MT_DELETE_IND,
|
||||
RSL_MT_PAGING_CMD,
|
||||
RSL_MT_IMMEDIATE_ASSIGN_CMD,
|
||||
RSL_MT_SMS_BC_REQ,
|
||||
/* empty */
|
||||
RSL_MT_RF_RES_IND = 0x19,
|
||||
RSL_MT_SACCH_FILL,
|
||||
RSL_MT_OVERLOAD,
|
||||
RSL_MT_ERROR_REPORT,
|
||||
RSL_MT_SMS_BC_CMD,
|
||||
RSL_MT_CBCH_LOAD_IND,
|
||||
RSL_MT_NOT_CMD, /* 0x1f */
|
||||
|
||||
/* Dedicate Channel Management */
|
||||
RSL_MT_CHAN_ACTIV = 0x21,
|
||||
RSL_MT_CHAN_ACTIV_ACK,
|
||||
RSL_MT_CHAN_ACTIV_NACK,
|
||||
RSL_MT_CONN_FAIL,
|
||||
RSL_MT_DEACTIVATE_SACCH,
|
||||
RSL_MT_ENCR_CMD,
|
||||
RSL_MT_HANDO_DET,
|
||||
RSL_MT_MEAS_RES,
|
||||
RSL_MT_MODE_MODIFY_REQ,
|
||||
RSL_MT_MODE_MODIFY_ACK,
|
||||
RSL_MT_MODE_MODIFY_NACK,
|
||||
RSL_MT_PHY_CONTEXT_REQ,
|
||||
RSL_MT_PHY_CONTEXT_CONF,
|
||||
RSL_MT_RF_CHAN_REL,
|
||||
RSL_MT_MS_POWER_CONTROL,
|
||||
RSL_MT_BS_POWER_CONTROL, /* 0x30 */
|
||||
RSL_MT_PREPROC_CONFIG,
|
||||
RSL_MT_PREPROC_MEAS_RES,
|
||||
RSL_MT_RF_CHAN_REL_ACK,
|
||||
RSL_MT_SACCH_INFO_MODIFY,
|
||||
RSL_MT_TALKER_DET,
|
||||
RSL_MT_LISTENER_DET,
|
||||
RSL_MT_REMOTE_CODEC_CONF_REP,
|
||||
RSL_MT_RTD_REP,
|
||||
RSL_MT_PRE_HANDO_NOTIF,
|
||||
RSL_MT_MR_CODEC_MOD_REQ,
|
||||
RSL_MT_MR_CODEC_MOD_ACK,
|
||||
RSL_MT_MR_CODEC_MOD_NACK,
|
||||
RSL_MT_MR_CODEC_MOD_PER,
|
||||
RSL_MT_TFO_REP,
|
||||
RSL_MT_TFO_MOD_REQ, /* 0x3f */
|
||||
RSL_MT_LOCATION_INFO = 0x41,
|
||||
|
||||
/* ip.access specific RSL message types */
|
||||
RSL_MT_IPAC_DIR_RETR_ENQ = 0x40,
|
||||
RSL_MT_IPAC_PDCH_ACT = 0x48,
|
||||
RSL_MT_IPAC_PDCH_ACT_ACK,
|
||||
RSL_MT_IPAC_PDCH_ACT_NACK,
|
||||
RSL_MT_IPAC_PDCH_DEACT = 0x4b,
|
||||
RSL_MT_IPAC_PDCH_DEACT_ACK,
|
||||
RSL_MT_IPAC_PDCH_DEACT_NACK,
|
||||
RSL_MT_IPAC_CONNECT_MUX = 0x50,
|
||||
RSL_MT_IPAC_CONNECT_MUX_ACK,
|
||||
RSL_MT_IPAC_CONNECT_MUX_NACK,
|
||||
RSL_MT_IPAC_BIND_MUX = 0x53,
|
||||
RSL_MT_IPAC_BIND_MUX_ACK,
|
||||
RSL_MT_IPAC_BIND_MUX_NACK,
|
||||
RSL_MT_IPAC_DISC_MUX = 0x56,
|
||||
RSL_MT_IPAC_DISC_MUX_ACK,
|
||||
RSL_MT_IPAC_DISC_MUX_NACK,
|
||||
RSL_MT_IPAC_CRCX = 0x70, /* Bind to local BTS RTP port */
|
||||
RSL_MT_IPAC_CRCX_ACK,
|
||||
RSL_MT_IPAC_CRCX_NACK,
|
||||
RSL_MT_IPAC_MDCX = 0x73,
|
||||
RSL_MT_IPAC_MDCX_ACK,
|
||||
RSL_MT_IPAC_MDCX_NACK,
|
||||
RSL_MT_IPAC_DLCX_IND = 0x76,
|
||||
RSL_MT_IPAC_DLCX = 0x77,
|
||||
RSL_MT_IPAC_DLCX_ACK,
|
||||
RSL_MT_IPAC_DLCX_NACK,
|
||||
};
|
||||
|
||||
/* Siemens vendor-specific */
|
||||
enum abis_rsl_msgtype_siemens {
|
||||
RSL_MT_SIEMENS_MRPCI = 0x41,
|
||||
RSL_MT_SIEMENS_INTRAC_HO_COND_IND = 0x42,
|
||||
RSL_MT_SIEMENS_INTERC_HO_COND_IND = 0x43,
|
||||
RSL_MT_SIEMENS_FORCED_HO_REQ = 0x44,
|
||||
RSL_MT_SIEMENS_PREF_AREA_REQ = 0x45,
|
||||
RSL_MT_SIEMENS_PREF_AREA = 0x46,
|
||||
RSL_MT_SIEMENS_START_TRACE = 0x47,
|
||||
RSL_MT_SIEMENS_START_TRACE_ACK = 0x48,
|
||||
RSL_MT_SIEMENS_STOP_TRACE = 0x49,
|
||||
RSL_MT_SIEMENS_TRMR = 0x4a,
|
||||
RSL_MT_SIEMENS_HO_FAIL_IND = 0x4b,
|
||||
RSL_MT_SIEMENS_STOP_TRACE_ACK = 0x4c,
|
||||
RSL_MT_SIEMENS_UPLF = 0x4d,
|
||||
RSL_MT_SIEMENS_UPLB = 0x4e,
|
||||
RSL_MT_SIEMENS_SET_SYS_INFO_10 = 0x4f,
|
||||
RSL_MT_SIEMENS_MODIF_COND_IND = 0x50,
|
||||
};
|
||||
|
||||
/* Chapter 9.3 */
|
||||
enum abis_rsl_ie {
|
||||
RSL_IE_CHAN_NR = 0x01,
|
||||
RSL_IE_LINK_IDENT,
|
||||
RSL_IE_ACT_TYPE,
|
||||
RSL_IE_BS_POWER,
|
||||
RSL_IE_CHAN_IDENT,
|
||||
RSL_IE_CHAN_MODE,
|
||||
RSL_IE_ENCR_INFO,
|
||||
RSL_IE_FRAME_NUMBER,
|
||||
RSL_IE_HANDO_REF,
|
||||
RSL_IE_L1_INFO,
|
||||
RSL_IE_L3_INFO,
|
||||
RSL_IE_MS_IDENTITY,
|
||||
RSL_IE_MS_POWER,
|
||||
RSL_IE_PAGING_GROUP,
|
||||
RSL_IE_PAGING_LOAD,
|
||||
RSL_IE_PYHS_CONTEXT = 0x10,
|
||||
RSL_IE_ACCESS_DELAY,
|
||||
RSL_IE_RACH_LOAD,
|
||||
RSL_IE_REQ_REFERENCE,
|
||||
RSL_IE_RELEASE_MODE,
|
||||
RSL_IE_RESOURCE_INFO,
|
||||
RSL_IE_RLM_CAUSE,
|
||||
RSL_IE_STARTNG_TIME,
|
||||
RSL_IE_TIMING_ADVANCE,
|
||||
RSL_IE_UPLINK_MEAS,
|
||||
RSL_IE_CAUSE,
|
||||
RSL_IE_MEAS_RES_NR,
|
||||
RSL_IE_MSG_ID,
|
||||
/* reserved */
|
||||
RSL_IE_SYSINFO_TYPE = 0x1e,
|
||||
RSL_IE_MS_POWER_PARAM,
|
||||
RSL_IE_BS_POWER_PARAM,
|
||||
RSL_IE_PREPROC_PARAM,
|
||||
RSL_IE_PREPROC_MEAS,
|
||||
RSL_IE_IMM_ASS_INFO, /* Phase 1 (3.6.0), later Full below */
|
||||
RSL_IE_SMSCB_INFO = 0x24,
|
||||
RSL_IE_MS_TIMING_OFFSET,
|
||||
RSL_IE_ERR_MSG,
|
||||
RSL_IE_FULL_BCCH_INFO,
|
||||
RSL_IE_CHAN_NEEDED,
|
||||
RSL_IE_CB_CMD_TYPE,
|
||||
RSL_IE_SMSCB_MSG,
|
||||
RSL_IE_FULL_IMM_ASS_INFO,
|
||||
RSL_IE_SACCH_INFO,
|
||||
RSL_IE_CBCH_LOAD_INFO,
|
||||
RSL_IE_SMSCB_CHAN_INDICATOR,
|
||||
RSL_IE_GROUP_CALL_REF,
|
||||
RSL_IE_CHAN_DESC = 0x30,
|
||||
RSL_IE_NCH_DRX_INFO,
|
||||
RSL_IE_CMD_INDICATOR,
|
||||
RSL_IE_EMLPP_PRIO,
|
||||
RSL_IE_UIC,
|
||||
RSL_IE_MAIN_CHAN_REF,
|
||||
RSL_IE_MR_CONFIG,
|
||||
RSL_IE_MR_CONTROL,
|
||||
RSL_IE_SUP_CODEC_TYPES,
|
||||
RSL_IE_CODEC_CONFIG,
|
||||
RSL_IE_RTD,
|
||||
RSL_IE_TFO_STATUS,
|
||||
RSL_IE_LLP_APDU,
|
||||
/* Siemens vendor-specific */
|
||||
RSL_IE_SIEMENS_MRPCI = 0x40,
|
||||
RSL_IE_SIEMENS_PREF_AREA_TYPE = 0x43,
|
||||
RSL_IE_SIEMENS_ININ_CELL_HO_PAR = 0x45,
|
||||
RSL_IE_SIEMENS_TRACE_REF_NR = 0x46,
|
||||
RSL_IE_SIEMENS_INT_TRACE_IDX = 0x47,
|
||||
RSL_IE_SIEMENS_L2_HDR_INFO = 0x48,
|
||||
RSL_IE_SIEMENS_HIGHEST_RATE = 0x4e,
|
||||
RSL_IE_SIEMENS_SUGGESTED_RATE = 0x4f,
|
||||
|
||||
/* ip.access */
|
||||
RSL_IE_IPAC_SRTP_CONFIG = 0xe0,
|
||||
RSL_IE_IPAC_PROXY_UDP = 0xe1,
|
||||
RSL_IE_IPAC_BSCMPL_TOUT = 0xe2,
|
||||
RSL_IE_IPAC_REMOTE_IP = 0xf0,
|
||||
RSL_IE_IPAC_REMOTE_PORT = 0xf1,
|
||||
RSL_IE_IPAC_RTP_PAYLOAD = 0xf2,
|
||||
RSL_IE_IPAC_LOCAL_PORT = 0xf3,
|
||||
RSL_IE_IPAC_SPEECH_MODE = 0xf4,
|
||||
RSL_IE_IPAC_LOCAL_IP = 0xf5,
|
||||
RSL_IE_IPAC_CONN_STAT = 0xf6,
|
||||
RSL_IE_IPAC_HO_C_PARMS = 0xf7,
|
||||
RSL_IE_IPAC_CONN_ID = 0xf8,
|
||||
RSL_IE_IPAC_RTP_CSD_FMT = 0xf9,
|
||||
RSL_IE_IPAC_RTP_JIT_BUF = 0xfa,
|
||||
RSL_IE_IPAC_RTP_COMPR = 0xfb,
|
||||
RSL_IE_IPAC_RTP_PAYLOAD2= 0xfc,
|
||||
RSL_IE_IPAC_RTP_MPLEX = 0xfd,
|
||||
RSL_IE_IPAC_RTP_MPLEX_ID= 0xfe,
|
||||
};
|
||||
|
||||
/* Chapter 9.3.1 */
|
||||
#define RSL_CHAN_NR_MASK 0xf8
|
||||
#define RSL_CHAN_Bm_ACCHs 0x08
|
||||
#define RSL_CHAN_Lm_ACCHs 0x10 /* .. 0x18 */
|
||||
#define RSL_CHAN_SDCCH4_ACCH 0x20 /* .. 0x38 */
|
||||
#define RSL_CHAN_SDCCH8_ACCH 0x40 /* ...0x78 */
|
||||
#define RSL_CHAN_BCCH 0x80
|
||||
#define RSL_CHAN_RACH 0x88
|
||||
#define RSL_CHAN_PCH_AGCH 0x90
|
||||
|
||||
/* Chapter 9.3.3 */
|
||||
#define RSL_ACT_TYPE_INITIAL 0x00
|
||||
#define RSL_ACT_TYPE_REACT 0x80
|
||||
#define RSL_ACT_INTRA_IMM_ASS 0x00
|
||||
#define RSL_ACT_INTRA_NORM_ASS 0x01
|
||||
#define RSL_ACT_INTER_ASYNC 0x02
|
||||
#define RSL_ACT_INTER_SYNC 0x03
|
||||
#define RSL_ACT_SECOND_ADD 0x04
|
||||
#define RSL_ACT_SECOND_MULTI 0x05
|
||||
|
||||
/* Chapter 9.3.6 */
|
||||
struct rsl_ie_chan_mode {
|
||||
uint8_t dtx_dtu;
|
||||
uint8_t spd_ind;
|
||||
uint8_t chan_rt;
|
||||
uint8_t chan_rate;
|
||||
} __attribute__ ((packed));
|
||||
#define RSL_CMOD_DTXu 0x01 /* uplink */
|
||||
#define RSL_CMOD_DTXd 0x02 /* downlink */
|
||||
enum rsl_cmod_spd {
|
||||
RSL_CMOD_SPD_SPEECH = 0x01,
|
||||
RSL_CMOD_SPD_DATA = 0x02,
|
||||
RSL_CMOD_SPD_SIGN = 0x03,
|
||||
};
|
||||
#define RSL_CMOD_CRT_SDCCH 0x01
|
||||
#define RSL_CMOD_CRT_TCH_Bm 0x08 /* full-rate */
|
||||
#define RSL_CMOD_CRT_TCH_Lm 0x09 /* half-rate */
|
||||
/* FIXME: More CRT types */
|
||||
/* Speech */
|
||||
#define RSL_CMOD_SP_GSM1 0x01
|
||||
#define RSL_CMOD_SP_GSM2 0x11
|
||||
#define RSL_CMOD_SP_GSM3 0x21
|
||||
/* Data */
|
||||
#define RSL_CMOD_SP_NT_14k5 0x58
|
||||
#define RSL_CMOD_SP_NT_12k0 0x50
|
||||
#define RSL_CMOD_SP_NT_6k0 0x51
|
||||
|
||||
/* Chapter 9.3.5 */
|
||||
struct rsl_ie_chan_ident {
|
||||
/* GSM 04.08 10.5.2.5 */
|
||||
struct {
|
||||
uint8_t iei;
|
||||
uint8_t chan_nr; /* enc_chan_nr */
|
||||
uint8_t oct3;
|
||||
uint8_t oct4;
|
||||
} chan_desc;
|
||||
#if 0 /* spec says we need this but Abissim doesn't use it */
|
||||
struct {
|
||||
uint8_t tag;
|
||||
uint8_t len;
|
||||
} mobile_alloc;
|
||||
#endif
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Chapter 9.3.22 */
|
||||
#define RLL_CAUSE_T200_EXPIRED 0x01
|
||||
#define RLL_CAUSE_REEST_REQ 0x02
|
||||
#define RLL_CAUSE_UNSOL_UA_RESP 0x03
|
||||
#define RLL_CAUSE_UNSOL_DM_RESP 0x04
|
||||
#define RLL_CAUSE_UNSOL_DM_RESP_MF 0x05
|
||||
#define RLL_CAUSE_UNSOL_SPRV_RESP 0x06
|
||||
#define RLL_CAUSE_SEQ_ERR 0x07
|
||||
#define RLL_CAUSE_UFRM_INC_PARAM 0x08
|
||||
#define RLL_CAUSE_SFRM_INC_PARAM 0x09
|
||||
#define RLL_CAUSE_IFRM_INC_MBITS 0x0a
|
||||
#define RLL_CAUSE_IFRM_INC_LEN 0x0b
|
||||
#define RLL_CAUSE_FRM_UNIMPL 0x0c
|
||||
#define RLL_CAUSE_SABM_MF 0x0d
|
||||
#define RLL_CAUSE_SABM_INFO_NOTALL 0x0e
|
||||
|
||||
/* Chapter 9.3.26 */
|
||||
#define RSL_ERRCLS_NORMAL 0x00
|
||||
#define RSL_ERRCLS_RESOURCE_UNAVAIL 0x20
|
||||
#define RSL_ERRCLS_SERVICE_UNAVAIL 0x30
|
||||
#define RSL_ERRCLS_SERVICE_UNIMPL 0x40
|
||||
#define RSL_ERRCLS_INVAL_MSG 0x50
|
||||
#define RSL_ERRCLS_PROTO_ERROR 0x60
|
||||
#define RSL_ERRCLS_INTERWORKING 0x70
|
||||
|
||||
/* normal event */
|
||||
#define RSL_ERR_RADIO_IF_FAIL 0x00
|
||||
#define RSL_ERR_RADIO_LINK_FAIL 0x01
|
||||
#define RSL_ERR_HANDOVER_ACC_FAIL 0x02
|
||||
#define RSL_ERR_TALKER_ACC_FAIL 0x03
|
||||
#define RSL_ERR_OM_INTERVENTION 0x07
|
||||
#define RSL_ERR_NORMAL_UNSPEC 0x0f
|
||||
#define RSL_ERR_T_MSRFPCI_EXP 0x18
|
||||
/* resource unavailable */
|
||||
#define RSL_ERR_EQUIPMENT_FAIL 0x20
|
||||
#define RSL_ERR_RR_UNAVAIL 0x21
|
||||
#define RSL_ERR_TERR_CH_FAIL 0x22
|
||||
#define RSL_ERR_CCCH_OVERLOAD 0x23
|
||||
#define RSL_ERR_ACCH_OVERLOAD 0x24
|
||||
#define RSL_ERR_PROCESSOR_OVERLOAD 0x25
|
||||
#define RSL_ERR_RES_UNAVAIL 0x2f
|
||||
/* service or option not available */
|
||||
#define RSL_ERR_TRANSC_UNAVAIL 0x30
|
||||
#define RSL_ERR_SERV_OPT_UNAVAIL 0x3f
|
||||
/* service or option not implemented */
|
||||
#define RSL_ERR_ENCR_UNIMPL 0x40
|
||||
#define RSL_ERR_SERV_OPT_UNIMPL 0x4f
|
||||
/* invalid message */
|
||||
#define RSL_ERR_RCH_ALR_ACTV_ALLOC 0x50
|
||||
#define RSL_ERR_INVALID_MESSAGE 0x5f
|
||||
/* protocol error */
|
||||
#define RSL_ERR_MSG_DISCR 0x60
|
||||
#define RSL_ERR_MSG_TYPE 0x61
|
||||
#define RSL_ERR_MSG_SEQ 0x62
|
||||
#define RSL_ERR_IE_ERROR 0x63
|
||||
#define RSL_ERR_MAND_IE_ERROR 0x64
|
||||
#define RSL_ERR_OPT_IE_ERROR 0x65
|
||||
#define RSL_ERR_IE_NONEXIST 0x66
|
||||
#define RSL_ERR_IE_LENGTH 0x67
|
||||
#define RSL_ERR_IE_CONTENT 0x68
|
||||
#define RSL_ERR_PROTO 0x6f
|
||||
/* interworking */
|
||||
#define RSL_ERR_INTERWORKING 0x7f
|
||||
|
||||
/* Chapter 9.3.30 */
|
||||
#define RSL_SYSTEM_INFO_8 0x00
|
||||
#define RSL_SYSTEM_INFO_1 0x01
|
||||
#define RSL_SYSTEM_INFO_2 0x02
|
||||
#define RSL_SYSTEM_INFO_3 0x03
|
||||
#define RSL_SYSTEM_INFO_4 0x04
|
||||
#define RSL_SYSTEM_INFO_5 0x05
|
||||
#define RSL_SYSTEM_INFO_6 0x06
|
||||
#define RSL_SYSTEM_INFO_7 0x07
|
||||
#define RSL_SYSTEM_INFO_16 0x08
|
||||
#define RSL_SYSTEM_INFO_17 0x09
|
||||
#define RSL_SYSTEM_INFO_2bis 0x0a
|
||||
#define RSL_SYSTEM_INFO_2ter 0x0b
|
||||
#define RSL_SYSTEM_INFO_5bis 0x0d
|
||||
#define RSL_SYSTEM_INFO_5ter 0x0e
|
||||
#define RSL_SYSTEM_INFO_10 0x0f
|
||||
#define REL_EXT_MEAS_ORDER 0x47
|
||||
#define RSL_MEAS_INFO 0x48
|
||||
#define RSL_SYSTEM_INFO_13 0x28
|
||||
#define RSL_SYSTEM_INFO_2quater 0x29
|
||||
#define RSL_SYSTEM_INFO_9 0x2a
|
||||
#define RSL_SYSTEM_INFO_18 0x2b
|
||||
#define RSL_SYSTEM_INFO_19 0x2c
|
||||
#define RSL_SYSTEM_INFO_20 0x2d
|
||||
|
||||
/* Chapter 9.3.40 */
|
||||
#define RSL_CHANNEED_ANY 0x00
|
||||
#define RSL_CHANNEED_SDCCH 0x01
|
||||
#define RSL_CHANNEED_TCH_F 0x02
|
||||
#define RSL_CHANNEED_TCH_ForH 0x03
|
||||
|
||||
/* Chapter 3.3.2.3 Brocast control channel */
|
||||
/* CCCH-CONF, NC is not combined */
|
||||
#define RSL_BCCH_CCCH_CONF_1_NC 0x00
|
||||
#define RSL_BCCH_CCCH_CONF_1_C 0x01
|
||||
#define RSL_BCCH_CCCH_CONF_2_NC 0x02
|
||||
#define RSL_BCCH_CCCH_CONF_3_NC 0x04
|
||||
#define RSL_BCCH_CCCH_CONF_4_NC 0x06
|
||||
|
||||
/* BS-PA-MFRMS */
|
||||
#define RSL_BS_PA_MFRMS_2 0x00
|
||||
#define RSL_BS_PA_MFRMS_3 0x01
|
||||
#define RSL_BS_PA_MFRMS_4 0x02
|
||||
#define RSL_BS_PA_MFRMS_5 0x03
|
||||
#define RSL_BS_PA_MFRMS_6 0x04
|
||||
#define RSL_BS_PA_MFRMS_7 0x05
|
||||
#define RSL_BS_PA_MFRMS_8 0x06
|
||||
#define RSL_BS_PA_MFRMS_9 0x07
|
||||
|
||||
/* RSL_IE_IPAC_RTP_PAYLOAD[2] */
|
||||
enum rsl_ipac_rtp_payload {
|
||||
RSL_IPAC_RTP_GSM = 1,
|
||||
RSL_IPAC_RTP_EFR,
|
||||
RSL_IPAC_RTP_AMR,
|
||||
RSL_IPAC_RTP_CSD,
|
||||
RSL_IPAC_RTP_MUX,
|
||||
};
|
||||
|
||||
/* RSL_IE_IPAC_SPEECH_MODE, lower four bits */
|
||||
enum rsl_ipac_speech_mode_s {
|
||||
RSL_IPAC_SPEECH_GSM_FR = 0, /* GSM FR (Type 1, FS) */
|
||||
RSL_IPAC_SPEECH_GSM_EFR = 1, /* GSM EFR (Type 2, FS) */
|
||||
RSL_IPAC_SPEECH_GSM_AMR_FR = 2, /* GSM AMR/FR (Type 3, FS) */
|
||||
RSL_IPAC_SPEECH_GSM_HR = 3, /* GSM HR (Type 1, HS) */
|
||||
RSL_IPAC_SPEECH_GSM_AMR_HR = 5, /* GSM AMR/hr (Type 3, HS) */
|
||||
RSL_IPAC_SPEECH_AS_RTP = 0xf, /* As specified by RTP Payload IE */
|
||||
};
|
||||
/* RSL_IE_IPAC_SPEECH_MODE, upper four bits */
|
||||
enum rsl_ipac_speech_mode_m {
|
||||
RSL_IPAC_SPEECH_M_RXTX = 0, /* Send and Receive */
|
||||
RSL_IPAC_SPEECH_M_RX = 1, /* Receive only */
|
||||
RSL_IPAC_SPEECH_M_TX = 2, /* Send only */
|
||||
};
|
||||
|
||||
/* RSL_IE_IPAC_RTP_CSD_FMT, lower four bits */
|
||||
enum rsl_ipac_rtp_csd_format_d {
|
||||
RSL_IPAC_RTP_CSD_EXT_TRAU = 0,
|
||||
RSL_IPAC_RTP_CSD_NON_TRAU = 1,
|
||||
RSL_IPAC_RTP_CSD_TRAU_BTS = 2,
|
||||
RSL_IPAC_RTP_CSD_IWF_FREE = 3,
|
||||
};
|
||||
/* RSL_IE_IPAC_RTP_CSD_FMT, upper four bits */
|
||||
enum rsl_ipac_rtp_csd_format_ir {
|
||||
RSL_IPAC_RTP_CSD_IR_8k = 0,
|
||||
RSL_IPAC_RTP_CSD_IR_16k = 1,
|
||||
RSL_IPAC_RTP_CSD_IR_32k = 2,
|
||||
RSL_IPAC_RTP_CSD_IR_64k = 3,
|
||||
};
|
||||
|
||||
/* Siemens vendor-specific RSL extensions */
|
||||
struct rsl_mrpci {
|
||||
uint8_t power_class:3,
|
||||
vgcs_capable:1,
|
||||
vbs_capable:1,
|
||||
gsm_phase:2;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
enum rsl_mrpci_pwrclass {
|
||||
RSL_MRPCI_PWRC_1 = 0,
|
||||
RSL_MRPCI_PWRC_2 = 1,
|
||||
RSL_MRPCI_PWRC_3 = 2,
|
||||
RSL_MRPCI_PWRC_4 = 3,
|
||||
RSL_MRPCI_PWRC_5 = 4,
|
||||
};
|
||||
enum rsl_mrpci_phase {
|
||||
RSL_MRPCI_PHASE_1 = 0,
|
||||
/* reserved */
|
||||
RSL_MRPCI_PHASE_2 = 2,
|
||||
RSL_MRPCI_PHASE_2PLUS = 3,
|
||||
};
|
||||
|
||||
|
||||
#endif /* PROTO_GSM_08_58_H */
|
||||
@@ -1,713 +0,0 @@
|
||||
#ifndef PROTO_GSM_12_21_H
|
||||
#define PROTO_GSM_12_21_H
|
||||
|
||||
/* GSM Network Management messages on the A-bis interface
|
||||
* 3GPP TS 12.21 version 8.0.0 Release 1999 / ETSI TS 100 623 V8.0.0 */
|
||||
|
||||
/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <osmocore/tlv.h>
|
||||
|
||||
/* generic header in front of every OML message according to TS 08.59 */
|
||||
struct abis_om_hdr {
|
||||
uint8_t mdisc;
|
||||
uint8_t placement;
|
||||
uint8_t sequence;
|
||||
uint8_t length;
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define ABIS_OM_MDISC_FOM 0x80
|
||||
#define ABIS_OM_MDISC_MMI 0x40
|
||||
#define ABIS_OM_MDISC_TRAU 0x20
|
||||
#define ABIS_OM_MDISC_MANUF 0x10
|
||||
#define ABIS_OM_PLACEMENT_ONLY 0x80
|
||||
#define ABIS_OM_PLACEMENT_FIRST 0x40
|
||||
#define ABIS_OM_PLACEMENT_MIDDLE 0x20
|
||||
#define ABIS_OM_PLACEMENT_LAST 0x10
|
||||
|
||||
struct abis_om_obj_inst {
|
||||
uint8_t bts_nr;
|
||||
uint8_t trx_nr;
|
||||
uint8_t ts_nr;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct abis_om_fom_hdr {
|
||||
uint8_t msg_type;
|
||||
uint8_t obj_class;
|
||||
struct abis_om_obj_inst obj_inst;
|
||||
uint8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define ABIS_OM_FOM_HDR_SIZE (sizeof(struct abis_om_hdr) + sizeof(struct abis_om_fom_hdr))
|
||||
|
||||
/* Section 9.1: Message Types */
|
||||
enum abis_nm_msgtype {
|
||||
/* SW Download Management Messages */
|
||||
NM_MT_LOAD_INIT = 0x01,
|
||||
NM_MT_LOAD_INIT_ACK,
|
||||
NM_MT_LOAD_INIT_NACK,
|
||||
NM_MT_LOAD_SEG,
|
||||
NM_MT_LOAD_SEG_ACK,
|
||||
NM_MT_LOAD_ABORT,
|
||||
NM_MT_LOAD_END,
|
||||
NM_MT_LOAD_END_ACK,
|
||||
NM_MT_LOAD_END_NACK,
|
||||
NM_MT_SW_ACT_REQ, /* BTS->BSC */
|
||||
NM_MT_SW_ACT_REQ_ACK,
|
||||
NM_MT_SW_ACT_REQ_NACK,
|
||||
NM_MT_ACTIVATE_SW, /* BSC->BTS */
|
||||
NM_MT_ACTIVATE_SW_ACK,
|
||||
NM_MT_ACTIVATE_SW_NACK,
|
||||
NM_MT_SW_ACTIVATED_REP, /* 0x10 */
|
||||
/* A-bis Interface Management Messages */
|
||||
NM_MT_ESTABLISH_TEI = 0x21,
|
||||
NM_MT_ESTABLISH_TEI_ACK,
|
||||
NM_MT_ESTABLISH_TEI_NACK,
|
||||
NM_MT_CONN_TERR_SIGN,
|
||||
NM_MT_CONN_TERR_SIGN_ACK,
|
||||
NM_MT_CONN_TERR_SIGN_NACK,
|
||||
NM_MT_DISC_TERR_SIGN,
|
||||
NM_MT_DISC_TERR_SIGN_ACK,
|
||||
NM_MT_DISC_TERR_SIGN_NACK,
|
||||
NM_MT_CONN_TERR_TRAF,
|
||||
NM_MT_CONN_TERR_TRAF_ACK,
|
||||
NM_MT_CONN_TERR_TRAF_NACK,
|
||||
NM_MT_DISC_TERR_TRAF,
|
||||
NM_MT_DISC_TERR_TRAF_ACK,
|
||||
NM_MT_DISC_TERR_TRAF_NACK,
|
||||
/* Transmission Management Messages */
|
||||
NM_MT_CONN_MDROP_LINK = 0x31,
|
||||
NM_MT_CONN_MDROP_LINK_ACK,
|
||||
NM_MT_CONN_MDROP_LINK_NACK,
|
||||
NM_MT_DISC_MDROP_LINK,
|
||||
NM_MT_DISC_MDROP_LINK_ACK,
|
||||
NM_MT_DISC_MDROP_LINK_NACK,
|
||||
/* Air Interface Management Messages */
|
||||
NM_MT_SET_BTS_ATTR = 0x41,
|
||||
NM_MT_SET_BTS_ATTR_ACK,
|
||||
NM_MT_SET_BTS_ATTR_NACK,
|
||||
NM_MT_SET_RADIO_ATTR,
|
||||
NM_MT_SET_RADIO_ATTR_ACK,
|
||||
NM_MT_SET_RADIO_ATTR_NACK,
|
||||
NM_MT_SET_CHAN_ATTR,
|
||||
NM_MT_SET_CHAN_ATTR_ACK,
|
||||
NM_MT_SET_CHAN_ATTR_NACK,
|
||||
/* Test Management Messages */
|
||||
NM_MT_PERF_TEST = 0x51,
|
||||
NM_MT_PERF_TEST_ACK,
|
||||
NM_MT_PERF_TEST_NACK,
|
||||
NM_MT_TEST_REP,
|
||||
NM_MT_SEND_TEST_REP,
|
||||
NM_MT_SEND_TEST_REP_ACK,
|
||||
NM_MT_SEND_TEST_REP_NACK,
|
||||
NM_MT_STOP_TEST,
|
||||
NM_MT_STOP_TEST_ACK,
|
||||
NM_MT_STOP_TEST_NACK,
|
||||
/* State Management and Event Report Messages */
|
||||
NM_MT_STATECHG_EVENT_REP = 0x61,
|
||||
NM_MT_FAILURE_EVENT_REP,
|
||||
NM_MT_STOP_EVENT_REP,
|
||||
NM_MT_STOP_EVENT_REP_ACK,
|
||||
NM_MT_STOP_EVENT_REP_NACK,
|
||||
NM_MT_REST_EVENT_REP,
|
||||
NM_MT_REST_EVENT_REP_ACK,
|
||||
NM_MT_REST_EVENT_REP_NACK,
|
||||
NM_MT_CHG_ADM_STATE,
|
||||
NM_MT_CHG_ADM_STATE_ACK,
|
||||
NM_MT_CHG_ADM_STATE_NACK,
|
||||
NM_MT_CHG_ADM_STATE_REQ,
|
||||
NM_MT_CHG_ADM_STATE_REQ_ACK,
|
||||
NM_MT_CHG_ADM_STATE_REQ_NACK,
|
||||
NM_MT_REP_OUTST_ALARMS = 0x93,
|
||||
NM_MT_REP_OUTST_ALARMS_ACK,
|
||||
NM_MT_REP_OUTST_ALARMS_NACK,
|
||||
/* Equipment Management Messages */
|
||||
NM_MT_CHANGEOVER = 0x71,
|
||||
NM_MT_CHANGEOVER_ACK,
|
||||
NM_MT_CHANGEOVER_NACK,
|
||||
NM_MT_OPSTART,
|
||||
NM_MT_OPSTART_ACK,
|
||||
NM_MT_OPSTART_NACK,
|
||||
NM_MT_REINIT,
|
||||
NM_MT_REINIT_ACK,
|
||||
NM_MT_REINIT_NACK,
|
||||
NM_MT_SET_SITE_OUT, /* BS11: get alarm ?!? */
|
||||
NM_MT_SET_SITE_OUT_ACK,
|
||||
NM_MT_SET_SITE_OUT_NACK,
|
||||
NM_MT_CHG_HW_CONF = 0x90,
|
||||
NM_MT_CHG_HW_CONF_ACK,
|
||||
NM_MT_CHG_HW_CONF_NACK,
|
||||
/* Measurement Management Messages */
|
||||
NM_MT_MEAS_RES_REQ = 0x8a,
|
||||
NM_MT_MEAS_RES_RESP,
|
||||
NM_MT_STOP_MEAS,
|
||||
NM_MT_START_MEAS,
|
||||
/* Other Messages */
|
||||
NM_MT_GET_ATTR = 0x81,
|
||||
NM_MT_GET_ATTR_RESP,
|
||||
NM_MT_GET_ATTR_NACK,
|
||||
NM_MT_SET_ALARM_THRES,
|
||||
NM_MT_SET_ALARM_THRES_ACK,
|
||||
NM_MT_SET_ALARM_THRES_NACK,
|
||||
};
|
||||
|
||||
enum abis_nm_msgtype_bs11 {
|
||||
NM_MT_BS11_RESET_RESOURCE = 0x74,
|
||||
|
||||
NM_MT_BS11_BEGIN_DB_TX = 0xa3,
|
||||
NM_MT_BS11_BEGIN_DB_TX_ACK,
|
||||
NM_MT_BS11_BEGIN_DB_TX_NACK,
|
||||
NM_MT_BS11_END_DB_TX = 0xa6,
|
||||
NM_MT_BS11_END_DB_TX_ACK,
|
||||
NM_MT_BS11_END_DB_TX_NACK,
|
||||
NM_MT_BS11_CREATE_OBJ = 0xa9,
|
||||
NM_MT_BS11_CREATE_OBJ_ACK,
|
||||
NM_MT_BS11_CREATE_OBJ_NACK,
|
||||
NM_MT_BS11_DELETE_OBJ = 0xac,
|
||||
NM_MT_BS11_DELETE_OBJ_ACK,
|
||||
NM_MT_BS11_DELETE_OBJ_NACK,
|
||||
|
||||
NM_MT_BS11_SET_ATTR = 0xd0,
|
||||
NM_MT_BS11_SET_ATTR_ACK,
|
||||
NM_MT_BS11_SET_ATTR_NACK,
|
||||
NM_MT_BS11_LMT_SESSION = 0xdc,
|
||||
|
||||
NM_MT_BS11_GET_STATE = 0xe3,
|
||||
NM_MT_BS11_GET_STATE_ACK,
|
||||
NM_MT_BS11_LMT_LOGON = 0xe5,
|
||||
NM_MT_BS11_LMT_LOGON_ACK,
|
||||
NM_MT_BS11_RESTART = 0xe7,
|
||||
NM_MT_BS11_RESTART_ACK,
|
||||
NM_MT_BS11_DISCONNECT = 0xe9,
|
||||
NM_MT_BS11_DISCONNECT_ACK,
|
||||
NM_MT_BS11_LMT_LOGOFF = 0xec,
|
||||
NM_MT_BS11_LMT_LOGOFF_ACK,
|
||||
NM_MT_BS11_RECONNECT = 0xf1,
|
||||
NM_MT_BS11_RECONNECT_ACK,
|
||||
};
|
||||
|
||||
enum abis_nm_msgtype_ipacc {
|
||||
NM_MT_IPACC_RESTART = 0x87,
|
||||
NM_MT_IPACC_RESTART_ACK,
|
||||
NM_MT_IPACC_RESTART_NACK,
|
||||
NM_MT_IPACC_RSL_CONNECT = 0xe0,
|
||||
NM_MT_IPACC_RSL_CONNECT_ACK,
|
||||
NM_MT_IPACC_RSL_CONNECT_NACK,
|
||||
NM_MT_IPACC_RSL_DISCONNECT = 0xe3,
|
||||
NM_MT_IPACC_RSL_DISCONNECT_ACK,
|
||||
NM_MT_IPACC_RSL_DISCONNECT_NACK,
|
||||
NM_MT_IPACC_CONN_TRAF = 0xe6,
|
||||
NM_MT_IPACC_CONN_TRAF_ACK,
|
||||
NM_MT_IPACC_CONN_TRAF_NACK,
|
||||
NM_MT_IPACC_DEF_BOOT_SW = 0xec,
|
||||
NM_MT_IPACC_DEF_BOOT_SW_ACK,
|
||||
MN_MT_IPACC_DEF_BOOT_SW_NACK,
|
||||
NM_MT_IPACC_SET_NVATTR = 0xef,
|
||||
NM_MT_IPACC_SET_NVATTR_ACK,
|
||||
NM_MT_IPACC_SET_NVATTR_NACK,
|
||||
NM_MT_IPACC_GET_NVATTR = 0xf2,
|
||||
NM_MT_IPACC_GET_NVATTR_ACK,
|
||||
NM_MT_IPACC_GET_NVATTR_NACK,
|
||||
NM_MT_IPACC_SET_ATTR = 0xf5,
|
||||
NM_MT_IPACC_SET_ATTR_ACK,
|
||||
NM_MT_IPACC_SET_ATTR_NACK,
|
||||
};
|
||||
|
||||
enum abis_nm_bs11_cell_alloc {
|
||||
NM_BS11_CANR_GSM = 0x00,
|
||||
NM_BS11_CANR_DCS1800 = 0x01,
|
||||
};
|
||||
|
||||
/* Section 9.2: Object Class */
|
||||
enum abis_nm_obj_class {
|
||||
NM_OC_SITE_MANAGER = 0x00,
|
||||
NM_OC_BTS,
|
||||
NM_OC_RADIO_CARRIER,
|
||||
NM_OC_CHANNEL,
|
||||
NM_OC_BASEB_TRANSC,
|
||||
/* RFU: 05-FE */
|
||||
|
||||
NM_OC_IPAC_E1_TRUNK = 0x0e,
|
||||
NM_OC_IPAC_E1_PORT = 0x0f,
|
||||
NM_OC_IPAC_E1_CHAN = 0x10,
|
||||
NM_OC_IPAC_CLK_MODULE = 0x22,
|
||||
|
||||
NM_OC_BS11_ADJC = 0xa0,
|
||||
NM_OC_BS11_HANDOVER = 0xa1,
|
||||
NM_OC_BS11_PWR_CTRL = 0xa2,
|
||||
NM_OC_BS11_BTSE = 0xa3, /* LMT? */
|
||||
NM_OC_BS11_RACK = 0xa4,
|
||||
NM_OC_BS11 = 0xa5, /* 01: ALCO */
|
||||
NM_OC_BS11_TEST = 0xa6,
|
||||
NM_OC_BS11_ENVABTSE = 0xa8,
|
||||
NM_OC_BS11_BPORT = 0xa9,
|
||||
|
||||
NM_OC_GPRS_NSE = 0xf0,
|
||||
NM_OC_GPRS_CELL = 0xf1,
|
||||
NM_OC_GPRS_NSVC = 0xf2,
|
||||
|
||||
NM_OC_NULL = 0xff,
|
||||
};
|
||||
|
||||
/* Section 9.4: Attributes */
|
||||
enum abis_nm_attr {
|
||||
NM_ATT_ABIS_CHANNEL = 0x01,
|
||||
NM_ATT_ADD_INFO,
|
||||
NM_ATT_ADD_TEXT,
|
||||
NM_ATT_ADM_STATE,
|
||||
NM_ATT_ARFCN_LIST,
|
||||
NM_ATT_AUTON_REPORT,
|
||||
NM_ATT_AVAIL_STATUS,
|
||||
NM_ATT_BCCH_ARFCN,
|
||||
NM_ATT_BSIC,
|
||||
NM_ATT_BTS_AIR_TIMER,
|
||||
NM_ATT_CCCH_L_I_P,
|
||||
NM_ATT_CCCH_L_T,
|
||||
NM_ATT_CHAN_COMB,
|
||||
NM_ATT_CONN_FAIL_CRIT,
|
||||
NM_ATT_DEST,
|
||||
/* res */
|
||||
NM_ATT_EVENT_TYPE = 0x11, /* BS11: file data ?!? */
|
||||
NM_ATT_FILE_ID,
|
||||
NM_ATT_FILE_VERSION,
|
||||
NM_ATT_GSM_TIME,
|
||||
NM_ATT_HSN,
|
||||
NM_ATT_HW_CONFIG,
|
||||
NM_ATT_HW_DESC,
|
||||
NM_ATT_INTAVE_PARAM,
|
||||
NM_ATT_INTERF_BOUND,
|
||||
NM_ATT_LIST_REQ_ATTR,
|
||||
NM_ATT_MAIO,
|
||||
NM_ATT_MANUF_STATE,
|
||||
NM_ATT_MANUF_THRESH,
|
||||
NM_ATT_MANUF_ID,
|
||||
NM_ATT_MAX_TA,
|
||||
NM_ATT_MDROP_LINK, /* 0x20 */
|
||||
NM_ATT_MDROP_NEXT,
|
||||
NM_ATT_NACK_CAUSES,
|
||||
NM_ATT_NY1,
|
||||
NM_ATT_OPER_STATE,
|
||||
NM_ATT_OVERL_PERIOD,
|
||||
NM_ATT_PHYS_CONF,
|
||||
NM_ATT_POWER_CLASS,
|
||||
NM_ATT_POWER_THRESH,
|
||||
NM_ATT_PROB_CAUSE,
|
||||
NM_ATT_RACH_B_THRESH,
|
||||
NM_ATT_LDAVG_SLOTS,
|
||||
NM_ATT_RAD_SUBC,
|
||||
NM_ATT_RF_MAXPOWR_R,
|
||||
NM_ATT_SITE_INPUTS,
|
||||
NM_ATT_SITE_OUTPUTS,
|
||||
NM_ATT_SOURCE, /* 0x30 */
|
||||
NM_ATT_SPEC_PROB,
|
||||
NM_ATT_START_TIME,
|
||||
NM_ATT_T200,
|
||||
NM_ATT_TEI,
|
||||
NM_ATT_TEST_DUR,
|
||||
NM_ATT_TEST_NO,
|
||||
NM_ATT_TEST_REPORT,
|
||||
NM_ATT_VSWR_THRESH,
|
||||
NM_ATT_WINDOW_SIZE,
|
||||
/* Res */
|
||||
NM_ATT_BS11_RSSI_OFFS = 0x3d,
|
||||
NM_ATT_BS11_TXPWR = 0x3e,
|
||||
NM_ATT_BS11_DIVERSITY = 0x3f,
|
||||
/* Res */
|
||||
NM_ATT_TSC = 0x40,
|
||||
NM_ATT_SW_CONFIG,
|
||||
NM_ATT_SW_DESCR,
|
||||
NM_ATT_SEVERITY,
|
||||
NM_ATT_GET_ARI,
|
||||
NM_ATT_HW_CONF_CHG,
|
||||
NM_ATT_OUTST_ALARM,
|
||||
NM_ATT_FILE_DATA,
|
||||
NM_ATT_MEAS_RES,
|
||||
NM_ATT_MEAS_TYPE,
|
||||
|
||||
NM_ATT_BS11_ESN_FW_CODE_NO = 0x4c,
|
||||
NM_ATT_BS11_ESN_HW_CODE_NO = 0x4f,
|
||||
|
||||
NM_ATT_BS11_ESN_PCB_SERIAL = 0x55,
|
||||
NM_ATT_BS11_EXCESSIVE_DISTANCE = 0x58,
|
||||
|
||||
NM_ATT_BS11_ALL_TEST_CATG = 0x60,
|
||||
NM_ATT_BS11_BTSLS_HOPPING,
|
||||
NM_ATT_BS11_CELL_ALLOC_NR,
|
||||
NM_ATT_BS11_CELL_GLOBAL_ID,
|
||||
NM_ATT_BS11_ENA_INTERF_CLASS = 0x66,
|
||||
NM_ATT_BS11_ENA_INT_INTEC_HANDO = 0x67,
|
||||
NM_ATT_BS11_ENA_INT_INTRC_HANDO = 0x68,
|
||||
NM_ATT_BS11_ENA_MS_PWR_CTRL = 0x69,
|
||||
NM_ATT_BS11_ENA_PWR_BDGT_HO = 0x6a,
|
||||
NM_ATT_BS11_ENA_PWR_CTRL_RLFW = 0x6b,
|
||||
NM_ATT_BS11_ENA_RXLEV_HO = 0x6c,
|
||||
NM_ATT_BS11_ENA_RXQUAL_HO = 0x6d,
|
||||
NM_ATT_BS11_FACCH_QUAL = 0x6e,
|
||||
|
||||
NM_ATT_IPACC_DST_IP = 0x80,
|
||||
NM_ATT_IPACC_DST_IP_PORT = 0x81,
|
||||
NM_ATT_IPACC_SSRC = 0x82,
|
||||
NM_ATT_IPACC_RTP_PAYLD_TYPE = 0x83,
|
||||
NM_ATT_IPACC_BASEB_ID = 0x84,
|
||||
NM_ATT_IPACC_STREAM_ID = 0x85,
|
||||
NM_ATT_IPACC_NV_FLAGS = 0x86,
|
||||
NM_ATT_IPACC_FREQ_CTRL = 0x87,
|
||||
NM_ATT_IPACC_PRIM_OML_CFG = 0x88,
|
||||
NM_ATT_IPACC_SEC_OML_CFG = 0x89,
|
||||
NM_ATT_IPACC_IP_IF_CFG = 0x8a, /* IP interface */
|
||||
NM_ATT_IPACC_IP_GW_CFG = 0x8b, /* IP gateway */
|
||||
NM_ATT_IPACC_IN_SERV_TIME = 0x8c,
|
||||
NM_ATT_IPACC_TRX_BTS_ASS = 0x8d,
|
||||
NM_ATT_IPACC_LOCATION = 0x8e, /* string describing location */
|
||||
NM_ATT_IPACC_PAGING_CFG = 0x8f,
|
||||
NM_ATT_IPACC_FILE_DATA = 0x90,
|
||||
NM_ATT_IPACC_UNIT_ID = 0x91, /* Site/BTS/TRX */
|
||||
NM_ATT_IPACC_PARENT_UNIT_ID = 0x92,
|
||||
NM_ATT_IPACC_UNIT_NAME = 0x93, /* default: nbts-<mac-as-string> */
|
||||
NM_ATT_IPACC_SNMP_CFG = 0x94,
|
||||
NM_ATT_IPACC_PRIM_OML_CFG_LIST = 0x95,
|
||||
NM_ATT_IPACC_PRIM_OML_FB_TOUT = 0x96,
|
||||
NM_ATT_IPACC_CUR_SW_CFG = 0x97,
|
||||
NM_ATT_IPACC_TIMING_BUS = 0x98,
|
||||
NM_ATT_IPACC_CGI = 0x99,
|
||||
NM_ATT_IPACC_RAC = 0x9a,
|
||||
NM_ATT_IPACC_OBJ_VERSION = 0x9b,
|
||||
NM_ATT_IPACC_GPRS_PAGING_CFG = 0x9c,
|
||||
NM_ATT_IPACC_NSEI = 0x9d,
|
||||
NM_ATT_IPACC_BVCI = 0x9e,
|
||||
NM_ATT_IPACC_NSVCI = 0x9f,
|
||||
NM_ATT_IPACC_NS_CFG = 0xa0,
|
||||
NM_ATT_IPACC_BSSGP_CFG = 0xa1,
|
||||
NM_ATT_IPACC_NS_LINK_CFG = 0xa2,
|
||||
NM_ATT_IPACC_RLC_CFG = 0xa3,
|
||||
NM_ATT_IPACC_ALM_THRESH_LIST = 0xa4,
|
||||
NM_ATT_IPACC_MONIT_VAL_LIST = 0xa5,
|
||||
NM_ATT_IPACC_TIB_CONTROL = 0xa6,
|
||||
NM_ATT_IPACC_SUPP_FEATURES = 0xa7,
|
||||
NM_ATT_IPACC_CODING_SCHEMES = 0xa8,
|
||||
NM_ATT_IPACC_RLC_CFG_2 = 0xa9,
|
||||
NM_ATT_IPACC_HEARTB_TOUT = 0xaa,
|
||||
NM_ATT_IPACC_UPTIME = 0xab,
|
||||
NM_ATT_IPACC_RLC_CFG_3 = 0xac,
|
||||
NM_ATT_IPACC_SSL_CFG = 0xad,
|
||||
NM_ATT_IPACC_SEC_POSSIBLE = 0xae,
|
||||
NM_ATT_IPACC_IML_SSL_STATE = 0xaf,
|
||||
NM_ATT_IPACC_REVOC_DATE = 0xb0,
|
||||
|
||||
|
||||
NM_ATT_BS11_RF_RES_IND_PER = 0x8f,
|
||||
|
||||
NM_ATT_BS11_RX_LEV_MIN_CELL = 0x90,
|
||||
NM_ATT_BS11_ABIS_EXT_TIME = 0x91,
|
||||
NM_ATT_BS11_TIMER_HO_REQUEST = 0x92,
|
||||
NM_ATT_BS11_TIMER_NCELL = 0x93,
|
||||
NM_ATT_BS11_TSYNC = 0x94,
|
||||
NM_ATT_BS11_TTRAU = 0x95,
|
||||
NM_ATT_BS11_EMRG_CFG_MEMBER = 0x9b,
|
||||
NM_ATT_BS11_TRX_AREA = 0x9f,
|
||||
|
||||
NM_ATT_BS11_BCCH_RECONF = 0xd7,
|
||||
NM_ATT_BS11_BIT_ERR_THESH = 0xa0,
|
||||
NM_ATT_BS11_BOOT_SW_VERS = 0xa1,
|
||||
NM_ATT_BS11_CCLK_ACCURACY = 0xa3,
|
||||
NM_ATT_BS11_CCLK_TYPE = 0xa4,
|
||||
NM_ATT_BS11_INP_IMPEDANCE = 0xaa,
|
||||
NM_ATT_BS11_L1_PROT_TYPE = 0xab,
|
||||
NM_ATT_BS11_LINE_CFG = 0xac,
|
||||
NM_ATT_BS11_LI_PORT_1 = 0xad,
|
||||
NM_ATT_BS11_LI_PORT_2 = 0xae,
|
||||
|
||||
NM_ATT_BS11_L1_REM_ALM_TYPE = 0xb0,
|
||||
NM_ATT_BS11_SW_LOAD_INTENDED = 0xbb,
|
||||
NM_ATT_BS11_SW_LOAD_SAFETY = 0xbc,
|
||||
NM_ATT_BS11_SW_LOAD_STORED = 0xbd,
|
||||
|
||||
NM_ATT_BS11_VENDOR_NAME = 0xc1,
|
||||
NM_ATT_BS11_HOPPING_MODE = 0xc5,
|
||||
NM_ATT_BS11_LMT_LOGON_SESSION = 0xc6,
|
||||
NM_ATT_BS11_LMT_LOGIN_TIME = 0xc7,
|
||||
NM_ATT_BS11_LMT_USER_ACC_LEV = 0xc8,
|
||||
NM_ATT_BS11_LMT_USER_NAME = 0xc9,
|
||||
|
||||
NM_ATT_BS11_L1_CONTROL_TS = 0xd8,
|
||||
NM_ATT_BS11_RADIO_MEAS_GRAN = 0xdc, /* in SACCH multiframes */
|
||||
NM_ATT_BS11_RADIO_MEAS_REP = 0xdd,
|
||||
|
||||
NM_ATT_BS11_SH_LAPD_INT_TIMER = 0xe8,
|
||||
|
||||
NM_ATT_BS11_BTS_STATE = 0xf0,
|
||||
NM_ATT_BS11_E1_STATE = 0xf1,
|
||||
NM_ATT_BS11_PLL = 0xf2,
|
||||
NM_ATT_BS11_RX_OFFSET = 0xf3,
|
||||
NM_ATT_BS11_ANT_TYPE = 0xf4,
|
||||
NM_ATT_BS11_PLL_MODE = 0xfc,
|
||||
NM_ATT_BS11_PASSWORD = 0xfd,
|
||||
};
|
||||
#define NM_ATT_BS11_FILE_DATA NM_ATT_EVENT_TYPE
|
||||
|
||||
/* Section 9.4.4: Administrative State */
|
||||
enum abis_nm_adm_state {
|
||||
NM_STATE_LOCKED = 0x01,
|
||||
NM_STATE_UNLOCKED = 0x02,
|
||||
NM_STATE_SHUTDOWN = 0x03,
|
||||
NM_STATE_NULL = 0xff,
|
||||
};
|
||||
|
||||
/* Section 9.4.7: Administrative State */
|
||||
enum abis_nm_avail_state {
|
||||
NM_AVSTATE_IN_TEST = 1,
|
||||
NM_AVSTATE_POWER_OFF = 2,
|
||||
NM_AVSTATE_OFF_LINE = 3,
|
||||
NM_AVSTATE_DEPENDENCY = 5,
|
||||
NM_AVSTATE_DEGRADED = 6,
|
||||
NM_AVSTATE_NOT_INSTALLED= 7,
|
||||
NM_AVSTATE_OK = 0xff,
|
||||
};
|
||||
|
||||
enum abis_nm_op_state {
|
||||
NM_OPSTATE_DISABLED = 1,
|
||||
NM_OPSTATE_ENABLED = 2,
|
||||
NM_OPSTATE_NULL = 0xff,
|
||||
};
|
||||
|
||||
/* Section 9.4.13: Channel Combination */
|
||||
enum abis_nm_chan_comb {
|
||||
NM_CHANC_TCHFull = 0x00, /* TCH/F + TCH/H + SACCH/TF */
|
||||
NM_CHANC_TCHHalf = 0x01, /* TCH/H(0,1) + FACCH/H(0,1) +
|
||||
SACCH/TH(0,1) */
|
||||
NM_CHANC_TCHHalf2 = 0x02, /* TCH/H(0) + FACCH/H(0) + SACCH/TH(0) +
|
||||
TCH/H(1) */
|
||||
NM_CHANC_SDCCH = 0x03, /* SDCCH/8 + SACCH/8 */
|
||||
NM_CHANC_mainBCCH = 0x04, /* FCCH + SCH + BCCH + CCCH */
|
||||
NM_CHANC_BCCHComb = 0x05, /* FCCH + SCH + BCCH + CCCH + SDCCH/4 +
|
||||
SACCH/C4 */
|
||||
NM_CHANC_BCCH = 0x06, /* BCCH + CCCH */
|
||||
NM_CHANC_BCCH_CBCH = 0x07, /* CHANC_BCCHComb + CBCH */
|
||||
NM_CHANC_SDCCH_CBCH = 0x08, /* CHANC_SDCCH8 + CBCH */
|
||||
/* ip.access */
|
||||
NM_CHANC_IPAC_bPDCH = 0x0b, /* PBCCH + PCCCH + PDTCH/F + PACCH/F +
|
||||
PTCCH/F */
|
||||
NM_CHANC_IPAC_cPDCH = 0x0c, /* PBCCH + PDTCH/F + PACCH/F + PTCCH/F */
|
||||
NM_CHANC_IPAC_PDCH = 0x0d, /* PDTCH/F + PACCH/F + PTCCH/F */
|
||||
NM_CHANC_IPAC_TCHFull_PDCH = 0x80,
|
||||
NM_CHANC_IPAC_TCHFull_TCHHalf = 0x81,
|
||||
};
|
||||
|
||||
/* Section 9.4.16: Event Type */
|
||||
enum abis_nm_event_type {
|
||||
NM_EVT_COMM_FAIL = 0x00,
|
||||
NM_EVT_QOS_FAIL = 0x01,
|
||||
NM_EVT_PROC_FAIL = 0x02,
|
||||
NM_EVT_EQUIP_FAIL = 0x03,
|
||||
NM_EVT_ENV_FAIL = 0x04,
|
||||
};
|
||||
|
||||
/* Section: 9.4.63: Perceived Severity */
|
||||
enum abis_nm_severity {
|
||||
NM_SEVER_CEASED = 0x00,
|
||||
NM_SEVER_CRITICAL = 0x01,
|
||||
NM_SEVER_MAJOR = 0x02,
|
||||
NM_SEVER_MINOR = 0x03,
|
||||
NM_SEVER_WARNING = 0x04,
|
||||
NM_SEVER_INDETERMINATE = 0x05,
|
||||
};
|
||||
|
||||
/* Section 9.4.43: Probable Cause Type */
|
||||
enum abis_nm_pcause_type {
|
||||
NM_PCAUSE_T_X721 = 0x01,
|
||||
NM_PCAUSE_T_GSM = 0x02,
|
||||
NM_PCAUSE_T_MANUF = 0x03,
|
||||
};
|
||||
|
||||
/* Section 9.4.36: NACK Causes */
|
||||
enum abis_nm_nack_cause {
|
||||
/* General Nack Causes */
|
||||
NM_NACK_INCORR_STRUCT = 0x01,
|
||||
NM_NACK_MSGTYPE_INVAL = 0x02,
|
||||
NM_NACK_OBJCLASS_INVAL = 0x05,
|
||||
NM_NACK_OBJCLASS_NOTSUPP = 0x06,
|
||||
NM_NACK_BTSNR_UNKN = 0x07,
|
||||
NM_NACK_TRXNR_UNKN = 0x08,
|
||||
NM_NACK_OBJINST_UNKN = 0x09,
|
||||
NM_NACK_ATTRID_INVAL = 0x0c,
|
||||
NM_NACK_ATTRID_NOTSUPP = 0x0d,
|
||||
NM_NACK_PARAM_RANGE = 0x0e,
|
||||
NM_NACK_ATTRLIST_INCONSISTENT = 0x0f,
|
||||
NM_NACK_SPEC_IMPL_NOTSUPP = 0x10,
|
||||
NM_NACK_CANT_PERFORM = 0x11,
|
||||
/* Specific Nack Causes */
|
||||
NM_NACK_RES_NOTIMPL = 0x19,
|
||||
NM_NACK_RES_NOTAVAIL = 0x1a,
|
||||
NM_NACK_FREQ_NOTAVAIL = 0x1b,
|
||||
NM_NACK_TEST_NOTSUPP = 0x1c,
|
||||
NM_NACK_CAPACITY_RESTR = 0x1d,
|
||||
NM_NACK_PHYSCFG_NOTPERFORM = 0x1e,
|
||||
NM_NACK_TEST_NOTINIT = 0x1f,
|
||||
NM_NACK_PHYSCFG_NOTRESTORE = 0x20,
|
||||
NM_NACK_TEST_NOSUCH = 0x21,
|
||||
NM_NACK_TEST_NOSTOP = 0x22,
|
||||
NM_NACK_MSGINCONSIST_PHYSCFG = 0x23,
|
||||
NM_NACK_FILE_INCOMPLETE = 0x25,
|
||||
NM_NACK_FILE_NOTAVAIL = 0x26,
|
||||
NM_NACK_FILE_NOTACTIVATE = 0x27,
|
||||
NM_NACK_REQ_NOT_GRANT = 0x28,
|
||||
NM_NACK_WAIT = 0x29,
|
||||
NM_NACK_NOTH_REPORT_EXIST = 0x2a,
|
||||
NM_NACK_MEAS_NOTSUPP = 0x2b,
|
||||
NM_NACK_MEAS_NOTSTART = 0x2c,
|
||||
};
|
||||
|
||||
/* Section 9.4.1 */
|
||||
struct abis_nm_channel {
|
||||
uint8_t attrib;
|
||||
uint8_t bts_port;
|
||||
uint8_t timeslot;
|
||||
uint8_t subslot;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Siemens BS-11 specific objects in the SienemsHW (0xA5) object class */
|
||||
enum abis_bs11_objtype {
|
||||
BS11_OBJ_ALCO = 0x01,
|
||||
BS11_OBJ_BBSIG = 0x02, /* obj_class: 0,1 */
|
||||
BS11_OBJ_TRX1 = 0x03, /* only DEACTIVATE TRX1 */
|
||||
BS11_OBJ_CCLK = 0x04,
|
||||
BS11_OBJ_GPSU = 0x06,
|
||||
BS11_OBJ_LI = 0x07,
|
||||
BS11_OBJ_PA = 0x09, /* obj_class: 0, 1*/
|
||||
};
|
||||
|
||||
enum abis_bs11_trx_power {
|
||||
BS11_TRX_POWER_GSM_2W = 0x06,
|
||||
BS11_TRX_POWER_GSM_250mW= 0x07,
|
||||
BS11_TRX_POWER_GSM_80mW = 0x08,
|
||||
BS11_TRX_POWER_GSM_30mW = 0x09,
|
||||
BS11_TRX_POWER_DCS_3W = 0x0a,
|
||||
BS11_TRX_POWER_DCS_1W6 = 0x0b,
|
||||
BS11_TRX_POWER_DCS_500mW= 0x0c,
|
||||
BS11_TRX_POWER_DCS_160mW= 0x0d,
|
||||
};
|
||||
|
||||
enum abis_bs11_li_pll_mode {
|
||||
BS11_LI_PLL_LOCKED = 2,
|
||||
BS11_LI_PLL_STANDALONE = 3,
|
||||
};
|
||||
|
||||
enum abis_bs11_line_cfg {
|
||||
BS11_LINE_CFG_STAR = 0x00,
|
||||
BS11_LINE_CFG_MULTIDROP = 0x01,
|
||||
BS11_LINE_CFG_LOOP = 0x02,
|
||||
};
|
||||
|
||||
enum abis_bs11_phase {
|
||||
BS11_STATE_SOFTWARE_RQD = 0x01,
|
||||
BS11_STATE_LOAD_SMU_INTENDED = 0x11,
|
||||
BS11_STATE_LOAD_SMU_SAFETY = 0x21,
|
||||
BS11_STATE_LOAD_FAILED = 0x31,
|
||||
BS11_STATE_LOAD_DIAGNOSTIC = 0x41,
|
||||
BS11_STATE_WARM_UP = 0x51,
|
||||
BS11_STATE_WARM_UP_2 = 0x52,
|
||||
BS11_STATE_WAIT_MIN_CFG = 0x62,
|
||||
BS11_STATE_MAINTENANCE = 0x72,
|
||||
BS11_STATE_LOAD_MBCCU = 0x92,
|
||||
BS11_STATE_WAIT_MIN_CFG_2 = 0xA2,
|
||||
BS11_STATE_NORMAL = 0x03,
|
||||
BS11_STATE_ABIS_LOAD = 0x13,
|
||||
};
|
||||
|
||||
enum abis_nm_ipacc_test_no {
|
||||
NM_IPACC_TESTNO_RLOOP_ANT = 0x01,
|
||||
NM_IPACC_TESTNO_RLOOP_XCVR = 0x02,
|
||||
NM_IPACC_TESTNO_FUNC_OBJ = 0x03,
|
||||
NM_IPACC_TESTNO_CHAN_USAGE = 0x40,
|
||||
NM_IPACC_TESTNO_BCCH_CHAN_USAGE = 0x41,
|
||||
NM_IPACC_TESTNO_FREQ_SYNC = 0x42,
|
||||
NM_IPACC_TESTNO_BCCH_INFO = 0x43,
|
||||
NM_IPACC_TESTNO_TX_BEACON = 0x44,
|
||||
NM_IPACC_TESTNO_SYSINFO_MONITOR = 0x45,
|
||||
NM_IPACC_TESTNO_BCCCH_MONITOR = 0x46,
|
||||
};
|
||||
|
||||
/* first byte after length inside NM_ATT_TEST_REPORT */
|
||||
enum abis_nm_ipacc_test_res {
|
||||
NM_IPACC_TESTRES_SUCCESS = 0,
|
||||
NM_IPACC_TESTRES_TIMEOUT = 1,
|
||||
NM_IPACC_TESTRES_NO_CHANS = 2,
|
||||
NM_IPACC_TESTRES_PARTIAL = 3,
|
||||
NM_IPACC_TESTRES_STOPPED = 4,
|
||||
};
|
||||
|
||||
/* internal IE inside NM_ATT_TEST_REPORT */
|
||||
enum abis_nm_ipacc_testres_ie {
|
||||
NM_IPACC_TR_IE_FREQ_ERR_LIST = 3,
|
||||
NM_IPACC_TR_IE_CHAN_USAGE = 4,
|
||||
NM_IPACC_TR_IE_BCCH_INFO = 6,
|
||||
NM_IPACC_TR_IE_RESULT_DETAILS = 8,
|
||||
NM_IPACC_TR_IE_FREQ_ERR = 18,
|
||||
};
|
||||
|
||||
enum ipac_eie {
|
||||
NM_IPAC_EIE_ARFCN_WHITE = 0x01,
|
||||
NM_IPAC_EIE_ARFCH_BLACK = 0x02,
|
||||
NM_IPAC_EIE_FREQ_ERR_LIST = 0x03,
|
||||
NM_IPAC_EIE_CHAN_USE_LIST = 0x04,
|
||||
NM_IPAC_EIE_BCCH_INFO_TYPE = 0x05,
|
||||
NM_IPAC_EIE_BCCH_INFO = 0x06,
|
||||
NM_IPAC_EIE_CONFIG = 0x07,
|
||||
NM_IPAC_EIE_RES_DETAILS = 0x08,
|
||||
NM_IPAC_EIE_RXLEV_THRESH = 0x09,
|
||||
NM_IPAC_EIE_FREQ_SYNC_OPTS = 0x0a,
|
||||
NM_IPAC_EIE_MAC_ADDR = 0x0b,
|
||||
NM_IPAC_EIE_HW_SW_COMPAT_NR = 0x0c,
|
||||
NM_IPAC_EIE_MANUF_SER_NR = 0x0d,
|
||||
NM_IPAC_EIE_OEM_ID = 0x0e,
|
||||
NM_IPAC_EIE_DATE_TIME_MANUF = 0x0f,
|
||||
NM_IPAC_EIE_DATE_TIME_CALIB = 0x10,
|
||||
NM_IPAC_EIE_BEACON_INFO = 0x11,
|
||||
NM_IPAC_EIE_FREQ_ERR = 0x12,
|
||||
/* FIXME */
|
||||
NM_IPAC_EIE_FREQ_BANDS = 0x1c,
|
||||
NM_IPAC_EIE_MAX_TA = 0x1d,
|
||||
NM_IPAC_EIE_CIPH_ALGOS = 0x1e,
|
||||
NM_IPAC_EIE_CHAN_TYPES = 0x1f,
|
||||
NM_IPAC_EIE_CHAN_MODES = 0x20,
|
||||
NM_IPAC_EIE_GPRS_CODING = 0x21,
|
||||
NM_IPAC_EIE_RTP_FEATURES = 0x22,
|
||||
NM_IPAC_EIE_RSL_FEATURES = 0x23,
|
||||
NM_IPAC_EIE_BTS_HW_CLASS = 0x24,
|
||||
NM_IPAC_EIE_BTS_ID = 0x25,
|
||||
};
|
||||
|
||||
enum ipac_bcch_info_type {
|
||||
IPAC_BINF_RXLEV = (1 << 8),
|
||||
IPAC_BINF_RXQUAL = (1 << 9),
|
||||
IPAC_BINF_FREQ_ERR_QUAL = (1 << 10),
|
||||
IPAC_BINF_FRAME_OFFSET = (1 << 11),
|
||||
IPAC_BINF_FRAME_NR_OFFSET = (1 << 12),
|
||||
IPAC_BINF_BSIC = (1 << 13),
|
||||
IPAC_BINF_CGI = (1 << 14),
|
||||
IPAC_BINF_NEIGH_BA_SI2 = (1 << 15),
|
||||
IPAC_BINF_NEIGH_BA_SI2bis = (1 << 0),
|
||||
IPAC_BINF_NEIGH_BA_SI2ter = (1 << 1),
|
||||
IPAC_BINF_CELL_ALLOC = (1 << 2),
|
||||
};
|
||||
|
||||
#endif /* PROTO_GSM_12_21_H */
|
||||
@@ -1,33 +0,0 @@
|
||||
#ifndef _OSMOCORE_RSL_H
|
||||
#define _OSMOCORE_RSL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <osmocore/utils.h>
|
||||
#include <osmocore/protocol/gsm_08_58.h>
|
||||
|
||||
void rsl_init_rll_hdr(struct abis_rsl_rll_hdr *dh, uint8_t msg_type);
|
||||
|
||||
extern const struct tlv_definition rsl_att_tlvdef;
|
||||
#define rsl_tlv_parse(dec, buf, len) \
|
||||
tlv_parse(dec, &rsl_att_tlvdef, buf, len, 0, 0)
|
||||
|
||||
/* encode channel number as per Section 9.3.1 */
|
||||
uint8_t rsl_enc_chan_nr(uint8_t type, uint8_t subch, uint8_t timeslot);
|
||||
/* decode channel number as per Section 9.3.1 */
|
||||
int rsl_dec_chan_nr(uint8_t chan_nr, uint8_t *type, uint8_t *subch, uint8_t *timeslot);
|
||||
|
||||
extern const struct value_string rsl_rlm_cause_strs[];
|
||||
|
||||
const char *rsl_err_name(uint8_t err);
|
||||
|
||||
/* Section 3.3.2.3 TS 05.02. I think this looks like a table */
|
||||
int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf);
|
||||
|
||||
/* Push a RSL RLL header with L3_INFO IE */
|
||||
void rsl_rll_push_l3(struct msgb *msg, uint8_t msg_type, uint8_t chan_nr,
|
||||
uint8_t link_id, int transparent);
|
||||
|
||||
/* Allocate msgb and fill with simple RSL RLL header */
|
||||
struct msgb *rsl_rll_simple(uint8_t msg_type, uint8_t chan_nr,
|
||||
uint8_t link_id, int transparent);
|
||||
#endif /* _OSMOCORE_RSL_H */
|
||||
@@ -1,22 +0,0 @@
|
||||
#ifndef _OSMOCORE_RXLEV_STATS_H
|
||||
#define _OSMOCORE_RXLEV_STATS_H
|
||||
|
||||
#define NUM_RXLEVS 32
|
||||
#define NUM_ARFCNS 1024
|
||||
|
||||
struct rxlev_stats {
|
||||
/* the maximum number of ARFCN's is 1024, and there are 32 RxLevels,
|
||||
* so in we keep one 1024bit-bitvec for each RxLev */
|
||||
uint8_t rxlev_buckets[NUM_RXLEVS][NUM_ARFCNS/8];
|
||||
};
|
||||
|
||||
void rxlev_stat_input(struct rxlev_stats *st, uint16_t arfcn, uint8_t rxlev);
|
||||
|
||||
/* get the next ARFCN that has the specified Rxlev */
|
||||
int16_t rxlev_stat_get_next(const struct rxlev_stats *st, uint8_t rxlev, int16_t arfcn);
|
||||
|
||||
void rxlev_stat_reset(struct rxlev_stats *st);
|
||||
|
||||
void rxlev_stat_dump(const struct rxlev_stats *st);
|
||||
|
||||
#endif /* _OSMOCORE_RXLEV_STATS_H */
|
||||
@@ -1,15 +0,0 @@
|
||||
#ifndef OSMOCORE_SIGNAL_H
|
||||
#define OSMOCORE_SIGNAL_H
|
||||
|
||||
typedef int signal_cbfn(unsigned int subsys, unsigned int signal,
|
||||
void *handler_data, void *signal_data);
|
||||
|
||||
|
||||
/* Management */
|
||||
int register_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data);
|
||||
void unregister_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data);
|
||||
|
||||
/* Dispatch */
|
||||
void dispatch_signal(unsigned int subsys, unsigned int signal, void *signal_data);
|
||||
|
||||
#endif /* OSMOCORE_SIGNAL_H */
|
||||
@@ -1,31 +0,0 @@
|
||||
#ifndef _STATISTICS_H
|
||||
#define _STATISTICS_H
|
||||
|
||||
struct counter {
|
||||
struct llist_head list;
|
||||
const char *name;
|
||||
const char *description;
|
||||
unsigned long value;
|
||||
};
|
||||
|
||||
static inline void counter_inc(struct counter *ctr)
|
||||
{
|
||||
ctr->value++;
|
||||
}
|
||||
|
||||
static inline unsigned long counter_get(struct counter *ctr)
|
||||
{
|
||||
return ctr->value;
|
||||
}
|
||||
|
||||
static inline void counter_reset(struct counter *ctr)
|
||||
{
|
||||
ctr->value = 0;
|
||||
}
|
||||
|
||||
struct counter *counter_alloc(const char *name);
|
||||
void counter_free(struct counter *ctr);
|
||||
|
||||
int counters_for_each(int (*handle_counter)(struct counter *, void *), void *data);
|
||||
|
||||
#endif /* _STATISTICS_H */
|
||||
@@ -1,244 +0,0 @@
|
||||
#ifndef _TLV_H
|
||||
#define _TLV_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <osmocore/msgb.h>
|
||||
|
||||
/* Terminology / wording
|
||||
tag length value (in bits)
|
||||
|
||||
V - - 8
|
||||
LV - 8 N * 8
|
||||
TLV 8 8 N * 8
|
||||
TL16V 8 16 N * 8
|
||||
TLV16 8 8 N * 16
|
||||
TvLV 8 8/16 N * 8
|
||||
|
||||
*/
|
||||
|
||||
#define LV_GROSS_LEN(x) (x+1)
|
||||
#define TLV_GROSS_LEN(x) (x+2)
|
||||
#define TLV16_GROSS_LEN(x) ((2*x)+2)
|
||||
#define TL16V_GROSS_LEN(x) (x+3)
|
||||
#define L16TV_GROSS_LEN(x) (x+3)
|
||||
|
||||
#define TVLV_MAX_ONEBYTE 0x7f
|
||||
|
||||
static inline uint16_t TVLV_GROSS_LEN(uint16_t len)
|
||||
{
|
||||
if (len <= TVLV_MAX_ONEBYTE)
|
||||
return TLV_GROSS_LEN(len);
|
||||
else
|
||||
return TL16V_GROSS_LEN(len);
|
||||
}
|
||||
|
||||
/* TLV generation */
|
||||
|
||||
static inline uint8_t *lv_put(uint8_t *buf, uint8_t len,
|
||||
const uint8_t *val)
|
||||
{
|
||||
*buf++ = len;
|
||||
memcpy(buf, val, len);
|
||||
return buf + len;
|
||||
}
|
||||
|
||||
static inline uint8_t *tlv_put(uint8_t *buf, uint8_t tag, uint8_t len,
|
||||
const uint8_t *val)
|
||||
{
|
||||
*buf++ = tag;
|
||||
*buf++ = len;
|
||||
memcpy(buf, val, len);
|
||||
return buf + len;
|
||||
}
|
||||
|
||||
static inline uint8_t *tlv16_put(uint8_t *buf, uint8_t tag, uint8_t len,
|
||||
const uint16_t *val)
|
||||
{
|
||||
*buf++ = tag;
|
||||
*buf++ = len;
|
||||
memcpy(buf, val, len*2);
|
||||
return buf + len*2;
|
||||
}
|
||||
|
||||
static inline uint8_t *tl16v_put(uint8_t *buf, uint8_t tag, uint16_t len,
|
||||
const uint8_t *val)
|
||||
{
|
||||
*buf++ = tag;
|
||||
*buf++ = len >> 8;
|
||||
*buf++ = len & 0xff;
|
||||
memcpy(buf, val, len);
|
||||
return buf + len*2;
|
||||
}
|
||||
|
||||
static inline uint8_t *tvlv_put(uint8_t *buf, uint8_t tag, uint16_t len,
|
||||
const uint8_t *val)
|
||||
{
|
||||
uint8_t *ret;
|
||||
|
||||
if (len <= TVLV_MAX_ONEBYTE) {
|
||||
ret = tlv_put(buf, tag, len, val);
|
||||
buf[1] |= 0x80;
|
||||
} else
|
||||
ret = tl16v_put(buf, tag, len, val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline uint8_t *msgb_tlv16_put(struct msgb *msg, uint8_t tag, uint8_t len, const uint16_t *val)
|
||||
{
|
||||
uint8_t *buf = msgb_put(msg, TLV16_GROSS_LEN(len));
|
||||
return tlv16_put(buf, tag, len, val);
|
||||
}
|
||||
|
||||
static inline uint8_t *msgb_tl16v_put(struct msgb *msg, uint8_t tag, uint16_t len,
|
||||
const uint8_t *val)
|
||||
{
|
||||
uint8_t *buf = msgb_put(msg, TL16V_GROSS_LEN(len));
|
||||
return tl16v_put(buf, tag, len, val);
|
||||
}
|
||||
|
||||
static inline uint8_t *msgb_tvlv_put(struct msgb *msg, uint8_t tag, uint16_t len,
|
||||
const uint8_t *val)
|
||||
{
|
||||
uint8_t *buf = msgb_put(msg, TVLV_GROSS_LEN(len));
|
||||
return tvlv_put(buf, tag, len, val);
|
||||
}
|
||||
|
||||
static inline uint8_t *msgb_l16tv_put(struct msgb *msg, uint16_t len, uint8_t tag,
|
||||
const uint8_t *val)
|
||||
{
|
||||
uint8_t *buf = msgb_put(msg, L16TV_GROSS_LEN(len));
|
||||
|
||||
*buf++ = len >> 8;
|
||||
*buf++ = len & 0xff;
|
||||
*buf++ = tag;
|
||||
memcpy(buf, val, len);
|
||||
return buf + len;
|
||||
}
|
||||
|
||||
static inline uint8_t *v_put(uint8_t *buf, uint8_t val)
|
||||
{
|
||||
*buf++ = val;
|
||||
return buf;
|
||||
}
|
||||
|
||||
static inline uint8_t *tv_put(uint8_t *buf, uint8_t tag,
|
||||
uint8_t val)
|
||||
{
|
||||
*buf++ = tag;
|
||||
*buf++ = val;
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* 'val' is still in host byte order! */
|
||||
static inline uint8_t *tv16_put(uint8_t *buf, uint8_t tag,
|
||||
uint16_t val)
|
||||
{
|
||||
*buf++ = tag;
|
||||
*buf++ = val >> 8;
|
||||
*buf++ = val & 0xff;
|
||||
return buf;
|
||||
}
|
||||
|
||||
static inline uint8_t *msgb_lv_put(struct msgb *msg, uint8_t len, const uint8_t *val)
|
||||
{
|
||||
uint8_t *buf = msgb_put(msg, LV_GROSS_LEN(len));
|
||||
return lv_put(buf, len, val);
|
||||
}
|
||||
|
||||
static inline uint8_t *msgb_tlv_put(struct msgb *msg, uint8_t tag, uint8_t len, const uint8_t *val)
|
||||
{
|
||||
uint8_t *buf = msgb_put(msg, TLV_GROSS_LEN(len));
|
||||
return tlv_put(buf, tag, len, val);
|
||||
}
|
||||
|
||||
static inline uint8_t *msgb_tv_put(struct msgb *msg, uint8_t tag, uint8_t val)
|
||||
{
|
||||
uint8_t *buf = msgb_put(msg, 2);
|
||||
return tv_put(buf, tag, val);
|
||||
}
|
||||
|
||||
static inline uint8_t *msgb_v_put(struct msgb *msg, uint8_t val)
|
||||
{
|
||||
uint8_t *buf = msgb_put(msg, 1);
|
||||
return v_put(buf, val);
|
||||
}
|
||||
|
||||
static inline uint8_t *msgb_tv16_put(struct msgb *msg, uint8_t tag, uint16_t val)
|
||||
{
|
||||
uint8_t *buf = msgb_put(msg, 3);
|
||||
return tv16_put(buf, tag, val);
|
||||
}
|
||||
|
||||
static inline uint8_t *msgb_tlv_push(struct msgb *msg, uint8_t tag, uint8_t len, const uint8_t *val)
|
||||
{
|
||||
uint8_t *buf = msgb_push(msg, TLV_GROSS_LEN(len));
|
||||
return tlv_put(buf, tag, len, val);
|
||||
}
|
||||
|
||||
static inline uint8_t *msgb_tv_push(struct msgb *msg, uint8_t tag, uint8_t val)
|
||||
{
|
||||
uint8_t *buf = msgb_push(msg, 2);
|
||||
return tv_put(buf, tag, val);
|
||||
}
|
||||
|
||||
static inline uint8_t *msgb_tv16_push(struct msgb *msg, uint8_t tag, uint16_t val)
|
||||
{
|
||||
uint8_t *buf = msgb_push(msg, 3);
|
||||
return tv16_put(buf, tag, val);
|
||||
}
|
||||
|
||||
static inline uint8_t *msgb_tvlv_push(struct msgb *msg, uint8_t tag, uint16_t len,
|
||||
const uint8_t *val)
|
||||
{
|
||||
uint8_t *buf = msgb_push(msg, TVLV_GROSS_LEN(len));
|
||||
return tvlv_put(buf, tag, len, val);
|
||||
}
|
||||
|
||||
/* TLV parsing */
|
||||
|
||||
struct tlv_p_entry {
|
||||
uint16_t len;
|
||||
const uint8_t *val;
|
||||
};
|
||||
|
||||
enum tlv_type {
|
||||
TLV_TYPE_NONE,
|
||||
TLV_TYPE_FIXED,
|
||||
TLV_TYPE_T,
|
||||
TLV_TYPE_TV,
|
||||
TLV_TYPE_TLV,
|
||||
TLV_TYPE_TL16V,
|
||||
TLV_TYPE_TvLV,
|
||||
};
|
||||
|
||||
struct tlv_def {
|
||||
enum tlv_type type;
|
||||
uint8_t fixed_len;
|
||||
};
|
||||
|
||||
struct tlv_definition {
|
||||
struct tlv_def def[0xff];
|
||||
};
|
||||
|
||||
struct tlv_parsed {
|
||||
struct tlv_p_entry lv[0xff];
|
||||
};
|
||||
|
||||
extern struct tlv_definition tvlv_att_def;
|
||||
|
||||
int tlv_parse_one(uint8_t *o_tag, uint16_t *o_len, const uint8_t **o_val,
|
||||
const struct tlv_definition *def,
|
||||
const uint8_t *buf, int buf_len);
|
||||
int tlv_parse(struct tlv_parsed *dec, const struct tlv_definition *def,
|
||||
const uint8_t *buf, int buf_len, uint8_t lv_tag, uint8_t lv_tag2);
|
||||
/* take a master (src) tlvdev and fill up all empty slots in 'dst' */
|
||||
void tlv_def_patch(struct tlv_definition *dst, const struct tlv_definition *src);
|
||||
|
||||
#define TLVP_PRESENT(x, y) ((x)->lv[y].val)
|
||||
#define TLVP_LEN(x, y) (x)->lv[y].len
|
||||
#define TLVP_VAL(x, y) (x)->lv[y].val
|
||||
|
||||
#endif /* _TLV_H */
|
||||
@@ -1,20 +0,0 @@
|
||||
#ifndef OSMOCORE_UTIL_H
|
||||
#define OSMOCORE_UTIL_H
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct value_string {
|
||||
unsigned int value;
|
||||
const char *str;
|
||||
};
|
||||
|
||||
const char *get_value_string(const struct value_string *vs, uint32_t val);
|
||||
int get_string_value(const struct value_string *vs, const char *str);
|
||||
|
||||
char bcd2char(uint8_t bcd);
|
||||
/* only works for numbers in ascci */
|
||||
uint8_t char2bcd(char c);
|
||||
|
||||
#endif
|
||||
@@ -1,11 +0,0 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: Osmocom Core Library
|
||||
Description: C Utility Library
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -losmocore
|
||||
Cflags: -I${includedir}/
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
# This is _NOT_ the library release version, it's an API version.
|
||||
# Please read Chapter 6 "Library interface versions" of the libtool documentation before making any modification
|
||||
LIBVERSION=0:0:0
|
||||
|
||||
INCLUDES = $(all_includes) -I$(top_srcdir)/include
|
||||
AM_CFLAGS = -fPIC -Wall
|
||||
|
||||
lib_LTLIBRARIES = libosmocore.la
|
||||
|
||||
libosmocore_la_SOURCES = timer.c select.c signal.c msgb.c rxlev_stat.c \
|
||||
tlv_parser.c bitvec.c comp128.c gsm_utils.c statistics.c \
|
||||
write_queue.c utils.c rsl.c gsm48.c gsm48_ie.c
|
||||
|
||||
if ENABLE_TALLOC
|
||||
libosmocore_la_SOURCES += talloc.c
|
||||
endif
|
||||
@@ -1,230 +0,0 @@
|
||||
/*
|
||||
* COMP128 implementation
|
||||
*
|
||||
*
|
||||
* This code is inspired by original code from :
|
||||
* Marc Briceno <marc@scard.org>, Ian Goldberg <iang@cs.berkeley.edu>,
|
||||
* and David Wagner <daw@cs.berkeley.edu>
|
||||
*
|
||||
* But it has been fully rewritten from various PDFs found online describing
|
||||
* the algorithm because the licence of the code referenced above was unclear.
|
||||
* A comment snippet from the original code is included below, it describes
|
||||
* where the doc came from and how the algorithm was reverse engineered.
|
||||
*
|
||||
*
|
||||
* (C) 2009 by Sylvain Munaut <tnt@246tNt.com>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* --- SNIP ---
|
||||
*
|
||||
* This code derived from a leaked document from the GSM standards.
|
||||
* Some missing pieces were filled in by reverse-engineering a working SIM.
|
||||
* We have verified that this is the correct COMP128 algorithm.
|
||||
*
|
||||
* The first page of the document identifies it as
|
||||
* _Technical Information: GSM System Security Study_.
|
||||
* 10-1617-01, 10th June 1988.
|
||||
* The bottom of the title page is marked
|
||||
* Racal Research Ltd.
|
||||
* Worton Drive, Worton Grange Industrial Estate,
|
||||
* Reading, Berks. RG2 0SB, England.
|
||||
* Telephone: Reading (0734) 868601 Telex: 847152
|
||||
* The relevant bits are in Part I, Section 20 (pages 66--67). Enjoy!
|
||||
*
|
||||
* Note: There are three typos in the spec (discovered by
|
||||
* reverse-engineering).
|
||||
* First, "z = (2 * x[n] + x[n]) mod 2^(9-j)" should clearly read
|
||||
* "z = (2 * x[m] + x[n]) mod 2^(9-j)".
|
||||
* Second, the "k" loop in the "Form bits from bytes" section is severely
|
||||
* botched: the k index should run only from 0 to 3, and clearly the range
|
||||
* on "the (8-k)th bit of byte j" is also off (should be 0..7, not 1..8,
|
||||
* to be consistent with the subsequent section).
|
||||
* Third, SRES is taken from the first 8 nibbles of x[], not the last 8 as
|
||||
* claimed in the document. (And the document doesn't specify how Kc is
|
||||
* derived, but that was also easily discovered with reverse engineering.)
|
||||
* All of these typos have been corrected in the following code.
|
||||
*
|
||||
* --- /SNIP ---
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* The compression tables (just copied ...) */
|
||||
static const uint8_t table_0[512] = {
|
||||
102, 177, 186, 162, 2, 156, 112, 75, 55, 25, 8, 12, 251, 193, 246, 188,
|
||||
109, 213, 151, 53, 42, 79, 191, 115, 233, 242, 164, 223, 209, 148, 108, 161,
|
||||
252, 37, 244, 47, 64, 211, 6, 237, 185, 160, 139, 113, 76, 138, 59, 70,
|
||||
67, 26, 13, 157, 63, 179, 221, 30, 214, 36, 166, 69, 152, 124, 207, 116,
|
||||
247, 194, 41, 84, 71, 1, 49, 14, 95, 35, 169, 21, 96, 78, 215, 225,
|
||||
182, 243, 28, 92, 201, 118, 4, 74, 248, 128, 17, 11, 146, 132, 245, 48,
|
||||
149, 90, 120, 39, 87, 230, 106, 232, 175, 19, 126, 190, 202, 141, 137, 176,
|
||||
250, 27, 101, 40, 219, 227, 58, 20, 51, 178, 98, 216, 140, 22, 32, 121,
|
||||
61, 103, 203, 72, 29, 110, 85, 212, 180, 204, 150, 183, 15, 66, 172, 196,
|
||||
56, 197, 158, 0, 100, 45, 153, 7, 144, 222, 163, 167, 60, 135, 210, 231,
|
||||
174, 165, 38, 249, 224, 34, 220, 229, 217, 208, 241, 68, 206, 189, 125, 255,
|
||||
239, 54, 168, 89, 123, 122, 73, 145, 117, 234, 143, 99, 129, 200, 192, 82,
|
||||
104, 170, 136, 235, 93, 81, 205, 173, 236, 94, 105, 52, 46, 228, 198, 5,
|
||||
57, 254, 97, 155, 142, 133, 199, 171, 187, 50, 65, 181, 127, 107, 147, 226,
|
||||
184, 218, 131, 33, 77, 86, 31, 44, 88, 62, 238, 18, 24, 43, 154, 23,
|
||||
80, 159, 134, 111, 9, 114, 3, 91, 16, 130, 83, 10, 195, 240, 253, 119,
|
||||
177, 102, 162, 186, 156, 2, 75, 112, 25, 55, 12, 8, 193, 251, 188, 246,
|
||||
213, 109, 53, 151, 79, 42, 115, 191, 242, 233, 223, 164, 148, 209, 161, 108,
|
||||
37, 252, 47, 244, 211, 64, 237, 6, 160, 185, 113, 139, 138, 76, 70, 59,
|
||||
26, 67, 157, 13, 179, 63, 30, 221, 36, 214, 69, 166, 124, 152, 116, 207,
|
||||
194, 247, 84, 41, 1, 71, 14, 49, 35, 95, 21, 169, 78, 96, 225, 215,
|
||||
243, 182, 92, 28, 118, 201, 74, 4, 128, 248, 11, 17, 132, 146, 48, 245,
|
||||
90, 149, 39, 120, 230, 87, 232, 106, 19, 175, 190, 126, 141, 202, 176, 137,
|
||||
27, 250, 40, 101, 227, 219, 20, 58, 178, 51, 216, 98, 22, 140, 121, 32,
|
||||
103, 61, 72, 203, 110, 29, 212, 85, 204, 180, 183, 150, 66, 15, 196, 172,
|
||||
197, 56, 0, 158, 45, 100, 7, 153, 222, 144, 167, 163, 135, 60, 231, 210,
|
||||
165, 174, 249, 38, 34, 224, 229, 220, 208, 217, 68, 241, 189, 206, 255, 125,
|
||||
54, 239, 89, 168, 122, 123, 145, 73, 234, 117, 99, 143, 200, 129, 82, 192,
|
||||
170, 104, 235, 136, 81, 93, 173, 205, 94, 236, 52, 105, 228, 46, 5, 198,
|
||||
254, 57, 155, 97, 133, 142, 171, 199, 50, 187, 181, 65, 107, 127, 226, 147,
|
||||
218, 184, 33, 131, 86, 77, 44, 31, 62, 88, 18, 238, 43, 24, 23, 154,
|
||||
159, 80, 111, 134, 114, 9, 91, 3, 130, 16, 10, 83, 240, 195, 119, 253,
|
||||
}, table_1[256] = {
|
||||
19, 11, 80, 114, 43, 1, 69, 94, 39, 18, 127, 117, 97, 3, 85, 43,
|
||||
27, 124, 70, 83, 47, 71, 63, 10, 47, 89, 79, 4, 14, 59, 11, 5,
|
||||
35, 107, 103, 68, 21, 86, 36, 91, 85, 126, 32, 50, 109, 94, 120, 6,
|
||||
53, 79, 28, 45, 99, 95, 41, 34, 88, 68, 93, 55, 110, 125, 105, 20,
|
||||
90, 80, 76, 96, 23, 60, 89, 64, 121, 56, 14, 74, 101, 8, 19, 78,
|
||||
76, 66, 104, 46, 111, 50, 32, 3, 39, 0, 58, 25, 92, 22, 18, 51,
|
||||
57, 65, 119, 116, 22, 109, 7, 86, 59, 93, 62, 110, 78, 99, 77, 67,
|
||||
12, 113, 87, 98, 102, 5, 88, 33, 38, 56, 23, 8, 75, 45, 13, 75,
|
||||
95, 63, 28, 49, 123, 120, 20, 112, 44, 30, 15, 98, 106, 2, 103, 29,
|
||||
82, 107, 42, 124, 24, 30, 41, 16, 108, 100, 117, 40, 73, 40, 7, 114,
|
||||
82, 115, 36, 112, 12, 102, 100, 84, 92, 48, 72, 97, 9, 54, 55, 74,
|
||||
113, 123, 17, 26, 53, 58, 4, 9, 69, 122, 21, 118, 42, 60, 27, 73,
|
||||
118, 125, 34, 15, 65, 115, 84, 64, 62, 81, 70, 1, 24, 111, 121, 83,
|
||||
104, 81, 49, 127, 48, 105, 31, 10, 6, 91, 87, 37, 16, 54, 116, 126,
|
||||
31, 38, 13, 0, 72, 106, 77, 61, 26, 67, 46, 29, 96, 37, 61, 52,
|
||||
101, 17, 44, 108, 71, 52, 66, 57, 33, 51, 25, 90, 2, 119, 122, 35,
|
||||
}, table_2[128] = {
|
||||
52, 50, 44, 6, 21, 49, 41, 59, 39, 51, 25, 32, 51, 47, 52, 43,
|
||||
37, 4, 40, 34, 61, 12, 28, 4, 58, 23, 8, 15, 12, 22, 9, 18,
|
||||
55, 10, 33, 35, 50, 1, 43, 3, 57, 13, 62, 14, 7, 42, 44, 59,
|
||||
62, 57, 27, 6, 8, 31, 26, 54, 41, 22, 45, 20, 39, 3, 16, 56,
|
||||
48, 2, 21, 28, 36, 42, 60, 33, 34, 18, 0, 11, 24, 10, 17, 61,
|
||||
29, 14, 45, 26, 55, 46, 11, 17, 54, 46, 9, 24, 30, 60, 32, 0,
|
||||
20, 38, 2, 30, 58, 35, 1, 16, 56, 40, 23, 48, 13, 19, 19, 27,
|
||||
31, 53, 47, 38, 63, 15, 49, 5, 37, 53, 25, 36, 63, 29, 5, 7,
|
||||
}, table_3[64] = {
|
||||
1, 5, 29, 6, 25, 1, 18, 23, 17, 19, 0, 9, 24, 25, 6, 31,
|
||||
28, 20, 24, 30, 4, 27, 3, 13, 15, 16, 14, 18, 4, 3, 8, 9,
|
||||
20, 0, 12, 26, 21, 8, 28, 2, 29, 2, 15, 7, 11, 22, 14, 10,
|
||||
17, 21, 12, 30, 26, 27, 16, 31, 11, 7, 13, 23, 10, 5, 22, 19,
|
||||
}, table_4[32] = {
|
||||
15, 12, 10, 4, 1, 14, 11, 7, 5, 0, 14, 7, 1, 2, 13, 8,
|
||||
10, 3, 4, 9, 6, 0, 3, 2, 5, 6, 8, 9, 11, 13, 15, 12,
|
||||
};
|
||||
|
||||
static const uint8_t *_comp128_table[5] = { table_0, table_1, table_2, table_3, table_4 };
|
||||
|
||||
|
||||
static inline void
|
||||
_comp128_compression_round(uint8_t *x, int n, const uint8_t *tbl)
|
||||
{
|
||||
int i, j, m, a, b, y, z;
|
||||
m = 4 - n;
|
||||
for (i=0; i<(1<<n); i++)
|
||||
for (j=0; j<(1<<m); j++) {
|
||||
a = j + i * (2<<m);
|
||||
b = a + (1<<m);
|
||||
y = (x[a] + (x[b]<<1)) & ((32<<m)-1);
|
||||
z = ((x[a]<<1) + x[b]) & ((32<<m)-1);
|
||||
x[a] = tbl[y];
|
||||
x[b] = tbl[z];
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
_comp128_compression(uint8_t *x)
|
||||
{
|
||||
int n;
|
||||
for (n=0; n<5; n++)
|
||||
_comp128_compression_round(x, n, _comp128_table[n]);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_comp128_bitsfrombytes(uint8_t *x, uint8_t *bits)
|
||||
{
|
||||
int i;
|
||||
memset(bits, 0x00, 128);
|
||||
for (i=0; i<128; i++)
|
||||
if (x[i>>2] & (1<<(3-(i&3))))
|
||||
bits[i] = 1;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_comp128_permutation(uint8_t *x, uint8_t *bits)
|
||||
{
|
||||
int i;
|
||||
memset(&x[16], 0x00, 16);
|
||||
for (i=0; i<128; i++)
|
||||
x[(i>>3)+16] |= bits[(i*17) & 127] << (7-(i&7));
|
||||
}
|
||||
|
||||
void
|
||||
comp128(uint8_t *ki, uint8_t *rand, uint8_t *sres, uint8_t *kc)
|
||||
{
|
||||
int i;
|
||||
uint8_t x[32], bits[128];
|
||||
|
||||
/* x[16-31] = RAND */
|
||||
memcpy(&x[16], rand, 16);
|
||||
|
||||
/* Round 1-7 */
|
||||
for (i=0; i<7; i++) {
|
||||
/* x[0-15] = Ki */
|
||||
memcpy(x, ki, 16);
|
||||
|
||||
/* Compression */
|
||||
_comp128_compression(x);
|
||||
|
||||
/* FormBitFromBytes */
|
||||
_comp128_bitsfrombytes(x, bits);
|
||||
|
||||
/* Permutation */
|
||||
_comp128_permutation(x, bits);
|
||||
}
|
||||
|
||||
/* Round 8 (final) */
|
||||
/* x[0-15] = Ki */
|
||||
memcpy(x, ki, 16);
|
||||
|
||||
/* Compression */
|
||||
_comp128_compression(x);
|
||||
|
||||
/* Output stage */
|
||||
for (i=0; i<8; i+=2)
|
||||
sres[i>>1] = x[i]<<4 | x[i+1];
|
||||
|
||||
for (i=0; i<12; i+=2)
|
||||
kc[i>>1] = (x[i + 18] << 6) |
|
||||
(x[i + 19] << 2) |
|
||||
(x[i + 20] >> 2);
|
||||
|
||||
kc[6] = (x[30]<<6) | (x[31]<<2);
|
||||
kc[7] = 0;
|
||||
}
|
||||
|
||||
@@ -1,283 +0,0 @@
|
||||
/* GSM Mobile Radio Interface Layer 3 messages
|
||||
* 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */
|
||||
|
||||
/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2008, 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <osmocore/utils.h>
|
||||
#include <osmocore/tlv.h>
|
||||
#include <osmocore/gsm48.h>
|
||||
|
||||
#include <osmocore/protocol/gsm_04_08.h>
|
||||
|
||||
const struct tlv_definition gsm48_att_tlvdef = {
|
||||
.def = {
|
||||
[GSM48_IE_MOBILE_ID] = { TLV_TYPE_TLV },
|
||||
[GSM48_IE_NAME_LONG] = { TLV_TYPE_TLV },
|
||||
[GSM48_IE_NAME_SHORT] = { TLV_TYPE_TLV },
|
||||
[GSM48_IE_UTC] = { TLV_TYPE_TV },
|
||||
[GSM48_IE_NET_TIME_TZ] = { TLV_TYPE_FIXED, 7 },
|
||||
[GSM48_IE_LSA_IDENT] = { TLV_TYPE_TLV },
|
||||
|
||||
[GSM48_IE_BEARER_CAP] = { TLV_TYPE_TLV },
|
||||
[GSM48_IE_CAUSE] = { TLV_TYPE_TLV },
|
||||
[GSM48_IE_CC_CAP] = { TLV_TYPE_TLV },
|
||||
[GSM48_IE_ALERT] = { TLV_TYPE_TLV },
|
||||
[GSM48_IE_FACILITY] = { TLV_TYPE_TLV },
|
||||
[GSM48_IE_PROGR_IND] = { TLV_TYPE_TLV },
|
||||
[GSM48_IE_AUX_STATUS] = { TLV_TYPE_TLV },
|
||||
[GSM48_IE_NOTIFY] = { TLV_TYPE_TV },
|
||||
[GSM48_IE_KPD_FACILITY] = { TLV_TYPE_TV },
|
||||
[GSM48_IE_SIGNAL] = { TLV_TYPE_TV },
|
||||
[GSM48_IE_CONN_BCD] = { TLV_TYPE_TLV },
|
||||
[GSM48_IE_CONN_SUB] = { TLV_TYPE_TLV },
|
||||
[GSM48_IE_CALLING_BCD] = { TLV_TYPE_TLV },
|
||||
[GSM48_IE_CALLING_SUB] = { TLV_TYPE_TLV },
|
||||
[GSM48_IE_CALLED_BCD] = { TLV_TYPE_TLV },
|
||||
[GSM48_IE_CALLED_SUB] = { TLV_TYPE_TLV },
|
||||
[GSM48_IE_REDIR_BCD] = { TLV_TYPE_TLV },
|
||||
[GSM48_IE_REDIR_SUB] = { TLV_TYPE_TLV },
|
||||
[GSM48_IE_LOWL_COMPAT] = { TLV_TYPE_TLV },
|
||||
[GSM48_IE_HIGHL_COMPAT] = { TLV_TYPE_TLV },
|
||||
[GSM48_IE_USER_USER] = { TLV_TYPE_TLV },
|
||||
[GSM48_IE_SS_VERS] = { TLV_TYPE_TLV },
|
||||
[GSM48_IE_MORE_DATA] = { TLV_TYPE_T },
|
||||
[GSM48_IE_CLIR_SUPP] = { TLV_TYPE_T },
|
||||
[GSM48_IE_CLIR_INVOC] = { TLV_TYPE_T },
|
||||
[GSM48_IE_REV_C_SETUP] = { TLV_TYPE_T },
|
||||
[GSM48_IE_REPEAT_CIR] = { TLV_TYPE_T },
|
||||
[GSM48_IE_REPEAT_SEQ] = { TLV_TYPE_T },
|
||||
/* FIXME: more elements */
|
||||
},
|
||||
};
|
||||
|
||||
static const char *rr_cause_names[] = {
|
||||
[GSM48_RR_CAUSE_NORMAL] = "Normal event",
|
||||
[GSM48_RR_CAUSE_ABNORMAL_UNSPEC] = "Abnormal release, unspecified",
|
||||
[GSM48_RR_CAUSE_ABNORMAL_UNACCT] = "Abnormal release, channel unacceptable",
|
||||
[GSM48_RR_CAUSE_ABNORMAL_TIMER] = "Abnormal release, timer expired",
|
||||
[GSM48_RR_CAUSE_ABNORMAL_NOACT] = "Abnormal release, no activity on radio path",
|
||||
[GSM48_RR_CAUSE_PREMPTIVE_REL] = "Preemptive release",
|
||||
[GSM48_RR_CAUSE_HNDOVER_IMP] = "Handover impossible, timing advance out of range",
|
||||
[GSM48_RR_CAUSE_CHAN_MODE_UNACCT] = "Channel mode unacceptable",
|
||||
[GSM48_RR_CAUSE_FREQ_NOT_IMPL] = "Frequency not implemented",
|
||||
[GSM48_RR_CAUSE_CALL_CLEARED] = "Call already cleared",
|
||||
[GSM48_RR_CAUSE_SEMANT_INCORR] = "Semantically incorrect message",
|
||||
[GSM48_RR_CAUSE_INVALID_MAND_INF] = "Invalid mandatory information",
|
||||
[GSM48_RR_CAUSE_MSG_TYPE_N] = "Message type non-existant or not implemented",
|
||||
[GSM48_RR_CAUSE_MSG_TYPE_N_COMPAT] = "Message type not compatible with protocol state",
|
||||
[GSM48_RR_CAUSE_COND_IE_ERROR] = "Conditional IE error",
|
||||
[GSM48_RR_CAUSE_NO_CELL_ALLOC_A] = "No cell allocation available",
|
||||
[GSM48_RR_CAUSE_PROT_ERROR_UNSPC] = "Protocol error unspecified",
|
||||
};
|
||||
|
||||
const char *cc_state_names[32] = {
|
||||
"NULL",
|
||||
"INITIATED",
|
||||
"illegal state 2",
|
||||
"MO_CALL_PROC",
|
||||
"CALL_DELIVERED",
|
||||
"illegal state 5",
|
||||
"CALL_PRESENT",
|
||||
"CALL_RECEIVED",
|
||||
"CONNECT_REQUEST",
|
||||
"MO_TERM_CALL_CONF",
|
||||
"ACTIVE",
|
||||
"DISCONNECT_REQ",
|
||||
"DISCONNECT_IND",
|
||||
"illegal state 13",
|
||||
"illegal state 14",
|
||||
"illegal state 15",
|
||||
"illegal state 16",
|
||||
"illegal state 17",
|
||||
"illegal state 18",
|
||||
"RELEASE_REQ",
|
||||
"illegal state 20",
|
||||
"illegal state 21",
|
||||
"illegal state 22",
|
||||
"illegal state 23",
|
||||
"illegal state 24",
|
||||
"illegal state 25",
|
||||
"MO_ORIG_MODIFY",
|
||||
"MO_TERM_MODIFY",
|
||||
"CONNECT_IND",
|
||||
"illegal state 29",
|
||||
"illegal state 30",
|
||||
"illegal state 31",
|
||||
};
|
||||
|
||||
const char *gsm48_cc_msg_names[0x40] = {
|
||||
"unknown 0x00",
|
||||
"ALERTING",
|
||||
"CALL_PROC",
|
||||
"PROGRESS",
|
||||
"ESTAB",
|
||||
"SETUP",
|
||||
"ESTAB_CONF",
|
||||
"CONNECT",
|
||||
"CALL_CONF",
|
||||
"START_CC",
|
||||
"unknown 0x0a",
|
||||
"RECALL",
|
||||
"unknown 0x0c",
|
||||
"unknown 0x0d",
|
||||
"EMERG_SETUP",
|
||||
"CONNECT_ACK",
|
||||
"USER_INFO",
|
||||
"unknown 0x11",
|
||||
"unknown 0x12",
|
||||
"MODIFY_REJECT",
|
||||
"unknown 0x14",
|
||||
"unknown 0x15",
|
||||
"unknown 0x16",
|
||||
"MODIFY",
|
||||
"HOLD",
|
||||
"HOLD_ACK",
|
||||
"HOLD_REJ",
|
||||
"unknown 0x1b",
|
||||
"RETR",
|
||||
"RETR_ACK",
|
||||
"RETR_REJ",
|
||||
"MODIFY_COMPL",
|
||||
"unknown 0x20",
|
||||
"unknown 0x21",
|
||||
"unknown 0x22",
|
||||
"unknown 0x23",
|
||||
"unknown 0x24",
|
||||
"DISCONNECT",
|
||||
"unknown 0x26",
|
||||
"unknown 0x27",
|
||||
"unknown 0x28",
|
||||
"unknown 0x29",
|
||||
"RELEASE_COMPL",
|
||||
"unknown 0x2b",
|
||||
"unknown 0x2c",
|
||||
"RELEASE",
|
||||
"unknown 0x2e",
|
||||
"unknown 0x2f",
|
||||
"unknown 0x30",
|
||||
"STOP_DTMF",
|
||||
"STOP_DTMF_ACK",
|
||||
"unknown 0x33",
|
||||
"STATUS_ENQ",
|
||||
"START_DTMF",
|
||||
"START_DTMF_ACK",
|
||||
"START_DTMF_REJ",
|
||||
"unknown 0x38",
|
||||
"CONG_CTRL",
|
||||
"FACILITY",
|
||||
"unknown 0x3b",
|
||||
"STATUS",
|
||||
"unknown 0x3d",
|
||||
"NOTIFY",
|
||||
"unknown 0x3f",
|
||||
};
|
||||
|
||||
static char strbuf[64];
|
||||
|
||||
const char *rr_cause_name(uint8_t cause)
|
||||
{
|
||||
if (cause < ARRAY_SIZE(rr_cause_names) &&
|
||||
rr_cause_names[cause])
|
||||
return rr_cause_names[cause];
|
||||
|
||||
snprintf(strbuf, sizeof(strbuf), "0x%02x", cause);
|
||||
return strbuf;
|
||||
}
|
||||
|
||||
static void to_bcd(uint8_t *bcd, uint16_t val)
|
||||
{
|
||||
bcd[2] = val % 10;
|
||||
val = val / 10;
|
||||
bcd[1] = val % 10;
|
||||
val = val / 10;
|
||||
bcd[0] = val % 10;
|
||||
val = val / 10;
|
||||
}
|
||||
|
||||
void gsm48_generate_lai(struct gsm48_loc_area_id *lai48, uint16_t mcc,
|
||||
uint16_t mnc, uint16_t lac)
|
||||
{
|
||||
uint8_t bcd[3];
|
||||
|
||||
to_bcd(bcd, mcc);
|
||||
lai48->digits[0] = bcd[0] | (bcd[1] << 4);
|
||||
lai48->digits[1] = bcd[2];
|
||||
|
||||
to_bcd(bcd, mnc);
|
||||
/* FIXME: do we need three-digit MNC? See Table 10.5.3 */
|
||||
#if 0
|
||||
lai48->digits[1] |= bcd[2] << 4;
|
||||
lai48->digits[2] = bcd[0] | (bcd[1] << 4);
|
||||
#else
|
||||
lai48->digits[1] |= 0xf << 4;
|
||||
lai48->digits[2] = bcd[1] | (bcd[2] << 4);
|
||||
#endif
|
||||
|
||||
lai48->lac = htons(lac);
|
||||
}
|
||||
|
||||
int gsm48_generate_mid_from_tmsi(uint8_t *buf, uint32_t tmsi)
|
||||
{
|
||||
uint32_t *tptr = (uint32_t *) &buf[3];
|
||||
|
||||
buf[0] = GSM48_IE_MOBILE_ID;
|
||||
buf[1] = GSM48_TMSI_LEN;
|
||||
buf[2] = 0xf0 | GSM_MI_TYPE_TMSI;
|
||||
*tptr = htonl(tmsi);
|
||||
|
||||
return 7;
|
||||
}
|
||||
|
||||
int gsm48_generate_mid_from_imsi(uint8_t *buf, const char *imsi)
|
||||
{
|
||||
unsigned int length = strlen(imsi), i, off = 0;
|
||||
uint8_t odd = (length & 0x1) == 1;
|
||||
|
||||
buf[0] = GSM48_IE_MOBILE_ID;
|
||||
buf[2] = char2bcd(imsi[0]) << 4 | GSM_MI_TYPE_IMSI | (odd << 3);
|
||||
|
||||
/* if the length is even we will fill half of the last octet */
|
||||
if (odd)
|
||||
buf[1] = (length + 1) >> 1;
|
||||
else
|
||||
buf[1] = (length + 2) >> 1;
|
||||
|
||||
for (i = 1; i < buf[1]; ++i) {
|
||||
uint8_t lower, upper;
|
||||
|
||||
lower = char2bcd(imsi[++off]);
|
||||
if (!odd && off + 1 == length)
|
||||
upper = 0x0f;
|
||||
else
|
||||
upper = char2bcd(imsi[++off]) & 0x0f;
|
||||
|
||||
buf[2 + i] = (upper << 4) | lower;
|
||||
}
|
||||
|
||||
return 2 + buf[1];
|
||||
}
|
||||
@@ -1,659 +0,0 @@
|
||||
/* GSM Mobile Radio Interface Layer 3 messages
|
||||
* 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */
|
||||
|
||||
/* (C) 2008 by Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2008-2010 by Andreas Eversberg
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <osmocore/utils.h>
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/tlv.h>
|
||||
#include <osmocore/mncc.h>
|
||||
#include <osmocore/protocol/gsm_04_08.h>
|
||||
|
||||
static const char bcd_num_digits[] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', '*', '#', 'a', 'b', 'c', '\0'
|
||||
};
|
||||
|
||||
/* decode a 'called/calling/connect party BCD number' as in 10.5.4.7 */
|
||||
int gsm48_decode_bcd_number(char *output, int output_len,
|
||||
const uint8_t *bcd_lv, int h_len)
|
||||
{
|
||||
uint8_t in_len = bcd_lv[0];
|
||||
int i;
|
||||
|
||||
for (i = 1 + h_len; i <= in_len; i++) {
|
||||
/* lower nibble */
|
||||
output_len--;
|
||||
if (output_len <= 1)
|
||||
break;
|
||||
*output++ = bcd_num_digits[bcd_lv[i] & 0xf];
|
||||
|
||||
/* higher nibble */
|
||||
output_len--;
|
||||
if (output_len <= 1)
|
||||
break;
|
||||
*output++ = bcd_num_digits[bcd_lv[i] >> 4];
|
||||
}
|
||||
if (output_len >= 1)
|
||||
*output++ = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* convert a single ASCII character to call-control BCD */
|
||||
static int asc_to_bcd(const char asc)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(bcd_num_digits); i++) {
|
||||
if (bcd_num_digits[i] == asc)
|
||||
return i;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* convert a ASCII phone number to 'called/calling/connect party BCD number' */
|
||||
int gsm48_encode_bcd_number(uint8_t *bcd_lv, uint8_t max_len,
|
||||
int h_len, const char *input)
|
||||
{
|
||||
int in_len = strlen(input);
|
||||
int i;
|
||||
uint8_t *bcd_cur = bcd_lv + 1 + h_len;
|
||||
|
||||
/* two digits per byte, plus type byte */
|
||||
bcd_lv[0] = in_len/2 + h_len;
|
||||
if (in_len % 2)
|
||||
bcd_lv[0]++;
|
||||
|
||||
if (bcd_lv[0] > max_len)
|
||||
return -EIO;
|
||||
|
||||
for (i = 0; i < in_len; i++) {
|
||||
int rc = asc_to_bcd(input[i]);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
if (i % 2 == 0)
|
||||
*bcd_cur = rc;
|
||||
else
|
||||
*bcd_cur++ |= (rc << 4);
|
||||
}
|
||||
/* append padding nibble in case of odd length */
|
||||
if (i % 2)
|
||||
*bcd_cur++ |= 0xf0;
|
||||
|
||||
/* return how many bytes we used */
|
||||
return (bcd_cur - bcd_lv);
|
||||
}
|
||||
|
||||
/* decode 'bearer capability' */
|
||||
int gsm48_decode_bearer_cap(struct gsm_mncc_bearer_cap *bcap,
|
||||
const uint8_t *lv)
|
||||
{
|
||||
uint8_t in_len = lv[0];
|
||||
int i, s;
|
||||
|
||||
if (in_len < 1)
|
||||
return -EINVAL;
|
||||
|
||||
bcap->speech_ver[0] = -1; /* end of list, of maximum 7 values */
|
||||
|
||||
/* octet 3 */
|
||||
bcap->transfer = lv[1] & 0x07;
|
||||
bcap->mode = (lv[1] & 0x08) >> 3;
|
||||
bcap->coding = (lv[1] & 0x10) >> 4;
|
||||
bcap->radio = (lv[1] & 0x60) >> 5;
|
||||
|
||||
if (bcap->transfer == GSM_MNCC_BCAP_SPEECH) {
|
||||
i = 1;
|
||||
s = 0;
|
||||
while(!(lv[i] & 0x80)) {
|
||||
i++; /* octet 3a etc */
|
||||
if (in_len < i)
|
||||
return 0;
|
||||
bcap->speech_ver[s++] = lv[i] & 0x0f;
|
||||
bcap->speech_ver[s] = -1; /* end of list */
|
||||
if (i == 2) /* octet 3a */
|
||||
bcap->speech_ctm = (lv[i] & 0x20) >> 5;
|
||||
if (s == 7) /* maximum speech versions + end of list */
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
i = 1;
|
||||
while (!(lv[i] & 0x80)) {
|
||||
i++; /* octet 3a etc */
|
||||
if (in_len < i)
|
||||
return 0;
|
||||
/* ignore them */
|
||||
}
|
||||
/* FIXME: implement OCTET 4+ parsing */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* encode 'bearer capability' */
|
||||
int gsm48_encode_bearer_cap(struct msgb *msg, int lv_only,
|
||||
const struct gsm_mncc_bearer_cap *bcap)
|
||||
{
|
||||
uint8_t lv[32 + 1];
|
||||
int i = 1, s;
|
||||
|
||||
lv[1] = bcap->transfer;
|
||||
lv[1] |= bcap->mode << 3;
|
||||
lv[1] |= bcap->coding << 4;
|
||||
lv[1] |= bcap->radio << 5;
|
||||
|
||||
if (bcap->transfer == GSM_MNCC_BCAP_SPEECH) {
|
||||
for (s = 0; bcap->speech_ver[s] >= 0; s++) {
|
||||
i++; /* octet 3a etc */
|
||||
lv[i] = bcap->speech_ver[s];
|
||||
if (i == 2) /* octet 3a */
|
||||
lv[i] |= bcap->speech_ctm << 5;
|
||||
}
|
||||
lv[i] |= 0x80; /* last IE of octet 3 etc */
|
||||
} else {
|
||||
/* FIXME: implement OCTET 4+ encoding */
|
||||
}
|
||||
|
||||
lv[0] = i;
|
||||
if (lv_only)
|
||||
msgb_lv_put(msg, lv[0], lv+1);
|
||||
else
|
||||
msgb_tlv_put(msg, GSM48_IE_BEARER_CAP, lv[0], lv+1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* decode 'call control cap' */
|
||||
int gsm48_decode_cccap(struct gsm_mncc_cccap *ccap, const uint8_t *lv)
|
||||
{
|
||||
uint8_t in_len = lv[0];
|
||||
|
||||
if (in_len < 1)
|
||||
return -EINVAL;
|
||||
|
||||
/* octet 3 */
|
||||
ccap->dtmf = lv[1] & 0x01;
|
||||
ccap->pcp = (lv[1] & 0x02) >> 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* encode 'call control cap' */
|
||||
int gsm48_encode_cccap(struct msgb *msg,
|
||||
const struct gsm_mncc_cccap *ccap)
|
||||
{
|
||||
uint8_t lv[2];
|
||||
|
||||
lv[0] = 1;
|
||||
lv[1] = 0;
|
||||
if (ccap->dtmf)
|
||||
lv [1] |= 0x01;
|
||||
if (ccap->pcp)
|
||||
lv [1] |= 0x02;
|
||||
|
||||
msgb_tlv_put(msg, GSM48_IE_CC_CAP, lv[0], lv+1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* decode 'called party BCD number' */
|
||||
int gsm48_decode_called(struct gsm_mncc_number *called,
|
||||
const uint8_t *lv)
|
||||
{
|
||||
uint8_t in_len = lv[0];
|
||||
|
||||
if (in_len < 1)
|
||||
return -EINVAL;
|
||||
|
||||
/* octet 3 */
|
||||
called->plan = lv[1] & 0x0f;
|
||||
called->type = (lv[1] & 0x70) >> 4;
|
||||
|
||||
/* octet 4..N */
|
||||
gsm48_decode_bcd_number(called->number, sizeof(called->number), lv, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* encode 'called party BCD number' */
|
||||
int gsm48_encode_called(struct msgb *msg,
|
||||
const struct gsm_mncc_number *called)
|
||||
{
|
||||
uint8_t lv[18];
|
||||
int ret;
|
||||
|
||||
/* octet 3 */
|
||||
lv[1] = called->plan;
|
||||
lv[1] |= called->type << 4;
|
||||
|
||||
/* octet 4..N, octet 2 */
|
||||
ret = gsm48_encode_bcd_number(lv, sizeof(lv), 1, called->number);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
msgb_tlv_put(msg, GSM48_IE_CALLED_BCD, lv[0], lv+1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* decode callerid of various IEs */
|
||||
int gsm48_decode_callerid(struct gsm_mncc_number *callerid,
|
||||
const uint8_t *lv)
|
||||
{
|
||||
uint8_t in_len = lv[0];
|
||||
int i = 1;
|
||||
|
||||
if (in_len < 1)
|
||||
return -EINVAL;
|
||||
|
||||
/* octet 3 */
|
||||
callerid->plan = lv[1] & 0x0f;
|
||||
callerid->type = (lv[1] & 0x70) >> 4;
|
||||
|
||||
/* octet 3a */
|
||||
if (!(lv[1] & 0x80)) {
|
||||
callerid->screen = lv[2] & 0x03;
|
||||
callerid->present = (lv[2] & 0x60) >> 5;
|
||||
i = 2;
|
||||
}
|
||||
|
||||
/* octet 4..N */
|
||||
gsm48_decode_bcd_number(callerid->number, sizeof(callerid->number), lv, i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* encode callerid of various IEs */
|
||||
int gsm48_encode_callerid(struct msgb *msg, int ie, int max_len,
|
||||
const struct gsm_mncc_number *callerid)
|
||||
{
|
||||
uint8_t lv[max_len - 1];
|
||||
int h_len = 1;
|
||||
int ret;
|
||||
|
||||
/* octet 3 */
|
||||
lv[1] = callerid->plan;
|
||||
lv[1] |= callerid->type << 4;
|
||||
|
||||
if (callerid->present || callerid->screen) {
|
||||
/* octet 3a */
|
||||
lv[2] = callerid->screen;
|
||||
lv[2] |= callerid->present << 5;
|
||||
lv[2] |= 0x80;
|
||||
h_len++;
|
||||
} else
|
||||
lv[1] |= 0x80;
|
||||
|
||||
/* octet 4..N, octet 2 */
|
||||
ret = gsm48_encode_bcd_number(lv, sizeof(lv), h_len, callerid->number);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
msgb_tlv_put(msg, ie, lv[0], lv+1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* decode 'cause' */
|
||||
int gsm48_decode_cause(struct gsm_mncc_cause *cause,
|
||||
const uint8_t *lv)
|
||||
{
|
||||
uint8_t in_len = lv[0];
|
||||
int i;
|
||||
|
||||
if (in_len < 2)
|
||||
return -EINVAL;
|
||||
|
||||
cause->diag_len = 0;
|
||||
|
||||
/* octet 3 */
|
||||
cause->location = lv[1] & 0x0f;
|
||||
cause->coding = (lv[1] & 0x60) >> 5;
|
||||
|
||||
i = 1;
|
||||
if (!(lv[i] & 0x80)) {
|
||||
i++; /* octet 3a */
|
||||
if (in_len < i+1)
|
||||
return 0;
|
||||
cause->rec = 1;
|
||||
cause->rec_val = lv[i] & 0x7f;
|
||||
}
|
||||
i++;
|
||||
|
||||
/* octet 4 */
|
||||
cause->value = lv[i] & 0x7f;
|
||||
i++;
|
||||
|
||||
if (in_len < i) /* no diag */
|
||||
return 0;
|
||||
|
||||
if (in_len - (i-1) > 32) /* maximum 32 octets */
|
||||
return 0;
|
||||
|
||||
/* octet 5-N */
|
||||
memcpy(cause->diag, lv + i, in_len - (i-1));
|
||||
cause->diag_len = in_len - (i-1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* encode 'cause' */
|
||||
int gsm48_encode_cause(struct msgb *msg, int lv_only,
|
||||
const struct gsm_mncc_cause *cause)
|
||||
{
|
||||
uint8_t lv[32+4];
|
||||
int i;
|
||||
|
||||
if (cause->diag_len > 32)
|
||||
return -EINVAL;
|
||||
|
||||
/* octet 3 */
|
||||
lv[1] = cause->location;
|
||||
lv[1] |= cause->coding << 5;
|
||||
|
||||
i = 1;
|
||||
if (cause->rec) {
|
||||
i++; /* octet 3a */
|
||||
lv[i] = cause->rec_val;
|
||||
}
|
||||
lv[i] |= 0x80; /* end of octet 3 */
|
||||
|
||||
/* octet 4 */
|
||||
i++;
|
||||
lv[i] = 0x80 | cause->value;
|
||||
|
||||
/* octet 5-N */
|
||||
if (cause->diag_len) {
|
||||
memcpy(lv + i, cause->diag, cause->diag_len);
|
||||
i += cause->diag_len;
|
||||
}
|
||||
|
||||
lv[0] = i;
|
||||
if (lv_only)
|
||||
msgb_lv_put(msg, lv[0], lv+1);
|
||||
else
|
||||
msgb_tlv_put(msg, GSM48_IE_CAUSE, lv[0], lv+1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* decode 'calling number' */
|
||||
int gsm48_decode_calling(struct gsm_mncc_number *calling,
|
||||
const uint8_t *lv)
|
||||
{
|
||||
return gsm48_decode_callerid(calling, lv);
|
||||
}
|
||||
|
||||
/* encode 'calling number' */
|
||||
int gsm48_encode_calling(struct msgb *msg,
|
||||
const struct gsm_mncc_number *calling)
|
||||
{
|
||||
return gsm48_encode_callerid(msg, GSM48_IE_CALLING_BCD, 14, calling);
|
||||
}
|
||||
|
||||
/* decode 'connected number' */
|
||||
int gsm48_decode_connected(struct gsm_mncc_number *connected,
|
||||
const uint8_t *lv)
|
||||
{
|
||||
return gsm48_decode_callerid(connected, lv);
|
||||
}
|
||||
|
||||
/* encode 'connected number' */
|
||||
int gsm48_encode_connected(struct msgb *msg,
|
||||
const struct gsm_mncc_number *connected)
|
||||
{
|
||||
return gsm48_encode_callerid(msg, GSM48_IE_CONN_BCD, 14, connected);
|
||||
}
|
||||
|
||||
/* decode 'redirecting number' */
|
||||
int gsm48_decode_redirecting(struct gsm_mncc_number *redirecting,
|
||||
const uint8_t *lv)
|
||||
{
|
||||
return gsm48_decode_callerid(redirecting, lv);
|
||||
}
|
||||
|
||||
/* encode 'redirecting number' */
|
||||
int gsm48_encode_redirecting(struct msgb *msg,
|
||||
const struct gsm_mncc_number *redirecting)
|
||||
{
|
||||
return gsm48_encode_callerid(msg, GSM48_IE_REDIR_BCD, 19, redirecting);
|
||||
}
|
||||
|
||||
/* decode 'facility' */
|
||||
int gsm48_decode_facility(struct gsm_mncc_facility *facility,
|
||||
const uint8_t *lv)
|
||||
{
|
||||
uint8_t in_len = lv[0];
|
||||
|
||||
if (in_len < 1)
|
||||
return -EINVAL;
|
||||
|
||||
if (in_len > sizeof(facility->info))
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(facility->info, lv+1, in_len);
|
||||
facility->len = in_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* encode 'facility' */
|
||||
int gsm48_encode_facility(struct msgb *msg, int lv_only,
|
||||
const struct gsm_mncc_facility *facility)
|
||||
{
|
||||
uint8_t lv[GSM_MAX_FACILITY + 1];
|
||||
|
||||
if (facility->len < 1 || facility->len > GSM_MAX_FACILITY)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(lv+1, facility->info, facility->len);
|
||||
lv[0] = facility->len;
|
||||
if (lv_only)
|
||||
msgb_lv_put(msg, lv[0], lv+1);
|
||||
else
|
||||
msgb_tlv_put(msg, GSM48_IE_FACILITY, lv[0], lv+1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* decode 'notify' */
|
||||
int gsm48_decode_notify(int *notify, const uint8_t *v)
|
||||
{
|
||||
*notify = v[0] & 0x7f;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* encode 'notify' */
|
||||
int gsm48_encode_notify(struct msgb *msg, int notify)
|
||||
{
|
||||
msgb_v_put(msg, notify | 0x80);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* decode 'signal' */
|
||||
int gsm48_decode_signal(int *signal, const uint8_t *v)
|
||||
{
|
||||
*signal = v[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* encode 'signal' */
|
||||
int gsm48_encode_signal(struct msgb *msg, int signal)
|
||||
{
|
||||
msgb_tv_put(msg, GSM48_IE_SIGNAL, signal);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* decode 'keypad' */
|
||||
int gsm48_decode_keypad(int *keypad, const uint8_t *lv)
|
||||
{
|
||||
uint8_t in_len = lv[0];
|
||||
|
||||
if (in_len < 1)
|
||||
return -EINVAL;
|
||||
|
||||
*keypad = lv[1] & 0x7f;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* encode 'keypad' */
|
||||
int gsm48_encode_keypad(struct msgb *msg, int keypad)
|
||||
{
|
||||
msgb_tv_put(msg, GSM48_IE_KPD_FACILITY, keypad);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* decode 'progress' */
|
||||
int gsm48_decode_progress(struct gsm_mncc_progress *progress,
|
||||
const uint8_t *lv)
|
||||
{
|
||||
uint8_t in_len = lv[0];
|
||||
|
||||
if (in_len < 2)
|
||||
return -EINVAL;
|
||||
|
||||
progress->coding = (lv[1] & 0x60) >> 5;
|
||||
progress->location = lv[1] & 0x0f;
|
||||
progress->descr = lv[2] & 0x7f;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* encode 'progress' */
|
||||
int gsm48_encode_progress(struct msgb *msg, int lv_only,
|
||||
const struct gsm_mncc_progress *p)
|
||||
{
|
||||
uint8_t lv[3];
|
||||
|
||||
lv[0] = 2;
|
||||
lv[1] = 0x80 | ((p->coding & 0x3) << 5) | (p->location & 0xf);
|
||||
lv[2] = 0x80 | (p->descr & 0x7f);
|
||||
if (lv_only)
|
||||
msgb_lv_put(msg, lv[0], lv+1);
|
||||
else
|
||||
msgb_tlv_put(msg, GSM48_IE_PROGR_IND, lv[0], lv+1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* decode 'user-user' */
|
||||
int gsm48_decode_useruser(struct gsm_mncc_useruser *uu,
|
||||
const uint8_t *lv)
|
||||
{
|
||||
uint8_t in_len = lv[0];
|
||||
char *info = uu->info;
|
||||
int info_len = sizeof(uu->info);
|
||||
int i;
|
||||
|
||||
if (in_len < 1)
|
||||
return -EINVAL;
|
||||
|
||||
uu->proto = lv[1];
|
||||
|
||||
for (i = 2; i <= in_len; i++) {
|
||||
info_len--;
|
||||
if (info_len <= 1)
|
||||
break;
|
||||
*info++ = lv[i];
|
||||
}
|
||||
if (info_len >= 1)
|
||||
*info++ = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* encode 'useruser' */
|
||||
int gsm48_encode_useruser(struct msgb *msg, int lv_only,
|
||||
const struct gsm_mncc_useruser *uu)
|
||||
{
|
||||
uint8_t lv[GSM_MAX_USERUSER + 2];
|
||||
|
||||
if (strlen(uu->info) > GSM_MAX_USERUSER)
|
||||
return -EINVAL;
|
||||
|
||||
lv[0] = 1 + strlen(uu->info);
|
||||
lv[1] = uu->proto;
|
||||
memcpy(lv + 2, uu->info, strlen(uu->info));
|
||||
if (lv_only)
|
||||
msgb_lv_put(msg, lv[0], lv+1);
|
||||
else
|
||||
msgb_tlv_put(msg, GSM48_IE_USER_USER, lv[0], lv+1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* decode 'ss version' */
|
||||
int gsm48_decode_ssversion(struct gsm_mncc_ssversion *ssv,
|
||||
const uint8_t *lv)
|
||||
{
|
||||
uint8_t in_len = lv[0];
|
||||
|
||||
if (in_len < 1 || in_len < sizeof(ssv->info))
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(ssv->info, lv + 1, in_len);
|
||||
ssv->len = in_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* encode 'ss version' */
|
||||
int gsm48_encode_ssversion(struct msgb *msg,
|
||||
const struct gsm_mncc_ssversion *ssv)
|
||||
{
|
||||
uint8_t lv[GSM_MAX_SSVERSION + 1];
|
||||
|
||||
if (ssv->len > GSM_MAX_SSVERSION)
|
||||
return -EINVAL;
|
||||
|
||||
lv[0] = ssv->len;
|
||||
memcpy(lv + 1, ssv->info, ssv->len);
|
||||
msgb_tlv_put(msg, GSM48_IE_SS_VERS, lv[0], lv+1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* decode 'more data' does not require a function, because it has no value */
|
||||
|
||||
/* encode 'more data' */
|
||||
int gsm48_encode_more(struct msgb *msg)
|
||||
{
|
||||
uint8_t *ie;
|
||||
|
||||
ie = msgb_put(msg, 1);
|
||||
ie[0] = GSM48_IE_MORE_DATA;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,361 +0,0 @@
|
||||
/*
|
||||
* (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
|
||||
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
//#include <openbsc/gsm_data.h>
|
||||
#include <osmocore/utils.h>
|
||||
#include <osmocore/gsm_utils.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "../config.h"
|
||||
|
||||
/* GSM 03.38 6.2.1 Charachter packing */
|
||||
int gsm_7bit_decode(char *text, const uint8_t *user_data, uint8_t length)
|
||||
{
|
||||
int i = 0;
|
||||
int l = 0;
|
||||
|
||||
/* FIXME: We need to account for user data headers here */
|
||||
i += l;
|
||||
for (; i < length; i ++)
|
||||
*(text ++) =
|
||||
((user_data[(i * 7 + 7) >> 3] <<
|
||||
(7 - ((i * 7 + 7) & 7))) |
|
||||
(user_data[(i * 7) >> 3] >>
|
||||
((i * 7) & 7))) & 0x7f;
|
||||
*text = '\0';
|
||||
|
||||
return i - l;
|
||||
}
|
||||
|
||||
|
||||
/* GSM 03.38 6.2.1 Charachter packing */
|
||||
int gsm_7bit_encode(uint8_t *result, const char *data)
|
||||
{
|
||||
int i,j = 0;
|
||||
unsigned char ch1, ch2;
|
||||
int shift = 0;
|
||||
|
||||
for ( i=0; i<strlen(data); i++ ) {
|
||||
|
||||
ch1 = data[i] & 0x7F;
|
||||
ch1 = ch1 >> shift;
|
||||
ch2 = data[(i+1)] & 0x7F;
|
||||
ch2 = ch2 << (7-shift);
|
||||
|
||||
ch1 = ch1 | ch2;
|
||||
|
||||
result[j++] = ch1;
|
||||
|
||||
shift++;
|
||||
|
||||
if ((shift == 7) && (i+1<strlen(data))) {
|
||||
shift = 0;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/* determine power control level for given dBm value, as indicated
|
||||
* by the tables in chapter 4.1.1 of GSM TS 05.05 */
|
||||
int ms_pwr_ctl_lvl(enum gsm_band band, unsigned int dbm)
|
||||
{
|
||||
switch (band) {
|
||||
case GSM_BAND_450:
|
||||
case GSM_BAND_480:
|
||||
case GSM_BAND_750:
|
||||
case GSM_BAND_900:
|
||||
case GSM_BAND_810:
|
||||
case GSM_BAND_850:
|
||||
if (dbm >= 39)
|
||||
return 0;
|
||||
else if (dbm < 5)
|
||||
return 19;
|
||||
else {
|
||||
/* we are guaranteed to have (5 <= dbm < 39) */
|
||||
return 2 + ((39 - dbm) / 2);
|
||||
}
|
||||
break;
|
||||
case GSM_BAND_1800:
|
||||
if (dbm >= 36)
|
||||
return 29;
|
||||
else if (dbm >= 34)
|
||||
return 30;
|
||||
else if (dbm >= 32)
|
||||
return 31;
|
||||
else if (dbm == 31)
|
||||
return 0;
|
||||
else {
|
||||
/* we are guaranteed to have (0 <= dbm < 31) */
|
||||
return (30 - dbm) / 2;
|
||||
}
|
||||
break;
|
||||
case GSM_BAND_1900:
|
||||
if (dbm >= 33)
|
||||
return 30;
|
||||
else if (dbm >= 32)
|
||||
return 31;
|
||||
else if (dbm == 31)
|
||||
return 0;
|
||||
else {
|
||||
/* we are guaranteed to have (0 <= dbm < 31) */
|
||||
return (30 - dbm) / 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int ms_pwr_dbm(enum gsm_band band, uint8_t lvl)
|
||||
{
|
||||
lvl &= 0x1f;
|
||||
|
||||
switch (band) {
|
||||
case GSM_BAND_450:
|
||||
case GSM_BAND_480:
|
||||
case GSM_BAND_750:
|
||||
case GSM_BAND_900:
|
||||
case GSM_BAND_810:
|
||||
case GSM_BAND_850:
|
||||
if (lvl < 2)
|
||||
return 39;
|
||||
else if (lvl < 20)
|
||||
return 39 - ((lvl - 2) * 2) ;
|
||||
else
|
||||
return 5;
|
||||
break;
|
||||
case GSM_BAND_1800:
|
||||
if (lvl < 16)
|
||||
return 30 - (lvl * 2);
|
||||
else if (lvl < 29)
|
||||
return 0;
|
||||
else
|
||||
return 36 - ((lvl - 29) * 2);
|
||||
break;
|
||||
case GSM_BAND_1900:
|
||||
if (lvl < 16)
|
||||
return 30 - (lvl * 2);
|
||||
else if (lvl < 30)
|
||||
return -EINVAL;
|
||||
else
|
||||
return 33 - (lvl - 30);
|
||||
break;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* According to TS 08.05 Chapter 8.1.4 */
|
||||
int rxlev2dbm(uint8_t rxlev)
|
||||
{
|
||||
if (rxlev > 63)
|
||||
rxlev = 63;
|
||||
|
||||
return -110 + rxlev;
|
||||
}
|
||||
|
||||
/* According to TS 08.05 Chapter 8.1.4 */
|
||||
uint8_t dbm2rxlev(int dbm)
|
||||
{
|
||||
int rxlev = dbm + 110;
|
||||
|
||||
if (rxlev > 63)
|
||||
rxlev = 63;
|
||||
else if (rxlev < 0)
|
||||
rxlev = 0;
|
||||
|
||||
return rxlev;
|
||||
}
|
||||
|
||||
const char *gsm_band_name(enum gsm_band band)
|
||||
{
|
||||
switch (band) {
|
||||
case GSM_BAND_450:
|
||||
return "GSM450";
|
||||
case GSM_BAND_480:
|
||||
return "GSM450";
|
||||
case GSM_BAND_750:
|
||||
return "GSM750";
|
||||
case GSM_BAND_810:
|
||||
return "GSM810";
|
||||
case GSM_BAND_850:
|
||||
return "GSM850";
|
||||
case GSM_BAND_900:
|
||||
return "GSM900";
|
||||
case GSM_BAND_1800:
|
||||
return "DCS1800";
|
||||
case GSM_BAND_1900:
|
||||
return "PCS1900";
|
||||
}
|
||||
return "invalid";
|
||||
}
|
||||
|
||||
enum gsm_band gsm_band_parse(const char* mhz)
|
||||
{
|
||||
while (*mhz && !isdigit(*mhz))
|
||||
mhz++;
|
||||
|
||||
if (*mhz == '\0')
|
||||
return -EINVAL;
|
||||
|
||||
switch (strtol(mhz, NULL, 10)) {
|
||||
case 450:
|
||||
return GSM_BAND_450;
|
||||
case 480:
|
||||
return GSM_BAND_480;
|
||||
case 750:
|
||||
return GSM_BAND_750;
|
||||
case 810:
|
||||
return GSM_BAND_810;
|
||||
case 850:
|
||||
return GSM_BAND_850;
|
||||
case 900:
|
||||
return GSM_BAND_900;
|
||||
case 1800:
|
||||
return GSM_BAND_1800;
|
||||
case 1900:
|
||||
return GSM_BAND_1900;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_EXECINFO_H
|
||||
#include <execinfo.h>
|
||||
void generate_backtrace()
|
||||
{
|
||||
int i, nptrs;
|
||||
void *buffer[100];
|
||||
char **strings;
|
||||
|
||||
nptrs = backtrace(buffer, ARRAY_SIZE(buffer));
|
||||
printf("backtrace() returned %d addresses\n", nptrs);
|
||||
|
||||
strings = backtrace_symbols(buffer, nptrs);
|
||||
if (!strings)
|
||||
return;
|
||||
|
||||
for (i = 1; i < nptrs; i++)
|
||||
printf("%s\n", strings[i]);
|
||||
|
||||
free(strings);
|
||||
}
|
||||
#endif
|
||||
|
||||
enum gsm_band gsm_arfcn2band(uint16_t arfcn)
|
||||
{
|
||||
if (arfcn & ARFCN_PCS)
|
||||
return GSM_BAND_1900;
|
||||
else if (arfcn <= 124)
|
||||
return GSM_BAND_900;
|
||||
else if (arfcn >= 955 && arfcn <= 1023)
|
||||
return GSM_BAND_900;
|
||||
else if (arfcn >= 128 && arfcn <= 251)
|
||||
return GSM_BAND_850;
|
||||
else if (arfcn >= 512 && arfcn <= 885)
|
||||
return GSM_BAND_1800;
|
||||
else if (arfcn >= 259 && arfcn <= 293)
|
||||
return GSM_BAND_450;
|
||||
else if (arfcn >= 306 && arfcn <= 340)
|
||||
return GSM_BAND_480;
|
||||
else if (arfcn >= 350 && arfcn <= 425)
|
||||
return GSM_BAND_810;
|
||||
else if (arfcn >= 438 && arfcn <= 511)
|
||||
return GSM_BAND_750;
|
||||
else
|
||||
return GSM_BAND_1800;
|
||||
}
|
||||
|
||||
/* Convert an ARFCN to the frequency in MHz * 10 */
|
||||
uint16_t gsm_arfcn2freq10(uint16_t arfcn, int uplink)
|
||||
{
|
||||
uint16_t freq10_ul;
|
||||
uint16_t freq10_dl;
|
||||
|
||||
if (arfcn & ARFCN_PCS) {
|
||||
/* DCS 1900 */
|
||||
arfcn &= ~ARFCN_PCS;
|
||||
freq10_ul = 18502 + 2 * (arfcn-512);
|
||||
freq10_dl = freq10_ul + 800;
|
||||
} else if (arfcn <= 124) {
|
||||
/* Primary GSM + ARFCN 0 of E-GSM */
|
||||
freq10_ul = 8900 + 2 * arfcn;
|
||||
freq10_dl = freq10_ul + 450;
|
||||
} else if (arfcn >= 955 && arfcn <= 1023) {
|
||||
/* E-GSM and R-GSM */
|
||||
freq10_ul = 8900 + 2 * (arfcn - 1024);
|
||||
freq10_dl = freq10_ul + 450;
|
||||
} else if (arfcn >= 128 && arfcn <= 251) {
|
||||
/* GSM 850 */
|
||||
freq10_ul = 8242 + 2 * (arfcn - 128);
|
||||
freq10_dl = freq10_ul + 450;
|
||||
} else if (arfcn >= 512 && arfcn <= 885) {
|
||||
/* DCS 1800 */
|
||||
freq10_ul = 17102 + 2 * (arfcn - 512);
|
||||
freq10_dl = freq10_ul + 950;
|
||||
} else if (arfcn >= 259 && arfcn <= 293) {
|
||||
/* GSM 450 */
|
||||
freq10_ul = 4506 + 2 * (arfcn - 259);
|
||||
freq10_dl = freq10_ul + 100;
|
||||
} else if (arfcn >= 306 && arfcn <= 340) {
|
||||
/* GSM 480 */
|
||||
freq10_ul = 4790 + 2 * (arfcn - 306);
|
||||
freq10_dl = freq10_ul + 100;
|
||||
} else if (arfcn >= 350 && arfcn <= 425) {
|
||||
/* GSM 810 */
|
||||
freq10_ul = 8060 + 2 * (arfcn - 350);
|
||||
freq10_dl = freq10_ul + 450;
|
||||
} else if (arfcn >= 438 && arfcn <= 511) {
|
||||
/* GSM 750 */
|
||||
freq10_ul = 7472 + 2 * (arfcn - 438);
|
||||
freq10_dl = freq10_ul + 300;
|
||||
} else
|
||||
return 0xffff;
|
||||
|
||||
if (uplink)
|
||||
return freq10_ul;
|
||||
else
|
||||
return freq10_dl;
|
||||
}
|
||||
|
||||
void gsm_fn2gsmtime(struct gsm_time *time, uint32_t fn)
|
||||
{
|
||||
time->fn = fn;
|
||||
time->t1 = time->fn / (26*51);
|
||||
time->t2 = time->fn % 26;
|
||||
time->t3 = time->fn % 51;
|
||||
time->tc = (time->fn / 51) % 8;
|
||||
}
|
||||
|
||||
uint32_t gsm_gsmtime2fn(struct gsm_time *time)
|
||||
{
|
||||
/* TS 05.02 Chapter 4.3.3 TDMA frame number */
|
||||
return (51 * ((time->t3 - time->t2 + 26) % 26) + time->t3 + (26 * 51 * time->t1));
|
||||
}
|
||||
@@ -1,327 +0,0 @@
|
||||
/* GSM Radio Signalling Link messages on the A-bis interface
|
||||
* 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */
|
||||
|
||||
/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <osmocore/tlv.h>
|
||||
#include <osmocore/rsl.h>
|
||||
|
||||
#define RSL_ALLOC_SIZE 200
|
||||
#define RSL_ALLOC_HEADROOM 56
|
||||
|
||||
void rsl_init_rll_hdr(struct abis_rsl_rll_hdr *dh, uint8_t msg_type)
|
||||
{
|
||||
dh->c.msg_discr = ABIS_RSL_MDISC_RLL;
|
||||
dh->c.msg_type = msg_type;
|
||||
dh->ie_chan = RSL_IE_CHAN_NR;
|
||||
dh->ie_link_id = RSL_IE_LINK_IDENT;
|
||||
}
|
||||
|
||||
const struct tlv_definition rsl_att_tlvdef = {
|
||||
.def = {
|
||||
[RSL_IE_CHAN_NR] = { TLV_TYPE_TV },
|
||||
[RSL_IE_LINK_IDENT] = { TLV_TYPE_TV },
|
||||
[RSL_IE_ACT_TYPE] = { TLV_TYPE_TV },
|
||||
[RSL_IE_BS_POWER] = { TLV_TYPE_TV },
|
||||
[RSL_IE_CHAN_IDENT] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_CHAN_MODE] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_ENCR_INFO] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_FRAME_NUMBER] = { TLV_TYPE_FIXED, 2 },
|
||||
[RSL_IE_HANDO_REF] = { TLV_TYPE_TV },
|
||||
[RSL_IE_L1_INFO] = { TLV_TYPE_FIXED, 2 },
|
||||
[RSL_IE_L3_INFO] = { TLV_TYPE_TL16V },
|
||||
[RSL_IE_MS_IDENTITY] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_MS_POWER] = { TLV_TYPE_TV },
|
||||
[RSL_IE_PAGING_GROUP] = { TLV_TYPE_TV },
|
||||
[RSL_IE_PAGING_LOAD] = { TLV_TYPE_FIXED, 2 },
|
||||
[RSL_IE_PYHS_CONTEXT] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_ACCESS_DELAY] = { TLV_TYPE_TV },
|
||||
[RSL_IE_RACH_LOAD] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_REQ_REFERENCE] = { TLV_TYPE_FIXED, 3 },
|
||||
[RSL_IE_RELEASE_MODE] = { TLV_TYPE_TV },
|
||||
[RSL_IE_RESOURCE_INFO] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_RLM_CAUSE] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_STARTNG_TIME] = { TLV_TYPE_FIXED, 2 },
|
||||
[RSL_IE_TIMING_ADVANCE] = { TLV_TYPE_TV },
|
||||
[RSL_IE_UPLINK_MEAS] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_CAUSE] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_MEAS_RES_NR] = { TLV_TYPE_TV },
|
||||
[RSL_IE_MSG_ID] = { TLV_TYPE_TV },
|
||||
[RSL_IE_SYSINFO_TYPE] = { TLV_TYPE_TV },
|
||||
[RSL_IE_MS_POWER_PARAM] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_BS_POWER_PARAM] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_PREPROC_PARAM] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_PREPROC_MEAS] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_IMM_ASS_INFO] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_SMSCB_INFO] = { TLV_TYPE_FIXED, 23 },
|
||||
[RSL_IE_MS_TIMING_OFFSET] = { TLV_TYPE_TV },
|
||||
[RSL_IE_ERR_MSG] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_FULL_BCCH_INFO] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_CHAN_NEEDED] = { TLV_TYPE_TV },
|
||||
[RSL_IE_CB_CMD_TYPE] = { TLV_TYPE_TV },
|
||||
[RSL_IE_SMSCB_MSG] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_FULL_IMM_ASS_INFO] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_SACCH_INFO] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_CBCH_LOAD_INFO] = { TLV_TYPE_TV },
|
||||
[RSL_IE_SMSCB_CHAN_INDICATOR] = { TLV_TYPE_TV },
|
||||
[RSL_IE_GROUP_CALL_REF] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_CHAN_DESC] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_NCH_DRX_INFO] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_CMD_INDICATOR] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_EMLPP_PRIO] = { TLV_TYPE_TV },
|
||||
[RSL_IE_UIC] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_MAIN_CHAN_REF] = { TLV_TYPE_TV },
|
||||
[RSL_IE_MR_CONFIG] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_MR_CONTROL] = { TLV_TYPE_TV },
|
||||
[RSL_IE_SUP_CODEC_TYPES] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_CODEC_CONFIG] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_RTD] = { TLV_TYPE_TV },
|
||||
[RSL_IE_TFO_STATUS] = { TLV_TYPE_TV },
|
||||
[RSL_IE_LLP_APDU] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_SIEMENS_MRPCI] = { TLV_TYPE_TV },
|
||||
[RSL_IE_IPAC_PROXY_UDP] = { TLV_TYPE_FIXED, 2 },
|
||||
[RSL_IE_IPAC_BSCMPL_TOUT] = { TLV_TYPE_TV },
|
||||
[RSL_IE_IPAC_REMOTE_IP] = { TLV_TYPE_FIXED, 4 },
|
||||
[RSL_IE_IPAC_REMOTE_PORT] = { TLV_TYPE_FIXED, 2 },
|
||||
[RSL_IE_IPAC_RTP_PAYLOAD] = { TLV_TYPE_TV },
|
||||
[RSL_IE_IPAC_LOCAL_PORT] = { TLV_TYPE_FIXED, 2 },
|
||||
[RSL_IE_IPAC_SPEECH_MODE] = { TLV_TYPE_TV },
|
||||
[RSL_IE_IPAC_LOCAL_IP] = { TLV_TYPE_FIXED, 4 },
|
||||
[RSL_IE_IPAC_CONN_ID] = { TLV_TYPE_FIXED, 2 },
|
||||
[RSL_IE_IPAC_RTP_CSD_FMT] = { TLV_TYPE_TV },
|
||||
[RSL_IE_IPAC_RTP_JIT_BUF] = { TLV_TYPE_FIXED, 2 },
|
||||
[RSL_IE_IPAC_RTP_COMPR] = { TLV_TYPE_TV },
|
||||
[RSL_IE_IPAC_RTP_PAYLOAD2] = { TLV_TYPE_TV },
|
||||
[RSL_IE_IPAC_RTP_MPLEX] = { TLV_TYPE_FIXED, 8 },
|
||||
[RSL_IE_IPAC_RTP_MPLEX_ID] = { TLV_TYPE_TV },
|
||||
},
|
||||
};
|
||||
|
||||
/* encode channel number as per Section 9.3.1 */
|
||||
uint8_t rsl_enc_chan_nr(uint8_t type, uint8_t subch, uint8_t timeslot)
|
||||
{
|
||||
uint8_t ret;
|
||||
|
||||
ret = (timeslot & 0x07) | type;
|
||||
|
||||
switch (type) {
|
||||
case RSL_CHAN_Lm_ACCHs:
|
||||
subch &= 0x01;
|
||||
break;
|
||||
case RSL_CHAN_SDCCH4_ACCH:
|
||||
subch &= 0x03;
|
||||
break;
|
||||
case RSL_CHAN_SDCCH8_ACCH:
|
||||
subch &= 0x07;
|
||||
break;
|
||||
default:
|
||||
/* no subchannels allowed */
|
||||
subch = 0x00;
|
||||
break;
|
||||
}
|
||||
ret |= (subch << 3);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rsl_dec_chan_nr(uint8_t chan_nr, uint8_t *type, uint8_t *subch, uint8_t *timeslot)
|
||||
{
|
||||
*timeslot = chan_nr & 0x7;
|
||||
|
||||
if ((chan_nr & 0xf8) == RSL_CHAN_Bm_ACCHs) {
|
||||
*type = RSL_CHAN_Bm_ACCHs;
|
||||
*subch = 0;
|
||||
} else if ((chan_nr & 0xf0) == RSL_CHAN_Lm_ACCHs) {
|
||||
*type = RSL_CHAN_Lm_ACCHs;
|
||||
*subch = (chan_nr >> 3) & 0x1;
|
||||
} else if ((chan_nr & 0xe0) == RSL_CHAN_SDCCH4_ACCH) {
|
||||
*type = RSL_CHAN_SDCCH4_ACCH;
|
||||
*subch = (chan_nr >> 3) & 0x3;
|
||||
} else if ((chan_nr & 0xc0) == RSL_CHAN_SDCCH8_ACCH) {
|
||||
*type = RSL_CHAN_SDCCH8_ACCH;
|
||||
*subch = (chan_nr >> 3) & 0x7;
|
||||
} else if ((chan_nr & 0xf8) == RSL_CHAN_BCCH) {
|
||||
*type = RSL_CHAN_BCCH;
|
||||
*subch = 0;
|
||||
} else if ((chan_nr & 0xf8) == RSL_CHAN_RACH) {
|
||||
*type = RSL_CHAN_RACH;
|
||||
*subch = 0;
|
||||
} else if ((chan_nr & 0xf8) == RSL_CHAN_PCH_AGCH) {
|
||||
*type = RSL_CHAN_PCH_AGCH;
|
||||
*subch = 0;
|
||||
} else
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME: convert to value_string */
|
||||
static const char *rsl_err_vals[0xff] = {
|
||||
[RSL_ERR_RADIO_IF_FAIL] = "Radio Interface Failure",
|
||||
[RSL_ERR_RADIO_LINK_FAIL] = "Radio Link Failure",
|
||||
[RSL_ERR_HANDOVER_ACC_FAIL] = "Handover Access Failure",
|
||||
[RSL_ERR_TALKER_ACC_FAIL] = "Talker Access Failure",
|
||||
[RSL_ERR_OM_INTERVENTION] = "O&M Intervention",
|
||||
[RSL_ERR_NORMAL_UNSPEC] = "Normal event, unspecified",
|
||||
[RSL_ERR_T_MSRFPCI_EXP] = "Siemens: T_MSRFPCI Expired",
|
||||
[RSL_ERR_EQUIPMENT_FAIL] = "Equipment Failure",
|
||||
[RSL_ERR_RR_UNAVAIL] = "Radio Resource not available",
|
||||
[RSL_ERR_TERR_CH_FAIL] = "Terrestrial Channel Failure",
|
||||
[RSL_ERR_CCCH_OVERLOAD] = "CCCH Overload",
|
||||
[RSL_ERR_ACCH_OVERLOAD] = "ACCH Overload",
|
||||
[RSL_ERR_PROCESSOR_OVERLOAD] = "Processor Overload",
|
||||
[RSL_ERR_RES_UNAVAIL] = "Resource not available, unspecified",
|
||||
[RSL_ERR_TRANSC_UNAVAIL] = "Transcoding not available",
|
||||
[RSL_ERR_SERV_OPT_UNAVAIL] = "Service or Option not available",
|
||||
[RSL_ERR_ENCR_UNIMPL] = "Encryption algorithm not implemented",
|
||||
[RSL_ERR_SERV_OPT_UNIMPL] = "Service or Option not implemented",
|
||||
[RSL_ERR_RCH_ALR_ACTV_ALLOC] = "Radio channel already activated",
|
||||
[RSL_ERR_INVALID_MESSAGE] = "Invalid Message, unspecified",
|
||||
[RSL_ERR_MSG_DISCR] = "Message Discriminator Error",
|
||||
[RSL_ERR_MSG_TYPE] = "Message Type Error",
|
||||
[RSL_ERR_MSG_SEQ] = "Message Sequence Error",
|
||||
[RSL_ERR_IE_ERROR] = "General IE error",
|
||||
[RSL_ERR_MAND_IE_ERROR] = "Mandatory IE error",
|
||||
[RSL_ERR_OPT_IE_ERROR] = "Optional IE error",
|
||||
[RSL_ERR_IE_NONEXIST] = "IE non-existent",
|
||||
[RSL_ERR_IE_LENGTH] = "IE length error",
|
||||
[RSL_ERR_IE_CONTENT] = "IE content error",
|
||||
[RSL_ERR_PROTO] = "Protocol error, unspecified",
|
||||
[RSL_ERR_INTERWORKING] = "Interworking error, unspecified",
|
||||
};
|
||||
|
||||
const struct value_string rsl_rlm_cause_strs[] = {
|
||||
{ RLL_CAUSE_T200_EXPIRED, "Timer T200 expired (N200+1) times" },
|
||||
{ RLL_CAUSE_REEST_REQ, "Re-establishment request" },
|
||||
{ RLL_CAUSE_UNSOL_UA_RESP, "Unsolicited UA response" },
|
||||
{ RLL_CAUSE_UNSOL_DM_RESP, "Unsolicited DM response" },
|
||||
{ RLL_CAUSE_UNSOL_DM_RESP_MF, "Unsolicited DM response, multiple frame" },
|
||||
{ RLL_CAUSE_UNSOL_SPRV_RESP, "Unsolicited supervisory response" },
|
||||
{ RLL_CAUSE_SEQ_ERR, "Sequence Error" },
|
||||
{ RLL_CAUSE_UFRM_INC_PARAM, "U-Frame with incorrect parameters" },
|
||||
{ RLL_CAUSE_SFRM_INC_PARAM, "S-Frame with incorrect parameters" },
|
||||
{ RLL_CAUSE_IFRM_INC_MBITS, "I-Frame with incorrect use of M bit" },
|
||||
{ RLL_CAUSE_IFRM_INC_LEN, "I-Frame with incorrect length" },
|
||||
{ RLL_CAUSE_FRM_UNIMPL, "Fraeme not implemented" },
|
||||
{ RLL_CAUSE_SABM_MF, "SABM command, multiple frame established state" },
|
||||
{ RLL_CAUSE_SABM_INFO_NOTALL, "SABM frame with information not allowed in this state" },
|
||||
{ 0, NULL },
|
||||
};
|
||||
|
||||
const char *rsl_err_name(uint8_t err)
|
||||
{
|
||||
if (rsl_err_vals[err])
|
||||
return rsl_err_vals[err];
|
||||
else
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
/* Section 3.3.2.3 TS 05.02. I think this looks like a table */
|
||||
int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf)
|
||||
{
|
||||
switch (ccch_conf) {
|
||||
case RSL_BCCH_CCCH_CONF_1_NC:
|
||||
return 1;
|
||||
case RSL_BCCH_CCCH_CONF_1_C:
|
||||
return 1;
|
||||
case RSL_BCCH_CCCH_CONF_2_NC:
|
||||
return 2;
|
||||
case RSL_BCCH_CCCH_CONF_3_NC:
|
||||
return 3;
|
||||
case RSL_BCCH_CCCH_CONF_4_NC:
|
||||
return 4;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Section 3.3.2.3 TS 05.02 */
|
||||
int rsl_ccch_conf_to_bs_ccch_sdcch_comb(int ccch_conf)
|
||||
{
|
||||
switch (ccch_conf) {
|
||||
case RSL_BCCH_CCCH_CONF_1_NC:
|
||||
return 0;
|
||||
case RSL_BCCH_CCCH_CONF_1_C:
|
||||
return 1;
|
||||
case RSL_BCCH_CCCH_CONF_2_NC:
|
||||
return 0;
|
||||
case RSL_BCCH_CCCH_CONF_3_NC:
|
||||
return 0;
|
||||
case RSL_BCCH_CCCH_CONF_4_NC:
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Push a RSL RLL header with L3_INFO IE */
|
||||
void rsl_rll_push_l3(struct msgb *msg, uint8_t msg_type, uint8_t chan_nr,
|
||||
uint8_t link_id, int transparent)
|
||||
{
|
||||
uint8_t l3_len = msg->tail - (uint8_t *)msgb_l3(msg);
|
||||
struct abis_rsl_rll_hdr *rh;
|
||||
|
||||
/* construct a RSLms RLL message (DATA INDICATION, UNIT DATA
|
||||
* INDICATION) and send it off via RSLms */
|
||||
|
||||
/* Push the L3 IE tag and lengh */
|
||||
msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
|
||||
|
||||
/* Then push the RSL header */
|
||||
rh = (struct abis_rsl_rll_hdr *) msgb_push(msg, sizeof(*rh));
|
||||
rsl_init_rll_hdr(rh, msg_type);
|
||||
if (transparent)
|
||||
rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
|
||||
rh->chan_nr = chan_nr;
|
||||
rh->link_id = link_id;
|
||||
|
||||
/* set the l2 header pointer */
|
||||
msg->l2h = (uint8_t *)rh;
|
||||
}
|
||||
|
||||
struct msgb *rsl_rll_simple(uint8_t msg_type, uint8_t chan_nr,
|
||||
uint8_t link_id, int transparent)
|
||||
{
|
||||
struct abis_rsl_rll_hdr *rh;
|
||||
struct msgb *msg;
|
||||
|
||||
msg = msgb_alloc_headroom(RSL_ALLOC_SIZE+RSL_ALLOC_HEADROOM,
|
||||
RSL_ALLOC_HEADROOM, "rsl_rll_simple");
|
||||
|
||||
if (!msg)
|
||||
return NULL;
|
||||
|
||||
/* put the RSL header */
|
||||
rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
|
||||
rsl_init_rll_hdr(rh, msg_type);
|
||||
if (transparent)
|
||||
rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
|
||||
rh->chan_nr = chan_nr;
|
||||
rh->link_id = link_id;
|
||||
|
||||
/* set the l2 header pointer */
|
||||
msg->l2h = (uint8_t *)rh;
|
||||
|
||||
return msg;
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
/* Rx Level statistics */
|
||||
|
||||
/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <osmocore/bitvec.h>
|
||||
#include <osmocore/rxlev_stat.h>
|
||||
|
||||
int bitvec_find_bit_pos(const struct bitvec *bv, unsigned int n, enum bit_value val)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = n; i < bv->data_len*8; i++) {
|
||||
if (bitvec_get_bit_pos(bv, i) == val)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void rxlev_stat_input(struct rxlev_stats *st, uint16_t arfcn, uint8_t rxlev)
|
||||
{
|
||||
struct bitvec bv;
|
||||
|
||||
if (rxlev >= NUM_RXLEVS)
|
||||
rxlev = NUM_RXLEVS-1;
|
||||
|
||||
bv.data_len = NUM_ARFCNS/8;
|
||||
bv.data = st->rxlev_buckets[rxlev];
|
||||
|
||||
bitvec_set_bit_pos(&bv, arfcn, ONE);
|
||||
}
|
||||
|
||||
/* get the next ARFCN that has the specified Rxlev */
|
||||
int16_t rxlev_stat_get_next(const struct rxlev_stats *st, uint8_t rxlev, int16_t arfcn)
|
||||
{
|
||||
struct bitvec bv;
|
||||
|
||||
if (rxlev >= NUM_RXLEVS)
|
||||
rxlev = NUM_RXLEVS-1;
|
||||
|
||||
bv.data_len = NUM_ARFCNS/8;
|
||||
|
||||
if (arfcn < 0)
|
||||
arfcn = -1;
|
||||
|
||||
bv.data = st->rxlev_buckets[rxlev];
|
||||
|
||||
return bitvec_find_bit_pos(&bv, arfcn+1, ONE);
|
||||
}
|
||||
|
||||
void rxlev_stat_reset(struct rxlev_stats *st)
|
||||
{
|
||||
memset(st, 0, sizeof(*st));
|
||||
}
|
||||
|
||||
void rxlev_stat_dump(const struct rxlev_stats *st)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = NUM_RXLEVS-1; i >= 0; i--) {
|
||||
int16_t arfcn = -1;
|
||||
|
||||
printf("ARFCN with RxLev %u: ", i);
|
||||
while ((arfcn = rxlev_stat_get_next(st, i, arfcn)) >= 0) {
|
||||
printf("%u ", arfcn);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <osmocore/utils.h>
|
||||
|
||||
const char *get_value_string(const struct value_string *vs, uint32_t val)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0;; i++) {
|
||||
if (vs[i].value == 0 && vs[i].str == NULL)
|
||||
break;
|
||||
if (vs[i].value == val)
|
||||
return vs[i].str;
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
int get_string_value(const struct value_string *vs, const char *str)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0;; i++) {
|
||||
if (vs[i].value == 0 && vs[i].str == NULL)
|
||||
break;
|
||||
if (!strcasecmp(vs[i].str, str))
|
||||
return vs[i].value;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
char bcd2char(uint8_t bcd)
|
||||
{
|
||||
if (bcd < 0xa)
|
||||
return '0' + bcd;
|
||||
else
|
||||
return 'A' + (bcd - 0xa);
|
||||
}
|
||||
|
||||
/* only works for numbers in ascci */
|
||||
uint8_t char2bcd(char c)
|
||||
{
|
||||
return c - 0x30;
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/* Generic write queue implementation */
|
||||
/*
|
||||
* (C) 2010 by Holger Hans Peter Freyther
|
||||
* (C) 2010 by On-Waves
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <osmocore/write_queue.h>
|
||||
|
||||
int write_queue_bfd_cb(struct bsc_fd *fd, unsigned int what)
|
||||
{
|
||||
struct write_queue *queue;
|
||||
|
||||
queue = container_of(fd, struct write_queue, bfd);
|
||||
|
||||
if (what & BSC_FD_READ)
|
||||
queue->read_cb(fd);
|
||||
|
||||
if (what & BSC_FD_WRITE) {
|
||||
struct msgb *msg;
|
||||
|
||||
fd->when &= ~BSC_FD_WRITE;
|
||||
msg = msgb_dequeue(&queue->msg_queue);
|
||||
if (!msg)
|
||||
return -1;
|
||||
|
||||
--queue->current_length;
|
||||
queue->write_cb(fd, msg);
|
||||
msgb_free(msg);
|
||||
|
||||
if (!llist_empty(&queue->msg_queue))
|
||||
fd->when |= BSC_FD_WRITE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void write_queue_init(struct write_queue *queue, int max_length)
|
||||
{
|
||||
queue->max_length = max_length;
|
||||
queue->current_length = 0;
|
||||
queue->read_cb = NULL;
|
||||
queue->write_cb = NULL;
|
||||
queue->bfd.cb = write_queue_bfd_cb;
|
||||
INIT_LLIST_HEAD(&queue->msg_queue);
|
||||
}
|
||||
|
||||
int write_queue_enqueue(struct write_queue *queue, struct msgb *data)
|
||||
{
|
||||
// if (queue->current_length + 1 >= queue->max_length)
|
||||
// LOGP(DMSC, LOGL_ERROR, "The queue is full. Dropping not yet implemented.\n");
|
||||
|
||||
++queue->current_length;
|
||||
msgb_enqueue(&queue->msg_queue, data);
|
||||
queue->bfd.when |= BSC_FD_WRITE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
if ENABLE_TESTS
|
||||
SUBDIRS = timer sms
|
||||
endif
|
||||
@@ -1,6 +0,0 @@
|
||||
INCLUDES = $(all_includes) -I$(top_srcdir)/include
|
||||
noinst_PROGRAMS = timer_test
|
||||
|
||||
timer_test_SOURCES = timer_test.c
|
||||
timer_test_LDADD = $(top_builddir)/src/libosmocore.la
|
||||
|
||||
6
openbsc/.gitignore
vendored
6
openbsc/.gitignore
vendored
@@ -3,12 +3,8 @@
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
bscconfig.h
|
||||
bscconfig.h.in
|
||||
openbsc.pc
|
||||
bsc_hack
|
||||
bsc_msc_ip
|
||||
bsc_mgcp
|
||||
*.*~
|
||||
*.sw?
|
||||
|
||||
@@ -30,8 +26,6 @@ hlr.sqlite3
|
||||
bs11_config
|
||||
ipaccess-config
|
||||
ipaccess-find
|
||||
ipaccess-firmware
|
||||
ipaccess-proxy
|
||||
isdnsync
|
||||
|
||||
#tests
|
||||
|
||||
@@ -3,5 +3,3 @@ Holger Freyther <zecke@selfish.org>
|
||||
Jan Luebbe <jluebbe@debian.org>
|
||||
Stefan Schmidt <stefan@datenfreihafen.org>
|
||||
Daniel Willmann <daniel@totalueberwachung.de>
|
||||
Andreas Eversberg <Andreas.Eversberg@versatel.de>
|
||||
Sylvain Munaut <246tnt@gmail.com>
|
||||
|
||||
@@ -4,7 +4,7 @@ INCLUDES = $(all_includes) -I$(top_srcdir)/include
|
||||
SUBDIRS = include src tests
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = openbsc.pc libsccp.pc
|
||||
pkgconfig_DATA = openbsc.pc
|
||||
|
||||
#dist-hook:
|
||||
# rm -rf `find $(distdir) -name .svn`
|
||||
|
||||
@@ -1,30 +1,18 @@
|
||||
About OpenBSC
|
||||
=============
|
||||
|
||||
OpenBSC is a minimalistic implementation of the GSM Network, with
|
||||
particular emphasis on the functionality typically provided by the BSC,
|
||||
MSC, HLR, VLR and SMSC.
|
||||
OpenBSC is a minimalistic implementation of the GSM Network, with particular
|
||||
emphasis on the functionality typically provided by the BSC, MSC, HLR, VLR.
|
||||
|
||||
Its currently supported interfaces towards the BTS are:
|
||||
Its only current interface is a mISDN based E1 interface utilizing the A-bis
|
||||
protocol between BSC and BTS. In other words, you can connect an existing
|
||||
GSM Base Transceiver Station (BTS) through E1 to OpenBSC.
|
||||
|
||||
* Classic A-bis over E1 using a mISDN based E1 interface. In other
|
||||
words, you can connect existing GSM Base Transceiver Station (BTS)
|
||||
through E1 to OpenBSC. So far, we have only tested the Siemens BS-11
|
||||
Test reports with other BTS are much appreciated!
|
||||
|
||||
* A-bis over IP as used by the ip.access nanoBTS product family
|
||||
So far, it has only been tested with the Siemens microBTS BS-11. Test reports
|
||||
with other BTS are appreciated!
|
||||
|
||||
This project is still in its early days, and there are lots of areas where it
|
||||
doesn't behave as per GSM spec.
|
||||
|
||||
December 29, 2008
|
||||
Harald Welte <laforge@gnumonks.org>
|
||||
|
||||
|
||||
libosmocore
|
||||
===========
|
||||
|
||||
Please note that as of March 2010, OpenBSC has a dependency to a library
|
||||
called "libosmocore". You can obtain that library from
|
||||
|
||||
git://git.osmocom.org/libosmocore.git
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
dnl Process this file with autoconf to produce a configure script
|
||||
AC_INIT
|
||||
|
||||
AM_INIT_AUTOMAKE(openbsc, 0.0alpha1)
|
||||
AM_INIT_AUTOMAKE(openbsc, 0.3.4onwaves)
|
||||
|
||||
dnl kernel style compile messages
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
@@ -16,8 +16,6 @@ dnl checks for libraries
|
||||
AC_SEARCH_LIBS(crypt, crypt,
|
||||
[LIBCRYPT="-lcrypt"; AC_DEFINE([VTY_CRYPT_PW], [], [Use crypt functionality of vty.])])
|
||||
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore)
|
||||
|
||||
dnl checks for header files
|
||||
AC_HEADER_STDC
|
||||
|
||||
@@ -40,7 +38,6 @@ AM_CONFIG_HEADER(bscconfig.h)
|
||||
|
||||
AC_OUTPUT(
|
||||
openbsc.pc
|
||||
libsccp.pc
|
||||
include/openbsc/Makefile
|
||||
include/vty/Makefile
|
||||
include/sccp/Makefile
|
||||
@@ -48,6 +45,8 @@ AC_OUTPUT(
|
||||
src/Makefile
|
||||
tests/Makefile
|
||||
tests/debug/Makefile
|
||||
tests/timer/Makefile
|
||||
tests/sms/Makefile
|
||||
tests/gsm0408/Makefile
|
||||
tests/db/Makefile
|
||||
tests/channel/Makefile
|
||||
|
||||
2
openbsc/contrib/README
Normal file
2
openbsc/contrib/README
Normal file
@@ -0,0 +1,2 @@
|
||||
This contains a set of scripts used for the development of the
|
||||
MSC functionality.
|
||||
30
openbsc/contrib/send_handshake.py
Executable file
30
openbsc/contrib/send_handshake.py
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
|
||||
# packages
|
||||
ACK ="\x00\x01\xfe\x06"
|
||||
RESET_ACK = "\x00\x13\xfd\x09\x00\x03\x07\x0b\x04\x43\x01\x00\xfe\x04\x43\x5c\x00\xfe\x03\x00\x01\x31"
|
||||
PAGE = "\x00\x20\xfd\x09\x00\x03\x07\x0b\x04\x43\x01\x00\xfe\x04\x43\x5c\x00\xfe\x10\x00\x0e\x52\x08\x08\x29\x42\x08\x05\x03\x12\x23\x42\x1a\x01\x06"
|
||||
|
||||
|
||||
# simple handshake...
|
||||
sys.stdout.write(ACK)
|
||||
sys.stdout.flush()
|
||||
sys.stdin.read(4)
|
||||
|
||||
# wait for some data and send reset ack
|
||||
sys.stdin.read(21)
|
||||
sys.stdout.write(RESET_ACK)
|
||||
sys.stdout.flush()
|
||||
|
||||
sys.stdout.write(RESET_ACK)
|
||||
sys.stdout.flush()
|
||||
|
||||
# page a subscriber
|
||||
sys.stdout.write(PAGE)
|
||||
sys.stdout.flush()
|
||||
|
||||
while True:
|
||||
sys.stdin.read(1)
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
noinst_HEADERS = abis_nm.h abis_rsl.h db.h gsm_04_08.h gsm_data.h \
|
||||
gsm_subscriber.h gsm_04_11.h debug.h signal.h \
|
||||
misdn.h chan_alloc.h telnet_interface.h paging.h \
|
||||
subchan_demux.h trau_frame.h e1_input.h trau_mux.h \
|
||||
ipaccess.h rs232.h openbscdefines.h rtp_proxy.h \
|
||||
bsc_rll.h mncc.h transaction.h ussd.h gsm_04_80.h \
|
||||
silent_call.h mgcp.h meas_rep.h rest_octets.h \
|
||||
system_information.h handover.h mgcp_internal.h
|
||||
|
||||
openbsc_HEADERS = gsm_04_08.h meas_rep.h
|
||||
openbscdir = $(includedir)/openbsc
|
||||
noinst_HEADERS = abis_nm.h abis_rsl.h debug.h db.h gsm_04_08.h gsm_data.h \
|
||||
gsm_subscriber.h linuxlist.h msgb.h select.h tlv.h gsm_04_11.h \
|
||||
timer.h misdn.h chan_alloc.h telnet_interface.h paging.h \
|
||||
subchan_demux.h trau_frame.h e1_input.h trau_mux.h signal.h \
|
||||
gsm_utils.h ipaccess.h rs232.h openbscdefines.h rtp_proxy.h \
|
||||
bsc_rll.h mncc.h talloc.h transaction.h ussd.h gsm_04_80.h \
|
||||
silent_call.h mgcp.h meas_rep.h bitvec.h rest_octets.h \
|
||||
system_information.h handover.h bssap.h bsc_msc.h bsc_nat.h
|
||||
|
||||
@@ -24,8 +24,665 @@
|
||||
#define _NM_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <osmocore/tlv.h>
|
||||
#include <osmocore/protocol/gsm_12_21.h>
|
||||
|
||||
#include <openbsc/tlv.h>
|
||||
|
||||
/* PRIVATE */
|
||||
|
||||
/* generic header in front of every OML message according to TS 08.59 */
|
||||
struct abis_om_hdr {
|
||||
u_int8_t mdisc;
|
||||
u_int8_t placement;
|
||||
u_int8_t sequence;
|
||||
u_int8_t length;
|
||||
u_int8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define ABIS_OM_MDISC_FOM 0x80
|
||||
#define ABIS_OM_MDISC_MMI 0x40
|
||||
#define ABIS_OM_MDISC_TRAU 0x20
|
||||
#define ABIS_OM_MDISC_MANUF 0x10
|
||||
#define ABIS_OM_PLACEMENT_ONLY 0x80
|
||||
#define ABIS_OM_PLACEMENT_FIRST 0x40
|
||||
#define ABIS_OM_PLACEMENT_MIDDLE 0x20
|
||||
#define ABIS_OM_PLACEMENT_LAST 0x10
|
||||
|
||||
struct abis_om_obj_inst {
|
||||
u_int8_t bts_nr;
|
||||
u_int8_t trx_nr;
|
||||
u_int8_t ts_nr;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct abis_om_fom_hdr {
|
||||
u_int8_t msg_type;
|
||||
u_int8_t obj_class;
|
||||
struct abis_om_obj_inst obj_inst;
|
||||
u_int8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define ABIS_OM_FOM_HDR_SIZE (sizeof(struct abis_om_hdr) + sizeof(struct abis_om_fom_hdr))
|
||||
|
||||
/* Section 9.1: Message Types */
|
||||
enum abis_nm_msgtype {
|
||||
/* SW Download Management Messages */
|
||||
NM_MT_LOAD_INIT = 0x01,
|
||||
NM_MT_LOAD_INIT_ACK,
|
||||
NM_MT_LOAD_INIT_NACK,
|
||||
NM_MT_LOAD_SEG,
|
||||
NM_MT_LOAD_SEG_ACK,
|
||||
NM_MT_LOAD_ABORT,
|
||||
NM_MT_LOAD_END,
|
||||
NM_MT_LOAD_END_ACK,
|
||||
NM_MT_LOAD_END_NACK,
|
||||
NM_MT_SW_ACT_REQ, /* BTS->BSC */
|
||||
NM_MT_SW_ACT_REQ_ACK,
|
||||
NM_MT_SW_ACT_REQ_NACK,
|
||||
NM_MT_ACTIVATE_SW, /* BSC->BTS */
|
||||
NM_MT_ACTIVATE_SW_ACK,
|
||||
NM_MT_ACTIVATE_SW_NACK,
|
||||
NM_MT_SW_ACTIVATED_REP, /* 0x10 */
|
||||
/* A-bis Interface Management Messages */
|
||||
NM_MT_ESTABLISH_TEI = 0x21,
|
||||
NM_MT_ESTABLISH_TEI_ACK,
|
||||
NM_MT_ESTABLISH_TEI_NACK,
|
||||
NM_MT_CONN_TERR_SIGN,
|
||||
NM_MT_CONN_TERR_SIGN_ACK,
|
||||
NM_MT_CONN_TERR_SIGN_NACK,
|
||||
NM_MT_DISC_TERR_SIGN,
|
||||
NM_MT_DISC_TERR_SIGN_ACK,
|
||||
NM_MT_DISC_TERR_SIGN_NACK,
|
||||
NM_MT_CONN_TERR_TRAF,
|
||||
NM_MT_CONN_TERR_TRAF_ACK,
|
||||
NM_MT_CONN_TERR_TRAF_NACK,
|
||||
NM_MT_DISC_TERR_TRAF,
|
||||
NM_MT_DISC_TERR_TRAF_ACK,
|
||||
NM_MT_DISC_TERR_TRAF_NACK,
|
||||
/* Transmission Management Messages */
|
||||
NM_MT_CONN_MDROP_LINK = 0x31,
|
||||
NM_MT_CONN_MDROP_LINK_ACK,
|
||||
NM_MT_CONN_MDROP_LINK_NACK,
|
||||
NM_MT_DISC_MDROP_LINK,
|
||||
NM_MT_DISC_MDROP_LINK_ACK,
|
||||
NM_MT_DISC_MDROP_LINK_NACK,
|
||||
/* Air Interface Management Messages */
|
||||
NM_MT_SET_BTS_ATTR = 0x41,
|
||||
NM_MT_SET_BTS_ATTR_ACK,
|
||||
NM_MT_SET_BTS_ATTR_NACK,
|
||||
NM_MT_SET_RADIO_ATTR,
|
||||
NM_MT_SET_RADIO_ATTR_ACK,
|
||||
NM_MT_SET_RADIO_ATTR_NACK,
|
||||
NM_MT_SET_CHAN_ATTR,
|
||||
NM_MT_SET_CHAN_ATTR_ACK,
|
||||
NM_MT_SET_CHAN_ATTR_NACK,
|
||||
/* Test Management Messages */
|
||||
NM_MT_PERF_TEST = 0x51,
|
||||
NM_MT_PERF_TEST_ACK,
|
||||
NM_MT_PERF_TEST_NACK,
|
||||
NM_MT_TEST_REP,
|
||||
NM_MT_SEND_TEST_REP,
|
||||
NM_MT_SEND_TEST_REP_ACK,
|
||||
NM_MT_SEND_TEST_REP_NACK,
|
||||
NM_MT_STOP_TEST,
|
||||
NM_MT_STOP_TEST_ACK,
|
||||
NM_MT_STOP_TEST_NACK,
|
||||
/* State Management and Event Report Messages */
|
||||
NM_MT_STATECHG_EVENT_REP = 0x61,
|
||||
NM_MT_FAILURE_EVENT_REP,
|
||||
NM_MT_STOP_EVENT_REP,
|
||||
NM_MT_STOP_EVENT_REP_ACK,
|
||||
NM_MT_STOP_EVENT_REP_NACK,
|
||||
NM_MT_REST_EVENT_REP,
|
||||
NM_MT_REST_EVENT_REP_ACK,
|
||||
NM_MT_REST_EVENT_REP_NACK,
|
||||
NM_MT_CHG_ADM_STATE,
|
||||
NM_MT_CHG_ADM_STATE_ACK,
|
||||
NM_MT_CHG_ADM_STATE_NACK,
|
||||
NM_MT_CHG_ADM_STATE_REQ,
|
||||
NM_MT_CHG_ADM_STATE_REQ_ACK,
|
||||
NM_MT_CHG_ADM_STATE_REQ_NACK,
|
||||
NM_MT_REP_OUTST_ALARMS = 0x93,
|
||||
NM_MT_REP_OUTST_ALARMS_ACK,
|
||||
NM_MT_REP_OUTST_ALARMS_NACK,
|
||||
/* Equipment Management Messages */
|
||||
NM_MT_CHANGEOVER = 0x71,
|
||||
NM_MT_CHANGEOVER_ACK,
|
||||
NM_MT_CHANGEOVER_NACK,
|
||||
NM_MT_OPSTART,
|
||||
NM_MT_OPSTART_ACK,
|
||||
NM_MT_OPSTART_NACK,
|
||||
NM_MT_REINIT,
|
||||
NM_MT_REINIT_ACK,
|
||||
NM_MT_REINIT_NACK,
|
||||
NM_MT_SET_SITE_OUT, /* BS11: get alarm ?!? */
|
||||
NM_MT_SET_SITE_OUT_ACK,
|
||||
NM_MT_SET_SITE_OUT_NACK,
|
||||
NM_MT_CHG_HW_CONF = 0x90,
|
||||
NM_MT_CHG_HW_CONF_ACK,
|
||||
NM_MT_CHG_HW_CONF_NACK,
|
||||
/* Measurement Management Messages */
|
||||
NM_MT_MEAS_RES_REQ = 0x8a,
|
||||
NM_MT_MEAS_RES_RESP,
|
||||
NM_MT_STOP_MEAS,
|
||||
NM_MT_START_MEAS,
|
||||
/* Other Messages */
|
||||
NM_MT_GET_ATTR = 0x81,
|
||||
NM_MT_GET_ATTR_RESP,
|
||||
NM_MT_GET_ATTR_NACK,
|
||||
NM_MT_SET_ALARM_THRES,
|
||||
NM_MT_SET_ALARM_THRES_ACK,
|
||||
NM_MT_SET_ALARM_THRES_NACK,
|
||||
};
|
||||
|
||||
enum abis_nm_msgtype_bs11 {
|
||||
NM_MT_BS11_RESET_RESOURCE = 0x74,
|
||||
|
||||
NM_MT_BS11_BEGIN_DB_TX = 0xa3,
|
||||
NM_MT_BS11_BEGIN_DB_TX_ACK,
|
||||
NM_MT_BS11_BEGIN_DB_TX_NACK,
|
||||
NM_MT_BS11_END_DB_TX = 0xa6,
|
||||
NM_MT_BS11_END_DB_TX_ACK,
|
||||
NM_MT_BS11_END_DB_TX_NACK,
|
||||
NM_MT_BS11_CREATE_OBJ = 0xa9,
|
||||
NM_MT_BS11_CREATE_OBJ_ACK,
|
||||
NM_MT_BS11_CREATE_OBJ_NACK,
|
||||
NM_MT_BS11_DELETE_OBJ = 0xac,
|
||||
NM_MT_BS11_DELETE_OBJ_ACK,
|
||||
NM_MT_BS11_DELETE_OBJ_NACK,
|
||||
|
||||
NM_MT_BS11_SET_ATTR = 0xd0,
|
||||
NM_MT_BS11_SET_ATTR_ACK,
|
||||
NM_MT_BS11_SET_ATTR_NACK,
|
||||
NM_MT_BS11_LMT_SESSION = 0xdc,
|
||||
|
||||
NM_MT_BS11_GET_STATE = 0xe3,
|
||||
NM_MT_BS11_GET_STATE_ACK,
|
||||
NM_MT_BS11_LMT_LOGON = 0xe5,
|
||||
NM_MT_BS11_LMT_LOGON_ACK,
|
||||
NM_MT_BS11_RESTART = 0xe7,
|
||||
NM_MT_BS11_RESTART_ACK,
|
||||
NM_MT_BS11_DISCONNECT = 0xe9,
|
||||
NM_MT_BS11_DISCONNECT_ACK,
|
||||
NM_MT_BS11_LMT_LOGOFF = 0xec,
|
||||
NM_MT_BS11_LMT_LOGOFF_ACK,
|
||||
NM_MT_BS11_RECONNECT = 0xf1,
|
||||
NM_MT_BS11_RECONNECT_ACK,
|
||||
};
|
||||
|
||||
enum abis_nm_msgtype_ipacc {
|
||||
NM_MT_IPACC_RESTART = 0x87,
|
||||
NM_MT_IPACC_RESTART_ACK,
|
||||
NM_MT_IPACC_RSL_CONNECT = 0xe0,
|
||||
NM_MT_IPACC_RSL_CONNECT_ACK,
|
||||
NM_MT_IPACC_RSL_CONNECT_NACK,
|
||||
NM_MT_IPACC_RSL_DISCONNECT = 0xe3,
|
||||
NM_MT_IPACC_RSL_DISCONNECT_ACK,
|
||||
NM_MT_IPACC_RSL_DISCONNECT_NACK,
|
||||
NM_MT_IPACC_CONN_TRAF = 0xe6,
|
||||
NM_MT_IPACC_CONN_TRAF_ACK,
|
||||
NM_MT_IPACC_CONN_TRAF_NACK,
|
||||
NM_MT_IPACC_DEF_BOOT_SW = 0xec,
|
||||
NM_MT_IPACC_DEF_BOOT_SW_ACK,
|
||||
MN_MT_IPACC_DEF_BOOT_SW_NACK,
|
||||
NM_MT_IPACC_SET_NVATTR = 0xef,
|
||||
NM_MT_IPACC_SET_NVATTR_ACK,
|
||||
NM_MT_IPACC_SET_NVATTR_NACK,
|
||||
NM_MT_IPACC_GET_NVATTR = 0xf2,
|
||||
NM_MT_IPACC_GET_NVATTR_ACK,
|
||||
NM_MT_IPACC_GET_NVATTR_NACK,
|
||||
NM_MT_IPACC_SET_ATTR = 0xf5,
|
||||
NM_MT_IPACC_SET_ATTR_ACK,
|
||||
NM_MT_IPACC_SET_ATTR_NACK,
|
||||
};
|
||||
|
||||
enum abis_nm_bs11_cell_alloc {
|
||||
NM_BS11_CANR_GSM = 0x00,
|
||||
NM_BS11_CANR_DCS1800 = 0x01,
|
||||
};
|
||||
|
||||
/* Section 9.2: Object Class */
|
||||
enum abis_nm_obj_class {
|
||||
NM_OC_SITE_MANAGER = 0x00,
|
||||
NM_OC_BTS,
|
||||
NM_OC_RADIO_CARRIER,
|
||||
NM_OC_CHANNEL,
|
||||
NM_OC_BASEB_TRANSC,
|
||||
/* RFU: 05-FE */
|
||||
|
||||
NM_OC_IPAC_E1_TRUNK = 0x0e,
|
||||
NM_OC_IPAC_E1_PORT = 0x0f,
|
||||
NM_OC_IPAC_E1_CHAN = 0x10,
|
||||
NM_OC_IPAC_CLK_MODULE = 0x22,
|
||||
|
||||
NM_OC_BS11_ADJC = 0xa0,
|
||||
NM_OC_BS11_HANDOVER = 0xa1,
|
||||
NM_OC_BS11_PWR_CTRL = 0xa2,
|
||||
NM_OC_BS11_BTSE = 0xa3, /* LMT? */
|
||||
NM_OC_BS11_RACK = 0xa4,
|
||||
NM_OC_BS11 = 0xa5, /* 01: ALCO */
|
||||
NM_OC_BS11_TEST = 0xa6,
|
||||
NM_OC_BS11_ENVABTSE = 0xa8,
|
||||
NM_OC_BS11_BPORT = 0xa9,
|
||||
|
||||
NM_OC_GPRS_NSE = 0xf0,
|
||||
NM_OC_GPRS_CELL = 0xf1,
|
||||
NM_OC_GPRS_NSVC = 0xf2,
|
||||
|
||||
NM_OC_NULL = 0xff,
|
||||
};
|
||||
|
||||
/* Section 9.4: Attributes */
|
||||
enum abis_nm_attr {
|
||||
NM_ATT_ABIS_CHANNEL = 0x01,
|
||||
NM_ATT_ADD_INFO,
|
||||
NM_ATT_ADD_TEXT,
|
||||
NM_ATT_ADM_STATE,
|
||||
NM_ATT_ARFCN_LIST,
|
||||
NM_ATT_AUTON_REPORT,
|
||||
NM_ATT_AVAIL_STATUS,
|
||||
NM_ATT_BCCH_ARFCN,
|
||||
NM_ATT_BSIC,
|
||||
NM_ATT_BTS_AIR_TIMER,
|
||||
NM_ATT_CCCH_L_I_P,
|
||||
NM_ATT_CCCH_L_T,
|
||||
NM_ATT_CHAN_COMB,
|
||||
NM_ATT_CONN_FAIL_CRIT,
|
||||
NM_ATT_DEST,
|
||||
/* res */
|
||||
NM_ATT_EVENT_TYPE = 0x11, /* BS11: file data ?!? */
|
||||
NM_ATT_FILE_ID,
|
||||
NM_ATT_FILE_VERSION,
|
||||
NM_ATT_GSM_TIME,
|
||||
NM_ATT_HSN,
|
||||
NM_ATT_HW_CONFIG,
|
||||
NM_ATT_HW_DESC,
|
||||
NM_ATT_INTAVE_PARAM,
|
||||
NM_ATT_INTERF_BOUND,
|
||||
NM_ATT_LIST_REQ_ATTR,
|
||||
NM_ATT_MAIO,
|
||||
NM_ATT_MANUF_STATE,
|
||||
NM_ATT_MANUF_THRESH,
|
||||
NM_ATT_MANUF_ID,
|
||||
NM_ATT_MAX_TA,
|
||||
NM_ATT_MDROP_LINK, /* 0x20 */
|
||||
NM_ATT_MDROP_NEXT,
|
||||
NM_ATT_NACK_CAUSES,
|
||||
NM_ATT_NY1,
|
||||
NM_ATT_OPER_STATE,
|
||||
NM_ATT_OVERL_PERIOD,
|
||||
NM_ATT_PHYS_CONF,
|
||||
NM_ATT_POWER_CLASS,
|
||||
NM_ATT_POWER_THRESH,
|
||||
NM_ATT_PROB_CAUSE,
|
||||
NM_ATT_RACH_B_THRESH,
|
||||
NM_ATT_LDAVG_SLOTS,
|
||||
NM_ATT_RAD_SUBC,
|
||||
NM_ATT_RF_MAXPOWR_R,
|
||||
NM_ATT_SITE_INPUTS,
|
||||
NM_ATT_SITE_OUTPUTS,
|
||||
NM_ATT_SOURCE, /* 0x30 */
|
||||
NM_ATT_SPEC_PROB,
|
||||
NM_ATT_START_TIME,
|
||||
NM_ATT_T200,
|
||||
NM_ATT_TEI,
|
||||
NM_ATT_TEST_DUR,
|
||||
NM_ATT_TEST_NO,
|
||||
NM_ATT_TEST_REPORT,
|
||||
NM_ATT_VSWR_THRESH,
|
||||
NM_ATT_WINDOW_SIZE,
|
||||
/* Res */
|
||||
NM_ATT_BS11_RSSI_OFFS = 0x3d,
|
||||
NM_ATT_BS11_TXPWR = 0x3e,
|
||||
NM_ATT_BS11_DIVERSITY = 0x3f,
|
||||
/* Res */
|
||||
NM_ATT_TSC = 0x40,
|
||||
NM_ATT_SW_CONFIG,
|
||||
NM_ATT_SW_DESCR,
|
||||
NM_ATT_SEVERITY,
|
||||
NM_ATT_GET_ARI,
|
||||
NM_ATT_HW_CONF_CHG,
|
||||
NM_ATT_OUTST_ALARM,
|
||||
NM_ATT_FILE_DATA,
|
||||
NM_ATT_MEAS_RES,
|
||||
NM_ATT_MEAS_TYPE,
|
||||
|
||||
NM_ATT_BS11_ESN_FW_CODE_NO = 0x4c,
|
||||
NM_ATT_BS11_ESN_HW_CODE_NO = 0x4f,
|
||||
|
||||
NM_ATT_BS11_ESN_PCB_SERIAL = 0x55,
|
||||
NM_ATT_BS11_EXCESSIVE_DISTANCE = 0x58,
|
||||
|
||||
NM_ATT_BS11_ALL_TEST_CATG = 0x60,
|
||||
NM_ATT_BS11_BTSLS_HOPPING,
|
||||
NM_ATT_BS11_CELL_ALLOC_NR,
|
||||
NM_ATT_BS11_CELL_GLOBAL_ID,
|
||||
NM_ATT_BS11_ENA_INTERF_CLASS = 0x66,
|
||||
NM_ATT_BS11_ENA_INT_INTEC_HANDO = 0x67,
|
||||
NM_ATT_BS11_ENA_INT_INTRC_HANDO = 0x68,
|
||||
NM_ATT_BS11_ENA_MS_PWR_CTRL = 0x69,
|
||||
NM_ATT_BS11_ENA_PWR_BDGT_HO = 0x6a,
|
||||
NM_ATT_BS11_ENA_PWR_CTRL_RLFW = 0x6b,
|
||||
NM_ATT_BS11_ENA_RXLEV_HO = 0x6c,
|
||||
NM_ATT_BS11_ENA_RXQUAL_HO = 0x6d,
|
||||
NM_ATT_BS11_FACCH_QUAL = 0x6e,
|
||||
|
||||
NM_ATT_IPACC_DST_IP = 0x80,
|
||||
NM_ATT_IPACC_DST_IP_PORT = 0x81,
|
||||
NM_ATT_IPACC_SSRC = 0x82,
|
||||
NM_ATT_IPACC_RTP_PAYLD_TYPE = 0x83,
|
||||
NM_ATT_IPACC_BASEB_ID = 0x84,
|
||||
NM_ATT_IPACC_STREAM_ID = 0x85,
|
||||
NM_ATT_IPACC_NV_FLAGS = 0x86,
|
||||
NM_ATT_IPACC_FREQ_CTRL = 0x87,
|
||||
NM_ATT_IPACC_PRIM_OML_CFG = 0x88,
|
||||
NM_ATT_IPACC_SEC_OML_CFG = 0x89,
|
||||
NM_ATT_IPACC_IP_IF_CFG = 0x8a, /* IP interface */
|
||||
NM_ATT_IPACC_IP_GW_CFG = 0x8b, /* IP gateway */
|
||||
NM_ATT_IPACC_IN_SERV_TIME = 0x8c,
|
||||
NM_ATT_IPACC_TRX_BTS_ASS = 0x8d,
|
||||
NM_ATT_IPACC_LOCATION = 0x8e, /* string describing location */
|
||||
NM_ATT_IPACC_PAGING_CFG = 0x8f,
|
||||
NM_ATT_IPACC_FILE_DATA = 0x90,
|
||||
NM_ATT_IPACC_UNIT_ID = 0x91, /* Site/BTS/TRX */
|
||||
NM_ATT_IPACC_PARENT_UNIT_ID = 0x92,
|
||||
NM_ATT_IPACC_UNIT_NAME = 0x93, /* default: nbts-<mac-as-string> */
|
||||
NM_ATT_IPACC_SNMP_CFG = 0x94,
|
||||
NM_ATT_IPACC_PRIM_OML_CFG_LIST = 0x95,
|
||||
NM_ATT_IPACC_PRIM_OML_FB_TOUT = 0x96,
|
||||
NM_ATT_IPACC_CUR_SW_CFG = 0x97,
|
||||
NM_ATT_IPACC_TIMING_BUS = 0x98,
|
||||
NM_ATT_IPACC_CGI = 0x99,
|
||||
NM_ATT_IPACC_RAC = 0x9a,
|
||||
NM_ATT_IPACC_OBJ_VERSION = 0x9b,
|
||||
NM_ATT_IPACC_GPRS_PAGING_CFG = 0x9c,
|
||||
NM_ATT_IPACC_NSEI = 0x9d,
|
||||
NM_ATT_IPACC_BVCI = 0x9e,
|
||||
NM_ATT_IPACC_NSVCI = 0x9f,
|
||||
NM_ATT_IPACC_NS_CFG = 0xa0,
|
||||
NM_ATT_IPACC_BSSGP_CFG = 0xa1,
|
||||
NM_ATT_IPACC_NS_LINK_CFG = 0xa2,
|
||||
NM_ATT_IPACC_RLC_CFG = 0xa3,
|
||||
NM_ATT_IPACC_ALM_THRESH_LIST = 0xa4,
|
||||
NM_ATT_IPACC_MONIT_VAL_LIST = 0xa5,
|
||||
NM_ATT_IPACC_TIB_CONTROL = 0xa6,
|
||||
NM_ATT_IPACC_SUPP_FEATURES = 0xa7,
|
||||
NM_ATT_IPACC_CODING_SCHEMES = 0xa8,
|
||||
NM_ATT_IPACC_RLC_CFG_2 = 0xa9,
|
||||
NM_ATT_IPACC_HEARTB_TOUT = 0xaa,
|
||||
NM_ATT_IPACC_UPTIME = 0xab,
|
||||
NM_ATT_IPACC_RLC_CFG_3 = 0xac,
|
||||
NM_ATT_IPACC_SSL_CFG = 0xad,
|
||||
NM_ATT_IPACC_SEC_POSSIBLE = 0xae,
|
||||
NM_ATT_IPACC_IML_SSL_STATE = 0xaf,
|
||||
NM_ATT_IPACC_REVOC_DATE = 0xb0,
|
||||
|
||||
|
||||
NM_ATT_BS11_RF_RES_IND_PER = 0x8f,
|
||||
|
||||
NM_ATT_BS11_RX_LEV_MIN_CELL = 0x90,
|
||||
NM_ATT_BS11_ABIS_EXT_TIME = 0x91,
|
||||
NM_ATT_BS11_TIMER_HO_REQUEST = 0x92,
|
||||
NM_ATT_BS11_TIMER_NCELL = 0x93,
|
||||
NM_ATT_BS11_TSYNC = 0x94,
|
||||
NM_ATT_BS11_TTRAU = 0x95,
|
||||
NM_ATT_BS11_EMRG_CFG_MEMBER = 0x9b,
|
||||
NM_ATT_BS11_TRX_AREA = 0x9f,
|
||||
|
||||
NM_ATT_BS11_BCCH_RECONF = 0xd7,
|
||||
NM_ATT_BS11_BIT_ERR_THESH = 0xa0,
|
||||
NM_ATT_BS11_BOOT_SW_VERS = 0xa1,
|
||||
NM_ATT_BS11_CCLK_ACCURACY = 0xa3,
|
||||
NM_ATT_BS11_CCLK_TYPE = 0xa4,
|
||||
NM_ATT_BS11_INP_IMPEDANCE = 0xaa,
|
||||
NM_ATT_BS11_L1_PROT_TYPE = 0xab,
|
||||
NM_ATT_BS11_LINE_CFG = 0xac,
|
||||
NM_ATT_BS11_LI_PORT_1 = 0xad,
|
||||
NM_ATT_BS11_LI_PORT_2 = 0xae,
|
||||
|
||||
NM_ATT_BS11_L1_REM_ALM_TYPE = 0xb0,
|
||||
NM_ATT_BS11_SW_LOAD_INTENDED = 0xbb,
|
||||
NM_ATT_BS11_SW_LOAD_SAFETY = 0xbc,
|
||||
NM_ATT_BS11_SW_LOAD_STORED = 0xbd,
|
||||
|
||||
NM_ATT_BS11_VENDOR_NAME = 0xc1,
|
||||
NM_ATT_BS11_HOPPING_MODE = 0xc5,
|
||||
NM_ATT_BS11_LMT_LOGON_SESSION = 0xc6,
|
||||
NM_ATT_BS11_LMT_LOGIN_TIME = 0xc7,
|
||||
NM_ATT_BS11_LMT_USER_ACC_LEV = 0xc8,
|
||||
NM_ATT_BS11_LMT_USER_NAME = 0xc9,
|
||||
|
||||
NM_ATT_BS11_L1_CONTROL_TS = 0xd8,
|
||||
NM_ATT_BS11_RADIO_MEAS_GRAN = 0xdc, /* in SACCH multiframes */
|
||||
NM_ATT_BS11_RADIO_MEAS_REP = 0xdd,
|
||||
|
||||
NM_ATT_BS11_SH_LAPD_INT_TIMER = 0xe8,
|
||||
|
||||
NM_ATT_BS11_BTS_STATE = 0xf0,
|
||||
NM_ATT_BS11_E1_STATE = 0xf1,
|
||||
NM_ATT_BS11_PLL = 0xf2,
|
||||
NM_ATT_BS11_RX_OFFSET = 0xf3,
|
||||
NM_ATT_BS11_ANT_TYPE = 0xf4,
|
||||
NM_ATT_BS11_PLL_MODE = 0xfc,
|
||||
NM_ATT_BS11_PASSWORD = 0xfd,
|
||||
};
|
||||
#define NM_ATT_BS11_FILE_DATA NM_ATT_EVENT_TYPE
|
||||
|
||||
/* Section 9.4.4: Administrative State */
|
||||
enum abis_nm_adm_state {
|
||||
NM_STATE_LOCKED = 0x01,
|
||||
NM_STATE_UNLOCKED = 0x02,
|
||||
NM_STATE_SHUTDOWN = 0x03,
|
||||
NM_STATE_NULL = 0xff,
|
||||
};
|
||||
|
||||
/* Section 9.4.7: Administrative State */
|
||||
enum abis_nm_avail_state {
|
||||
NM_AVSTATE_IN_TEST = 1,
|
||||
NM_AVSTATE_POWER_OFF = 2,
|
||||
NM_AVSTATE_OFF_LINE = 3,
|
||||
NM_AVSTATE_DEPENDENCY = 5,
|
||||
NM_AVSTATE_DEGRADED = 6,
|
||||
NM_AVSTATE_NOT_INSTALLED= 7,
|
||||
NM_AVSTATE_OK = 0xff,
|
||||
};
|
||||
|
||||
/* Section 9.4.13: Channel Combination */
|
||||
enum abis_nm_chan_comb {
|
||||
NM_CHANC_TCHFull = 0x00, /* TCH/F + TCH/H + SACCH/TF */
|
||||
NM_CHANC_TCHHalf = 0x01, /* TCH/H(0,1) + FACCH/H(0,1) +
|
||||
SACCH/TH(0,1) */
|
||||
NM_CHANC_TCHHalf2 = 0x02, /* TCH/H(0) + FACCH/H(0) + SACCH/TH(0) +
|
||||
TCH/H(1) */
|
||||
NM_CHANC_SDCCH = 0x03, /* SDCCH/8 + SACCH/8 */
|
||||
NM_CHANC_mainBCCH = 0x04, /* FCCH + SCH + BCCH + CCCH */
|
||||
NM_CHANC_BCCHComb = 0x05, /* FCCH + SCH + BCCH + CCCH + SDCCH/4 +
|
||||
SACCH/C4 */
|
||||
NM_CHANC_BCCH = 0x06, /* BCCH + CCCH */
|
||||
NM_CHANC_BCCH_CBCH = 0x07, /* CHANC_BCCHComb + CBCH */
|
||||
NM_CHANC_SDCCH_CBCH = 0x08, /* CHANC_SDCCH8 + CBCH */
|
||||
/* ip.access */
|
||||
NM_CHANC_IPAC_bPDCH = 0x0b, /* PBCCH + PCCCH + PDTCH/F + PACCH/F +
|
||||
PTCCH/F */
|
||||
NM_CHANC_IPAC_cPDCH = 0x0c, /* PBCCH + PDTCH/F + PACCH/F + PTCCH/F */
|
||||
NM_CHANC_IPAC_PDCH = 0x0d, /* PDTCH/F + PACCH/F + PTCCH/F */
|
||||
NM_CHANC_IPAC_TCHFull_PDCH = 0x80,
|
||||
NM_CHANC_IPAC_TCHFull_TCHHalf = 0x81,
|
||||
};
|
||||
|
||||
/* Section 9.4.16: Event Type */
|
||||
enum abis_nm_event_type {
|
||||
NM_EVT_COMM_FAIL = 0x00,
|
||||
NM_EVT_QOS_FAIL = 0x01,
|
||||
NM_EVT_PROC_FAIL = 0x02,
|
||||
NM_EVT_EQUIP_FAIL = 0x03,
|
||||
NM_EVT_ENV_FAIL = 0x04,
|
||||
};
|
||||
|
||||
/* Section: 9.4.63: Perceived Severity */
|
||||
enum abis_nm_severity {
|
||||
NM_SEVER_CEASED = 0x00,
|
||||
NM_SEVER_CRITICAL = 0x01,
|
||||
NM_SEVER_MAJOR = 0x02,
|
||||
NM_SEVER_MINOR = 0x03,
|
||||
NM_SEVER_WARNING = 0x04,
|
||||
NM_SEVER_INDETERMINATE = 0x05,
|
||||
};
|
||||
|
||||
/* Section 9.4.43: Probable Cause Type */
|
||||
enum abis_nm_pcause_type {
|
||||
NM_PCAUSE_T_X721 = 0x01,
|
||||
NM_PCAUSE_T_GSM = 0x02,
|
||||
NM_PCAUSE_T_MANUF = 0x03,
|
||||
};
|
||||
|
||||
/* Section 9.4.36: NACK Causes */
|
||||
enum abis_nm_nack_cause {
|
||||
/* General Nack Causes */
|
||||
NM_NACK_INCORR_STRUCT = 0x01,
|
||||
NM_NACK_MSGTYPE_INVAL = 0x02,
|
||||
NM_NACK_OBJCLASS_INVAL = 0x05,
|
||||
NM_NACK_OBJCLASS_NOTSUPP = 0x06,
|
||||
NM_NACK_BTSNR_UNKN = 0x07,
|
||||
NM_NACK_TRXNR_UNKN = 0x08,
|
||||
NM_NACK_OBJINST_UNKN = 0x09,
|
||||
NM_NACK_ATTRID_INVAL = 0x0c,
|
||||
NM_NACK_ATTRID_NOTSUPP = 0x0d,
|
||||
NM_NACK_PARAM_RANGE = 0x0e,
|
||||
NM_NACK_ATTRLIST_INCONSISTENT = 0x0f,
|
||||
NM_NACK_SPEC_IMPL_NOTSUPP = 0x10,
|
||||
NM_NACK_CANT_PERFORM = 0x11,
|
||||
/* Specific Nack Causes */
|
||||
NM_NACK_RES_NOTIMPL = 0x19,
|
||||
NM_NACK_RES_NOTAVAIL = 0x1a,
|
||||
NM_NACK_FREQ_NOTAVAIL = 0x1b,
|
||||
NM_NACK_TEST_NOTSUPP = 0x1c,
|
||||
NM_NACK_CAPACITY_RESTR = 0x1d,
|
||||
NM_NACK_PHYSCFG_NOTPERFORM = 0x1e,
|
||||
NM_NACK_TEST_NOTINIT = 0x1f,
|
||||
NM_NACK_PHYSCFG_NOTRESTORE = 0x20,
|
||||
NM_NACK_TEST_NOSUCH = 0x21,
|
||||
NM_NACK_TEST_NOSTOP = 0x22,
|
||||
NM_NACK_MSGINCONSIST_PHYSCFG = 0x23,
|
||||
NM_NACK_FILE_INCOMPLETE = 0x25,
|
||||
NM_NACK_FILE_NOTAVAIL = 0x26,
|
||||
NM_NACK_FILE_NOTACTIVATE = 0x27,
|
||||
NM_NACK_REQ_NOT_GRANT = 0x28,
|
||||
NM_NACK_WAIT = 0x29,
|
||||
NM_NACK_NOTH_REPORT_EXIST = 0x2a,
|
||||
NM_NACK_MEAS_NOTSUPP = 0x2b,
|
||||
NM_NACK_MEAS_NOTSTART = 0x2c,
|
||||
};
|
||||
|
||||
/* Section 9.4.1 */
|
||||
struct abis_nm_channel {
|
||||
u_int8_t attrib;
|
||||
u_int8_t bts_port;
|
||||
u_int8_t timeslot;
|
||||
u_int8_t subslot;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Siemens BS-11 specific objects in the SienemsHW (0xA5) object class */
|
||||
enum abis_bs11_objtype {
|
||||
BS11_OBJ_ALCO = 0x01,
|
||||
BS11_OBJ_BBSIG = 0x02, /* obj_class: 0,1 */
|
||||
BS11_OBJ_TRX1 = 0x03, /* only DEACTIVATE TRX1 */
|
||||
BS11_OBJ_CCLK = 0x04,
|
||||
BS11_OBJ_GPSU = 0x06,
|
||||
BS11_OBJ_LI = 0x07,
|
||||
BS11_OBJ_PA = 0x09, /* obj_class: 0, 1*/
|
||||
};
|
||||
|
||||
enum abis_bs11_trx_power {
|
||||
BS11_TRX_POWER_GSM_2W = 0x06,
|
||||
BS11_TRX_POWER_GSM_250mW= 0x07,
|
||||
BS11_TRX_POWER_GSM_80mW = 0x08,
|
||||
BS11_TRX_POWER_GSM_30mW = 0x09,
|
||||
BS11_TRX_POWER_DCS_3W = 0x0a,
|
||||
BS11_TRX_POWER_DCS_1W6 = 0x0b,
|
||||
BS11_TRX_POWER_DCS_500mW= 0x0c,
|
||||
BS11_TRX_POWER_DCS_160mW= 0x0d,
|
||||
};
|
||||
|
||||
enum abis_bs11_li_pll_mode {
|
||||
BS11_LI_PLL_LOCKED = 2,
|
||||
BS11_LI_PLL_STANDALONE = 3,
|
||||
};
|
||||
|
||||
enum abis_bs11_line_cfg {
|
||||
BS11_LINE_CFG_STAR = 0x00,
|
||||
BS11_LINE_CFG_MULTIDROP = 0x01,
|
||||
BS11_LINE_CFG_LOOP = 0x02,
|
||||
};
|
||||
|
||||
enum abis_bs11_phase {
|
||||
BS11_STATE_SOFTWARE_RQD = 0x01,
|
||||
BS11_STATE_LOAD_SMU_INTENDED = 0x11,
|
||||
BS11_STATE_LOAD_SMU_SAFETY = 0x21,
|
||||
BS11_STATE_LOAD_FAILED = 0x31,
|
||||
BS11_STATE_LOAD_DIAGNOSTIC = 0x41,
|
||||
BS11_STATE_WARM_UP = 0x51,
|
||||
BS11_STATE_WARM_UP_2 = 0x52,
|
||||
BS11_STATE_WAIT_MIN_CFG = 0x62,
|
||||
BS11_STATE_MAINTENANCE = 0x72,
|
||||
BS11_STATE_LOAD_MBCCU = 0x92,
|
||||
BS11_STATE_WAIT_MIN_CFG_2 = 0xA2,
|
||||
BS11_STATE_NORMAL = 0x03,
|
||||
BS11_STATE_ABIS_LOAD = 0x13,
|
||||
};
|
||||
|
||||
enum abis_nm_ipacc_test_no {
|
||||
NM_IPACC_TESTNO_RLOOP_ANT = 0x01,
|
||||
NM_IPACC_TESTNO_RLOOP_XCVR = 0x02,
|
||||
NM_IPACC_TESTNO_FUNC_OBJ = 0x03,
|
||||
NM_IPACC_TESTNO_CHAN_USAGE = 0x40,
|
||||
NM_IPACC_TESTNO_BCCH_CHAN_USAGE = 0x41,
|
||||
NM_IPACC_TESTNO_FREQ_SYNC = 0x42,
|
||||
NM_IPACC_TESTNO_BCCH_INFO = 0x43,
|
||||
NM_IPACC_TESTNO_TX_BEACON = 0x44,
|
||||
NM_IPACC_TESTNO_SYSINFO_MONITOR = 0x45,
|
||||
NM_IPACC_TESTNO_BCCCH_MONITOR = 0x46,
|
||||
};
|
||||
|
||||
/* first byte after length inside NM_ATT_TEST_REPORT */
|
||||
enum abis_nm_ipacc_test_res {
|
||||
NM_IPACC_TESTRES_SUCCESS = 0,
|
||||
NM_IPACC_TESTRES_TIMEOUT = 1,
|
||||
NM_IPACC_TESTRES_NO_CHANS = 2,
|
||||
NM_IPACC_TESTRES_PARTIAL = 3,
|
||||
NM_IPACC_TESTRES_STOPPED = 4,
|
||||
};
|
||||
|
||||
/* internal IE inside NM_ATT_TEST_REPORT */
|
||||
enum abis_nm_ipacc_testres_ie {
|
||||
NM_IPACC_TR_IE_FREQ_ERR_LIST = 3,
|
||||
NM_IPACC_TR_IE_CHAN_USAGE = 4,
|
||||
NM_IPACC_TR_IE_BCCH_INFO = 6,
|
||||
NM_IPACC_TR_IE_RESULT_DETAILS = 8,
|
||||
NM_IPACC_TR_IE_FREQ_ERR = 18,
|
||||
};
|
||||
|
||||
enum ipac_eie {
|
||||
NM_IPAC_EIE_ARFCN_WHITE = 0x01,
|
||||
NM_IPAC_EIE_ARFCH_BLACK = 0x02,
|
||||
NM_IPAC_EIE_FREQ_ERR_LIST = 0x03,
|
||||
NM_IPAC_EIE_CHAN_USE_LIST = 0x04,
|
||||
NM_IPAC_EIE_BCCH_INFO_TYPE = 0x05,
|
||||
NM_IPAC_EIE_BCCH_INFO = 0x06,
|
||||
/* FIXME */
|
||||
};
|
||||
|
||||
enum ipac_bcch_info_type {
|
||||
IPAC_BINF_RXLEV = (1 << 8),
|
||||
IPAC_BINF_RXQUAL = (1 << 9),
|
||||
IPAC_BINF_FREQ_ERR_QUAL = (1 << 10),
|
||||
IPAC_BINF_FRAME_OFFSET = (1 << 11),
|
||||
IPAC_BINF_FRAME_NR_OFFSET = (1 << 12),
|
||||
IPAC_BINF_BSIC = (1 << 13),
|
||||
IPAC_BINF_CGI = (1 << 14),
|
||||
IPAC_BINF_NEIGH_BA_SI2 = (1 << 15),
|
||||
IPAC_BINF_NEIGH_BA_SI2bis = (1 << 0),
|
||||
IPAC_BINF_NEIGH_BA_SI2ter = (1 << 1),
|
||||
IPAC_BINF_CELL_ALLOC = (1 << 2),
|
||||
};
|
||||
|
||||
struct cell_global_id {
|
||||
u_int16_t mcc;
|
||||
@@ -55,8 +712,6 @@ struct ipac_bcch_info {
|
||||
u_int8_t ca_list_si1[16];
|
||||
};
|
||||
|
||||
extern const struct tlv_definition nm_att_tlvdef;
|
||||
|
||||
/* PUBLIC */
|
||||
|
||||
struct msgb;
|
||||
@@ -71,7 +726,7 @@ struct abis_nm_cfg {
|
||||
|
||||
extern int abis_nm_rcvmsg(struct msgb *msg);
|
||||
|
||||
int abis_nm_tlv_parse(struct tlv_parsed *tp, struct gsm_bts *bts, const u_int8_t *buf, int len);
|
||||
int abis_nm_tlv_parse(struct tlv_parsed *tp, const u_int8_t *buf, int len);
|
||||
int abis_nm_rx(struct msgb *msg);
|
||||
int abis_nm_opstart(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i0, u_int8_t i1, u_int8_t i2);
|
||||
int abis_nm_chg_adm_state(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i0,
|
||||
@@ -125,13 +780,10 @@ int abis_nm_bs11_get_oml_tei_ts(struct gsm_bts *bts);
|
||||
int abis_nm_bs11_get_serno(struct gsm_bts *bts);
|
||||
int abis_nm_bs11_set_trx_power(struct gsm_bts_trx *trx, u_int8_t level);
|
||||
int abis_nm_bs11_get_trx_power(struct gsm_bts_trx *trx);
|
||||
int abis_nm_bs11_logon(struct gsm_bts *bts, u_int8_t level, const char *name, int on);
|
||||
int abis_nm_bs11_factory_logon(struct gsm_bts *bts, int on);
|
||||
int abis_nm_bs11_infield_logon(struct gsm_bts *bts, int on);
|
||||
int abis_nm_bs11_set_trx1_pw(struct gsm_bts *bts, const char *password);
|
||||
int abis_nm_bs11_set_pll_locked(struct gsm_bts *bts, int locked);
|
||||
int abis_nm_bs11_get_pll_mode(struct gsm_bts *bts);
|
||||
int abis_nm_bs11_set_pll(struct gsm_bts *bts, int value);
|
||||
int abis_nm_bs11_get_cclk(struct gsm_bts *bts);
|
||||
int abis_nm_bs11_get_state(struct gsm_bts *bts);
|
||||
int abis_nm_bs11_load_swl(struct gsm_bts *bts, const char *fname,
|
||||
@@ -146,7 +798,7 @@ int abis_nm_ipaccess_msg(struct gsm_bts *bts, u_int8_t msg_type,
|
||||
u_int8_t obj_class, u_int8_t bts_nr,
|
||||
u_int8_t trx_nr, u_int8_t ts_nr,
|
||||
u_int8_t *attr, int attr_len);
|
||||
int abis_nm_ipaccess_set_nvattr(struct gsm_bts_trx *trx, u_int8_t *attr,
|
||||
int abis_nm_ipaccess_set_nvattr(struct gsm_bts *bts, u_int8_t *attr,
|
||||
int attr_len);
|
||||
int abis_nm_ipaccess_restart(struct gsm_bts *bts);
|
||||
int abis_nm_ipaccess_set_attr(struct gsm_bts *bts, u_int8_t obj_class,
|
||||
@@ -154,7 +806,6 @@ int abis_nm_ipaccess_set_attr(struct gsm_bts *bts, u_int8_t obj_class,
|
||||
u_int8_t *attr, u_int8_t attr_len);
|
||||
int abis_nm_ipaccess_rsl_connect(struct gsm_bts_trx *trx,
|
||||
u_int32_t ip, u_int16_t port, u_int8_t stream);
|
||||
void abis_nm_ipaccess_cgi(u_int8_t *buf, struct gsm_bts *bts);
|
||||
int ipac_parse_bcch_info(struct ipac_bcch_info *binf, u_int8_t *buf);
|
||||
const char *ipacc_testres_name(u_int8_t res);
|
||||
|
||||
@@ -168,5 +819,4 @@ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
|
||||
|
||||
const char *nm_opstate_name(u_int8_t os);
|
||||
const char *nm_avail_name(u_int8_t avail);
|
||||
int nm_is_running(struct gsm_nm_state *s);
|
||||
#endif /* _NM_H */
|
||||
|
||||
@@ -23,9 +23,468 @@
|
||||
#ifndef _RSL_H
|
||||
#define _RSL_H
|
||||
|
||||
#include <osmocore/protocol/gsm_08_58.h>
|
||||
struct abis_rsl_common_hdr {
|
||||
u_int8_t msg_discr;
|
||||
u_int8_t msg_type;
|
||||
u_int8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#include <osmocore/msgb.h>
|
||||
/* Chapter 8.3 */
|
||||
struct abis_rsl_rll_hdr {
|
||||
struct abis_rsl_common_hdr c;
|
||||
u_int8_t ie_chan;
|
||||
u_int8_t chan_nr;
|
||||
u_int8_t ie_link_id;
|
||||
u_int8_t link_id;
|
||||
u_int8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Chapter 8.3 and 8.4 */
|
||||
struct abis_rsl_dchan_hdr {
|
||||
struct abis_rsl_common_hdr c;
|
||||
u_int8_t ie_chan;
|
||||
u_int8_t chan_nr;
|
||||
u_int8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/* Chapter 9.1 */
|
||||
#define ABIS_RSL_MDISC_RLL 0x02
|
||||
#define ABIS_RSL_MDISC_DED_CHAN 0x08
|
||||
#define ABIS_RSL_MDISC_COM_CHAN 0x0c
|
||||
#define ABIS_RSL_MDISC_TRX 0x10
|
||||
#define ABIS_RSL_MDISC_LOC 0x20
|
||||
#define ABIS_RSL_MDISC_IPACCESS 0x7e
|
||||
#define ABIS_RSL_MDISC_TRANSP 0x01
|
||||
|
||||
#define ABIS_RSL_MDISC_IS_TRANSP(x) (x & 0x01)
|
||||
|
||||
/* Chapter 9.1 */
|
||||
enum abis_rsl_msgtype {
|
||||
/* Radio Link Layer Management */
|
||||
RSL_MT_DATA_REQ = 0x01,
|
||||
RSL_MT_DATA_IND,
|
||||
RSL_MT_ERROR_IND,
|
||||
RSL_MT_EST_REQ,
|
||||
RSL_MT_EST_CONF,
|
||||
RSL_MT_EST_IND,
|
||||
RSL_MT_REL_REQ,
|
||||
RSL_MT_REL_CONF,
|
||||
RSL_MT_REL_IND,
|
||||
RSL_MT_UNIT_DATA_REQ,
|
||||
RSL_MT_UNIT_DATA_IND, /* 0x0b */
|
||||
|
||||
/* Common Channel Management / TRX Management */
|
||||
RSL_MT_BCCH_INFO = 0x11,
|
||||
RSL_MT_CCCH_LOAD_IND,
|
||||
RSL_MT_CHAN_RQD,
|
||||
RSL_MT_DELETE_IND,
|
||||
RSL_MT_PAGING_CMD,
|
||||
RSL_MT_IMMEDIATE_ASSIGN_CMD,
|
||||
RSL_MT_SMS_BC_REQ,
|
||||
/* empty */
|
||||
RSL_MT_RF_RES_IND = 0x19,
|
||||
RSL_MT_SACCH_FILL,
|
||||
RSL_MT_OVERLOAD,
|
||||
RSL_MT_ERROR_REPORT,
|
||||
RSL_MT_SMS_BC_CMD,
|
||||
RSL_MT_CBCH_LOAD_IND,
|
||||
RSL_MT_NOT_CMD, /* 0x1f */
|
||||
|
||||
/* Dedicate Channel Management */
|
||||
RSL_MT_CHAN_ACTIV = 0x21,
|
||||
RSL_MT_CHAN_ACTIV_ACK,
|
||||
RSL_MT_CHAN_ACTIV_NACK,
|
||||
RSL_MT_CONN_FAIL,
|
||||
RSL_MT_DEACTIVATE_SACCH,
|
||||
RSL_MT_ENCR_CMD,
|
||||
RSL_MT_HANDO_DET,
|
||||
RSL_MT_MEAS_RES,
|
||||
RSL_MT_MODE_MODIFY_REQ,
|
||||
RSL_MT_MODE_MODIFY_ACK,
|
||||
RSL_MT_MODE_MODIFY_NACK,
|
||||
RSL_MT_PHY_CONTEXT_REQ,
|
||||
RSL_MT_PHY_CONTEXT_CONF,
|
||||
RSL_MT_RF_CHAN_REL,
|
||||
RSL_MT_MS_POWER_CONTROL,
|
||||
RSL_MT_BS_POWER_CONTROL, /* 0x30 */
|
||||
RSL_MT_PREPROC_CONFIG,
|
||||
RSL_MT_PREPROC_MEAS_RES,
|
||||
RSL_MT_RF_CHAN_REL_ACK,
|
||||
RSL_MT_SACCH_INFO_MODIFY,
|
||||
RSL_MT_TALKER_DET,
|
||||
RSL_MT_LISTENER_DET,
|
||||
RSL_MT_REMOTE_CODEC_CONF_REP,
|
||||
RSL_MT_RTD_REP,
|
||||
RSL_MT_PRE_HANDO_NOTIF,
|
||||
RSL_MT_MR_CODEC_MOD_REQ,
|
||||
RSL_MT_MR_CODEC_MOD_ACK,
|
||||
RSL_MT_MR_CODEC_MOD_NACK,
|
||||
RSL_MT_MR_CODEC_MOD_PER,
|
||||
RSL_MT_TFO_REP,
|
||||
RSL_MT_TFO_MOD_REQ, /* 0x3f */
|
||||
RSL_MT_LOCATION_INFO = 0x41,
|
||||
|
||||
/* ip.access specific RSL message types */
|
||||
RSL_MT_IPAC_DIR_RETR_ENQ = 0x40,
|
||||
RSL_MT_IPAC_PDCH_ACT = 0x48,
|
||||
RSL_MT_IPAC_PDCH_ACT_ACK,
|
||||
RSL_MT_IPAC_PDCH_ACT_NACK,
|
||||
RSL_MT_IPAC_PDCH_DEACT = 0x4b,
|
||||
RSL_MT_IPAC_PDCH_DEACT_ACK,
|
||||
RSL_MT_IPAC_PDCH_DEACT_NACK,
|
||||
RSL_MT_IPAC_CONNECT_MUX = 0x50,
|
||||
RSL_MT_IPAC_CONNECT_MUX_ACK,
|
||||
RSL_MT_IPAC_CONNECT_MUX_NACK,
|
||||
RSL_MT_IPAC_BIND_MUX = 0x53,
|
||||
RSL_MT_IPAC_BIND_MUX_ACK,
|
||||
RSL_MT_IPAC_BIND_MUX_NACK,
|
||||
RSL_MT_IPAC_DISC_MUX = 0x56,
|
||||
RSL_MT_IPAC_DISC_MUX_ACK,
|
||||
RSL_MT_IPAC_DISC_MUX_NACK,
|
||||
RSL_MT_IPAC_CRCX = 0x70, /* Bind to local BTS RTP port */
|
||||
RSL_MT_IPAC_CRCX_ACK,
|
||||
RSL_MT_IPAC_CRCX_NACK,
|
||||
RSL_MT_IPAC_MDCX = 0x73,
|
||||
RSL_MT_IPAC_MDCX_ACK,
|
||||
RSL_MT_IPAC_MDCX_NACK,
|
||||
RSL_MT_IPAC_DLCX_IND = 0x76,
|
||||
RSL_MT_IPAC_DLCX = 0x77,
|
||||
RSL_MT_IPAC_DLCX_ACK,
|
||||
RSL_MT_IPAC_DLCX_NACK,
|
||||
};
|
||||
|
||||
/* Siemens vendor-specific */
|
||||
enum abis_rsl_msgtype_siemens {
|
||||
RSL_MT_SIEMENS_MRPCI = 0x41,
|
||||
RSL_MT_SIEMENS_INTRAC_HO_COND_IND = 0x42,
|
||||
RSL_MT_SIEMENS_INTERC_HO_COND_IND = 0x43,
|
||||
RSL_MT_SIEMENS_FORCED_HO_REQ = 0x44,
|
||||
RSL_MT_SIEMENS_PREF_AREA_REQ = 0x45,
|
||||
RSL_MT_SIEMENS_PREF_AREA = 0x46,
|
||||
RSL_MT_SIEMENS_START_TRACE = 0x47,
|
||||
RSL_MT_SIEMENS_START_TRACE_ACK = 0x48,
|
||||
RSL_MT_SIEMENS_STOP_TRACE = 0x49,
|
||||
RSL_MT_SIEMENS_TRMR = 0x4a,
|
||||
RSL_MT_SIEMENS_HO_FAIL_IND = 0x4b,
|
||||
RSL_MT_SIEMENS_STOP_TRACE_ACK = 0x4c,
|
||||
RSL_MT_SIEMENS_UPLF = 0x4d,
|
||||
RSL_MT_SIEMENS_UPLB = 0x4e,
|
||||
RSL_MT_SIEMENS_SET_SYS_INFO_10 = 0x4f,
|
||||
RSL_MT_SIEMENS_MODIF_COND_IND = 0x50,
|
||||
};
|
||||
|
||||
/* Chapter 9.3 */
|
||||
enum abis_rsl_ie {
|
||||
RSL_IE_CHAN_NR = 0x01,
|
||||
RSL_IE_LINK_IDENT,
|
||||
RSL_IE_ACT_TYPE,
|
||||
RSL_IE_BS_POWER,
|
||||
RSL_IE_CHAN_IDENT,
|
||||
RSL_IE_CHAN_MODE,
|
||||
RSL_IE_ENCR_INFO,
|
||||
RSL_IE_FRAME_NUMBER,
|
||||
RSL_IE_HANDO_REF,
|
||||
RSL_IE_L1_INFO,
|
||||
RSL_IE_L3_INFO,
|
||||
RSL_IE_MS_IDENTITY,
|
||||
RSL_IE_MS_POWER,
|
||||
RSL_IE_PAGING_GROUP,
|
||||
RSL_IE_PAGING_LOAD,
|
||||
RSL_IE_PYHS_CONTEXT = 0x10,
|
||||
RSL_IE_ACCESS_DELAY,
|
||||
RSL_IE_RACH_LOAD,
|
||||
RSL_IE_REQ_REFERENCE,
|
||||
RSL_IE_RELEASE_MODE,
|
||||
RSL_IE_RESOURCE_INFO,
|
||||
RSL_IE_RLM_CAUSE,
|
||||
RSL_IE_STARTNG_TIME,
|
||||
RSL_IE_TIMING_ADVANCE,
|
||||
RSL_IE_UPLINK_MEAS,
|
||||
RSL_IE_CAUSE,
|
||||
RSL_IE_MEAS_RES_NR,
|
||||
RSL_IE_MSG_ID,
|
||||
/* reserved */
|
||||
RSL_IE_SYSINFO_TYPE = 0x1e,
|
||||
RSL_IE_MS_POWER_PARAM,
|
||||
RSL_IE_BS_POWER_PARAM,
|
||||
RSL_IE_PREPROC_PARAM,
|
||||
RSL_IE_PREPROC_MEAS,
|
||||
RSL_IE_IMM_ASS_INFO, /* Phase 1 (3.6.0), later Full below */
|
||||
RSL_IE_SMSCB_INFO = 0x24,
|
||||
RSL_IE_MS_TIMING_OFFSET,
|
||||
RSL_IE_ERR_MSG,
|
||||
RSL_IE_FULL_BCCH_INFO,
|
||||
RSL_IE_CHAN_NEEDED,
|
||||
RSL_IE_CB_CMD_TYPE,
|
||||
RSL_IE_SMSCB_MSG,
|
||||
RSL_IE_FULL_IMM_ASS_INFO,
|
||||
RSL_IE_SACCH_INFO,
|
||||
RSL_IE_CBCH_LOAD_INFO,
|
||||
RSL_IE_SMSCB_CHAN_INDICATOR,
|
||||
RSL_IE_GROUP_CALL_REF,
|
||||
RSL_IE_CHAN_DESC = 0x30,
|
||||
RSL_IE_NCH_DRX_INFO,
|
||||
RSL_IE_CMD_INDICATOR,
|
||||
RSL_IE_EMLPP_PRIO,
|
||||
RSL_IE_UIC,
|
||||
RSL_IE_MAIN_CHAN_REF,
|
||||
RSL_IE_MR_CONFIG,
|
||||
RSL_IE_MR_CONTROL,
|
||||
RSL_IE_SUP_CODEC_TYPES,
|
||||
RSL_IE_CODEC_CONFIG,
|
||||
RSL_IE_RTD,
|
||||
RSL_IE_TFO_STATUS,
|
||||
RSL_IE_LLP_APDU,
|
||||
/* Siemens vendor-specific */
|
||||
RSL_IE_SIEMENS_MRPCI = 0x40,
|
||||
RSL_IE_SIEMENS_PREF_AREA_TYPE = 0x43,
|
||||
RSL_IE_SIEMENS_ININ_CELL_HO_PAR = 0x45,
|
||||
RSL_IE_SIEMENS_TRACE_REF_NR = 0x46,
|
||||
RSL_IE_SIEMENS_INT_TRACE_IDX = 0x47,
|
||||
RSL_IE_SIEMENS_L2_HDR_INFO = 0x48,
|
||||
RSL_IE_SIEMENS_HIGHEST_RATE = 0x4e,
|
||||
RSL_IE_SIEMENS_SUGGESTED_RATE = 0x4f,
|
||||
|
||||
/* ip.access */
|
||||
RSL_IE_IPAC_SRTP_CONFIG = 0xe0,
|
||||
RSL_IE_IPAC_PROXY_UDP = 0xe1,
|
||||
RSL_IE_IPAC_BSCMPL_TOUT = 0xe2,
|
||||
RSL_IE_IPAC_REMOTE_IP = 0xf0,
|
||||
RSL_IE_IPAC_REMOTE_PORT = 0xf1,
|
||||
RSL_IE_IPAC_RTP_PAYLOAD = 0xf2,
|
||||
RSL_IE_IPAC_LOCAL_PORT = 0xf3,
|
||||
RSL_IE_IPAC_SPEECH_MODE = 0xf4,
|
||||
RSL_IE_IPAC_LOCAL_IP = 0xf5,
|
||||
RSL_IE_IPAC_CONN_STAT = 0xf6,
|
||||
RSL_IE_IPAC_HO_C_PARMS = 0xf7,
|
||||
RSL_IE_IPAC_CONN_ID = 0xf8,
|
||||
RSL_IE_IPAC_RTP_CSD_FMT = 0xf9,
|
||||
RSL_IE_IPAC_RTP_JIT_BUF = 0xfa,
|
||||
RSL_IE_IPAC_RTP_COMPR = 0xfb,
|
||||
RSL_IE_IPAC_RTP_PAYLOAD2= 0xfc,
|
||||
RSL_IE_IPAC_RTP_MPLEX = 0xfd,
|
||||
RSL_IE_IPAC_RTP_MPLEX_ID= 0xfe,
|
||||
};
|
||||
|
||||
/* Chapter 9.3.1 */
|
||||
#define RSL_CHAN_NR_MASK 0xf8
|
||||
#define RSL_CHAN_Bm_ACCHs 0x08
|
||||
#define RSL_CHAN_Lm_ACCHs 0x10 /* .. 0x18 */
|
||||
#define RSL_CHAN_SDCCH4_ACCH 0x20 /* .. 0x38 */
|
||||
#define RSL_CHAN_SDCCH8_ACCH 0x40 /* ...0x78 */
|
||||
#define RSL_CHAN_BCCH 0x80
|
||||
#define RSL_CHAN_RACH 0x88
|
||||
#define RSL_CHAN_PCH_AGCH 0x90
|
||||
|
||||
/* Chapter 9.3.3 */
|
||||
#define RSL_ACT_TYPE_INITIAL 0x00
|
||||
#define RSL_ACT_TYPE_REACT 0x80
|
||||
#define RSL_ACT_INTRA_IMM_ASS 0x00
|
||||
#define RSL_ACT_INTRA_NORM_ASS 0x01
|
||||
#define RSL_ACT_INTER_ASYNC 0x02
|
||||
#define RSL_ACT_INTER_SYNC 0x03
|
||||
#define RSL_ACT_SECOND_ADD 0x04
|
||||
#define RSL_ACT_SECOND_MULTI 0x05
|
||||
|
||||
/* Chapter 9.3.6 */
|
||||
struct rsl_ie_chan_mode {
|
||||
u_int8_t dtx_dtu;
|
||||
u_int8_t spd_ind;
|
||||
u_int8_t chan_rt;
|
||||
u_int8_t chan_rate;
|
||||
} __attribute__ ((packed));
|
||||
#define RSL_CMOD_DTXu 0x01 /* uplink */
|
||||
#define RSL_CMOD_DTXd 0x02 /* downlink */
|
||||
enum rsl_cmod_spd {
|
||||
RSL_CMOD_SPD_SPEECH = 0x01,
|
||||
RSL_CMOD_SPD_DATA = 0x02,
|
||||
RSL_CMOD_SPD_SIGN = 0x03,
|
||||
};
|
||||
#define RSL_CMOD_CRT_SDCCH 0x01
|
||||
#define RSL_CMOD_CRT_TCH_Bm 0x08 /* full-rate */
|
||||
#define RSL_CMOD_CRT_TCH_Lm 0x09 /* half-rate */
|
||||
/* FIXME: More CRT types */
|
||||
/* Speech */
|
||||
#define RSL_CMOD_SP_GSM1 0x01
|
||||
#define RSL_CMOD_SP_GSM2 0x11
|
||||
#define RSL_CMOD_SP_GSM3 0x21
|
||||
/* Data */
|
||||
#define RSL_CMOD_SP_NT_14k5 0x58
|
||||
#define RSL_CMOD_SP_NT_12k0 0x50
|
||||
#define RSL_CMOD_SP_NT_6k0 0x51
|
||||
|
||||
/* Chapter 9.3.5 */
|
||||
struct rsl_ie_chan_ident {
|
||||
/* GSM 04.08 10.5.2.5 */
|
||||
struct {
|
||||
u_int8_t iei;
|
||||
u_int8_t chan_nr; /* enc_chan_nr */
|
||||
u_int8_t oct3;
|
||||
u_int8_t oct4;
|
||||
} chan_desc;
|
||||
#if 0 /* spec says we need this but Abissim doesn't use it */
|
||||
struct {
|
||||
u_int8_t tag;
|
||||
u_int8_t len;
|
||||
} mobile_alloc;
|
||||
#endif
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Chapter 9.3.22 */
|
||||
#define RLL_CAUSE_T200_EXPIRED 0x01
|
||||
#define RLL_CAUSE_REEST_REQ 0x02
|
||||
#define RLL_CAUSE_UNSOL_UA_RESP 0x03
|
||||
#define RLL_CAUSE_UNSOL_DM_RESP 0x04
|
||||
#define RLL_CAUSE_UNSOL_DM_RESP_MF 0x05
|
||||
#define RLL_CAUSE_UNSOL_SPRV_RESP 0x06
|
||||
#define RLL_CAUSE_SEQ_ERR 0x07
|
||||
#define RLL_CAUSE_UFRM_INC_PARAM 0x08
|
||||
#define RLL_CAUSE_SFRM_INC_PARAM 0x09
|
||||
#define RLL_CAUSE_IFRM_INC_MBITS 0x0a
|
||||
#define RLL_CAUSE_IFRM_INC_LEN 0x0b
|
||||
#define RLL_CAUSE_FRM_UNIMPL 0x0c
|
||||
#define RLL_CAUSE_SABM_MF 0x0d
|
||||
#define RLL_CAUSE_SABM_INFO_NOTALL 0x0e
|
||||
|
||||
/* Chapter 9.3.26 */
|
||||
#define RSL_ERRCLS_NORMAL 0x00
|
||||
#define RSL_ERRCLS_RESOURCE_UNAVAIL 0x20
|
||||
#define RSL_ERRCLS_SERVICE_UNAVAIL 0x30
|
||||
#define RSL_ERRCLS_SERVICE_UNIMPL 0x40
|
||||
#define RSL_ERRCLS_INVAL_MSG 0x50
|
||||
#define RSL_ERRCLS_PROTO_ERROR 0x60
|
||||
#define RSL_ERRCLS_INTERWORKING 0x70
|
||||
|
||||
/* normal event */
|
||||
#define RSL_ERR_RADIO_IF_FAIL 0x00
|
||||
#define RSL_ERR_RADIO_LINK_FAIL 0x01
|
||||
#define RSL_ERR_HANDOVER_ACC_FAIL 0x02
|
||||
#define RSL_ERR_TALKER_ACC_FAIL 0x03
|
||||
#define RSL_ERR_OM_INTERVENTION 0x07
|
||||
#define RSL_ERR_NORMAL_UNSPEC 0x0f
|
||||
#define RSL_ERR_T_MSRFPCI_EXP 0x18
|
||||
/* resource unavailable */
|
||||
#define RSL_ERR_EQUIPMENT_FAIL 0x20
|
||||
#define RSL_ERR_RR_UNAVAIL 0x21
|
||||
#define RSL_ERR_TERR_CH_FAIL 0x22
|
||||
#define RSL_ERR_CCCH_OVERLOAD 0x23
|
||||
#define RSL_ERR_ACCH_OVERLOAD 0x24
|
||||
#define RSL_ERR_PROCESSOR_OVERLOAD 0x25
|
||||
#define RSL_ERR_RES_UNAVAIL 0x2f
|
||||
/* service or option not available */
|
||||
#define RSL_ERR_TRANSC_UNAVAIL 0x30
|
||||
#define RSL_ERR_SERV_OPT_UNAVAIL 0x3f
|
||||
/* service or option not implemented */
|
||||
#define RSL_ERR_ENCR_UNIMPL 0x40
|
||||
#define RSL_ERR_SERV_OPT_UNIMPL 0x4f
|
||||
/* invalid message */
|
||||
#define RSL_ERR_RCH_ALR_ACTV_ALLOC 0x50
|
||||
#define RSL_ERR_INVALID_MESSAGE 0x5f
|
||||
/* protocol error */
|
||||
#define RSL_ERR_MSG_DISCR 0x60
|
||||
#define RSL_ERR_MSG_TYPE 0x61
|
||||
#define RSL_ERR_MSG_SEQ 0x62
|
||||
#define RSL_ERR_IE_ERROR 0x63
|
||||
#define RSL_ERR_MAND_IE_ERROR 0x64
|
||||
#define RSL_ERR_OPT_IE_ERROR 0x65
|
||||
#define RSL_ERR_IE_NONEXIST 0x66
|
||||
#define RSL_ERR_IE_LENGTH 0x67
|
||||
#define RSL_ERR_IE_CONTENT 0x68
|
||||
#define RSL_ERR_PROTO 0x6f
|
||||
/* interworking */
|
||||
#define RSL_ERR_INTERWORKING 0x7f
|
||||
|
||||
/* Chapter 9.3.30 */
|
||||
#define RSL_SYSTEM_INFO_8 0x00
|
||||
#define RSL_SYSTEM_INFO_1 0x01
|
||||
#define RSL_SYSTEM_INFO_2 0x02
|
||||
#define RSL_SYSTEM_INFO_3 0x03
|
||||
#define RSL_SYSTEM_INFO_4 0x04
|
||||
#define RSL_SYSTEM_INFO_5 0x05
|
||||
#define RSL_SYSTEM_INFO_6 0x06
|
||||
#define RSL_SYSTEM_INFO_7 0x07
|
||||
#define RSL_SYSTEM_INFO_16 0x08
|
||||
#define RSL_SYSTEM_INFO_17 0x09
|
||||
#define RSL_SYSTEM_INFO_2bis 0x0a
|
||||
#define RSL_SYSTEM_INFO_2ter 0x0b
|
||||
#define RSL_SYSTEM_INFO_5bis 0x0d
|
||||
#define RSL_SYSTEM_INFO_5ter 0x0e
|
||||
#define RSL_SYSTEM_INFO_10 0x0f
|
||||
#define REL_EXT_MEAS_ORDER 0x47
|
||||
#define RSL_MEAS_INFO 0x48
|
||||
#define RSL_SYSTEM_INFO_13 0x28
|
||||
#define RSL_SYSTEM_INFO_2quater 0x29
|
||||
#define RSL_SYSTEM_INFO_9 0x2a
|
||||
#define RSL_SYSTEM_INFO_18 0x2b
|
||||
#define RSL_SYSTEM_INFO_19 0x2c
|
||||
#define RSL_SYSTEM_INFO_20 0x2d
|
||||
|
||||
/* Chapter 9.3.40 */
|
||||
#define RSL_CHANNEED_ANY 0x00
|
||||
#define RSL_CHANNEED_SDCCH 0x01
|
||||
#define RSL_CHANNEED_TCH_F 0x02
|
||||
#define RSL_CHANNEED_TCH_ForH 0x03
|
||||
|
||||
/* Chapter 3.3.2.3 Brocast control channel */
|
||||
/* CCCH-CONF, NC is not combined */
|
||||
#define RSL_BCCH_CCCH_CONF_1_NC 0x00
|
||||
#define RSL_BCCH_CCCH_CONF_1_C 0x01
|
||||
#define RSL_BCCH_CCCH_CONF_2_NC 0x02
|
||||
#define RSL_BCCH_CCCH_CONF_3_NC 0x04
|
||||
#define RSL_BCCH_CCCH_CONF_4_NC 0x06
|
||||
|
||||
/* BS-PA-MFRMS */
|
||||
#define RSL_BS_PA_MFRMS_2 0x00
|
||||
#define RSL_BS_PA_MFRMS_3 0x01
|
||||
#define RSL_BS_PA_MFRMS_4 0x02
|
||||
#define RSL_BS_PA_MFRMS_5 0x03
|
||||
#define RSL_BS_PA_MFRMS_6 0x04
|
||||
#define RSL_BS_PA_MFRMS_7 0x05
|
||||
#define RSL_BS_PA_MFRMS_8 0x06
|
||||
#define RSL_BS_PA_MFRMS_9 0x07
|
||||
|
||||
/* RSL_IE_IPAC_RTP_PAYLOAD[2] */
|
||||
enum rsl_ipac_rtp_payload {
|
||||
RSL_IPAC_RTP_GSM = 1,
|
||||
RSL_IPAC_RTP_EFR,
|
||||
RSL_IPAC_RTP_AMR,
|
||||
RSL_IPAC_RTP_CSD,
|
||||
RSL_IPAC_RTP_MUX,
|
||||
};
|
||||
|
||||
/* RSL_IE_IPAC_SPEECH_MODE, lower four bits */
|
||||
enum rsl_ipac_speech_mode_s {
|
||||
RSL_IPAC_SPEECH_GSM_FR = 0, /* GSM FR (Type 1, FS) */
|
||||
RSL_IPAC_SPEECH_GSM_EFR = 1, /* GSM EFR (Type 2, FS) */
|
||||
RSL_IPAC_SPEECH_GSM_AMR_FR = 2, /* GSM AMR/FR (Type 3, FS) */
|
||||
RSL_IPAC_SPEECH_GSM_HR = 3, /* GSM HR (Type 1, HS) */
|
||||
RSL_IPAC_SPEECH_GSM_AMR_HR = 5, /* GSM AMR/hr (Type 3, HS) */
|
||||
RSL_IPAC_SPEECH_AS_RTP = 0xf, /* As specified by RTP Payload IE */
|
||||
};
|
||||
/* RSL_IE_IPAC_SPEECH_MODE, upper four bits */
|
||||
enum rsl_ipac_speech_mode_m {
|
||||
RSL_IPAC_SPEECH_M_RXTX = 0, /* Send and Receive */
|
||||
RSL_IPAC_SPEECH_M_RX = 1, /* Receive only */
|
||||
RSL_IPAC_SPEECH_M_TX = 2, /* Send only */
|
||||
};
|
||||
|
||||
/* RSL_IE_IPAC_RTP_CSD_FMT, lower four bits */
|
||||
enum rsl_ipac_rtp_csd_format_d {
|
||||
RSL_IPAC_RTP_CSD_EXT_TRAU = 0,
|
||||
RSL_IPAC_RTP_CSD_NON_TRAU = 1,
|
||||
RSL_IPAC_RTP_CSD_TRAU_BTS = 2,
|
||||
RSL_IPAC_RTP_CSD_IWF_FREE = 3,
|
||||
};
|
||||
/* RSL_IE_IPAC_RTP_CSD_FMT, upper four bits */
|
||||
enum rsl_ipac_rtp_csd_format_ir {
|
||||
RSL_IPAC_RTP_CSD_IR_8k = 0,
|
||||
RSL_IPAC_RTP_CSD_IR_16k = 1,
|
||||
RSL_IPAC_RTP_CSD_IR_32k = 2,
|
||||
RSL_IPAC_RTP_CSD_IR_64k = 3,
|
||||
};
|
||||
|
||||
#include "msgb.h"
|
||||
|
||||
int rsl_bcch_info(struct gsm_bts_trx *trx, u_int8_t type,
|
||||
const u_int8_t *data, int len);
|
||||
@@ -52,6 +511,27 @@ int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id);
|
||||
int rsl_relase_request(struct gsm_lchan *lchan, u_int8_t link_id);
|
||||
|
||||
/* Siemens vendor-specific RSL extensions */
|
||||
struct rsl_mrpci {
|
||||
u_int8_t power_class:3,
|
||||
vgcs_capable:1,
|
||||
vbs_capable:1,
|
||||
gsm_phase:2;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
enum rsl_mrpci_pwrclass {
|
||||
RSL_MRPCI_PWRC_1 = 0,
|
||||
RSL_MRPCI_PWRC_2 = 1,
|
||||
RSL_MRPCI_PWRC_3 = 2,
|
||||
RSL_MRPCI_PWRC_4 = 3,
|
||||
RSL_MRPCI_PWRC_5 = 4,
|
||||
};
|
||||
enum rsl_mrpci_phase {
|
||||
RSL_MRPCI_PHASE_1 = 0,
|
||||
/* reserved */
|
||||
RSL_MRPCI_PHASE_2 = 2,
|
||||
RSL_MRPCI_PHASE_2PLUS = 3,
|
||||
};
|
||||
|
||||
int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci);
|
||||
|
||||
/* ip.access specfic RSL extensions */
|
||||
|
||||
@@ -36,14 +36,14 @@ enum bit_value {
|
||||
struct bitvec {
|
||||
unsigned int cur_bit; /* curser to the next unused bit */
|
||||
unsigned int data_len; /* length of data array in bytes */
|
||||
uint8_t *data; /* pointer to data array */
|
||||
u_int8_t *data; /* pointer to data array */
|
||||
};
|
||||
|
||||
/* check if the bit is 0 or 1 for a given position inside a bitvec */
|
||||
enum bit_value bitvec_get_bit_pos(const struct bitvec *bv, unsigned int bitnr);
|
||||
enum bit_value bitvec_get_bit_pos(struct bitvec *bv, unsigned int bitnr);
|
||||
|
||||
/* get the Nth set bit inside the bit vector */
|
||||
unsigned int bitvec_get_nth_set_bit(const struct bitvec *bv, unsigned int n);
|
||||
unsigned int bitvec_get_nth_set_bit(struct bitvec *bv, unsigned int n);
|
||||
|
||||
/* Set a bit at given position */
|
||||
int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnum,
|
||||
@@ -1,8 +1,7 @@
|
||||
/* Generic write queue implementation */
|
||||
/* Routines to talk to the MSC using the IPA Protocol */
|
||||
/*
|
||||
* (C) 2010 by Holger Hans Peter Freyther
|
||||
* (C) 2010 by On-Waves
|
||||
*
|
||||
* (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2010 by on-waves.com
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -20,25 +19,12 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
#ifndef write_queue_h
|
||||
#define write_queue_h
|
||||
|
||||
#ifndef BSC_MSC_H
|
||||
#define BSC_MSC_H
|
||||
|
||||
#include "select.h"
|
||||
#include "msgb.h"
|
||||
|
||||
struct write_queue {
|
||||
struct bsc_fd bfd;
|
||||
unsigned int max_length;
|
||||
unsigned int current_length;
|
||||
|
||||
struct llist_head msg_queue;
|
||||
|
||||
int (*read_cb)(struct bsc_fd *fd);
|
||||
int (*write_cb)(struct bsc_fd *fd, struct msgb *msg);
|
||||
};
|
||||
|
||||
void write_queue_init(struct write_queue *queue, int max_length);
|
||||
int write_queue_enqueue(struct write_queue *queue, struct msgb *data);
|
||||
int write_queue_bfd_cb(struct bsc_fd *fd, unsigned int what);
|
||||
int connect_to_msc(struct bsc_fd *fd, const char *ip, int port);
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,6 @@
|
||||
/* Generic BTS - VTY code tries to allocate this BTS before type is known */
|
||||
|
||||
/* (C) 2010 by Daniel Willmann <daniel@totalueberwachung.de>
|
||||
*
|
||||
/*
|
||||
* (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2010 by on-waves.com
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -20,21 +19,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BSC_NAT_H
|
||||
#define BSC_NAT_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "msgb.h"
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <osmocore/tlv.h>
|
||||
#include <openbsc/abis_nm.h>
|
||||
/**
|
||||
* filter based on IP Access header in both directions
|
||||
*/
|
||||
int bsc_nat_filter_ipa(struct msgb *msg);
|
||||
|
||||
static struct gsm_bts_model model_unknown = {
|
||||
.type = GSM_BTS_TYPE_UNKNOWN,
|
||||
.nm_att_tlvdef = {
|
||||
.def = {
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
int bts_model_unknown_init(void)
|
||||
{
|
||||
return gsm_bts_model_register(&model_unknown);
|
||||
}
|
||||
#endif
|
||||
334
openbsc/include/openbsc/bssap.h
Normal file
334
openbsc/include/openbsc/bssap.h
Normal file
@@ -0,0 +1,334 @@
|
||||
/* From GSM08.08 */
|
||||
|
||||
#ifndef BSSAP_H
|
||||
#define BSSAP_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <openbsc/msgb.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
|
||||
/*
|
||||
* this is from GSM 03.03 CGI but is copied in GSM 08.08
|
||||
* in § 3.2.2.27 for Cell Identifier List
|
||||
*/
|
||||
enum CELL_IDENT {
|
||||
CELL_IDENT_WHOLE_GLOBAL = 0,
|
||||
CELL_IDENT_LAC_AND_CI = 1,
|
||||
CELL_IDENT_CI = 2,
|
||||
CELL_IDENT_NO_CELL = 3,
|
||||
CELL_IDENT_LAI_AND_LAC = 4,
|
||||
CELL_IDENT_LAC = 5,
|
||||
CELL_IDENT_BSS = 6,
|
||||
CELL_IDENT_UTRAN_PLMN_LAC_RNC = 8,
|
||||
CELL_IDENT_UTRAN_RNC = 9,
|
||||
CELL_IDENT_UTRAN_LAC_RNC = 10,
|
||||
};
|
||||
|
||||
|
||||
/* GSM 08.06 § 6.3 */
|
||||
enum BSSAP_MSG_TYPE {
|
||||
BSSAP_MSG_BSS_MANAGEMENT = 0x0,
|
||||
BSSAP_MSG_DTAP = 0x1,
|
||||
};
|
||||
|
||||
struct bssmap_header {
|
||||
u_int8_t type;
|
||||
u_int8_t length;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct dtap_header {
|
||||
u_int8_t type;
|
||||
u_int8_t link_id;
|
||||
u_int8_t length;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
enum BSS_MAP_MSG_TYPE {
|
||||
BSS_MAP_MSG_RESERVED_0 = 0,
|
||||
|
||||
/* ASSIGNMENT MESSAGES */
|
||||
BSS_MAP_MSG_ASSIGMENT_RQST = 1,
|
||||
BSS_MAP_MSG_ASSIGMENT_COMPLETE = 2,
|
||||
BSS_MAP_MSG_ASSIGMENT_FAILURE = 3,
|
||||
|
||||
/* HANDOVER MESSAGES */
|
||||
BSS_MAP_MSG_HANDOVER_RQST = 16,
|
||||
BSS_MAP_MSG_HANDOVER_REQUIRED = 17,
|
||||
BSS_MAP_MSG_HANDOVER_RQST_ACKNOWLEDGE= 18,
|
||||
BSS_MAP_MSG_HANDOVER_CMD = 19,
|
||||
BSS_MAP_MSG_HANDOVER_COMPLETE = 20,
|
||||
BSS_MAP_MSG_HANDOVER_SUCCEEDED = 21,
|
||||
BSS_MAP_MSG_HANDOVER_FAILURE = 22,
|
||||
BSS_MAP_MSG_HANDOVER_PERFORMED = 23,
|
||||
BSS_MAP_MSG_HANDOVER_CANDIDATE_ENQUIRE = 24,
|
||||
BSS_MAP_MSG_HANDOVER_CANDIDATE_RESPONSE = 25,
|
||||
BSS_MAP_MSG_HANDOVER_REQUIRED_REJECT = 26,
|
||||
BSS_MAP_MSG_HANDOVER_DETECT = 27,
|
||||
|
||||
/* RELEASE MESSAGES */
|
||||
BSS_MAP_MSG_CLEAR_CMD = 32,
|
||||
BSS_MAP_MSG_CLEAR_COMPLETE = 33,
|
||||
BSS_MAP_MSG_CLEAR_RQST = 34,
|
||||
BSS_MAP_MSG_RESERVED_1 = 35,
|
||||
BSS_MAP_MSG_RESERVED_2 = 36,
|
||||
BSS_MAP_MSG_SAPI_N_REJECT = 37,
|
||||
BSS_MAP_MSG_CONFUSION = 38,
|
||||
|
||||
/* OTHER CONNECTION RELATED MESSAGES */
|
||||
BSS_MAP_MSG_SUSPEND = 40,
|
||||
BSS_MAP_MSG_RESUME = 41,
|
||||
BSS_MAP_MSG_CONNECTION_ORIENTED_INFORMATION = 42,
|
||||
BSS_MAP_MSG_PERFORM_LOCATION_RQST = 43,
|
||||
BSS_MAP_MSG_LSA_INFORMATION = 44,
|
||||
BSS_MAP_MSG_PERFORM_LOCATION_RESPONSE = 45,
|
||||
BSS_MAP_MSG_PERFORM_LOCATION_ABORT = 46,
|
||||
BSS_MAP_MSG_COMMON_ID = 47,
|
||||
|
||||
/* GENERAL MESSAGES */
|
||||
BSS_MAP_MSG_RESET = 48,
|
||||
BSS_MAP_MSG_RESET_ACKNOWLEDGE = 49,
|
||||
BSS_MAP_MSG_OVERLOAD = 50,
|
||||
BSS_MAP_MSG_RESERVED_3 = 51,
|
||||
BSS_MAP_MSG_RESET_CIRCUIT = 52,
|
||||
BSS_MAP_MSG_RESET_CIRCUIT_ACKNOWLEDGE = 53,
|
||||
BSS_MAP_MSG_MSC_INVOKE_TRACE = 54,
|
||||
BSS_MAP_MSG_BSS_INVOKE_TRACE = 55,
|
||||
BSS_MAP_MSG_CONNECTIONLESS_INFORMATION = 58,
|
||||
|
||||
/* TERRESTRIAL RESOURCE MESSAGES */
|
||||
BSS_MAP_MSG_BLOCK = 64,
|
||||
BSS_MAP_MSG_BLOCKING_ACKNOWLEDGE = 65,
|
||||
BSS_MAP_MSG_UNBLOCK = 66,
|
||||
BSS_MAP_MSG_UNBLOCKING_ACKNOWLEDGE = 67,
|
||||
BSS_MAP_MSG_CIRCUIT_GROUP_BLOCK = 68,
|
||||
BSS_MAP_MSG_CIRCUIT_GROUP_BLOCKING_ACKNOWLEDGE = 69,
|
||||
BSS_MAP_MSG_CIRCUIT_GROUP_UNBLOCK = 70,
|
||||
BSS_MAP_MSG_CIRCUIT_GROUP_UNBLOCKING_ACKNOWLEDGE = 71,
|
||||
BSS_MAP_MSG_UNEQUIPPED_CIRCUIT = 72,
|
||||
BSS_MAP_MSG_CHANGE_CIRCUIT = 78,
|
||||
BSS_MAP_MSG_CHANGE_CIRCUIT_ACKNOWLEDGE = 79,
|
||||
|
||||
/* RADIO RESOURCE MESSAGES */
|
||||
BSS_MAP_MSG_RESOURCE_RQST = 80,
|
||||
BSS_MAP_MSG_RESOURCE_INDICATION = 81,
|
||||
BSS_MAP_MSG_PAGING = 82,
|
||||
BSS_MAP_MSG_CIPHER_MODE_CMD = 83,
|
||||
BSS_MAP_MSG_CLASSMARK_UPDATE = 84,
|
||||
BSS_MAP_MSG_CIPHER_MODE_COMPLETE = 85,
|
||||
BSS_MAP_MSG_QUEUING_INDICATION = 86,
|
||||
BSS_MAP_MSG_COMPLETE_LAYER_3 = 87,
|
||||
BSS_MAP_MSG_CLASSMARK_RQST = 88,
|
||||
BSS_MAP_MSG_CIPHER_MODE_REJECT = 89,
|
||||
BSS_MAP_MSG_LOAD_INDICATION = 90,
|
||||
|
||||
/* VGCS/VBS */
|
||||
BSS_MAP_MSG_VGCS_VBS_SETUP = 4,
|
||||
BSS_MAP_MSG_VGCS_VBS_SETUP_ACK = 5,
|
||||
BSS_MAP_MSG_VGCS_VBS_SETUP_REFUSE = 6,
|
||||
BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RQST = 7,
|
||||
BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RESULT = 28,
|
||||
BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_FAILURE = 29,
|
||||
BSS_MAP_MSG_VGCS_VBS_QUEUING_INDICATION = 30,
|
||||
BSS_MAP_MSG_UPLINK_RQST = 31,
|
||||
BSS_MAP_MSG_UPLINK_RQST_ACKNOWLEDGE = 39,
|
||||
BSS_MAP_MSG_UPLINK_RQST_CONFIRMATION = 73,
|
||||
BSS_MAP_MSG_UPLINK_RELEASE_INDICATION = 74,
|
||||
BSS_MAP_MSG_UPLINK_REJECT_CMD = 75,
|
||||
BSS_MAP_MSG_UPLINK_RELEASE_CMD = 76,
|
||||
BSS_MAP_MSG_UPLINK_SEIZED_CMD = 77,
|
||||
};
|
||||
|
||||
enum GSM0808_IE_CODING {
|
||||
GSM0808_IE_CIRCUIT_IDENTITY_CODE = 1,
|
||||
GSM0808_IE_RESERVED_0 = 2,
|
||||
GSM0808_IE_RESOURCE_AVAILABLE = 3,
|
||||
GSM0808_IE_CAUSE = 4,
|
||||
GSM0808_IE_CELL_IDENTIFIER = 5,
|
||||
GSM0808_IE_PRIORITY = 6,
|
||||
GSM0808_IE_LAYER_3_HEADER_INFORMATION = 7,
|
||||
GSM0808_IE_IMSI = 8,
|
||||
GSM0808_IE_TMSI = 9,
|
||||
GSM0808_IE_ENCRYPTION_INFORMATION = 10,
|
||||
GSM0808_IE_CHANNEL_TYPE = 11,
|
||||
GSM0808_IE_PERIODICITY = 12,
|
||||
GSM0808_IE_EXTENDED_RESOURCE_INDICATOR = 13,
|
||||
GSM0808_IE_NUMBER_OF_MSS = 14,
|
||||
GSM0808_IE_RESERVED_1 = 15,
|
||||
GSM0808_IE_RESERVED_2 = 16,
|
||||
GSM0808_IE_RESERVED_3 = 17,
|
||||
GSM0808_IE_CLASSMARK_INFORMATION_T2 = 18,
|
||||
GSM0808_IE_CLASSMARK_INFORMATION_T3 = 19,
|
||||
GSM0808_IE_INTERFERENCE_BAND_TO_USE = 20,
|
||||
GSM0808_IE_RR_CAUSE = 21,
|
||||
GSM0808_IE_RESERVED_4 = 22,
|
||||
GSM0808_IE_LAYER_3_INFORMATION = 23,
|
||||
GSM0808_IE_DLCI = 24,
|
||||
GSM0808_IE_DOWNLINK_DTX_FLAG = 25,
|
||||
GSM0808_IE_CELL_IDENTIFIER_LIST = 26,
|
||||
GSM0808_IE_RESPONSE_RQST = 27,
|
||||
GSM0808_IE_RESOURCE_INDICATION_METHOD = 28,
|
||||
GSM0808_IE_CLASSMARK_INFORMATION_TYPE_1 = 29,
|
||||
GSM0808_IE_CIRCUIT_IDENTITY_CODE_LIST = 30,
|
||||
GSM0808_IE_DIAGNOSTIC = 31,
|
||||
GSM0808_IE_LAYER_3_MESSAGE_CONTENTS = 32,
|
||||
GSM0808_IE_CHOSEN_CHANNEL = 33,
|
||||
GSM0808_IE_TOTAL_RESOURCE_ACCESSIBLE = 34,
|
||||
GSM0808_IE_CIPHER_RESPONSE_MODE = 35,
|
||||
GSM0808_IE_CHANNEL_NEEDED = 36,
|
||||
GSM0808_IE_TRACE_TYPE = 37,
|
||||
GSM0808_IE_TRIGGERID = 38,
|
||||
GSM0808_IE_TRACE_REFERENCE = 39,
|
||||
GSM0808_IE_TRANSACTIONID = 40,
|
||||
GSM0808_IE_MOBILE_IDENTITY = 41,
|
||||
GSM0808_IE_OMCID = 42,
|
||||
GSM0808_IE_FORWARD_INDICATOR = 43,
|
||||
GSM0808_IE_CHOSEN_ENCR_ALG = 44,
|
||||
GSM0808_IE_CIRCUIT_POOL = 45,
|
||||
GSM0808_IE_CIRCUIT_POOL_LIST = 46,
|
||||
GSM0808_IE_TIME_INDICATION = 47,
|
||||
GSM0808_IE_RESOURCE_SITUATION = 48,
|
||||
GSM0808_IE_CURRENT_CHANNEL_TYPE_1 = 49,
|
||||
GSM0808_IE_QUEUEING_INDICATOR = 50,
|
||||
GSM0808_IE_SPEECH_VERSION = 64,
|
||||
GSM0808_IE_ASSIGNMENT_REQUIREMENT = 51,
|
||||
GSM0808_IE_TALKER_FLAG = 53,
|
||||
GSM0808_IE_CONNECTION_RELEASE_RQSTED = 54,
|
||||
GSM0808_IE_GROUP_CALL_REFERENCE = 55,
|
||||
GSM0808_IE_EMLPP_PRIORITY = 56,
|
||||
GSM0808_IE_CONFIG_EVO_INDI = 57,
|
||||
GSM0808_IE_OLD_BSS_TO_NEW_BSS_INFORMATION = 58,
|
||||
GSM0808_IE_LSA_IDENTIFIER = 59,
|
||||
GSM0808_IE_LSA_IDENTIFIER_LIST = 60,
|
||||
GSM0808_IE_LSA_INFORMATION = 61,
|
||||
GSM0808_IE_LCS_QOS = 62,
|
||||
GSM0808_IE_LSA_ACCESS_CTRL_SUPPR = 63,
|
||||
GSM0808_IE_LCS_PRIORITY = 67,
|
||||
GSM0808_IE_LOCATION_TYPE = 68,
|
||||
GSM0808_IE_LOCATION_ESTIMATE = 69,
|
||||
GSM0808_IE_POSITIONING_DATA = 70,
|
||||
GSM0808_IE_LCS_CAUSE = 71,
|
||||
GSM0808_IE_LCS_CLIENT_TYPE = 72,
|
||||
GSM0808_IE_APDU = 73,
|
||||
GSM0808_IE_NETWORK_ELEMENT_IDENTITY = 74,
|
||||
GSM0808_IE_GPS_ASSISTANCE_DATA = 75,
|
||||
GSM0808_IE_DECIPHERING_KEYS = 76,
|
||||
GSM0808_IE_RETURN_ERROR_RQST = 77,
|
||||
GSM0808_IE_RETURN_ERROR_CAUSE = 78,
|
||||
GSM0808_IE_SEGMENTATION = 79,
|
||||
GSM0808_IE_SERVICE_HANDOVER = 80,
|
||||
GSM0808_IE_SOURCE_RNC_TO_TARGET_RNC_TRANSPARENT_UMTS = 81,
|
||||
GSM0808_IE_SOURCE_RNC_TO_TARGET_RNC_TRANSPARENT_CDMA2000= 82,
|
||||
GSM0808_IE_RESERVED_5 = 65,
|
||||
GSM0808_IE_RESERVED_6 = 66,
|
||||
};
|
||||
|
||||
enum gsm0808_cause {
|
||||
GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE = 0,
|
||||
GSM0808_CAUSE_RADIO_INTERFACE_FAILURE = 1,
|
||||
GSM0808_CAUSE_UPLINK_QUALITY = 2,
|
||||
GSM0808_CAUSE_UPLINK_STRENGTH = 3,
|
||||
GSM0808_CAUSE_DOWNLINK_QUALITY = 4,
|
||||
GSM0808_CAUSE_DOWNLINK_STRENGTH = 5,
|
||||
GSM0808_CAUSE_DISTANCE = 6,
|
||||
GSM0808_CAUSE_O_AND_M_INTERVENTION = 7,
|
||||
GSM0808_CAUSE_RESPONSE_TO_MSC_INVOCATION = 8,
|
||||
GSM0808_CAUSE_CALL_CONTROL = 9,
|
||||
GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION = 10,
|
||||
GSM0808_CAUSE_HANDOVER_SUCCESSFUL = 11,
|
||||
GSM0808_CAUSE_BETTER_CELL = 12,
|
||||
GSM0808_CAUSE_DIRECTED_RETRY = 13,
|
||||
GSM0808_CAUSE_JOINED_GROUP_CALL_CHANNEL = 14,
|
||||
GSM0808_CAUSE_TRAFFIC = 15,
|
||||
GSM0808_CAUSE_EQUIPMENT_FAILURE = 32,
|
||||
GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE = 33,
|
||||
GSM0808_CAUSE_RQSTED_TERRESTRIAL_RESOURCE_UNAVAILABLE = 34,
|
||||
GSM0808_CAUSE_CCCH_OVERLOAD = 35,
|
||||
GSM0808_CAUSE_PROCESSOR_OVERLOAD = 36,
|
||||
GSM0808_CAUSE_BSS_NOT_EQUIPPED = 37,
|
||||
GSM0808_CAUSE_MS_NOT_EQUIPPED = 38,
|
||||
GSM0808_CAUSE_INVALID_CELL = 39,
|
||||
GSM0808_CAUSE_TRAFFIC_LOAD = 40,
|
||||
GSM0808_CAUSE_PREEMPTION = 41,
|
||||
GSM0808_CAUSE_RQSTED_TRANSCODING_RATE_ADAPTION_UNAVAILABLE = 48,
|
||||
GSM0808_CAUSE_CIRCUIT_POOL_MISMATCH = 49,
|
||||
GSM0808_CAUSE_SWITCH_CIRCUIT_POOL = 50,
|
||||
GSM0808_CAUSE_RQSTED_SPEECH_VERSION_UNAVAILABLE = 51,
|
||||
GSM0808_CAUSE_LSA_NOT_ALLOWED = 52,
|
||||
GSM0808_CAUSE_CIPHERING_ALGORITHM_NOT_SUPPORTED = 64,
|
||||
GSM0808_CAUSE_TERRESTRIAL_CIRCUIT_ALREADY_ALLOCATED = 80,
|
||||
GSM0808_CAUSE_INVALID_MESSAGE_CONTENTS = 81,
|
||||
GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING = 82,
|
||||
GSM0808_CAUSE_INCORRECT_VALUE = 83,
|
||||
GSM0808_CAUSE_UNKNOWN_MESSAGE_TYPE = 84,
|
||||
GSM0808_CAUSE_UNKNOWN_INFORMATION_ELEMENT = 85,
|
||||
GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC = 96,
|
||||
};
|
||||
|
||||
/* GSM 08.08 3.2.2.11 Channel Type */
|
||||
enum gsm0808_chan_indicator {
|
||||
GSM0808_CHAN_SPEECH = 1,
|
||||
GSM0808_CHAN_DATA = 2,
|
||||
GSM0808_CHAN_SIGN = 3,
|
||||
};
|
||||
|
||||
enum gsm0808_chan_rate_type_data {
|
||||
GSM0808_DATA_FULL_BM = 0x8,
|
||||
GSM0808_DATA_HALF_LM = 0x9,
|
||||
GSM0808_DATA_FULL_RPREF = 0xa,
|
||||
GSM0808_DATA_HALF_PREF = 0xb,
|
||||
GSM0808_DATA_FULL_PREF_NO_CHANGE = 0x1a,
|
||||
GSM0808_DATA_HALF_PREF_NO_CHANGE = 0x1b,
|
||||
GSM0808_DATA_MULTI_MASK = 0x20,
|
||||
GSM0808_DATA_MULTI_MASK_NO_CHANGE = 0x30,
|
||||
};
|
||||
|
||||
enum gsm0808_chan_rate_type_speech {
|
||||
GSM0808_SPEECH_FULL_BM = 0x8,
|
||||
GSM0808_SPEECH_HALF_LM = 0x9,
|
||||
GSM0808_SPEECH_FULL_PREF= 0xa,
|
||||
GSM0808_SPEECH_HALF_PREF= 0xb,
|
||||
GSM0808_SPEECH_FULL_PREF_NO_CHANGE = 0x1a,
|
||||
GSM0808_SPEECH_HALF_PREF_NO_CHANGE = 0x1b,
|
||||
GSM0808_SPEECH_PERM = 0xf,
|
||||
GSM0808_SPEECH_PERM_NO_CHANGE = 0x1f,
|
||||
};
|
||||
|
||||
enum gsm0808_permitted_speech {
|
||||
GSM0808_PERM_FR1 = 0x01,
|
||||
GSM0808_PERM_FR2 = 0x11,
|
||||
GSM0808_PERM_FR3 = 0x21,
|
||||
GSM0808_PERM_HR1 = GSM0808_PERM_FR1 | 0x4,
|
||||
GSM0808_PERM_HR2 = GSM0808_PERM_FR2 | 0x4,
|
||||
GSM0808_PERM_HR3 = GSM0808_PERM_FR3 | 0x4,
|
||||
};
|
||||
|
||||
int bssmap_rcvmsg_dt1(struct sccp_connection *conn, struct msgb *msg, unsigned int length);
|
||||
int bssmap_rcvmsg_udt(struct gsm_network *net, struct msgb *msg, unsigned int length);
|
||||
|
||||
struct msgb *bssmap_create_layer3(struct msgb *msg);
|
||||
struct msgb *bssmap_create_reset(void);
|
||||
struct msgb *bssmap_create_clear_complete(void);
|
||||
struct msgb *bssmap_create_cipher_complete(struct msgb *layer3);
|
||||
struct msgb *bssmap_create_cipher_reject(u_int8_t cause);
|
||||
struct msgb *bssmap_create_sapi_reject(u_int8_t link_id);
|
||||
struct msgb *bssmap_create_assignment_completed(struct gsm_lchan *lchan, u_int8_t rr_cause);
|
||||
struct msgb *bssmap_create_assignment_failure(u_int8_t cause, u_int8_t *rr_cause);
|
||||
struct msgb *bssmap_create_classmark_update(const u_int8_t *classmark, u_int8_t length);
|
||||
|
||||
void gsm0808_send_assignment_failure(struct gsm_lchan *l, u_int8_t cause, u_int8_t *rr_value);
|
||||
void gsm0808_send_assignment_compl(struct gsm_lchan *l, u_int8_t rr_value);
|
||||
|
||||
int dtap_rcvmsg(struct gsm_lchan *lchan, struct msgb *msg, unsigned int length);
|
||||
struct msgb *dtap_create_msg(struct msgb *msg_l3, u_int8_t link_id);
|
||||
|
||||
void bsc_queue_connection_write(struct sccp_connection *conn, struct msgb *msg);
|
||||
void bsc_free_queued(struct sccp_connection *conn);
|
||||
void bsc_send_queued(struct sccp_connection *conn);
|
||||
|
||||
void bts_queue_send(struct msgb *msg, int link_id);
|
||||
void bts_send_queued(struct bss_sccp_connection_data*);
|
||||
void bts_free_queued(struct bss_sccp_connection_data*);
|
||||
void bts_unblock_queue(struct bss_sccp_connection_data*);
|
||||
|
||||
#endif
|
||||
@@ -23,6 +23,28 @@
|
||||
|
||||
#include "gsm_subscriber.h"
|
||||
|
||||
/*
|
||||
* Refcounting for the lchan. If the refcount drops to zero
|
||||
* the channel will send a RSL release request.
|
||||
*/
|
||||
#define use_lchan(lchan) \
|
||||
do { lchan->use_count++; \
|
||||
DEBUGP(DCC, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) increases usage to: %d\n", \
|
||||
lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, \
|
||||
lchan->nr, lchan->use_count); \
|
||||
} while(0);
|
||||
|
||||
#define put_lchan(lchan) \
|
||||
do { lchan->use_count--; \
|
||||
DEBUGP(DCC, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) decreases usage to: %d\n", \
|
||||
lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, \
|
||||
lchan->nr, lchan->use_count); \
|
||||
if (lchan->use_count <= 0) \
|
||||
_lchan_release(lchan); \
|
||||
} while(0);
|
||||
|
||||
|
||||
|
||||
/* Special allocator for C0 of BTS */
|
||||
struct gsm_bts_trx_ts *ts_c0_alloc(struct gsm_bts *bts,
|
||||
enum gsm_phys_chan_config pchan);
|
||||
@@ -46,21 +68,7 @@ struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type);
|
||||
/* Free a logical channel (SDCCH, TCH, ...) */
|
||||
void lchan_free(struct gsm_lchan *lchan);
|
||||
|
||||
/* Consider releasing the channel */
|
||||
int lchan_auto_release(struct gsm_lchan *lchan);
|
||||
|
||||
struct load_counter {
|
||||
unsigned int total;
|
||||
unsigned int used;
|
||||
};
|
||||
|
||||
struct pchan_load {
|
||||
struct load_counter pchan[GSM_PCHAN_UNKNOWN];
|
||||
};
|
||||
|
||||
void bts_chan_load(struct pchan_load *cl, const struct gsm_bts *bts);
|
||||
void network_chan_load(struct pchan_load *pl, struct gsm_network *net);
|
||||
|
||||
int trx_is_usable(struct gsm_bts_trx *trx);
|
||||
/* internal.. do not use */
|
||||
int _lchan_release(struct gsm_lchan *lchan);
|
||||
|
||||
#endif /* _CHAN_ALLOC_H */
|
||||
|
||||
@@ -43,20 +43,9 @@ int db_subscriber_alloc_token(struct gsm_subscriber* subscriber, u_int32_t* toke
|
||||
int db_subscriber_assoc_imei(struct gsm_subscriber* subscriber, char *imei);
|
||||
int db_sync_equipment(struct gsm_equipment *equip);
|
||||
|
||||
/* auth info */
|
||||
int get_authinfo_by_subscr(struct gsm_auth_info *ainfo,
|
||||
struct gsm_subscriber *subscr);
|
||||
int set_authinfo_for_subscr(struct gsm_auth_info *ainfo,
|
||||
struct gsm_subscriber *subscr);
|
||||
int get_authtuple_by_subscr(struct gsm_auth_tuple *atuple,
|
||||
struct gsm_subscriber *subscr);
|
||||
int set_authtuple_for_subscr(struct gsm_auth_tuple *atuple,
|
||||
struct gsm_subscriber *subscr);
|
||||
|
||||
/* SMS store-and-forward */
|
||||
int db_sms_store(struct gsm_sms *sms);
|
||||
struct gsm_sms *db_sms_get_unsent(struct gsm_network *net, int min_id);
|
||||
struct gsm_sms *db_sms_get_unsent_by_subscr(struct gsm_network *net, int min_subscr_id);
|
||||
struct gsm_sms *db_sms_get_unsent_for_subscr(struct gsm_subscriber *subscr);
|
||||
int db_sms_mark_sent(struct gsm_sms *sms);
|
||||
|
||||
@@ -64,8 +53,4 @@ int db_sms_mark_sent(struct gsm_sms *sms);
|
||||
int db_apdu_blob_store(struct gsm_subscriber *subscr,
|
||||
u_int8_t apdu_id_flags, u_int8_t len,
|
||||
u_int8_t *apdu);
|
||||
|
||||
/* Statistics counter storage */
|
||||
int db_store_counter(struct counter *ctr);
|
||||
|
||||
#endif /* _DB_H */
|
||||
|
||||
@@ -1,53 +1,52 @@
|
||||
#ifndef _DEBUG_H
|
||||
#define _DEBUG_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <osmocore/linuxlist.h>
|
||||
|
||||
#define DEBUG
|
||||
|
||||
/* Debug Areas of the code */
|
||||
enum {
|
||||
DRLL,
|
||||
DCC,
|
||||
DMM,
|
||||
DRR,
|
||||
DRSL,
|
||||
DNM,
|
||||
DMNCC,
|
||||
DSMS,
|
||||
DPAG,
|
||||
DMEAS,
|
||||
DMI,
|
||||
DMIB,
|
||||
DMUX,
|
||||
DINP,
|
||||
DSCCP,
|
||||
DMSC,
|
||||
DMGCP,
|
||||
DHO,
|
||||
DDB,
|
||||
DREF,
|
||||
Debug_LastEntry,
|
||||
};
|
||||
#define DRLL 0x0001
|
||||
#define DCC 0x0002
|
||||
#define DMM 0x0004
|
||||
#define DRR 0x0008
|
||||
#define DRSL 0x0010
|
||||
#define DNM 0x0020
|
||||
|
||||
#define DMNCC 0x0080
|
||||
#define DSMS 0x0100
|
||||
#define DPAG 0x0200
|
||||
#define DMEAS 0x0400
|
||||
|
||||
#define DMI 0x1000
|
||||
#define DMIB 0x2000
|
||||
#define DMUX 0x4000
|
||||
#define DINP 0x8000
|
||||
|
||||
#define DSCCP 0x10000
|
||||
#define DMSC 0x20000
|
||||
|
||||
#define DMGCP 0x40000
|
||||
|
||||
#define DHO 0x80000
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUGP(ss, fmt, args...) debugp(ss, __FILE__, __LINE__, 0, fmt, ## args)
|
||||
#define DEBUGPC(ss, fmt, args...) debugp(ss, __FILE__, __LINE__, 1, fmt, ## args)
|
||||
#else
|
||||
#define DEBUGP(xss, fmt, args...)
|
||||
#define DEBUGP(xss, fmt, args...)
|
||||
#define DEBUGPC(ss, fmt, args...)
|
||||
#endif
|
||||
|
||||
|
||||
#define static_assert(exp, name) typedef int dummy##name [(exp) ? 1 : -1];
|
||||
|
||||
char *hexdump(const unsigned char *buf, int len);
|
||||
void debugp(unsigned int subsys, char *file, int line, int cont, const char *format, ...) __attribute__ ((format (printf, 5, 6)));
|
||||
void debug_parse_category_mask(const char* mask);
|
||||
void debug_use_color(int use_color);
|
||||
void debug_timestamp(int enable);
|
||||
extern unsigned int debug_mask;
|
||||
|
||||
/* new logging interface */
|
||||
#define LOGP(ss, level, fmt, args...) debugp2(ss, level, __FILE__, __LINE__, 0, fmt, ##args)
|
||||
#define LOGPC(ss, level, fmt, args...) debugp2(ss, level, __FILE__, __LINE__, 1, fmt, ##args)
|
||||
#define LOGP(ss, level, fmt, args...) debugp(ss, __FILE__, __LINE__, 0, fmt, ##args)
|
||||
#define LOGPC(ss, level, fmt, args...) debugp(ss, __FILE__, __LINE__, 1, fmt, ##args)
|
||||
|
||||
/* different levels */
|
||||
#define LOGL_DEBUG 1 /* debugging information */
|
||||
@@ -56,76 +55,4 @@ void debugp(unsigned int subsys, char *file, int line, int cont, const char *for
|
||||
#define LOGL_ERROR 7 /* error condition, requires user action */
|
||||
#define LOGL_FATAL 8 /* fatal, program aborted */
|
||||
|
||||
/* context */
|
||||
#define BSC_CTX_LCHAN 0
|
||||
#define BSC_CTX_SUBSCR 1
|
||||
#define BSC_CTX_BTS 2
|
||||
#define BSC_CTX_SCCP 3
|
||||
|
||||
/* target */
|
||||
|
||||
enum {
|
||||
DEBUG_FILTER_IMSI = 1 << 0,
|
||||
DEBUG_FILTER_ALL = 1 << 1,
|
||||
};
|
||||
|
||||
struct debug_category {
|
||||
int enabled;
|
||||
int loglevel;
|
||||
};
|
||||
|
||||
struct debug_target {
|
||||
int filter_map;
|
||||
char *imsi_filter;
|
||||
|
||||
|
||||
struct debug_category categories[Debug_LastEntry];
|
||||
int use_color;
|
||||
int print_timestamp;
|
||||
int loglevel;
|
||||
|
||||
union {
|
||||
struct {
|
||||
FILE *out;
|
||||
} tgt_stdout;
|
||||
|
||||
struct {
|
||||
int priority;
|
||||
} tgt_syslog;
|
||||
|
||||
struct {
|
||||
void *vty;
|
||||
} tgt_vty;
|
||||
};
|
||||
|
||||
void (*output) (struct debug_target *target, const char *string);
|
||||
|
||||
struct llist_head entry;
|
||||
};
|
||||
|
||||
/* use the above macros */
|
||||
void debugp2(unsigned int subsys, unsigned int level, char *file, int line, int cont, const char *format, ...) __attribute__ ((format (printf, 6, 7)));
|
||||
void debug_init(void);
|
||||
|
||||
/* context management */
|
||||
void debug_reset_context(void);
|
||||
void debug_set_context(int ctx, void *value);
|
||||
|
||||
/* filter on the targets */
|
||||
void debug_set_imsi_filter(struct debug_target *target, const char *imsi);
|
||||
void debug_set_all_filter(struct debug_target *target, int);
|
||||
void debug_set_use_color(struct debug_target *target, int);
|
||||
void debug_set_print_timestamp(struct debug_target *target, int);
|
||||
void debug_set_log_level(struct debug_target *target, int log_level);
|
||||
void debug_parse_category_mask(struct debug_target *target, const char* mask);
|
||||
int debug_parse_level(const char *lvl);
|
||||
int debug_parse_category(const char *category);
|
||||
void debug_set_category_filter(struct debug_target *target, int category, int enable, int level);
|
||||
|
||||
|
||||
/* management of the targets */
|
||||
struct debug_target *debug_target_create(void);
|
||||
struct debug_target *debug_target_create_stderr(void);
|
||||
void debug_add_target(struct debug_target *target);
|
||||
void debug_del_target(struct debug_target *target);
|
||||
#endif /* _DEBUG_H */
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <openbsc/linuxlist.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/select.h>
|
||||
#include <openbsc/msgb.h>
|
||||
#include <openbsc/select.h>
|
||||
#include <openbsc/subchan_demux.h>
|
||||
|
||||
#define NUM_E1_TS 32
|
||||
|
||||
@@ -3,8 +3,742 @@
|
||||
|
||||
#include <openbsc/meas_rep.h>
|
||||
|
||||
#include <osmocore/protocol/gsm_04_08.h>
|
||||
#include <osmocore/gsm48.h>
|
||||
/* GSM TS 04.08 definitions */
|
||||
struct gsm_lchan;
|
||||
|
||||
struct gsm48_classmark1 {
|
||||
u_int8_t spare:1,
|
||||
rev_level:2,
|
||||
es_ind:1,
|
||||
a5_1:1,
|
||||
pwr_lev:3;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Chapter 10.5.2.5 */
|
||||
struct gsm48_chan_desc {
|
||||
u_int8_t chan_nr;
|
||||
union {
|
||||
struct {
|
||||
u_int8_t maio_high:4,
|
||||
h:1,
|
||||
tsc:3;
|
||||
u_int8_t hsn:6,
|
||||
maio_low:2;
|
||||
} h1;
|
||||
struct {
|
||||
u_int8_t arfcn_high:2,
|
||||
spare:2,
|
||||
h:1,
|
||||
tsc:3;
|
||||
u_int8_t arfcn_low;
|
||||
} h0;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Chapter 10.5.2.21aa */
|
||||
struct gsm48_multi_rate_conf {
|
||||
u_int8_t smod : 2,
|
||||
spare: 1,
|
||||
icmi : 1,
|
||||
nscb : 1,
|
||||
ver : 3;
|
||||
u_int8_t m4_75 : 1,
|
||||
m5_15 : 1,
|
||||
m5_90 : 1,
|
||||
m6_70 : 1,
|
||||
m7_40 : 1,
|
||||
m7_95 : 1,
|
||||
m10_2 : 1,
|
||||
m12_2 : 1;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Chapter 10.5.2.30 */
|
||||
struct gsm48_req_ref {
|
||||
u_int8_t ra;
|
||||
u_int8_t t3_high:3,
|
||||
t1_:5;
|
||||
u_int8_t t2:5,
|
||||
t3_low:3;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/*
|
||||
* Chapter 9.1.5/9.1.6
|
||||
*
|
||||
* For 9.1.6 the chan_desc has the meaning of 10.5.2.5a
|
||||
*/
|
||||
struct gsm48_chan_mode_modify {
|
||||
struct gsm48_chan_desc chan_desc;
|
||||
u_int8_t mode;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
enum gsm48_chan_mode {
|
||||
GSM48_CMODE_SIGN = 0x00,
|
||||
GSM48_CMODE_SPEECH_V1 = 0x01,
|
||||
GSM48_CMODE_SPEECH_EFR = 0x21,
|
||||
GSM48_CMODE_SPEECH_AMR = 0x41,
|
||||
GSM48_CMODE_DATA_14k5 = 0x0f,
|
||||
GSM48_CMODE_DATA_12k0 = 0x03,
|
||||
GSM48_CMODE_DATA_6k0 = 0x0b,
|
||||
GSM48_CMODE_DATA_3k6 = 0x23,
|
||||
};
|
||||
|
||||
/* Chapter 9.1.2 */
|
||||
struct gsm48_ass_cmd {
|
||||
/* Semantic is from 10.5.2.5a */
|
||||
struct gsm48_chan_desc chan_desc;
|
||||
u_int8_t power_command;
|
||||
u_int8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Chapter 10.5.2.2 */
|
||||
struct gsm48_cell_desc {
|
||||
u_int8_t bcc:3,
|
||||
ncc:3,
|
||||
arfcn_hi:2;
|
||||
u_int8_t arfcn_lo;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Chapter 9.1.15 */
|
||||
struct gsm48_ho_cmd {
|
||||
struct gsm48_cell_desc cell_desc;
|
||||
struct gsm48_chan_desc chan_desc;
|
||||
u_int8_t ho_ref;
|
||||
u_int8_t power_command;
|
||||
u_int8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Chapter 9.1.18 */
|
||||
struct gsm48_imm_ass {
|
||||
u_int8_t l2_plen;
|
||||
u_int8_t proto_discr;
|
||||
u_int8_t msg_type;
|
||||
u_int8_t page_mode;
|
||||
struct gsm48_chan_desc chan_desc;
|
||||
struct gsm48_req_ref req_ref;
|
||||
u_int8_t timing_advance;
|
||||
u_int8_t mob_alloc_len;
|
||||
u_int8_t mob_alloc[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Chapter 10.5.1.3 */
|
||||
struct gsm48_loc_area_id {
|
||||
u_int8_t digits[3]; /* BCD! */
|
||||
u_int16_t lac;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.2.2 */
|
||||
struct gsm48_auth_req {
|
||||
u_int8_t key_seq:4,
|
||||
spare:4;
|
||||
u_int8_t rand[16];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.2.15 */
|
||||
struct gsm48_loc_upd_req {
|
||||
u_int8_t type:4,
|
||||
key_seq:4;
|
||||
struct gsm48_loc_area_id lai;
|
||||
struct gsm48_classmark1 classmark1;
|
||||
u_int8_t mi_len;
|
||||
u_int8_t mi[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 10.1 */
|
||||
struct gsm48_hdr {
|
||||
u_int8_t proto_discr;
|
||||
u_int8_t msg_type;
|
||||
u_int8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.3x System information Type header */
|
||||
struct gsm48_system_information_type_header {
|
||||
u_int8_t l2_plen;
|
||||
u_int8_t rr_protocol_discriminator :4,
|
||||
skip_indicator:4;
|
||||
u_int8_t system_information;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct gsm48_rach_control {
|
||||
u_int8_t re :1,
|
||||
cell_bar :1,
|
||||
tx_integer :4,
|
||||
max_trans :2;
|
||||
u_int8_t t2;
|
||||
u_int8_t t3;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 10.5.2.4 Cell Selection Parameters */
|
||||
struct gsm48_cell_sel_par {
|
||||
u_int8_t ms_txpwr_max_ccch:5, /* GSM 05.08 MS-TXPWR-MAX-CCCH */
|
||||
cell_resel_hyst:3; /* GSM 05.08 CELL-RESELECT-HYSTERESIS */
|
||||
u_int8_t rxlev_acc_min:6, /* GSM 05.08 RXLEV-ACCESS-MIN */
|
||||
neci:1,
|
||||
acs:1;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 10.5.2.11 Control Channel Description , Figure 10.5.33 */
|
||||
struct gsm48_control_channel_descr {
|
||||
u_int8_t ccch_conf :3,
|
||||
bs_ag_blks_res :3,
|
||||
att :1,
|
||||
spare1 :1;
|
||||
u_int8_t bs_pa_mfrms : 3,
|
||||
spare2 :5;
|
||||
u_int8_t t3212;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct gsm48_cell_options {
|
||||
u_int8_t radio_link_timeout:4,
|
||||
dtx:2,
|
||||
pwrc:1,
|
||||
spare:1;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.2.9 CM service request */
|
||||
struct gsm48_service_request {
|
||||
u_int8_t cm_service_type : 4,
|
||||
cipher_key_seq : 4;
|
||||
/* length + 3 bytes */
|
||||
u_int32_t classmark;
|
||||
u_int8_t mi_len;
|
||||
u_int8_t mi[0];
|
||||
/* optional priority level */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.31 System information Type 1 */
|
||||
struct gsm48_system_information_type_1 {
|
||||
struct gsm48_system_information_type_header header;
|
||||
u_int8_t cell_channel_description[16];
|
||||
struct gsm48_rach_control rach_control;
|
||||
u_int8_t rest_octets[0]; /* NCH position on the CCCH */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.32 System information Type 2 */
|
||||
struct gsm48_system_information_type_2 {
|
||||
struct gsm48_system_information_type_header header;
|
||||
u_int8_t bcch_frequency_list[16];
|
||||
u_int8_t ncc_permitted;
|
||||
struct gsm48_rach_control rach_control;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.35 System information Type 3 */
|
||||
struct gsm48_system_information_type_3 {
|
||||
struct gsm48_system_information_type_header header;
|
||||
u_int16_t cell_identity;
|
||||
struct gsm48_loc_area_id lai;
|
||||
struct gsm48_control_channel_descr control_channel_desc;
|
||||
struct gsm48_cell_options cell_options;
|
||||
struct gsm48_cell_sel_par cell_sel_par;
|
||||
struct gsm48_rach_control rach_control;
|
||||
u_int8_t rest_octets[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.36 System information Type 4 */
|
||||
struct gsm48_system_information_type_4 {
|
||||
struct gsm48_system_information_type_header header;
|
||||
struct gsm48_loc_area_id lai;
|
||||
struct gsm48_cell_sel_par cell_sel_par;
|
||||
struct gsm48_rach_control rach_control;
|
||||
/* optional CBCH conditional CBCH... followed by
|
||||
mandantory SI 4 Reset Octets
|
||||
*/
|
||||
u_int8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.37 System information Type 5 */
|
||||
struct gsm48_system_information_type_5 {
|
||||
u_int8_t rr_protocol_discriminator :4,
|
||||
skip_indicator:4;
|
||||
u_int8_t system_information;
|
||||
u_int8_t bcch_frequency_list[16];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.40 System information Type 6 */
|
||||
struct gsm48_system_information_type_6 {
|
||||
u_int8_t rr_protocol_discriminator :4,
|
||||
skip_indicator:4;
|
||||
u_int8_t system_information;
|
||||
u_int16_t cell_identity;
|
||||
struct gsm48_loc_area_id lai;
|
||||
struct gsm48_cell_options cell_options;
|
||||
u_int8_t ncc_permitted;
|
||||
u_int8_t rest_octets[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.43a System Information type 13 */
|
||||
struct gsm48_system_information_type_13 {
|
||||
struct gsm48_system_information_type_header header;
|
||||
u_int8_t rest_octets[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.2.12 IMSI Detach Indication */
|
||||
struct gsm48_imsi_detach_ind {
|
||||
struct gsm48_classmark1 classmark1;
|
||||
u_int8_t mi_len;
|
||||
u_int8_t mi[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 10.2 + GSM 04.07 12.2.3.1.1 */
|
||||
#define GSM48_PDISC_GROUP_CC 0x00
|
||||
#define GSM48_PDISC_BCAST_CC 0x01
|
||||
#define GSM48_PDISC_PDSS1 0x02
|
||||
#define GSM48_PDISC_CC 0x03
|
||||
#define GSM48_PDISC_PDSS2 0x04
|
||||
#define GSM48_PDISC_MM 0x05
|
||||
#define GSM48_PDISC_RR 0x06
|
||||
#define GSM48_PDISC_MM_GPRS 0x08
|
||||
#define GSM48_PDISC_SMS 0x09
|
||||
#define GSM48_PDISC_SM_GPRS 0x0a
|
||||
#define GSM48_PDISC_NC_SS 0x0b
|
||||
#define GSM48_PDISC_LOC 0x0c
|
||||
#define GSM48_PDISC_MASK 0x0f
|
||||
#define GSM48_PDISC_USSD 0x11
|
||||
|
||||
/* Section 10.4 */
|
||||
#define GSM48_MT_RR_INIT_REQ 0x3c
|
||||
#define GSM48_MT_RR_ADD_ASS 0x3b
|
||||
#define GSM48_MT_RR_IMM_ASS 0x3f
|
||||
#define GSM48_MT_RR_IMM_ASS_EXT 0x39
|
||||
#define GSM48_MT_RR_IMM_ASS_REJ 0x3a
|
||||
|
||||
#define GSM48_MT_RR_CIPH_M_CMD 0x35
|
||||
#define GSM48_MT_RR_CIPH_M_COMPL 0x32
|
||||
|
||||
#define GSM48_MT_RR_CFG_CHG_CMD 0x30
|
||||
#define GSM48_MT_RR_CFG_CHG_ACK 0x31
|
||||
#define GSM48_MT_RR_CFG_CHG_REJ 0x33
|
||||
|
||||
#define GSM48_MT_RR_ASS_CMD 0x2e
|
||||
#define GSM48_MT_RR_ASS_COMPL 0x29
|
||||
#define GSM48_MT_RR_ASS_FAIL 0x2f
|
||||
#define GSM48_MT_RR_HANDO_CMD 0x2b
|
||||
#define GSM48_MT_RR_HANDO_COMPL 0x2c
|
||||
#define GSM48_MT_RR_HANDO_FAIL 0x28
|
||||
#define GSM48_MT_RR_HANDO_INFO 0x2d
|
||||
|
||||
#define GSM48_MT_RR_CELL_CHG_ORDER 0x08
|
||||
#define GSM48_MT_RR_PDCH_ASS_CMD 0x23
|
||||
|
||||
#define GSM48_MT_RR_CHAN_REL 0x0d
|
||||
#define GSM48_MT_RR_PART_REL 0x0a
|
||||
#define GSM48_MT_RR_PART_REL_COMP 0x0f
|
||||
|
||||
#define GSM48_MT_RR_PAG_REQ_1 0x21
|
||||
#define GSM48_MT_RR_PAG_REQ_2 0x22
|
||||
#define GSM48_MT_RR_PAG_REQ_3 0x24
|
||||
#define GSM48_MT_RR_PAG_RESP 0x27
|
||||
#define GSM48_MT_RR_NOTIF_NCH 0x20
|
||||
#define GSM48_MT_RR_NOTIF_FACCH 0x25
|
||||
#define GSM48_MT_RR_NOTIF_RESP 0x26
|
||||
|
||||
#define GSM48_MT_RR_SYSINFO_8 0x18
|
||||
#define GSM48_MT_RR_SYSINFO_1 0x19
|
||||
#define GSM48_MT_RR_SYSINFO_2 0x1a
|
||||
#define GSM48_MT_RR_SYSINFO_3 0x1b
|
||||
#define GSM48_MT_RR_SYSINFO_4 0x1c
|
||||
#define GSM48_MT_RR_SYSINFO_5 0x1d
|
||||
#define GSM48_MT_RR_SYSINFO_6 0x1e
|
||||
#define GSM48_MT_RR_SYSINFO_7 0x1f
|
||||
|
||||
#define GSM48_MT_RR_SYSINFO_2bis 0x02
|
||||
#define GSM48_MT_RR_SYSINFO_2ter 0x03
|
||||
#define GSM48_MT_RR_SYSINFO_5bis 0x05
|
||||
#define GSM48_MT_RR_SYSINFO_5ter 0x06
|
||||
#define GSM48_MT_RR_SYSINFO_9 0x04
|
||||
#define GSM48_MT_RR_SYSINFO_13 0x00
|
||||
|
||||
#define GSM48_MT_RR_SYSINFO_16 0x3d
|
||||
#define GSM48_MT_RR_SYSINFO_17 0x3e
|
||||
|
||||
#define GSM48_MT_RR_CHAN_MODE_MODIF 0x10
|
||||
#define GSM48_MT_RR_STATUS 0x12
|
||||
#define GSM48_MT_RR_CHAN_MODE_MODIF_ACK 0x17
|
||||
#define GSM48_MT_RR_FREQ_REDEF 0x14
|
||||
#define GSM48_MT_RR_MEAS_REP 0x15
|
||||
#define GSM48_MT_RR_CLSM_CHG 0x16
|
||||
#define GSM48_MT_RR_CLSM_ENQ 0x13
|
||||
#define GSM48_MT_RR_EXT_MEAS_REP 0x36
|
||||
#define GSM48_MT_RR_EXT_MEAS_REP_ORD 0x37
|
||||
#define GSM48_MT_RR_GPRS_SUSP_REQ 0x34
|
||||
|
||||
#define GSM48_MT_RR_VGCS_UPL_GRANT 0x08
|
||||
#define GSM48_MT_RR_UPLINK_RELEASE 0x0e
|
||||
#define GSM48_MT_RR_UPLINK_FREE 0x0c
|
||||
#define GSM48_MT_RR_UPLINK_BUSY 0x2a
|
||||
#define GSM48_MT_RR_TALKER_IND 0x11
|
||||
|
||||
#define GSM48_MT_RR_APP_INFO 0x38
|
||||
|
||||
/* Table 10.2/3GPP TS 04.08 */
|
||||
#define GSM48_MT_MM_IMSI_DETACH_IND 0x01
|
||||
#define GSM48_MT_MM_LOC_UPD_ACCEPT 0x02
|
||||
#define GSM48_MT_MM_LOC_UPD_REJECT 0x04
|
||||
#define GSM48_MT_MM_LOC_UPD_REQUEST 0x08
|
||||
|
||||
#define GSM48_MT_MM_AUTH_REJ 0x11
|
||||
#define GSM48_MT_MM_AUTH_REQ 0x12
|
||||
#define GSM48_MT_MM_AUTH_RESP 0x14
|
||||
#define GSM48_MT_MM_ID_REQ 0x18
|
||||
#define GSM48_MT_MM_ID_RESP 0x19
|
||||
#define GSM48_MT_MM_TMSI_REALL_CMD 0x1a
|
||||
#define GSM48_MT_MM_TMSI_REALL_COMPL 0x1b
|
||||
|
||||
#define GSM48_MT_MM_CM_SERV_ACC 0x21
|
||||
#define GSM48_MT_MM_CM_SERV_REJ 0x22
|
||||
#define GSM48_MT_MM_CM_SERV_ABORT 0x23
|
||||
#define GSM48_MT_MM_CM_SERV_REQ 0x24
|
||||
#define GSM48_MT_MM_CM_SERV_PROMPT 0x25
|
||||
#define GSM48_MT_MM_CM_REEST_REQ 0x28
|
||||
#define GSM48_MT_MM_ABORT 0x29
|
||||
|
||||
#define GSM48_MT_MM_NULL 0x30
|
||||
#define GSM48_MT_MM_STATUS 0x31
|
||||
#define GSM48_MT_MM_INFO 0x32
|
||||
|
||||
/* Table 10.3/3GPP TS 04.08 */
|
||||
#define GSM48_MT_CC_ALERTING 0x01
|
||||
#define GSM48_MT_CC_CALL_CONF 0x08
|
||||
#define GSM48_MT_CC_CALL_PROC 0x02
|
||||
#define GSM48_MT_CC_CONNECT 0x07
|
||||
#define GSM48_MT_CC_CONNECT_ACK 0x0f
|
||||
#define GSM48_MT_CC_EMERG_SETUP 0x0e
|
||||
#define GSM48_MT_CC_PROGRESS 0x03
|
||||
#define GSM48_MT_CC_ESTAB 0x04
|
||||
#define GSM48_MT_CC_ESTAB_CONF 0x06
|
||||
#define GSM48_MT_CC_RECALL 0x0b
|
||||
#define GSM48_MT_CC_START_CC 0x09
|
||||
#define GSM48_MT_CC_SETUP 0x05
|
||||
|
||||
#define GSM48_MT_CC_MODIFY 0x17
|
||||
#define GSM48_MT_CC_MODIFY_COMPL 0x1f
|
||||
#define GSM48_MT_CC_MODIFY_REJECT 0x13
|
||||
#define GSM48_MT_CC_USER_INFO 0x10
|
||||
#define GSM48_MT_CC_HOLD 0x18
|
||||
#define GSM48_MT_CC_HOLD_ACK 0x19
|
||||
#define GSM48_MT_CC_HOLD_REJ 0x1a
|
||||
#define GSM48_MT_CC_RETR 0x1c
|
||||
#define GSM48_MT_CC_RETR_ACK 0x1d
|
||||
#define GSM48_MT_CC_RETR_REJ 0x1e
|
||||
|
||||
#define GSM48_MT_CC_DISCONNECT 0x25
|
||||
#define GSM48_MT_CC_RELEASE 0x2d
|
||||
#define GSM48_MT_CC_RELEASE_COMPL 0x2a
|
||||
|
||||
#define GSM48_MT_CC_CONG_CTRL 0x39
|
||||
#define GSM48_MT_CC_NOTIFY 0x3e
|
||||
#define GSM48_MT_CC_STATUS 0x3d
|
||||
#define GSM48_MT_CC_STATUS_ENQ 0x34
|
||||
#define GSM48_MT_CC_START_DTMF 0x35
|
||||
#define GSM48_MT_CC_STOP_DTMF 0x31
|
||||
#define GSM48_MT_CC_STOP_DTMF_ACK 0x32
|
||||
#define GSM48_MT_CC_START_DTMF_ACK 0x36
|
||||
#define GSM48_MT_CC_START_DTMF_REJ 0x37
|
||||
#define GSM48_MT_CC_FACILITY 0x3a
|
||||
|
||||
/* FIXME: Table 10.4 / 10.4a (GPRS) */
|
||||
|
||||
/* Section 10.5.2.26, Table 10.5.64 */
|
||||
#define GSM48_PM_MASK 0x03
|
||||
#define GSM48_PM_NORMAL 0x00
|
||||
#define GSM48_PM_EXTENDED 0x01
|
||||
#define GSM48_PM_REORG 0x02
|
||||
#define GSM48_PM_SAME 0x03
|
||||
|
||||
/* Chapter 10.5.3.5 / Table 10.5.93 */
|
||||
#define GSM48_LUPD_NORMAL 0x0
|
||||
#define GSM48_LUPD_PERIODIC 0x1
|
||||
#define GSM48_LUPD_IMSI_ATT 0x2
|
||||
#define GSM48_LUPD_RESERVED 0x3
|
||||
|
||||
/* Table 10.5.4 */
|
||||
#define GSM_MI_TYPE_MASK 0x07
|
||||
#define GSM_MI_TYPE_NONE 0x00
|
||||
#define GSM_MI_TYPE_IMSI 0x01
|
||||
#define GSM_MI_TYPE_IMEI 0x02
|
||||
#define GSM_MI_TYPE_IMEISV 0x03
|
||||
#define GSM_MI_TYPE_TMSI 0x04
|
||||
#define GSM_MI_ODD 0x08
|
||||
|
||||
#define GSM48_IE_MUL_RATE_CFG 0x03 /* 10.5.2.21aa */
|
||||
#define GSM48_IE_MOBILE_ID 0x17
|
||||
#define GSM48_IE_NAME_LONG 0x43 /* 10.5.3.5a */
|
||||
#define GSM48_IE_NAME_SHORT 0x45 /* 10.5.3.5a */
|
||||
#define GSM48_IE_UTC 0x46 /* 10.5.3.8 */
|
||||
#define GSM48_IE_NET_TIME_TZ 0x47 /* 10.5.3.9 */
|
||||
#define GSM48_IE_LSA_IDENT 0x48 /* 10.5.3.11 */
|
||||
|
||||
#define GSM48_IE_BEARER_CAP 0x04 /* 10.5.4.5 */
|
||||
#define GSM48_IE_CAUSE 0x08 /* 10.5.4.11 */
|
||||
#define GSM48_IE_CC_CAP 0x15 /* 10.5.4.5a */
|
||||
#define GSM48_IE_ALERT 0x19 /* 10.5.4.26 */
|
||||
#define GSM48_IE_FACILITY 0x1c /* 10.5.4.15 */
|
||||
#define GSM48_IE_PROGR_IND 0x1e /* 10.5.4.21 */
|
||||
#define GSM48_IE_AUX_STATUS 0x24 /* 10.5.4.4 */
|
||||
#define GSM48_IE_NOTIFY 0x27 /* 10.5.4.20 */
|
||||
#define GSM48_IE_KPD_FACILITY 0x2c /* 10.5.4.17 */
|
||||
#define GSM48_IE_SIGNAL 0x34 /* 10.5.4.23 */
|
||||
#define GSM48_IE_CONN_BCD 0x4c /* 10.5.4.13 */
|
||||
#define GSM48_IE_CONN_SUB 0x4d /* 10.5.4.14 */
|
||||
#define GSM48_IE_CALLING_BCD 0x5c /* 10.5.4.9 */
|
||||
#define GSM48_IE_CALLING_SUB 0x5d /* 10.5.4.10 */
|
||||
#define GSM48_IE_CALLED_BCD 0x5e /* 10.5.4.7 */
|
||||
#define GSM48_IE_CALLED_SUB 0x6d /* 10.5.4.8 */
|
||||
#define GSM48_IE_REDIR_BCD 0x74 /* 10.5.4.21a */
|
||||
#define GSM48_IE_REDIR_SUB 0x75 /* 10.5.4.21b */
|
||||
#define GSM48_IE_LOWL_COMPAT 0x7c /* 10.5.4.18 */
|
||||
#define GSM48_IE_HIGHL_COMPAT 0x7d /* 10.5.4.16 */
|
||||
#define GSM48_IE_USER_USER 0x7e /* 10.5.4.25 */
|
||||
#define GSM48_IE_SS_VERS 0x7f /* 10.5.4.24 */
|
||||
#define GSM48_IE_MORE_DATA 0xa0 /* 10.5.4.19 */
|
||||
#define GSM48_IE_CLIR_SUPP 0xa1 /* 10.5.4.11a */
|
||||
#define GSM48_IE_CLIR_INVOC 0xa2 /* 10.5.4.11b */
|
||||
#define GSM48_IE_REV_C_SETUP 0xa3 /* 10.5.4.22a */
|
||||
#define GSM48_IE_REPEAT_CIR 0xd1 /* 10.5.4.22 */
|
||||
#define GSM48_IE_REPEAT_SEQ 0xd3 /* 10.5.4.22 */
|
||||
|
||||
/* Section 10.5.4.11 / Table 10.5.122 */
|
||||
#define GSM48_CAUSE_CS_GSM 0x60
|
||||
|
||||
/* Section 9.1.2 / Table 9.3 */
|
||||
#define GSM48_IE_FRQLIST_AFTER 0x05
|
||||
#define GSM48_IE_CELL_CH_DESC 0x62
|
||||
#define GSM48_IE_MSLOT_DESC 0x10
|
||||
#define GSM48_IE_CHANMODE_1 0x63
|
||||
#define GSM48_IE_CHANMODE_2 0x11
|
||||
#define GSM48_IE_CHANMODE_3 0x13
|
||||
#define GSM48_IE_CHANMODE_4 0x14
|
||||
#define GSM48_IE_CHANMODE_5 0x15
|
||||
#define GSM48_IE_CHANMODE_6 0x16
|
||||
#define GSM48_IE_CHANMODE_7 0x17
|
||||
#define GSM48_IE_CHANMODE_8 0x18
|
||||
#define GSM48_IE_CHANDESC_2 0x64
|
||||
/* FIXME */
|
||||
|
||||
/* Section 10.5.4.23 / Table 10.5.130 */
|
||||
enum gsm48_signal_val {
|
||||
GSM48_SIGNAL_DIALTONE = 0x00,
|
||||
GSM48_SIGNAL_RINGBACK = 0x01,
|
||||
GSM48_SIGNAL_INTERCEPT = 0x02,
|
||||
GSM48_SIGNAL_NET_CONG = 0x03,
|
||||
GSM48_SIGNAL_BUSY = 0x04,
|
||||
GSM48_SIGNAL_CONFIRM = 0x05,
|
||||
GSM48_SIGNAL_ANSWER = 0x06,
|
||||
GSM48_SIGNAL_CALL_WAIT = 0x07,
|
||||
GSM48_SIGNAL_OFF_HOOK = 0x08,
|
||||
GSM48_SIGNAL_OFF = 0x3f,
|
||||
GSM48_SIGNAL_ALERT_OFF = 0x4f,
|
||||
};
|
||||
|
||||
enum gsm48_cause_loc {
|
||||
GSM48_CAUSE_LOC_USER = 0x00,
|
||||
GSM48_CAUSE_LOC_PRN_S_LU = 0x01,
|
||||
GSM48_CAUSE_LOC_PUN_S_LU = 0x02,
|
||||
GSM48_CAUSE_LOC_TRANS_NET = 0x03,
|
||||
GSM48_CAUSE_LOC_PUN_S_RU = 0x04,
|
||||
GSM48_CAUSE_LOC_PRN_S_RU = 0x05,
|
||||
/* not defined */
|
||||
GSM48_CAUSE_LOC_INN_NET = 0x07,
|
||||
GSM48_CAUSE_LOC_NET_BEYOND = 0x0a,
|
||||
};
|
||||
|
||||
/* Section 10.5.2.31 RR Cause / Table 10.5.70 */
|
||||
enum gsm48_rr_cause {
|
||||
GSM48_RR_CAUSE_NORMAL = 0x00,
|
||||
GSM48_RR_CAUSE_ABNORMAL_UNSPEC = 0x01,
|
||||
GSM48_RR_CAUSE_ABNORMAL_UNACCT = 0x02,
|
||||
GSM48_RR_CAUSE_ABNORMAL_TIMER = 0x03,
|
||||
GSM48_RR_CAUSE_ABNORMAL_NOACT = 0x04,
|
||||
GSM48_RR_CAUSE_PREMPTIVE_REL = 0x05,
|
||||
GSM48_RR_CAUSE_HNDOVER_IMP = 0x06,
|
||||
GSM48_RR_CAUSE_CHAN_MODE_UNACCT = 0x07,
|
||||
GSM48_RR_CAUSE_FREQ_NOT_IMPL = 0x08,
|
||||
GSM48_RR_CAUSE_CALL_CLEARED = 0x41,
|
||||
GSM48_RR_CAUSE_SEMANT_INCORR = 0x5f,
|
||||
GSM48_RR_CAUSE_INVALID_MAND_INF = 0x60,
|
||||
GSM48_RR_CAUSE_MSG_TYPE_N = 0x61,
|
||||
GSM48_RR_CAUSE_MSG_TYPE_N_COMPAT= 0x62,
|
||||
GSM48_RR_CAUSE_COND_IE_ERROR = 0x64,
|
||||
GSM48_RR_CAUSE_NO_CELL_ALLOC_A = 0x65,
|
||||
GSM48_RR_CAUSE_PROT_ERROR_UNSPC = 0x6f,
|
||||
};
|
||||
|
||||
/* Section 10.5.4.11 CC Cause / Table 10.5.123 */
|
||||
enum gsm48_cc_cause {
|
||||
GSM48_CC_CAUSE_UNASSIGNED_NR = 1,
|
||||
GSM48_CC_CAUSE_NO_ROUTE = 3,
|
||||
GSM48_CC_CAUSE_CHAN_UNACCEPT = 6,
|
||||
GSM48_CC_CAUSE_OP_DET_BARRING = 8,
|
||||
GSM48_CC_CAUSE_NORM_CALL_CLEAR = 16,
|
||||
GSM48_CC_CAUSE_USER_BUSY = 17,
|
||||
GSM48_CC_CAUSE_USER_NOTRESPOND = 18,
|
||||
GSM48_CC_CAUSE_USER_ALERTING_NA = 19,
|
||||
GSM48_CC_CAUSE_CALL_REJECTED = 21,
|
||||
GSM48_CC_CAUSE_NUMBER_CHANGED = 22,
|
||||
GSM48_CC_CAUSE_PRE_EMPTION = 25,
|
||||
GSM48_CC_CAUSE_NONSE_USER_CLR = 26,
|
||||
GSM48_CC_CAUSE_DEST_OOO = 27,
|
||||
GSM48_CC_CAUSE_INV_NR_FORMAT = 28,
|
||||
GSM48_CC_CAUSE_FACILITY_REJ = 29,
|
||||
GSM48_CC_CAUSE_RESP_STATUS_INQ = 30,
|
||||
GSM48_CC_CAUSE_NORMAL_UNSPEC = 31,
|
||||
GSM48_CC_CAUSE_NO_CIRCUIT_CHAN = 34,
|
||||
GSM48_CC_CAUSE_NETWORK_OOO = 38,
|
||||
GSM48_CC_CAUSE_TEMP_FAILURE = 41,
|
||||
GSM48_CC_CAUSE_SWITCH_CONG = 42,
|
||||
GSM48_CC_CAUSE_ACC_INF_DISCARD = 43,
|
||||
GSM48_CC_CAUSE_REQ_CHAN_UNAVAIL = 44,
|
||||
GSM48_CC_CAUSE_RESOURCE_UNAVAIL = 47,
|
||||
GSM48_CC_CAUSE_QOS_UNAVAIL = 49,
|
||||
GSM48_CC_CAUSE_REQ_FAC_NOT_SUBSC= 50,
|
||||
GSM48_CC_CAUSE_INC_BARRED_CUG = 55,
|
||||
GSM48_CC_CAUSE_BEARER_CAP_UNAUTH= 57,
|
||||
GSM48_CC_CAUSE_BEARER_CA_UNAVAIL= 58,
|
||||
GSM48_CC_CAUSE_SERV_OPT_UNAVAIL = 63,
|
||||
GSM48_CC_CAUSE_BEARERSERV_UNIMPL= 65,
|
||||
GSM48_CC_CAUSE_ACM_GE_ACM_MAX = 68,
|
||||
GSM48_CC_CAUSE_REQ_FAC_NOTIMPL = 69,
|
||||
GSM48_CC_CAUSE_RESTR_BCAP_AVAIL = 70,
|
||||
GSM48_CC_CAUSE_SERV_OPT_UNIMPL = 79,
|
||||
GSM48_CC_CAUSE_INVAL_TRANS_ID = 81,
|
||||
GSM48_CC_CAUSE_USER_NOT_IN_CUG = 87,
|
||||
GSM48_CC_CAUSE_INCOMPAT_DEST = 88,
|
||||
GSM48_CC_CAUSE_INVAL_TRANS_NET = 91,
|
||||
GSM48_CC_CAUSE_SEMANTIC_INCORR = 95,
|
||||
GSM48_CC_CAUSE_INVAL_MAND_INF = 96,
|
||||
GSM48_CC_CAUSE_MSGTYPE_NOTEXIST = 97,
|
||||
GSM48_CC_CAUSE_MSGTYPE_INCOMPAT = 98,
|
||||
GSM48_CC_CAUSE_IE_NOTEXIST = 99,
|
||||
GSM48_CC_CAUSE_COND_IE_ERR = 100,
|
||||
GSM48_CC_CAUSE_MSG_INCOMP_STATE = 101,
|
||||
GSM48_CC_CAUSE_RECOVERY_TIMER = 102,
|
||||
GSM48_CC_CAUSE_PROTO_ERR = 111,
|
||||
GSM48_CC_CAUSE_INTERWORKING = 127,
|
||||
};
|
||||
|
||||
/* Annex G, GSM specific cause values for mobility management */
|
||||
enum gsm48_reject_value {
|
||||
GSM48_REJECT_IMSI_UNKNOWN_IN_HLR = 2,
|
||||
GSM48_REJECT_ILLEGAL_MS = 3,
|
||||
GSM48_REJECT_IMSI_UNKNOWN_IN_VLR = 4,
|
||||
GSM48_REJECT_IMEI_NOT_ACCEPTED = 5,
|
||||
GSM48_REJECT_ILLEGAL_ME = 6,
|
||||
GSM48_REJECT_PLMN_NOT_ALLOWED = 11,
|
||||
GSM48_REJECT_LOC_NOT_ALLOWED = 12,
|
||||
GSM48_REJECT_ROAMING_NOT_ALLOWED = 13,
|
||||
GSM48_REJECT_NETWORK_FAILURE = 17,
|
||||
GSM48_REJECT_CONGESTION = 22,
|
||||
GSM48_REJECT_SRV_OPT_NOT_SUPPORTED = 32,
|
||||
GSM48_REJECT_RQD_SRV_OPT_NOT_SUPPORTED = 33,
|
||||
GSM48_REJECT_SRV_OPT_TMP_OUT_OF_ORDER = 34,
|
||||
GSM48_REJECT_CALL_CAN_NOT_BE_IDENTIFIED = 38,
|
||||
GSM48_REJECT_INCORRECT_MESSAGE = 95,
|
||||
GSM48_REJECT_INVALID_MANDANTORY_INF = 96,
|
||||
GSM48_REJECT_MSG_TYPE_NOT_IMPLEMENTED = 97,
|
||||
GSM48_REJECT_MSG_TYPE_NOT_COMPATIBLE = 98,
|
||||
GSM48_REJECT_INF_ELEME_NOT_IMPLEMENTED = 99,
|
||||
GSM48_REJECT_CONDTIONAL_IE_ERROR = 100,
|
||||
GSM48_REJECT_MSG_NOT_COMPATIBLE = 101,
|
||||
GSM48_REJECT_PROTOCOL_ERROR = 111,
|
||||
|
||||
/* according to G.6 Additional cause codes for GMM */
|
||||
GSM48_REJECT_GPRS_NOT_ALLOWED = 7,
|
||||
GSM48_REJECT_SERVICES_NOT_ALLOWED = 8,
|
||||
GSM48_REJECT_MS_IDENTITY_NOT_DERVIVABLE = 9,
|
||||
GSM48_REJECT_IMPLICITLY_DETACHED = 10,
|
||||
GSM48_REJECT_GPRS_NOT_ALLOWED_IN_PLMN = 14,
|
||||
GSM48_REJECT_MSC_TMP_NOT_REACHABLE = 16,
|
||||
};
|
||||
|
||||
enum chreq_type {
|
||||
CHREQ_T_EMERG_CALL,
|
||||
CHREQ_T_CALL_REEST_TCH_F,
|
||||
CHREQ_T_CALL_REEST_TCH_H,
|
||||
CHREQ_T_CALL_REEST_TCH_H_DBL,
|
||||
CHREQ_T_SDCCH,
|
||||
CHREQ_T_TCH_F,
|
||||
CHREQ_T_VOICE_CALL_TCH_H,
|
||||
CHREQ_T_DATA_CALL_TCH_H,
|
||||
CHREQ_T_LOCATION_UPD,
|
||||
CHREQ_T_PAG_R_ANY_NECI0,
|
||||
CHREQ_T_PAG_R_ANY_NECI1,
|
||||
CHREQ_T_PAG_R_TCH_F,
|
||||
CHREQ_T_PAG_R_TCH_FH,
|
||||
CHREQ_T_LMU,
|
||||
CHREQ_T_RESERVED_SDCCH,
|
||||
CHREQ_T_RESERVED_IGNORE,
|
||||
};
|
||||
|
||||
/* Chapter 11.3 */
|
||||
#define GSM48_T301 180, 0
|
||||
#define GSM48_T303 30, 0
|
||||
#define GSM48_T305 30, 0
|
||||
#define GSM48_T306 30, 0
|
||||
#define GSM48_T308 10, 0
|
||||
#define GSM48_T310 180, 0
|
||||
#define GSM48_T313 30, 0
|
||||
#define GSM48_T323 30, 0
|
||||
#define GSM48_T331 30, 0
|
||||
#define GSM48_T333 30, 0
|
||||
#define GSM48_T334 25, 0 /* min 15 */
|
||||
#define GSM48_T338 30, 0
|
||||
|
||||
/* Chapter 5.1.2.2 */
|
||||
#define GSM_CSTATE_NULL 0
|
||||
#define GSM_CSTATE_INITIATED 1
|
||||
#define GSM_CSTATE_MO_CALL_PROC 3
|
||||
#define GSM_CSTATE_CALL_DELIVERED 4
|
||||
#define GSM_CSTATE_CALL_PRESENT 6
|
||||
#define GSM_CSTATE_CALL_RECEIVED 7
|
||||
#define GSM_CSTATE_CONNECT_REQUEST 8
|
||||
#define GSM_CSTATE_MO_TERM_CALL_CONF 9
|
||||
#define GSM_CSTATE_ACTIVE 10
|
||||
#define GSM_CSTATE_DISCONNECT_REQ 12
|
||||
#define GSM_CSTATE_DISCONNECT_IND 12
|
||||
#define GSM_CSTATE_RELEASE_REQ 19
|
||||
#define GSM_CSTATE_MO_ORIG_MODIFY 26
|
||||
#define GSM_CSTATE_MO_TERM_MODIFY 27
|
||||
#define GSM_CSTATE_CONNECT_IND 28
|
||||
|
||||
#define SBIT(a) (1 << a)
|
||||
#define ALL_STATES 0xffffffff
|
||||
|
||||
/* Table 10.5.3/3GPP TS 04.08: Location Area Identification information element */
|
||||
#define GSM_LAC_RESERVED_DETACHED 0x0
|
||||
#define GSM_LAC_RESERVED_ALL_BTS 0xfffe
|
||||
|
||||
/* GSM 04.08 Bearer Capability: Information Transfer Capability */
|
||||
enum gsm48_bcap_itcap {
|
||||
GSM48_BCAP_ITCAP_SPEECH = 0,
|
||||
GSM48_BCAP_ITCAP_UNR_DIG_INF = 1,
|
||||
GSM48_BCAP_ITCAP_3k1_AUDIO = 2,
|
||||
GSM48_BCAP_ITCAP_FAX_G3 = 3,
|
||||
GSM48_BCAP_ITCAP_OTHER = 5,
|
||||
GSM48_BCAP_ITCAP_RESERVED = 7,
|
||||
};
|
||||
|
||||
/* GSM 04.08 Bearer Capability: Transfer Mode */
|
||||
enum gsm48_bcap_tmod {
|
||||
GSM48_BCAP_TMOD_CIRCUIT = 0,
|
||||
GSM48_BCAP_TMOD_PACKET = 1,
|
||||
};
|
||||
|
||||
/* GSM 04.08 Bearer Capability: Coding Standard */
|
||||
enum gsm48_bcap_coding {
|
||||
GSM48_BCAP_CODING_GSM_STD = 0,
|
||||
};
|
||||
|
||||
/* GSM 04.08 Bearer Capability: Radio Channel Requirements */
|
||||
enum gsm48_bcap_rrq {
|
||||
GSM48_BCAP_RRQ_FR_ONLY = 1,
|
||||
GSM48_BCAP_RRQ_DUAL_HR = 2,
|
||||
GSM48_BCAP_RRQ_DUAL_FR = 3,
|
||||
};
|
||||
|
||||
|
||||
#define GSM48_TMSI_LEN 5
|
||||
#define GSM48_MID_TMSI_LEN (GSM48_TMSI_LEN + 2)
|
||||
#define GSM48_MI_SIZE 32
|
||||
|
||||
|
||||
struct msgb;
|
||||
struct gsm_bts;
|
||||
@@ -16,14 +750,18 @@ struct gsm_trans;
|
||||
void gsm0408_allow_everyone(int allow);
|
||||
|
||||
int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id);
|
||||
void gsm0408_generate_lai(struct gsm48_loc_area_id *lai48, u_int16_t mcc,
|
||||
u_int16_t mnc, u_int16_t lac);
|
||||
enum gsm_chan_t get_ctype_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci);
|
||||
enum gsm_chreq_reason_t get_reason_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci);
|
||||
|
||||
int gsm48_tx_mm_info(struct gsm_lchan *lchan);
|
||||
int gsm48_tx_mm_auth_req(struct gsm_lchan *lchan, u_int8_t *rand, int key_seq);
|
||||
int gsm48_tx_mm_auth_req(struct gsm_lchan *lchan, u_int8_t *rand);
|
||||
int gsm48_tx_mm_auth_rej(struct gsm_lchan *lchan);
|
||||
struct msgb *gsm48_msgb_alloc(void);
|
||||
int gsm48_sendmsg(struct msgb *msg, struct gsm_trans *trans);
|
||||
int gsm48_generate_mid_from_tmsi(u_int8_t *buf, u_int32_t tmsi);
|
||||
int gsm48_generate_mid_from_imsi(u_int8_t *buf, const char* imsi);
|
||||
int gsm48_mi_to_string(char *string, const int str_len, const u_int8_t *mi, const int mi_len);
|
||||
|
||||
int gsm48_send_rr_release(struct gsm_lchan *lchan);
|
||||
@@ -44,6 +782,8 @@ int encode_bcd_number(u_int8_t *bcd_lv, u_int8_t max_len,
|
||||
int decode_bcd_number(char *output, int output_len, const u_int8_t *bcd_lv,
|
||||
int h_len);
|
||||
|
||||
extern const char *gsm0408_cc_msg_names[];
|
||||
|
||||
int send_siemens_mrpci(struct gsm_lchan *lchan, u_int8_t *classmark2_lv);
|
||||
int gsm48_paging_extract_mi(struct msgb *msg, char *mi_string, u_int8_t *mi_type);
|
||||
int gsm48_handle_paging_resp(struct msgb *msg, struct gsm_subscriber *subscr);
|
||||
|
||||
@@ -1,7 +1,187 @@
|
||||
#ifndef _GSM_04_11_H
|
||||
#define _GSM_04_11_H
|
||||
|
||||
#include <osmocore/protocol/gsm_04_11.h>
|
||||
/* GSM TS 04.11 definitions */
|
||||
|
||||
/* Chapter 5.2.3: SMC-CS states at the network side */
|
||||
enum gsm411_cp_state {
|
||||
GSM411_CPS_IDLE = 0,
|
||||
GSM411_CPS_MM_CONN_PENDING = 1, /* only MT ! */
|
||||
GSM411_CPS_WAIT_CP_ACK = 2,
|
||||
GSM411_CPS_MM_ESTABLISHED = 3,
|
||||
};
|
||||
|
||||
/* Chapter 6.2.2: SMR states at the network side */
|
||||
enum gsm411_rp_state {
|
||||
GSM411_RPS_IDLE = 0,
|
||||
GSM411_RPS_WAIT_FOR_RP_ACK = 1,
|
||||
GSM411_RPS_WAIT_TO_TX_RP_ACK = 3,
|
||||
};
|
||||
|
||||
/* Chapter 8.1.2 (refers to GSM 04.07 Chapter 11.2.3.1.1 */
|
||||
#define GSM411_PDISC_SMS 0x09
|
||||
|
||||
/* Chapter 8.1.3 */
|
||||
#define GSM411_MT_CP_DATA 0x01
|
||||
#define GSM411_MT_CP_ACK 0x04
|
||||
#define GSM411_MT_CP_ERROR 0x10
|
||||
|
||||
enum gsm411_cp_ie {
|
||||
GSM411_CP_IE_USER_DATA = 0x01, /* 8.1.4.1 */
|
||||
GSM411_CP_IE_CAUSE = 0x02, /* 8.1.4.2. */
|
||||
};
|
||||
|
||||
/* Section 8.1.4.2 / Table 8.2 */
|
||||
enum gsm411_cp_cause {
|
||||
GSM411_CP_CAUSE_NET_FAIL = 17,
|
||||
GSM411_CP_CAUSE_CONGESTION = 22,
|
||||
GSM411_CP_CAUSE_INV_TRANS_ID = 81,
|
||||
GSM411_CP_CAUSE_SEMANT_INC_MSG = 95,
|
||||
GSM411_CP_CAUSE_INV_MAND_INF = 96,
|
||||
GSM411_CP_CAUSE_MSGTYPE_NOTEXIST= 97,
|
||||
GSM411_CP_CAUSE_MSG_INCOMP_STATE= 98,
|
||||
GSM411_CP_CAUSE_IE_NOTEXIST = 99,
|
||||
GSM411_CP_CAUSE_PROTOCOL_ERR = 111,
|
||||
};
|
||||
|
||||
/* Chapter 8.2.2 */
|
||||
#define GSM411_MT_RP_DATA_MO 0x00
|
||||
#define GSM411_MT_RP_DATA_MT 0x01
|
||||
#define GSM411_MT_RP_ACK_MO 0x02
|
||||
#define GSM411_MT_RP_ACK_MT 0x03
|
||||
#define GSM411_MT_RP_ERROR_MO 0x04
|
||||
#define GSM411_MT_RP_ERROR_MT 0x05
|
||||
#define GSM411_MT_RP_SMMA_MO 0x06
|
||||
|
||||
enum gsm411_rp_ie {
|
||||
GSM411_IE_RP_USER_DATA = 0x41, /* 8.2.5.3 */
|
||||
GSM411_IE_RP_CAUSE = 0x42, /* 8.2.5.4 */
|
||||
};
|
||||
|
||||
/* Chapter 8.2.5.4 Table 8.4 */
|
||||
enum gsm411_rp_cause {
|
||||
/* valid only for MO */
|
||||
GSM411_RP_CAUSE_MO_NUM_UNASSIGNED = 1,
|
||||
GSM411_RP_CAUSE_MO_OP_DET_BARR = 8,
|
||||
GSM411_RP_CAUSE_MO_CALL_BARRED = 10,
|
||||
GSM411_RP_CAUSE_MO_SMS_REJECTED = 21,
|
||||
GSM411_RP_CAUSE_MO_DEST_OUT_OF_ORDER = 27,
|
||||
GSM411_RP_CAUSE_MO_UNIDENTIFIED_SUBSCR = 28,
|
||||
GSM411_RP_CAUSE_MO_FACILITY_REJ = 29,
|
||||
GSM411_RP_CAUSE_MO_UNKNOWN_SUBSCR = 30,
|
||||
GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER = 38,
|
||||
GSM411_RP_CAUSE_MO_TEMP_FAIL = 41,
|
||||
GSM411_RP_CAUSE_MO_CONGESTION = 42,
|
||||
GSM411_RP_CAUSE_MO_RES_UNAVAIL = 47,
|
||||
GSM411_RP_CAUSE_MO_REQ_FAC_NOTSUBSCR = 50,
|
||||
GSM411_RP_CAUSE_MO_REQ_FAC_NOTIMPL = 69,
|
||||
GSM411_RP_CAUSE_MO_INTERWORKING = 127,
|
||||
/* valid only for MT */
|
||||
GSM411_RP_CAUSE_MT_MEM_EXCEEDED = 22,
|
||||
/* valid for both directions */
|
||||
GSM411_RP_CAUSE_INV_TRANS_REF = 81,
|
||||
GSM411_RP_CAUSE_SEMANT_INC_MSG = 95,
|
||||
GSM411_RP_CAUSE_INV_MAND_INF = 96,
|
||||
GSM411_RP_CAUSE_MSGTYPE_NOTEXIST = 97,
|
||||
GSM411_RP_CAUSE_MSG_INCOMP_STATE = 98,
|
||||
GSM411_RP_CAUSE_IE_NOTEXIST = 99,
|
||||
GSM411_RP_CAUSE_PROTOCOL_ERR = 111,
|
||||
};
|
||||
|
||||
/* Chapter 10: Timers */
|
||||
#define GSM411_TMR_TR1M 40, 0 /* 35 < x < 45 seconds */
|
||||
#define GSM411_TMR_TRAM 30, 0 /* 25 < x < 35 seconds */
|
||||
#define GSM411_TMR_TR2M 15, 0 /* 12 < x < 20 seconds */
|
||||
|
||||
#define GSM411_TMR_TC1A 30, 0
|
||||
|
||||
/* Chapter 8.2.1 */
|
||||
struct gsm411_rp_hdr {
|
||||
u_int8_t len;
|
||||
u_int8_t msg_type;
|
||||
u_int8_t msg_ref;
|
||||
u_int8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* our own enum, not related to on-air protocol */
|
||||
enum sms_alphabet {
|
||||
DCS_NONE,
|
||||
DCS_7BIT_DEFAULT,
|
||||
DCS_UCS2,
|
||||
DCS_8BIT_DATA,
|
||||
};
|
||||
|
||||
/* GSM 03.40 / Chapter 9.2.3.1: TP-Message-Type-Indicator */
|
||||
#define GSM340_SMS_DELIVER_SC2MS 0x00
|
||||
#define GSM340_SMS_DELIVER_REP_MS2SC 0x00
|
||||
#define GSM340_SMS_STATUS_REP_SC2MS 0x02
|
||||
#define GSM340_SMS_COMMAND_MS2SC 0x02
|
||||
#define GSM340_SMS_SUBMIT_MS2SC 0x01
|
||||
#define GSM340_SMS_SUBMIT_REP_SC2MS 0x01
|
||||
#define GSM340_SMS_RESSERVED 0x03
|
||||
|
||||
/* GSM 03.40 / Chapter 9.2.3.2: TP-More-Messages-to-Send */
|
||||
#define GSM340_TP_MMS_MORE 0
|
||||
#define GSM340_TP_MMS_NO_MORE 1
|
||||
|
||||
/* GSM 03.40 / Chapter 9.2.3.3: TP-Validity-Period-Format */
|
||||
#define GSM340_TP_VPF_NONE 0
|
||||
#define GSM340_TP_VPF_RELATIVE 2
|
||||
#define GSM340_TP_VPF_ENHANCED 1
|
||||
#define GSM340_TP_VPF_ABSOLUTE 3
|
||||
|
||||
/* GSM 03.40 / Chapter 9.2.3.4: TP-Status-Report-Indication */
|
||||
#define GSM340_TP_SRI_NONE 0
|
||||
#define GSM340_TP_SRI_PRESENT 1
|
||||
|
||||
/* GSM 03.40 / Chapter 9.2.3.5: TP-Status-Report-Request */
|
||||
#define GSM340_TP_SRR_NONE 0
|
||||
#define GSM340_TP_SRR_REQUESTED 1
|
||||
|
||||
/* GSM 03.40 / Chapter 9.2.3.9: TP-Protocol-Identifier */
|
||||
/* telematic interworking (001 or 111 in bits 7-5) */
|
||||
#define GSM340_TP_PID_IMPLICIT 0x00
|
||||
#define GSM340_TP_PID_TELEX 0x01
|
||||
#define GSM340_TP_PID_FAX_G3 0x02
|
||||
#define GSM340_TP_PID_FAX_G4 0x03
|
||||
#define GSM340_TP_PID_VOICE 0x04
|
||||
#define GSM430_TP_PID_ERMES 0x05
|
||||
#define GSM430_TP_PID_NATIONAL_PAGING 0x06
|
||||
#define GSM430_TP_PID_VIDEOTEX 0x07
|
||||
#define GSM430_TP_PID_TELETEX_UNSPEC 0x08
|
||||
#define GSM430_TP_PID_TELETEX_PSPDN 0x09
|
||||
#define GSM430_TP_PID_TELETEX_CSPDN 0x0a
|
||||
#define GSM430_TP_PID_TELETEX_PSTN 0x0b
|
||||
#define GSM430_TP_PID_TELETEX_ISDN 0x0c
|
||||
#define GSM430_TP_PID_TELETEX_UCI 0x0d
|
||||
#define GSM430_TP_PID_MSG_HANDLING 0x10
|
||||
#define GSM430_TP_PID_MSG_X400 0x11
|
||||
#define GSM430_TP_PID_EMAIL 0x12
|
||||
#define GSM430_TP_PID_GSM_MS 0x1f
|
||||
/* if bit 7 = 0 and bit 6 = 1 */
|
||||
#define GSM430_TP_PID_SMS_TYPE_0 0
|
||||
#define GSM430_TP_PID_SMS_TYPE_1 1
|
||||
#define GSM430_TP_PID_SMS_TYPE_2 2
|
||||
#define GSM430_TP_PID_SMS_TYPE_3 3
|
||||
#define GSM430_TP_PID_SMS_TYPE_4 4
|
||||
#define GSM430_TP_PID_SMS_TYPE_5 5
|
||||
#define GSM430_TP_PID_SMS_TYPE_6 6
|
||||
#define GSM430_TP_PID_SMS_TYPE_7 7
|
||||
#define GSM430_TP_PID_RETURN_CALL_MSG 0x1f
|
||||
#define GSM430_TP_PID_ME_DATA_DNLOAD 0x3d
|
||||
#define GSM430_TP_PID_ME_DE_PERSONAL 0x3e
|
||||
#define GSM430_TP_PID_ME_SIM_DNLOAD 0x3f
|
||||
|
||||
/* GSM 03.38 Chapter 4: SMS Data Coding Scheme */
|
||||
#define GSM338_DCS_00_
|
||||
|
||||
#define GSM338_DCS_1110_7BIT (0 << 2)
|
||||
#define GSM338_DCS_1111_7BIT (0 << 2)
|
||||
#define GSM338_DCS_1111_8BIT_DATA (1 << 2)
|
||||
#define GSM338_DCS_1111_CLASS0 0
|
||||
#define GSM338_DCS_1111_CLASS1_ME 1
|
||||
#define GSM338_DCS_1111_CLASS2_SIM 2
|
||||
#define GSM338_DCS_1111_CLASS3_TE 3 /* See TS 07.05 */
|
||||
|
||||
/* SMS deliver PDU */
|
||||
struct sms_deliver {
|
||||
|
||||
@@ -1,8 +1,129 @@
|
||||
#ifndef _GSM_04_80_H
|
||||
#define _GSM_04_80_H
|
||||
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/protocol/gsm_04_80.h>
|
||||
/* GSM TS 04.80 definitions (Supplementary Services Specification, Formats and Coding) */
|
||||
|
||||
/* Section 3.4 */
|
||||
#define GSM0480_MTYPE_RELEASE_COMPLETE 0x2A
|
||||
#define GSM0480_MTYPE_FACILITY 0x3A
|
||||
#define GSM0480_MTYPE_REGISTER 0x3B
|
||||
|
||||
/* Section 3.5 */
|
||||
#define GSM0480_IE_FACILITY 0x1C
|
||||
#define GSM0480_IE_SS_VERSION 0x7F
|
||||
|
||||
/* Section 3.6.2 */
|
||||
#define GSM0480_CTYPE_INVOKE 0xA1
|
||||
#define GSM0480_CTYPE_RETURN_RESULT 0xA2
|
||||
#define GSM0480_CTYPE_RETURN_ERROR 0xA3
|
||||
#define GSM0480_CTYPE_REJECT 0xA4
|
||||
|
||||
/* Section 3.6.3 */
|
||||
#define GSM0480_COMPIDTAG_INVOKE_ID 0x02
|
||||
#define GSM0480_COMPIDTAG_LINKED_ID 0x80
|
||||
|
||||
/* Section 3.6.4 */
|
||||
#define GSM0480_OPERATION_CODE 0x02
|
||||
|
||||
/* Section 3.6.5 */
|
||||
#define GSM_0480_SEQUENCE_TAG 0x30
|
||||
#define GSM_0480_SET_TAG 0x31
|
||||
|
||||
/* Section 3.6.6 */
|
||||
#define GSM_0480_ERROR_CODE_TAG 0x02
|
||||
|
||||
/* Section 3.6.7 */
|
||||
/* Table 3.13 */
|
||||
#define GSM_0480_PROBLEM_CODE_TAG_GENERAL 0x80
|
||||
#define GSM_0480_PROBLEM_CODE_TAG_INVOKE 0x81
|
||||
#define GSM_0480_PROBLEM_CODE_TAG_RETURN_RESULT 0x82
|
||||
#define GSM_0480_PROBLEM_CODE_TAG_RETURN_ERROR 0x83
|
||||
|
||||
/* Table 3.14 */
|
||||
#define GSM_0480_GEN_PROB_CODE_UNRECOGNISED 0x00
|
||||
#define GSM_0480_GEN_PROB_CODE_MISTYPED 0x01
|
||||
#define GSM_0480_GEN_PROB_CODE_BAD_STRUCTURE 0x02
|
||||
|
||||
/* Table 3.15 */
|
||||
#define GSM_0480_INVOKE_PROB_CODE_DUPLICATE_INVOKE_ID 0x00
|
||||
#define GSM_0480_INVOKE_PROB_CODE_UNRECOGNISED_OPERATION 0x01
|
||||
#define GSM_0480_INVOKE_PROB_CODE_MISTYPED_PARAMETER 0x02
|
||||
#define GSM_0480_INVOKE_PROB_CODE_RESOURCE_LIMITATION 0x03
|
||||
#define GSM_0480_INVOKE_PROB_CODE_INITIATING_RELEASE 0x04
|
||||
#define GSM_0480_INVOKE_PROB_CODE_UNRECOGNISED_LINKED_ID 0x05
|
||||
#define GSM_0480_INVOKE_PROB_CODE_UNEXPECTED_LINKED_RESPONSE 0x06
|
||||
#define GSM_0480_INVOKE_PROB_CODE_UNEXPECTED_LINKED_OPERATION 0x07
|
||||
|
||||
/* Table 3.16 */
|
||||
#define GSM_0480_RESULT_PROB_CODE_UNRECOGNISED_INVOKE_ID 0x00
|
||||
#define GSM_0480_RESULT_PROB_CODE_RETURN_RESULT_UNEXPECTED 0x01
|
||||
#define GSM_0480_RESULT_PROB_CODE_MISTYPED_PARAMETER 0x02
|
||||
|
||||
/* Table 3.17 */
|
||||
#define GSM_0480_ERROR_PROB_CODE_UNRECOGNISED_INVOKE_ID 0x00
|
||||
#define GSM_0480_ERROR_PROB_CODE_RETURN_ERROR_UNEXPECTED 0x01
|
||||
#define GSM_0480_ERROR_PROB_CODE_UNRECOGNISED_ERROR 0x02
|
||||
#define GSM_0480_ERROR_PROB_CODE_UNEXPECTED_ERROR 0x03
|
||||
#define GSM_0480_ERROR_PROB_CODE_MISTYPED_PARAMETER 0x04
|
||||
|
||||
/* Section 4.5 */
|
||||
#define GSM0480_OP_CODE_REGISTER_SS 0x0A
|
||||
#define GSM0480_OP_CODE_ERASE_SS 0x0B
|
||||
#define GSM0480_OP_CODE_ACTIVATE_SS 0x0C
|
||||
#define GSM0480_OP_CODE_DEACTIVATE_SS 0x0D
|
||||
#define GSM0480_OP_CODE_INTERROGATE_SS 0x0E
|
||||
#define GSM0480_OP_CODE_NOTIFY_SS 0x10
|
||||
#define GSM0480_OP_CODE_REGISTER_PASSWORD 0x11
|
||||
#define GSM0480_OP_CODE_GET_PASSWORD 0x12
|
||||
#define GSM0480_OP_CODE_PROCESS_USS_DATA 0x13
|
||||
#define GSM0480_OP_CODE_FORWARD_CHECK_SS_IND 0x26
|
||||
#define GSM0480_OP_CODE_PROCESS_USS_REQ 0x3B
|
||||
#define GSM0480_OP_CODE_USS_REQUEST 0x3C
|
||||
#define GSM0480_OP_CODE_USS_NOTIFY 0x3D
|
||||
#define GSM0480_OP_CODE_FORWARD_CUG_INFO 0x78
|
||||
#define GSM0480_OP_CODE_SPLIT_MPTY 0x79
|
||||
#define GSM0480_OP_CODE_RETRIEVE_MPTY 0x7A
|
||||
#define GSM0480_OP_CODE_HOLD_MPTY 0x7B
|
||||
#define GSM0480_OP_CODE_BUILD_MPTY 0x7C
|
||||
#define GSM0480_OP_CODE_FORWARD_CHARGE_ADVICE 0x7D
|
||||
|
||||
#define GSM0480_ERR_CODE_UNKNOWN_SUBSCRIBER 0x01
|
||||
#define GSM0480_ERR_CODE_ILLEGAL_SUBSCRIBER 0x09
|
||||
#define GSM0480_ERR_CODE_BEARER_SERVICE_NOT_PROVISIONED 0x0A
|
||||
#define GSM0480_ERR_CODE_TELESERVICE_NOT_PROVISIONED 0x0B
|
||||
#define GSM0480_ERR_CODE_ILLEGAL_EQUIPMENT 0x0C
|
||||
#define GSM0480_ERR_CODE_CALL_BARRED 0x0D
|
||||
#define GSM0480_ERR_CODE_ILLEGAL_SS_OPERATION 0x10
|
||||
#define GSM0480_ERR_CODE_SS_ERROR_STATUS 0x11
|
||||
#define GSM0480_ERR_CODE_SS_NOT_AVAILABLE 0x12
|
||||
#define GSM0480_ERR_CODE_SS_SUBSCRIPTION_VIOLATION 0x13
|
||||
#define GSM0480_ERR_CODE_SS_INCOMPATIBILITY 0x14
|
||||
#define GSM0480_ERR_CODE_FACILITY_NOT_SUPPORTED 0x15
|
||||
#define GSM0480_ERR_CODE_ABSENT_SUBSCRIBER 0x1B
|
||||
#define GSM0480_ERR_CODE_SYSTEM_FAILURE 0x22
|
||||
#define GSM0480_ERR_CODE_DATA_MISSING 0x23
|
||||
#define GSM0480_ERR_CODE_UNEXPECTED_DATA_VALUE 0x24
|
||||
#define GSM0480_ERR_CODE_PW_REGISTRATION_FAILURE 0x25
|
||||
#define GSM0480_ERR_CODE_NEGATIVE_PW_CHECK 0x26
|
||||
#define GSM0480_ERR_CODE_NUM_PW_ATTEMPTS_VIOLATION 0x2B
|
||||
#define GSM0480_ERR_CODE_UNKNOWN_ALPHABET 0x47
|
||||
#define GSM0480_ERR_CODE_USSD_BUSY 0x48
|
||||
#define GSM0480_ERR_CODE_MAX_MPTY_PARTICIPANTS 0x7E
|
||||
#define GSM0480_ERR_CODE_RESOURCES_NOT_AVAILABLE 0x7F
|
||||
|
||||
/* ASN.1 type-tags */
|
||||
#define ASN1_BOOLEAN_TAG 0x01
|
||||
#define ASN1_INTEGER_TAG 0x02
|
||||
#define ASN1_BIT_STRING_TAG 0x03
|
||||
#define ASN1_OCTET_STRING_TAG 0x04
|
||||
#define ASN1_NULL_TYPE_TAG 0x05
|
||||
#define ASN1_OBJECT_ID_TAG 0x06
|
||||
#define ASN1_UTF8_STRING_TAG 0x0C
|
||||
#define ASN1_PRINTABLE_STRING_TAG 0x13
|
||||
#define ASN1_IA5_STRING_TAG 0x16
|
||||
#define ASN1_UNICODE_STRING_TAG 0x1E
|
||||
|
||||
#include <openbsc/msgb.h>
|
||||
|
||||
#define MAX_LEN_USSD_STRING 31
|
||||
|
||||
|
||||
@@ -3,6 +3,21 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
struct value_string {
|
||||
unsigned int value;
|
||||
const char *str;
|
||||
};
|
||||
|
||||
const char *get_value_string(const struct value_string *vs, u_int32_t val);
|
||||
|
||||
enum gsm_band {
|
||||
GSM_BAND_400,
|
||||
GSM_BAND_850,
|
||||
GSM_BAND_900,
|
||||
GSM_BAND_1800,
|
||||
GSM_BAND_1900,
|
||||
};
|
||||
|
||||
enum gsm_phys_chan_config {
|
||||
GSM_PCHAN_NONE,
|
||||
GSM_PCHAN_CCCH,
|
||||
@@ -40,15 +55,14 @@ enum gsm_chreq_reason_t {
|
||||
GSM_CHREQ_REASON_OTHER,
|
||||
};
|
||||
|
||||
#include <osmocore/timer.h>
|
||||
#include <openbsc/timer.h>
|
||||
#include <openbsc/gsm_04_08.h>
|
||||
#include <openbsc/abis_rsl.h>
|
||||
#include <openbsc/mncc.h>
|
||||
#include <osmocore/tlv.h>
|
||||
#include <osmocore/bitvec.h>
|
||||
#include <osmocore/statistics.h>
|
||||
#include <osmocore/gsm_utils.h>
|
||||
#include <osmocore/utils.h>
|
||||
#include <openbsc/tlv.h>
|
||||
#include <openbsc/bitvec.h>
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
#define TRX_NR_TS 8
|
||||
#define TS_MAX_LCHAN 8
|
||||
@@ -79,58 +93,51 @@ typedef int gsm_cbfn(unsigned int hooknum,
|
||||
struct msgb *msg,
|
||||
void *data, void *param);
|
||||
|
||||
/*
|
||||
* Use the channel. As side effect the lchannel recycle timer
|
||||
* will be started.
|
||||
*/
|
||||
#define LCHAN_RELEASE_TIMEOUT 20, 0
|
||||
#define use_lchan(lchan) \
|
||||
do { lchan->use_count++; \
|
||||
DEBUGP(DREF, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) increases usage to: %d\n", \
|
||||
lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, \
|
||||
lchan->nr, lchan->use_count); \
|
||||
bsc_schedule_timer(&lchan->release_timer, LCHAN_RELEASE_TIMEOUT); } while(0);
|
||||
|
||||
#define put_lchan(lchan) \
|
||||
do { lchan->use_count--; \
|
||||
DEBUGP(DREF, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) decreases usage to: %d\n", \
|
||||
lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, \
|
||||
lchan->nr, lchan->use_count); \
|
||||
} while(0);
|
||||
|
||||
|
||||
/* communications link with a BTS */
|
||||
struct gsm_bts_link {
|
||||
struct gsm_bts *bts;
|
||||
};
|
||||
|
||||
/* Real authentication information containing Ki */
|
||||
enum gsm_auth_algo {
|
||||
AUTH_ALGO_NONE,
|
||||
AUTH_ALGO_XOR,
|
||||
AUTH_ALGO_COMP128v1,
|
||||
};
|
||||
|
||||
struct gsm_auth_info {
|
||||
enum gsm_auth_algo auth_algo;
|
||||
unsigned int a3a8_ki_len;
|
||||
u_int8_t a3a8_ki[16];
|
||||
};
|
||||
|
||||
struct gsm_auth_tuple {
|
||||
int use_count;
|
||||
int key_seq;
|
||||
u_int8_t rand[16];
|
||||
u_int8_t sres[4];
|
||||
u_int8_t kc[8];
|
||||
};
|
||||
|
||||
|
||||
struct sccp_connection;
|
||||
struct gsm_lchan;
|
||||
struct gsm_subscriber;
|
||||
struct gsm_mncc;
|
||||
struct rtp_socket;
|
||||
|
||||
/* BSC/MSC data holding them together */
|
||||
struct bss_sccp_connection_data {
|
||||
struct gsm_lchan *lchan;
|
||||
struct gsm_lchan *secondary_lchan;
|
||||
struct sccp_connection *sccp;
|
||||
int ciphering_handled : 1;
|
||||
|
||||
/* Timers... */
|
||||
|
||||
/* for assginment command */
|
||||
struct timer_list T10;
|
||||
|
||||
/* for SCCP ... */
|
||||
struct timer_list sccp_it;
|
||||
|
||||
/* audio handling */
|
||||
int rtp_port;
|
||||
|
||||
/* Queue SCCP and GSM0408 messages */
|
||||
int block_gsm;
|
||||
struct llist_head gsm_queue;
|
||||
unsigned int gsm_queue_size;
|
||||
|
||||
struct llist_head sccp_queue;
|
||||
unsigned int sccp_queue_size;
|
||||
};
|
||||
|
||||
#define GSM0808_T10_VALUE 6, 0
|
||||
#define sccp_get_lchan(data_ctx) ((struct bss_sccp_connection_data *)data_ctx)->lchan
|
||||
#define lchan_get_sccp(lchan) lchan->msc_data->sccp
|
||||
struct bss_sccp_connection_data *bss_sccp_create_data();
|
||||
void bss_sccp_free_data(struct bss_sccp_connection_data *);
|
||||
|
||||
|
||||
/* Network Management State */
|
||||
struct gsm_nm_state {
|
||||
u_int8_t operational;
|
||||
@@ -176,9 +183,7 @@ struct neigh_meas_proc {
|
||||
/* state of a logical channel */
|
||||
enum gsm_lchan_state {
|
||||
LCHAN_S_NONE, /* channel is not active */
|
||||
LCHAN_S_ACT_REQ, /* channel activatin requested */
|
||||
LCHAN_S_ACTIVE, /* channel is active and operational */
|
||||
LCHAN_S_REL_REQ, /* channel release has been requested */
|
||||
LCHAN_S_INACTIVE, /* channel is set inactive */
|
||||
};
|
||||
|
||||
@@ -204,8 +209,6 @@ struct gsm_lchan {
|
||||
u_int8_t key_len;
|
||||
u_int8_t key[MAX_A5_KEY_LEN];
|
||||
} encr;
|
||||
/* Are we part of a special "silent" call */
|
||||
int silent_call;
|
||||
|
||||
/* AMR bits */
|
||||
struct gsm48_multi_rate_conf mr_conf;
|
||||
@@ -213,9 +216,6 @@ struct gsm_lchan {
|
||||
/* To whom we are allocated at the moment */
|
||||
struct gsm_subscriber *subscr;
|
||||
|
||||
/* Timer started to release the channel */
|
||||
struct timer_list release_timer;
|
||||
|
||||
struct timer_list T3101;
|
||||
|
||||
/* Established data link layer services */
|
||||
@@ -226,6 +226,12 @@ struct gsm_lchan {
|
||||
*/
|
||||
struct gsm_loc_updating_operation *loc_operation;
|
||||
|
||||
/*
|
||||
* MSC handling...
|
||||
*/
|
||||
struct bss_sccp_connection_data *msc_data;
|
||||
|
||||
|
||||
/* use count. how many users use this channel */
|
||||
unsigned int use_count;
|
||||
|
||||
@@ -311,6 +317,9 @@ struct gsm_bts_trx {
|
||||
} bs11;
|
||||
};
|
||||
struct gsm_bts_trx_ts ts[TRX_NR_TS];
|
||||
|
||||
/* NM state */
|
||||
int rf_locked;
|
||||
};
|
||||
|
||||
enum gsm_bts_type {
|
||||
@@ -319,15 +328,6 @@ enum gsm_bts_type {
|
||||
GSM_BTS_TYPE_NANOBTS,
|
||||
};
|
||||
|
||||
struct gsm_bts_model {
|
||||
struct llist_head list;
|
||||
|
||||
enum gsm_bts_type type;
|
||||
const char *name;
|
||||
|
||||
struct tlv_definition nm_att_tlvdef;
|
||||
};
|
||||
|
||||
/**
|
||||
* A pending paging request
|
||||
*/
|
||||
@@ -374,10 +374,6 @@ struct gsm_envabtse {
|
||||
struct gsm_bts_gprs_nsvc {
|
||||
struct gsm_bts *bts;
|
||||
int id;
|
||||
u_int16_t nsvci;
|
||||
u_int16_t local_port;
|
||||
u_int16_t remote_port;
|
||||
u_int32_t remote_ip;
|
||||
struct gsm_nm_state nm_state;
|
||||
};
|
||||
|
||||
@@ -399,7 +395,6 @@ struct gsm_bts {
|
||||
u_int8_t bsic;
|
||||
/* type of BTS */
|
||||
enum gsm_bts_type type;
|
||||
struct gsm_bts_model *model;
|
||||
enum gsm_band band;
|
||||
/* should the channel allocator allocate channels from high TRX to TRX0,
|
||||
* rather than starting from TRX0 and go upwards? */
|
||||
@@ -466,17 +461,13 @@ struct gsm_bts {
|
||||
|
||||
/* Not entirely sure how ip.access specific this is */
|
||||
struct {
|
||||
int enabled;
|
||||
struct {
|
||||
struct gsm_nm_state nm_state;
|
||||
u_int16_t nsei;
|
||||
} nse;
|
||||
struct {
|
||||
struct gsm_nm_state nm_state;
|
||||
u_int16_t bvci;
|
||||
} cell;
|
||||
struct gsm_bts_gprs_nsvc nsvc[2];
|
||||
u_int8_t rac;
|
||||
} gprs;
|
||||
|
||||
/* transceivers */
|
||||
@@ -487,43 +478,43 @@ struct gsm_bts {
|
||||
/* Some statistics of our network */
|
||||
struct gsmnet_stats {
|
||||
struct {
|
||||
struct counter *total;
|
||||
struct counter *no_channel;
|
||||
unsigned long total;
|
||||
unsigned long no_channel;
|
||||
} chreq;
|
||||
struct {
|
||||
struct counter *attempted;
|
||||
struct counter *no_channel; /* no channel available */
|
||||
struct counter *timeout; /* T3103 timeout */
|
||||
struct counter *completed; /* HO COMPL received */
|
||||
struct counter *failed; /* HO FAIL received */
|
||||
unsigned long attempted;
|
||||
unsigned long no_channel; /* no channel available */
|
||||
unsigned long timeout; /* T3103 timeout */
|
||||
unsigned long completed; /* HO COMPL received */
|
||||
unsigned long failed; /* HO FAIL received */
|
||||
} handover;
|
||||
struct {
|
||||
struct counter *attach;
|
||||
struct counter *normal;
|
||||
struct counter *periodic;
|
||||
struct counter *detach;
|
||||
unsigned long attach;
|
||||
unsigned long normal;
|
||||
unsigned long periodic;
|
||||
unsigned long detach;
|
||||
} loc_upd_type;
|
||||
struct {
|
||||
struct counter *reject;
|
||||
struct counter *accept;
|
||||
unsigned long reject;
|
||||
unsigned long accept;
|
||||
} loc_upd_resp;
|
||||
struct {
|
||||
struct counter *attempted;
|
||||
struct counter *detached;
|
||||
struct counter *completed;
|
||||
struct counter *expired;
|
||||
unsigned long attempted;
|
||||
unsigned long detached;
|
||||
unsigned long completed;
|
||||
unsigned long expired;
|
||||
} paging;
|
||||
struct {
|
||||
struct counter *submitted; /* MO SMS submissions */
|
||||
struct counter *no_receiver;
|
||||
struct counter *delivered; /* MT SMS deliveries */
|
||||
struct counter *rp_err_mem;
|
||||
struct counter *rp_err_other;
|
||||
unsigned long submitted; /* MO SMS submissions */
|
||||
unsigned long no_receiver;
|
||||
unsigned long delivered; /* MT SMS deliveries */
|
||||
unsigned long rp_err_mem;
|
||||
unsigned long rp_err_other;
|
||||
} sms;
|
||||
struct {
|
||||
struct counter *dialled; /* total number of dialled calls */
|
||||
struct counter *alerted; /* we alerted the other end */
|
||||
struct counter *connected;/* how many calls were accepted */
|
||||
unsigned long dialled; /* total number of dialled calls */
|
||||
unsigned long alerted; /* we alerted the other end */
|
||||
unsigned long connected;/* how many calls were accepted */
|
||||
} call;
|
||||
};
|
||||
|
||||
@@ -536,6 +527,14 @@ enum gsm_auth_policy {
|
||||
#define GSM_T3101_DEFAULT 10
|
||||
#define GSM_T3113_DEFAULT 60
|
||||
|
||||
/*
|
||||
* internal data for audio management
|
||||
*/
|
||||
struct gsm_audio_support {
|
||||
u_int8_t hr : 1,
|
||||
ver : 7;
|
||||
};
|
||||
|
||||
struct gsm_network {
|
||||
/* global parameters */
|
||||
u_int16_t country_code;
|
||||
@@ -566,6 +565,11 @@ struct gsm_network {
|
||||
|
||||
struct gsmnet_stats stats;
|
||||
|
||||
struct gsm_audio_support **audio_support;
|
||||
int audio_length;
|
||||
int rtp_payload;
|
||||
int rtp_base_port;
|
||||
|
||||
/* layer 4 */
|
||||
int (*mncc_recv) (struct gsm_network *net, int msg_type, void *arg);
|
||||
struct llist_head upqueue;
|
||||
@@ -591,6 +595,10 @@ struct gsm_network {
|
||||
struct {
|
||||
enum rrlp_mode mode;
|
||||
} rrlp;
|
||||
|
||||
/* a hack for On Waves. It must be signed */
|
||||
int32_t core_country_code;
|
||||
int32_t core_network_code;
|
||||
};
|
||||
|
||||
#define SMS_HDR_SIZE 128
|
||||
@@ -615,13 +623,11 @@ struct gsm_sms {
|
||||
char text[SMS_TEXT_SIZE];
|
||||
};
|
||||
|
||||
|
||||
struct gsm_network *gsm_network_init(u_int16_t country_code, u_int16_t network_code,
|
||||
int (*mncc_recv)(struct gsm_network *, int, void *));
|
||||
struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, enum gsm_bts_type type,
|
||||
u_int8_t tsc, u_int8_t bsic);
|
||||
struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts);
|
||||
int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type);
|
||||
|
||||
struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num);
|
||||
|
||||
@@ -633,12 +639,9 @@ struct gsm_bts_trx *gsm_bts_trx_num(struct gsm_bts *bts, int num);
|
||||
|
||||
const char *gsm_pchan_name(enum gsm_phys_chan_config c);
|
||||
enum gsm_phys_chan_config gsm_pchan_parse(const char *name);
|
||||
const char *gsm_lchant_name(enum gsm_chan_t c);
|
||||
const char *gsm_lchan_name(enum gsm_chan_t c);
|
||||
const char *gsm_chreq_name(enum gsm_chreq_reason_t c);
|
||||
char *gsm_trx_name(struct gsm_bts_trx *trx);
|
||||
char *gsm_ts_name(struct gsm_bts_trx_ts *ts);
|
||||
char *gsm_lchan_name(struct gsm_lchan *lchan);
|
||||
const char *gsm_lchans_name(enum gsm_lchan_state s);
|
||||
|
||||
enum gsm_e1_event {
|
||||
EVT_E1_NONE,
|
||||
@@ -650,10 +653,12 @@ void set_ts_e1link(struct gsm_bts_trx_ts *ts, u_int8_t e1_nr,
|
||||
u_int8_t e1_ts, u_int8_t e1_ts_ss);
|
||||
enum gsm_bts_type parse_btstype(const char *arg);
|
||||
const char *btstype2str(enum gsm_bts_type type);
|
||||
struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr);
|
||||
struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac,
|
||||
struct gsm_bts *start_bts);
|
||||
|
||||
char *gsm_band_name(enum gsm_band band);
|
||||
enum gsm_band gsm_band_parse(const char *mhz);
|
||||
|
||||
extern void *tall_bsc_ctx;
|
||||
extern int ipacc_rtp_direct;
|
||||
|
||||
@@ -689,18 +694,6 @@ const char *rrlp_mode_name(enum rrlp_mode mode);
|
||||
|
||||
void gsm_trx_lock_rf(struct gsm_bts_trx *trx, int locked);
|
||||
|
||||
/* A parsed GPRS routing area */
|
||||
struct gprs_ra_id {
|
||||
u_int16_t mnc;
|
||||
u_int16_t mcc;
|
||||
u_int16_t lac;
|
||||
u_int8_t rac;
|
||||
};
|
||||
|
||||
int gsm48_ra_id_by_bts(u_int8_t *buf, struct gsm_bts *bts);
|
||||
void gprs_ra_id_by_bts(struct gprs_ra_id *raid, struct gsm_bts *bts);
|
||||
struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan);
|
||||
|
||||
int gsm_bts_model_register(struct gsm_bts_model *model);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "gsm_data.h"
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include "linuxlist.h"
|
||||
|
||||
#define GSM_IMEI_LENGTH 17
|
||||
#define GSM_IMSI_LENGTH 17
|
||||
@@ -81,13 +81,13 @@ struct gsm_subscriber *subscr_get_by_extension(struct gsm_network *net,
|
||||
const char *ext);
|
||||
struct gsm_subscriber *subscr_get_by_id(struct gsm_network *net,
|
||||
unsigned long long id);
|
||||
struct gsm_subscriber *subscr_get_or_create(struct gsm_network *net,
|
||||
const char *imsi);
|
||||
int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason);
|
||||
void subscr_put_channel(struct gsm_lchan *lchan);
|
||||
void subscr_get_channel(struct gsm_subscriber *subscr,
|
||||
int type, gsm_cbfn *cbfn, void *param);
|
||||
|
||||
char *subscr_name(struct gsm_subscriber *subscr);
|
||||
|
||||
/* internal */
|
||||
struct gsm_subscriber *subscr_alloc(void);
|
||||
extern struct llist_head active_subscribers;
|
||||
|
||||
41
openbsc/include/openbsc/gsm_utils.h
Normal file
41
openbsc/include/openbsc/gsm_utils.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/* GSM utility functions, e.g. coding and decoding */
|
||||
/*
|
||||
* (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
|
||||
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GSM_UTILS_H
|
||||
#define GSM_UTILS_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
int gsm_7bit_decode(char *decoded, const u_int8_t *user_data, u_int8_t length);
|
||||
int gsm_7bit_encode(u_int8_t *result, const char *data);
|
||||
|
||||
int ms_pwr_ctl_lvl(enum gsm_band band, unsigned int dbm);
|
||||
int ms_pwr_dbm(enum gsm_band band, u_int8_t lvl);
|
||||
|
||||
/* According to TS 08.05 Chapter 8.1.4 */
|
||||
int rxlev2dbm(u_int8_t rxlev);
|
||||
u_int8_t dbm2rxlev(int dbm);
|
||||
|
||||
void generate_backtrace();
|
||||
#endif
|
||||
@@ -2,10 +2,6 @@
|
||||
#define _IPACCESS_H
|
||||
|
||||
#include "e1_input.h"
|
||||
#include <osmocore/linuxlist.h>
|
||||
|
||||
#define IPA_TCP_PORT_OML 3002
|
||||
#define IPA_TCP_PORT_RSL 3003
|
||||
|
||||
struct ipaccess_head {
|
||||
u_int16_t len; /* network byte order */
|
||||
@@ -49,59 +45,5 @@ int ipaccess_rcvmsg_base(struct msgb *msg, struct bsc_fd *bfd);
|
||||
struct msgb *ipaccess_read_msg(struct bsc_fd *bfd, int *error);
|
||||
void ipaccess_prepend_header(struct msgb *msg, int proto);
|
||||
int ipaccess_send_id_ack(int fd);
|
||||
int ipaccess_send_id_req(int fd);
|
||||
|
||||
int ipaccess_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len);
|
||||
|
||||
|
||||
/*
|
||||
* Firmware specific header
|
||||
*/
|
||||
struct sdp_firmware {
|
||||
char magic[4];
|
||||
char more_magic[2];
|
||||
u_int16_t more_more_magic;
|
||||
u_int32_t header_length;
|
||||
u_int32_t file_length;
|
||||
char sw_part[20];
|
||||
char text1[64];
|
||||
char time[12];
|
||||
char date[14];
|
||||
char text2[10];
|
||||
char version[20];
|
||||
u_int16_t table_offset;
|
||||
/* stuff i don't know */
|
||||
} __attribute__((packed));
|
||||
|
||||
struct sdp_header_entry {
|
||||
u_int16_t something1;
|
||||
char text1[64];
|
||||
char time[12];
|
||||
char date[14];
|
||||
char text2[10];
|
||||
char version[20];
|
||||
u_int32_t length;
|
||||
u_int32_t addr1;
|
||||
u_int32_t addr2;
|
||||
u_int32_t start;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct sdp_header_item {
|
||||
struct sdp_header_entry header_entry;
|
||||
struct llist_head entry;
|
||||
off_t absolute_offset;
|
||||
};
|
||||
|
||||
struct sdp_header {
|
||||
struct sdp_firmware firmware_info;
|
||||
|
||||
/* for more_magic a list of sdp_header_entry_list */
|
||||
struct llist_head header_list;
|
||||
|
||||
/* the entry of the sdp_header */
|
||||
struct llist_head entry;
|
||||
};
|
||||
|
||||
int ipaccess_analyze_file(int fd, const unsigned int st_size, const unsigned base_offset, struct llist_head *list);
|
||||
|
||||
#endif /* _IPACCESS_H */
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
struct gsm_meas_rep_cell {
|
||||
u_int8_t rxlev;
|
||||
u_int8_t bsic;
|
||||
u_int8_t neigh_idx;
|
||||
u_int16_t arfcn;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
|
||||
|
||||
/*
|
||||
* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009-2010 by On-Waves
|
||||
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009 by on-waves.com
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -21,15 +21,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OPENBSC_MGCP_H
|
||||
#define OPENBSC_MGCP_H
|
||||
|
||||
#include <osmocore/msgb.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#define RTP_PORT_DEFAULT 4000
|
||||
|
||||
/**
|
||||
* Calculate the RTP audio port for the given multiplex
|
||||
* and the direction. This allows a semi static endpoint
|
||||
@@ -49,74 +40,7 @@
|
||||
* network and BTS.
|
||||
*
|
||||
*/
|
||||
static inline int rtp_calculate_port(int multiplex, int base)
|
||||
int rtp_calculate_port(int multiplex, int base)
|
||||
{
|
||||
return base + (multiplex * 2);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handling of MGCP Endpoints and the MGCP Config
|
||||
*/
|
||||
struct mgcp_endpoint;
|
||||
struct mgcp_config;
|
||||
|
||||
#define MGCP_ENDP_CRCX 1
|
||||
#define MGCP_ENDP_DLCX 2
|
||||
#define MGCP_ENDP_MDCX 3
|
||||
|
||||
/*
|
||||
* what to do with the msg?
|
||||
* - continue as usual?
|
||||
* - reject and send a failure code?
|
||||
* - defer? do not send anything
|
||||
*/
|
||||
#define MGCP_POLICY_CONT 4
|
||||
#define MGCP_POLICY_REJECT 5
|
||||
#define MGCP_POLICY_DEFER 6
|
||||
|
||||
typedef int (*mgcp_change)(struct mgcp_config *cfg, int endpoint, int state, int local_rtp);
|
||||
typedef int (*mgcp_policy)(struct mgcp_config *cfg, int endpoint, int state, const char *transactio_id);
|
||||
|
||||
struct mgcp_config {
|
||||
int source_port;
|
||||
char *local_ip;
|
||||
char *source_addr;
|
||||
unsigned int number_endpoints;
|
||||
char *bts_ip;
|
||||
|
||||
struct in_addr bts_in;
|
||||
char *audio_name;
|
||||
int audio_payload;
|
||||
int audio_loop;
|
||||
int early_bind;
|
||||
int rtp_base_port;
|
||||
|
||||
char *forward_ip;
|
||||
int forward_port;
|
||||
|
||||
mgcp_change change_cb;
|
||||
mgcp_policy policy_cb;
|
||||
void *data;
|
||||
|
||||
struct mgcp_endpoint *endpoints;
|
||||
unsigned int last_call_id;
|
||||
};
|
||||
|
||||
/* config management */
|
||||
struct mgcp_config *mgcp_config_alloc(void);
|
||||
int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg);
|
||||
int mgcp_vty_init(void);
|
||||
int mgcp_endpoints_allocate(struct mgcp_config *cfg);
|
||||
int mgcp_bind_rtp_port(struct mgcp_endpoint *endp, int rtp_port);
|
||||
void mgcp_free_endp(struct mgcp_endpoint *endp);
|
||||
|
||||
/*
|
||||
* format helper functions
|
||||
*/
|
||||
struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg);
|
||||
struct msgb *mgcp_create_rsip(void);
|
||||
struct msgb *mgcp_create_response_with_data(int code, const char *msg, const char *trans, const char *data);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
/* MGCP Private Data */
|
||||
|
||||
/*
|
||||
* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009-2010 by On-Waves
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OPENBSC_MGCP_DATA_H
|
||||
#define OPENBSC_MGCP_DATA_H
|
||||
|
||||
#include <osmocore/select.h>
|
||||
|
||||
#define CI_UNUSED 0
|
||||
|
||||
struct mgcp_endpoint {
|
||||
int ci;
|
||||
char *callid;
|
||||
char *local_options;
|
||||
int conn_mode;
|
||||
|
||||
int bts_payload_type;
|
||||
int net_payload_type;
|
||||
|
||||
/* the local rtp port we are binding to */
|
||||
int rtp_port;
|
||||
|
||||
/*
|
||||
* RTP mangling:
|
||||
* - we get RTP and RTCP to us and need to forward to the BTS
|
||||
* - we get RTP and RTCP from the BTS and forward to the network
|
||||
*/
|
||||
struct bsc_fd local_rtp;
|
||||
struct bsc_fd local_rtcp;
|
||||
|
||||
struct in_addr remote;
|
||||
struct in_addr bts;
|
||||
|
||||
/* in network byte order */
|
||||
int net_rtp, net_rtcp;
|
||||
int bts_rtp, bts_rtcp;
|
||||
|
||||
/* backpointer */
|
||||
struct mgcp_config *cfg;
|
||||
};
|
||||
|
||||
#define ENDPOINT_NUMBER(endp) abs(endp - endp->cfg->endpoints)
|
||||
|
||||
#endif
|
||||
@@ -25,8 +25,7 @@
|
||||
#ifndef _MNCC_H
|
||||
#define _MNCC_H
|
||||
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <osmocore/mncc.h>
|
||||
#include <openbsc/linuxlist.h>
|
||||
|
||||
/* One end of a call */
|
||||
struct gsm_call {
|
||||
@@ -110,6 +109,69 @@ struct gsm_call {
|
||||
#define MNCC_F_KEYPAD 0x1000
|
||||
#define MNCC_F_SIGNAL 0x2000
|
||||
|
||||
/* Expanded fields from GSM TS 04.08, Table 10.5.102 */
|
||||
struct gsm_mncc_bearer_cap {
|
||||
int transfer; /* Information Transfer Capability */
|
||||
int mode; /* Transfer Mode */
|
||||
int coding; /* Coding Standard */
|
||||
int radio; /* Radio Channel Requirement */
|
||||
int speech_ctm; /* CTM text telephony indication */
|
||||
int speech_ver[8]; /* Speech version indication */
|
||||
};
|
||||
|
||||
struct gsm_mncc_number {
|
||||
int type;
|
||||
int plan;
|
||||
int present;
|
||||
int screen;
|
||||
char number[33];
|
||||
};
|
||||
|
||||
struct gsm_mncc_cause {
|
||||
int location;
|
||||
int coding;
|
||||
int rec;
|
||||
int rec_val;
|
||||
int value;
|
||||
int diag_len;
|
||||
char diag[32];
|
||||
};
|
||||
|
||||
struct gsm_mncc_useruser {
|
||||
int proto;
|
||||
char info[GSM_MAX_USERUSER + 1]; /* + termination char */
|
||||
};
|
||||
|
||||
struct gsm_mncc_progress {
|
||||
int coding;
|
||||
int location;
|
||||
int descr;
|
||||
};
|
||||
|
||||
struct gsm_mncc_facility {
|
||||
int len;
|
||||
char info[GSM_MAX_FACILITY];
|
||||
};
|
||||
|
||||
struct gsm_mncc_ssversion {
|
||||
int len;
|
||||
char info[GSM_MAX_SSVERSION];
|
||||
};
|
||||
|
||||
struct gsm_mncc_cccap {
|
||||
int dtmf;
|
||||
int pcp;
|
||||
};
|
||||
|
||||
enum {
|
||||
GSM_MNCC_BCAP_SPEECH = 0,
|
||||
GSM_MNCC_BCAP_UNR_DIG = 1,
|
||||
GSM_MNCC_BCAP_AUDIO = 2,
|
||||
GSM_MNCC_BCAP_FAX_G3 = 3,
|
||||
GSM_MNCC_BCAP_OTHER_ITC = 5,
|
||||
GSM_MNCC_BCAP_RESERVED = 7,
|
||||
};
|
||||
|
||||
struct gsm_mncc {
|
||||
/* context based information */
|
||||
u_int32_t msg_type;
|
||||
|
||||
@@ -20,8 +20,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "linuxlist.h"
|
||||
#include <openbsc/linuxlist.h>
|
||||
|
||||
struct bts_link;
|
||||
|
||||
@@ -35,26 +34,13 @@ struct msgb {
|
||||
struct gsm_bts_trx *trx;
|
||||
struct gsm_lchan *lchan;
|
||||
|
||||
/* the Layer1 header (if any) */
|
||||
unsigned char *l1h;
|
||||
/* the A-bis layer 2 header: OML, RSL(RLL), NS */
|
||||
unsigned char *l2h;
|
||||
/* the layer 3 header. For OML: FOM; RSL: 04.08; GPRS: BSSGP */
|
||||
unsigned char *l3h;
|
||||
unsigned char *smsh;
|
||||
unsigned char *l4h;
|
||||
|
||||
/* the layer 4 header */
|
||||
union {
|
||||
unsigned char *smsh;
|
||||
unsigned char *llch;
|
||||
unsigned char *l4h;
|
||||
};
|
||||
|
||||
/* the layer 5 header, GPRS: GMM header */
|
||||
unsigned char *gmmh;
|
||||
uint32_t tlli;
|
||||
|
||||
uint16_t data_len;
|
||||
uint16_t len;
|
||||
u_int16_t data_len;
|
||||
u_int16_t len;
|
||||
|
||||
unsigned char *head;
|
||||
unsigned char *tail;
|
||||
@@ -62,30 +48,25 @@ struct msgb {
|
||||
unsigned char _data[0];
|
||||
};
|
||||
|
||||
extern struct msgb *msgb_alloc(uint16_t size, const char *name);
|
||||
extern struct msgb *msgb_alloc(u_int16_t size, const char *name);
|
||||
extern void msgb_free(struct msgb *m);
|
||||
extern void msgb_enqueue(struct llist_head *queue, struct msgb *msg);
|
||||
extern struct msgb *msgb_dequeue(struct llist_head *queue);
|
||||
extern void msgb_reset(struct msgb *m);
|
||||
|
||||
#define msgb_l1(m) ((void *)(m->l1h))
|
||||
#define msgb_l2(m) ((void *)(m->l2h))
|
||||
#define msgb_l3(m) ((void *)(m->l3h))
|
||||
#define msgb_l4(m) ((void *)(m->l4h))
|
||||
#define msgb_sms(m) ((void *)(m->smsh))
|
||||
|
||||
static inline unsigned int msgb_l1len(const struct msgb *msgb)
|
||||
{
|
||||
return msgb->tail - (uint8_t *)msgb_l1(msgb);
|
||||
}
|
||||
|
||||
static inline unsigned int msgb_l2len(const struct msgb *msgb)
|
||||
{
|
||||
return msgb->tail - (uint8_t *)msgb_l2(msgb);
|
||||
return msgb->tail - (u_int8_t *)msgb_l2(msgb);
|
||||
}
|
||||
|
||||
static inline unsigned int msgb_l3len(const struct msgb *msgb)
|
||||
{
|
||||
return msgb->tail - (uint8_t *)msgb_l3(msgb);
|
||||
return msgb->tail - (u_int8_t *)msgb_l3(msgb);
|
||||
}
|
||||
|
||||
static inline unsigned int msgb_headlen(const struct msgb *msgb)
|
||||
@@ -99,47 +80,6 @@ static inline unsigned char *msgb_put(struct msgb *msgb, unsigned int len)
|
||||
msgb->len += len;
|
||||
return tmp;
|
||||
}
|
||||
static inline void msgb_put_u8(struct msgb *msgb, uint8_t word)
|
||||
{
|
||||
uint8_t *space = msgb_put(msgb, 1);
|
||||
space[0] = word & 0xFF;
|
||||
}
|
||||
static inline void msgb_put_u16(struct msgb *msgb, uint16_t word)
|
||||
{
|
||||
uint8_t *space = msgb_put(msgb, 2);
|
||||
space[0] = word >> 8 & 0xFF;
|
||||
space[1] = word & 0xFF;
|
||||
}
|
||||
static inline void msgb_put_u32(struct msgb *msgb, uint32_t word)
|
||||
{
|
||||
uint8_t *space = msgb_put(msgb, 4);
|
||||
space[0] = word >> 24 & 0xFF;
|
||||
space[1] = word >> 16 & 0xFF;
|
||||
space[2] = word >> 8 & 0xFF;
|
||||
space[3] = word & 0xFF;
|
||||
}
|
||||
static inline unsigned char *msgb_get(struct msgb *msgb, unsigned int len)
|
||||
{
|
||||
unsigned char *tmp = msgb->data;
|
||||
msgb->data += len;
|
||||
msgb->len -= len;
|
||||
return tmp;
|
||||
}
|
||||
static inline uint8_t msgb_get_u8(struct msgb *msgb)
|
||||
{
|
||||
uint8_t *space = msgb_get(msgb, 1);
|
||||
return space[0];
|
||||
}
|
||||
static inline uint16_t msgb_get_u16(struct msgb *msgb)
|
||||
{
|
||||
uint8_t *space = msgb_get(msgb, 2);
|
||||
return space[0] << 8 | space[1];
|
||||
}
|
||||
static inline uint32_t msgb_get_u32(struct msgb *msgb)
|
||||
{
|
||||
uint8_t *space = msgb_get(msgb, 4);
|
||||
return space[0] << 24 | space[1] << 16 | space[2] << 8 | space[3];
|
||||
}
|
||||
static inline unsigned char *msgb_push(struct msgb *msgb, unsigned int len)
|
||||
{
|
||||
msgb->data -= len;
|
||||
@@ -153,7 +93,7 @@ static inline unsigned char *msgb_pull(struct msgb *msgb, unsigned int len)
|
||||
}
|
||||
static inline int msgb_tailroom(const struct msgb *msgb)
|
||||
{
|
||||
return (msgb->head + msgb->data_len) - msgb->tail;
|
||||
return (msgb->data + msgb->data_len) - msgb->tail;
|
||||
}
|
||||
|
||||
/* increase the headroom of an empty msgb, reducing the tailroom */
|
||||
@@ -24,10 +24,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include "linuxlist.h"
|
||||
#include "gsm_data.h"
|
||||
#include "gsm_subscriber.h"
|
||||
#include <osmocore/timer.h>
|
||||
#include "timer.h"
|
||||
|
||||
/* call once for every gsm_bts... */
|
||||
void paging_init(struct gsm_bts *bts);
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <osmocore/select.h>
|
||||
#include <openbsc/linuxlist.h>
|
||||
#include <openbsc/select.h>
|
||||
|
||||
enum rtp_rx_action {
|
||||
RTP_NONE,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef _BSC_SELECT_H
|
||||
#define _BSC_SELECT_H
|
||||
|
||||
#include "linuxlist.h"
|
||||
#include <openbsc/linuxlist.h>
|
||||
|
||||
#define BSC_FD_READ 0x0001
|
||||
#define BSC_FD_WRITE 0x0002
|
||||
@@ -28,7 +28,6 @@
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/gsm_subscriber.h>
|
||||
|
||||
#include <osmocore/signal.h>
|
||||
|
||||
/*
|
||||
* Signalling subsystems
|
||||
@@ -46,8 +45,7 @@ enum signal_subsystems {
|
||||
|
||||
/* SS_PAGING signals */
|
||||
enum signal_paging {
|
||||
S_PAGING_SUCCEEDED,
|
||||
S_PAGING_EXPIRED,
|
||||
S_PAGING_COMPLETED,
|
||||
};
|
||||
|
||||
/* SS_SMS signals */
|
||||
@@ -71,9 +69,6 @@ enum signal_nm {
|
||||
S_NM_FAIL_REP, /* GSM 12.21 failure event report */
|
||||
S_NM_NACK, /* GSM 12.21 various NM_MT_*_NACK happened */
|
||||
S_NM_IPACC_NACK, /* GSM 12.21 nanoBTS extensions NM_MT_IPACC_*_*_NACK happened */
|
||||
S_NM_IPACC_ACK, /* GSM 12.21 nanoBTS extensions NM_MT_IPACC_*_*_ACK happened */
|
||||
S_NM_IPACC_RESTART_ACK, /* nanoBTS has send a restart ack */
|
||||
S_NM_IPACC_RESTART_NACK,/* nanoBTS has send a restart ack */
|
||||
S_NM_TEST_REP, /* GSM 12.21 Test Report */
|
||||
};
|
||||
|
||||
@@ -111,6 +106,9 @@ enum signal_global {
|
||||
S_GLOBAL_SHUTDOWN,
|
||||
};
|
||||
|
||||
typedef int signal_cbfn(unsigned int subsys, unsigned int signal,
|
||||
void *handler_data, void *signal_data);
|
||||
|
||||
struct paging_signal_data {
|
||||
struct gsm_subscriber *subscr;
|
||||
struct gsm_bts *bts;
|
||||
@@ -125,9 +123,12 @@ struct scall_signal_data {
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct ipacc_ack_signal_data {
|
||||
struct gsm_bts *bts;
|
||||
u_int8_t msg_type;
|
||||
};
|
||||
/* Management */
|
||||
int register_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data);
|
||||
void unregister_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data);
|
||||
|
||||
/* Dispatch */
|
||||
void dispatch_signal(unsigned int subsys, unsigned int signal, void *signal_data);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
#ifndef _SILENT_CALL_H
|
||||
#define _SILENT_CALL_H
|
||||
|
||||
extern int gsm_silent_call_start(struct gsm_subscriber *subscr,
|
||||
void *data, int type);
|
||||
extern int gsm_silent_call_start(struct gsm_subscriber *subscr, void *data);
|
||||
extern int gsm_silent_call_stop(struct gsm_subscriber *subscr);
|
||||
extern int silent_call_rx(struct msgb *msg);
|
||||
extern int silent_call_reroute(struct msgb *msg);
|
||||
|
||||
#endif /* _SILENT_CALL_H */
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <openbsc/linuxlist.h>
|
||||
|
||||
#define NR_SUBCH 4
|
||||
#define TRAU_FRAME_SIZE 40
|
||||
|
||||
@@ -22,17 +22,19 @@
|
||||
#define TELNET_INTERFACE_H
|
||||
|
||||
#include "gsm_data.h"
|
||||
#include "debug.h"
|
||||
#include <osmocore/select.h>
|
||||
#include "linuxlist.h"
|
||||
#include "select.h"
|
||||
|
||||
#include <vty/vty.h>
|
||||
|
||||
#define TELNET_COMMAND_48 1
|
||||
#define TELNET_COMMAND_11 2
|
||||
|
||||
struct telnet_connection {
|
||||
struct llist_head entry;
|
||||
struct gsm_network *network;
|
||||
struct bsc_fd fd;
|
||||
struct vty *vty;
|
||||
struct debug_target *dbg;
|
||||
};
|
||||
|
||||
|
||||
|
||||
221
openbsc/include/openbsc/tlv.h
Normal file
221
openbsc/include/openbsc/tlv.h
Normal file
@@ -0,0 +1,221 @@
|
||||
#ifndef _TLV_H
|
||||
#define _TLV_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openbsc/msgb.h>
|
||||
|
||||
/* Terminology / wording
|
||||
tag length value (in bits)
|
||||
|
||||
V - - 8
|
||||
LV - 8 N * 8
|
||||
TLV 8 8 N * 8
|
||||
TL16V 8 16 N * 8
|
||||
TLV16 8 8 N * 16
|
||||
TvLV 8 8/16 N * 8
|
||||
|
||||
*/
|
||||
|
||||
#define LV_GROSS_LEN(x) (x+1)
|
||||
#define TLV_GROSS_LEN(x) (x+2)
|
||||
#define TLV16_GROSS_LEN(x) ((2*x)+2)
|
||||
#define TL16V_GROSS_LEN(x) (x+3)
|
||||
|
||||
#define TVLV_MAX_ONEBYTE 0x7f
|
||||
|
||||
static inline u_int16_t TVLV_GROSS_LEN(u_int16_t len)
|
||||
{
|
||||
if (len <= TVLV_MAX_ONEBYTE)
|
||||
return TLV_GROSS_LEN(len);
|
||||
else
|
||||
return TL16V_GROSS_LEN(len);
|
||||
}
|
||||
|
||||
/* TLV generation */
|
||||
|
||||
static inline u_int8_t *lv_put(u_int8_t *buf, u_int8_t len,
|
||||
const u_int8_t *val)
|
||||
{
|
||||
*buf++ = len;
|
||||
memcpy(buf, val, len);
|
||||
return buf + len;
|
||||
}
|
||||
|
||||
static inline u_int8_t *tlv_put(u_int8_t *buf, u_int8_t tag, u_int8_t len,
|
||||
const u_int8_t *val)
|
||||
{
|
||||
*buf++ = tag;
|
||||
*buf++ = len;
|
||||
memcpy(buf, val, len);
|
||||
return buf + len;
|
||||
}
|
||||
|
||||
static inline u_int8_t *tlv16_put(u_int8_t *buf, u_int8_t tag, u_int8_t len,
|
||||
const u_int16_t *val)
|
||||
{
|
||||
*buf++ = tag;
|
||||
*buf++ = len;
|
||||
memcpy(buf, val, len*2);
|
||||
return buf + len*2;
|
||||
}
|
||||
|
||||
static inline u_int8_t *tl16v_put(u_int8_t *buf, u_int8_t tag, u_int16_t len,
|
||||
const u_int8_t *val)
|
||||
{
|
||||
*buf++ = tag;
|
||||
*buf++ = len >> 8;
|
||||
*buf++ = len & 0xff;
|
||||
memcpy(buf, val, len);
|
||||
return buf + len*2;
|
||||
}
|
||||
|
||||
static inline u_int8_t *tvlv_put(u_int8_t *buf, u_int8_t tag, u_int16_t len,
|
||||
const u_int8_t *val)
|
||||
{
|
||||
u_int8_t *ret;
|
||||
|
||||
if (len <= TVLV_MAX_ONEBYTE) {
|
||||
ret = tlv_put(buf, tag, len, val);
|
||||
buf[1] |= 0x80;
|
||||
} else
|
||||
ret = tl16v_put(buf, tag, len, val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_tlv16_put(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int16_t *val)
|
||||
{
|
||||
u_int8_t *buf = msgb_put(msg, TLV16_GROSS_LEN(len));
|
||||
return tlv16_put(buf, tag, len, val);
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_tl16v_put(struct msgb *msg, u_int8_t tag, u_int16_t len,
|
||||
const u_int8_t *val)
|
||||
{
|
||||
u_int8_t *buf = msgb_put(msg, TL16V_GROSS_LEN(len));
|
||||
return tl16v_put(buf, tag, len, val);
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_tvlv_put(struct msgb *msg, u_int8_t tag, u_int16_t len,
|
||||
const u_int8_t *val)
|
||||
{
|
||||
u_int8_t *buf = msgb_put(msg, TVLV_GROSS_LEN(len));
|
||||
return tvlv_put(buf, tag, len, val);
|
||||
}
|
||||
|
||||
static inline u_int8_t *v_put(u_int8_t *buf, u_int8_t val)
|
||||
{
|
||||
*buf++ = val;
|
||||
return buf;
|
||||
}
|
||||
|
||||
static inline u_int8_t *tv_put(u_int8_t *buf, u_int8_t tag,
|
||||
u_int8_t val)
|
||||
{
|
||||
*buf++ = tag;
|
||||
*buf++ = val;
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* 'val' is still in host byte order! */
|
||||
static inline u_int8_t *tv16_put(u_int8_t *buf, u_int8_t tag,
|
||||
u_int16_t val)
|
||||
{
|
||||
*buf++ = tag;
|
||||
*buf++ = val >> 8;
|
||||
*buf++ = val & 0xff;
|
||||
return buf;
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_lv_put(struct msgb *msg, u_int8_t len, const u_int8_t *val)
|
||||
{
|
||||
u_int8_t *buf = msgb_put(msg, LV_GROSS_LEN(len));
|
||||
return lv_put(buf, len, val);
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_tlv_put(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int8_t *val)
|
||||
{
|
||||
u_int8_t *buf = msgb_put(msg, TLV_GROSS_LEN(len));
|
||||
return tlv_put(buf, tag, len, val);
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_tv_put(struct msgb *msg, u_int8_t tag, u_int8_t val)
|
||||
{
|
||||
u_int8_t *buf = msgb_put(msg, 2);
|
||||
return tv_put(buf, tag, val);
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_v_put(struct msgb *msg, u_int8_t val)
|
||||
{
|
||||
u_int8_t *buf = msgb_put(msg, 1);
|
||||
return v_put(buf, val);
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_tv16_put(struct msgb *msg, u_int8_t tag, u_int16_t val)
|
||||
{
|
||||
u_int8_t *buf = msgb_put(msg, 3);
|
||||
return tv16_put(buf, tag, val);
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_tlv_push(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int8_t *val)
|
||||
{
|
||||
u_int8_t *buf = msgb_push(msg, TLV_GROSS_LEN(len));
|
||||
return tlv_put(buf, tag, len, val);
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_tv_push(struct msgb *msg, u_int8_t tag, u_int8_t val)
|
||||
{
|
||||
u_int8_t *buf = msgb_push(msg, 2);
|
||||
return tv_put(buf, tag, val);
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_tv16_push(struct msgb *msg, u_int8_t tag, u_int16_t val)
|
||||
{
|
||||
u_int8_t *buf = msgb_push(msg, 3);
|
||||
return tv16_put(buf, tag, val);
|
||||
}
|
||||
|
||||
/* TLV parsing */
|
||||
|
||||
struct tlv_p_entry {
|
||||
u_int16_t len;
|
||||
const u_int8_t *val;
|
||||
};
|
||||
|
||||
enum tlv_type {
|
||||
TLV_TYPE_FIXED,
|
||||
TLV_TYPE_T,
|
||||
TLV_TYPE_TV,
|
||||
TLV_TYPE_TLV,
|
||||
TLV_TYPE_TL16V,
|
||||
TLV_TYPE_TvLV,
|
||||
};
|
||||
|
||||
struct tlv_def {
|
||||
enum tlv_type type;
|
||||
u_int8_t fixed_len;
|
||||
};
|
||||
|
||||
struct tlv_definition {
|
||||
struct tlv_def def[0xff];
|
||||
};
|
||||
|
||||
struct tlv_parsed {
|
||||
struct tlv_p_entry lv[0xff];
|
||||
};
|
||||
|
||||
extern struct tlv_definition tvlv_att_def;
|
||||
|
||||
int tlv_parse_one(u_int8_t *o_tag, u_int16_t *o_len, const u_int8_t **o_val,
|
||||
const struct tlv_definition *def,
|
||||
const u_int8_t *buf, int buf_len);
|
||||
int tlv_parse(struct tlv_parsed *dec, const struct tlv_definition *def,
|
||||
const u_int8_t *buf, int buf_len, u_int8_t lv_tag, u_int8_t lv_tag2);
|
||||
|
||||
#define TLVP_PRESENT(x, y) ((x)->lv[y].val)
|
||||
#define TLVP_LEN(x, y) (x)->lv[y].len
|
||||
#define TLVP_VAL(x, y) (x)->lv[y].val
|
||||
|
||||
#endif /* _TLV_H */
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/gsm_subscriber.h>
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <openbsc/linuxlist.h>
|
||||
#include <openbsc/gsm_04_11.h>
|
||||
|
||||
/* One transaction */
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
/* Handler function for mobile-originated USSD messages */
|
||||
|
||||
#include <osmocore/msgb.h>
|
||||
#include <openbsc/msgb.h>
|
||||
|
||||
int handle_rcv_ussd(struct msgb *msg);
|
||||
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
sccp_HEADERS = sccp_types.h sccp.h
|
||||
sccpdir = $(includedir)/sccp
|
||||
noinst_HEADERS = sccp_types.h sccp.h
|
||||
|
||||
@@ -27,11 +27,11 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openbsc/msgb.h>
|
||||
|
||||
#include "sccp_types.h"
|
||||
|
||||
struct msgb;
|
||||
struct sccp_system;
|
||||
|
||||
enum {
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
#ifndef SCCP_TYPES_H
|
||||
#define SCCP_TYPES_H
|
||||
|
||||
#include <endian.h>
|
||||
|
||||
/* Table 1/Q.713 - SCCP message types */
|
||||
enum sccp_message_types {
|
||||
SCCP_MSG_TYPE_CR = 1,
|
||||
@@ -89,19 +87,11 @@ enum {
|
||||
};
|
||||
|
||||
struct sccp_called_party_address {
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
u_int8_t point_code_indicator : 1,
|
||||
ssn_indicator : 1,
|
||||
global_title_indicator : 4,
|
||||
routing_indicator : 1,
|
||||
reserved : 1;
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
u_int8_t reserved : 1,
|
||||
routing_indicator : 1,
|
||||
global_title_indicator : 4,
|
||||
ssn_indicator : 1,
|
||||
point_code_indicator : 1;
|
||||
#endif
|
||||
u_int8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
@@ -110,13 +100,8 @@ struct sccp_called_party_address {
|
||||
/* Figure 6/Q.713 */
|
||||
struct sccp_signalling_point_code {
|
||||
u_int8_t lsb;
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
u_int8_t msb : 6,
|
||||
reserved : 2;
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
u_int8_t reserved : 2,
|
||||
msb : 6;
|
||||
#endif
|
||||
} __attribute__((packed));
|
||||
|
||||
/* SSN == subsystem number */
|
||||
@@ -152,13 +137,8 @@ enum {
|
||||
};
|
||||
|
||||
struct sccp_global_title {
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
u_int8_t nature_of_addr_ind : 7,
|
||||
odd_even : 1;
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
u_int8_t odd_even : 1,
|
||||
nature_of_addr_ind : 7;
|
||||
#endif
|
||||
u_int8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
@@ -356,6 +356,4 @@ void host_config_set(const char *);
|
||||
|
||||
void print_version(const char *);
|
||||
|
||||
extern void *tall_vty_cmd_ctx;
|
||||
|
||||
#endif /* _ZEBRA_COMMAND_H */
|
||||
|
||||
@@ -59,6 +59,4 @@ vector vector_copy(vector v);
|
||||
void *vector_lookup(vector, unsigned int);
|
||||
void *vector_lookup_ensure(vector, unsigned int);
|
||||
|
||||
extern void *tall_vty_vec_ctx;
|
||||
|
||||
#endif /* _ZEBRA_VECTOR_H */
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: OpenBSC SCCP Lib
|
||||
Description: OpenBSC SCCP Lib
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -lsccp
|
||||
Cflags: -I${includedir}/
|
||||
@@ -1,7 +1,7 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@/
|
||||
includedir=@includedir@/openbsc-1.0
|
||||
|
||||
Name: OpenBSC
|
||||
Description: OpenBSC base station controller
|
||||
|
||||
@@ -1,28 +1,23 @@
|
||||
INCLUDES = $(all_includes) -I$(top_srcdir)/include
|
||||
AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS)
|
||||
AM_LDFLAGS = $(LIBOSMOCORE_LIBS)
|
||||
AM_CFLAGS=-Wall
|
||||
|
||||
sbin_PROGRAMS = bsc_hack bs11_config ipaccess-find ipaccess-config \
|
||||
isdnsync bsc_mgcp ipaccess-proxy
|
||||
noinst_LIBRARIES = libbsc.a libmsc.a libvty.a
|
||||
isdnsync bsc_mgcp bsc_msc_ip bsc_nat
|
||||
noinst_LIBRARIES = libbsc.a libmsc.a libvty.a libsccp.a
|
||||
noinst_HEADERS = vty/cardshell.h
|
||||
|
||||
bscdir = $(libdir)
|
||||
bsc_LIBRARIES = libsccp.a
|
||||
|
||||
libbsc_a_SOURCES = abis_rsl.c abis_nm.c gsm_data.c gsm_04_08_utils.c \
|
||||
chan_alloc.c debug.c \
|
||||
msgb.c select.c chan_alloc.c timer.c debug.c \
|
||||
gsm_subscriber_base.c subchan_demux.c bsc_rll.c transaction.c \
|
||||
trau_frame.c trau_mux.c paging.c e1_config.c e1_input.c \
|
||||
input/misdn.c input/ipaccess.c \
|
||||
talloc_ctx.c system_information.c rest_octets.c \
|
||||
rtp_proxy.c bts_siemens_bs11.c bts_ipaccess_nanobts.c \
|
||||
bts_unknown.c
|
||||
trau_frame.c trau_mux.c paging.c e1_config.c e1_input.c tlv_parser.c \
|
||||
input/misdn.c input/ipaccess.c signal.c gsm_utils.c talloc.c \
|
||||
talloc_ctx.c system_information.c bitvec.c rest_octets.c \
|
||||
rtp_proxy.c telnet_interface.c
|
||||
|
||||
libmsc_a_SOURCES = gsm_subscriber.c db.c telnet_interface.c \
|
||||
libmsc_a_SOURCES = gsm_subscriber.c db.c \
|
||||
mncc.c gsm_04_08.c gsm_04_11.c transaction.c \
|
||||
token_auth.c rrlp.c gsm_04_80.c ussd.c silent_call.c \
|
||||
handover_logic.c handover_decision.c meas_rep.c
|
||||
handover_logic.c handover_decision.c meas_rep.c
|
||||
|
||||
libvty_a_SOURCES = vty/buffer.c vty/command.c vty/vector.c vty/vty.c
|
||||
|
||||
@@ -31,18 +26,22 @@ libsccp_a_SOURCES = sccp/sccp.c
|
||||
bsc_hack_SOURCES = bsc_hack.c bsc_init.c vty_interface.c vty_interface_layer3.c
|
||||
bsc_hack_LDADD = libmsc.a libbsc.a libmsc.a libvty.a -ldl -ldbi $(LIBCRYPT)
|
||||
|
||||
bs11_config_SOURCES = bs11_config.c abis_nm.c gsm_data.c debug.c \
|
||||
rs232.c bts_siemens_bs11.c
|
||||
bsc_msc_ip_SOURCES = bssap.c bsc_msc_ip.c bsc_init.c vty_interface.c vty_interface_bsc.c \
|
||||
bsc_msc.c
|
||||
bsc_msc_ip_LDADD = libbsc.a libvty.a libsccp.a
|
||||
|
||||
ipaccess_find_SOURCES = ipaccess/ipaccess-find.c
|
||||
bs11_config_SOURCES = bs11_config.c abis_nm.c gsm_data.c msgb.c debug.c \
|
||||
select.c timer.c rs232.c tlv_parser.c signal.c talloc.c
|
||||
|
||||
ipaccess_config_SOURCES = ipaccess/ipaccess-config.c ipaccess/ipaccess-firmware.c
|
||||
ipaccess_find_SOURCES = ipaccess-find.c select.c timer.c
|
||||
|
||||
ipaccess_config_SOURCES = ipaccess-config.c
|
||||
ipaccess_config_LDADD = libbsc.a libmsc.a libbsc.a libvty.a -ldl -ldbi $(LIBCRYPT)
|
||||
|
||||
isdnsync_SOURCES = isdnsync.c
|
||||
|
||||
bsc_mgcp_SOURCES = mgcp/mgcp_main.c mgcp/mgcp_protocol.c mgcp/mgcp_network.c mgcp/mgcp_vty.c \
|
||||
debug.c telnet_interface.c
|
||||
bsc_mgcp_SOURCES = bsc_mgcp.c msgb.c talloc.c debug.c select.c timer.c telnet_interface.c
|
||||
bsc_mgcp_LDADD = libvty.a
|
||||
|
||||
ipaccess_proxy_SOURCES = ipaccess/ipaccess-proxy.c debug.c
|
||||
bsc_nat_SOURCES = nat/bsc_nat.c nat/bsc_filter.c bsc_msc.c
|
||||
bsc_nat_LDADD = libbsc.a libsccp.a
|
||||
|
||||
@@ -38,16 +38,15 @@
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/tlv.h>
|
||||
#include <osmocore/talloc.h>
|
||||
#include <openbsc/msgb.h>
|
||||
#include <openbsc/tlv.h>
|
||||
#include <openbsc/abis_nm.h>
|
||||
#include <openbsc/misdn.h>
|
||||
#include <openbsc/signal.h>
|
||||
#include <openbsc/talloc.h>
|
||||
|
||||
#define OM_ALLOC_SIZE 1024
|
||||
#define OM_HEADROOM_SIZE 128
|
||||
#define IPACC_SEGMENT_SIZE 245
|
||||
|
||||
/* unidirectional messages from BTS to BSC */
|
||||
static const enum abis_nm_msgtype reports[] = {
|
||||
@@ -264,7 +263,7 @@ static const enum abis_nm_attr nm_att_settable[] = {
|
||||
NM_ATT_MEAS_TYPE,
|
||||
};
|
||||
|
||||
const struct tlv_definition nm_att_tlvdef = {
|
||||
static const struct tlv_definition nm_att_tlvdef = {
|
||||
.def = {
|
||||
[NM_ATT_ABIS_CHANNEL] = { TLV_TYPE_FIXED, 3 },
|
||||
[NM_ATT_ADD_INFO] = { TLV_TYPE_TL16V },
|
||||
@@ -330,6 +329,77 @@ const struct tlv_definition nm_att_tlvdef = {
|
||||
[NM_ATT_HW_CONF_CHG] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_OUTST_ALARM] = { TLV_TYPE_TV },
|
||||
[NM_ATT_MEAS_RES] = { TLV_TYPE_TL16V },
|
||||
/* BS11 specifics */
|
||||
[NM_ATT_BS11_ESN_FW_CODE_NO] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_ESN_HW_CODE_NO] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_ESN_PCB_SERIAL] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_BOOT_SW_VERS] = { TLV_TYPE_TLV },
|
||||
[0xd5] = { TLV_TYPE_TLV },
|
||||
[0xa8] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_PASSWORD] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_TXPWR] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_RSSI_OFFS] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_LINE_CFG] = { TLV_TYPE_TV },
|
||||
[NM_ATT_BS11_L1_PROT_TYPE] = { TLV_TYPE_TV },
|
||||
[NM_ATT_BS11_BIT_ERR_THESH] = { TLV_TYPE_FIXED, 2 },
|
||||
[NM_ATT_BS11_DIVERSITY] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_LMT_LOGON_SESSION]={ TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_LMT_LOGIN_TIME] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_LMT_USER_ACC_LEV] ={ TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_LMT_USER_NAME] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_BTS_STATE] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_E1_STATE] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_PLL_MODE] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_PLL] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_CCLK_ACCURACY] = { TLV_TYPE_TV },
|
||||
[NM_ATT_BS11_CCLK_TYPE] = { TLV_TYPE_TV },
|
||||
/* ip.access specifics */
|
||||
[NM_ATT_IPACC_DST_IP] = { TLV_TYPE_FIXED, 4 },
|
||||
[NM_ATT_IPACC_DST_IP_PORT] = { TLV_TYPE_FIXED, 2 },
|
||||
[NM_ATT_IPACC_STREAM_ID] = { TLV_TYPE_TV, },
|
||||
[NM_ATT_IPACC_FREQ_CTRL] = { TLV_TYPE_TV, },
|
||||
[NM_ATT_IPACC_SEC_OML_CFG] = { TLV_TYPE_FIXED, 6 },
|
||||
[NM_ATT_IPACC_IP_IF_CFG] = { TLV_TYPE_FIXED, 8 },
|
||||
[NM_ATT_IPACC_IP_GW_CFG] = { TLV_TYPE_FIXED, 12 },
|
||||
[NM_ATT_IPACC_IN_SERV_TIME] = { TLV_TYPE_FIXED, 4 },
|
||||
[NM_ATT_IPACC_LOCATION] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_PAGING_CFG] = { TLV_TYPE_FIXED, 2 },
|
||||
[NM_ATT_IPACC_UNIT_ID] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_UNIT_NAME] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_SNMP_CFG] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_PRIM_OML_CFG_LIST] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_NV_FLAGS] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_FREQ_CTRL] = { TLV_TYPE_FIXED, 2 },
|
||||
[NM_ATT_IPACC_PRIM_OML_FB_TOUT] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_CUR_SW_CFG] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_TIMING_BUS] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_CGI] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_RAC] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_OBJ_VERSION] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_GPRS_PAGING_CFG]= { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_NSEI] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_BVCI] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_NSVCI] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_NS_CFG] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_BSSGP_CFG] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_NS_LINK_CFG] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_RLC_CFG] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_ALM_THRESH_LIST]= { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_MONIT_VAL_LIST] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_TIB_CONTROL] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_SUPP_FEATURES] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_CODING_SCHEMES] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_RLC_CFG_2] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_HEARTB_TOUT] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_UPTIME] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_RLC_CFG_3] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_SSL_CFG] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_SEC_POSSIBLE] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_IML_SSL_STATE] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_REVOC_DATE] = { TLV_TYPE_TL16V },
|
||||
//[0x95] = { TLV_TYPE_FIXED, 2 },
|
||||
[0x85] = { TLV_TYPE_TV },
|
||||
|
||||
},
|
||||
};
|
||||
|
||||
@@ -352,11 +422,9 @@ int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int abis_nm_tlv_parse(struct tlv_parsed *tp, struct gsm_bts *bts, const u_int8_t *buf, int len)
|
||||
int abis_nm_tlv_parse(struct tlv_parsed *tp, const u_int8_t *buf, int len)
|
||||
{
|
||||
if (!bts->model)
|
||||
return -EIO;
|
||||
return tlv_parse(tp, &bts->model->nm_att_tlvdef, buf, len, 0, 0);
|
||||
return tlv_parse(tp, &nm_att_tlvdef, buf, len, 0, 0);
|
||||
}
|
||||
|
||||
static int is_in_arr(enum abis_nm_msgtype mt, const enum abis_nm_msgtype *arr, int size)
|
||||
@@ -472,11 +540,11 @@ static const char *obj_class_name(u_int8_t oc)
|
||||
const char *nm_opstate_name(u_int8_t os)
|
||||
{
|
||||
switch (os) {
|
||||
case NM_OPSTATE_DISABLED:
|
||||
case 1:
|
||||
return "Disabled";
|
||||
case NM_OPSTATE_ENABLED:
|
||||
case 2:
|
||||
return "Enabled";
|
||||
case NM_OPSTATE_NULL:
|
||||
case 0xff:
|
||||
return "NULL";
|
||||
default:
|
||||
return "RFU";
|
||||
@@ -530,13 +598,6 @@ const char *nm_adm_name(u_int8_t adm)
|
||||
}
|
||||
}
|
||||
|
||||
int nm_is_running(struct gsm_nm_state *s) {
|
||||
return (s->operational == NM_OPSTATE_ENABLED) && (
|
||||
(s->availability == NM_AVSTATE_OK) ||
|
||||
(s->availability == 0xff)
|
||||
);
|
||||
}
|
||||
|
||||
static void debugp_foh(struct abis_om_fom_hdr *foh)
|
||||
{
|
||||
DEBUGP(DNM, "OC=%s(%02x) INST=(%02x,%02x,%02x) ",
|
||||
@@ -732,7 +793,7 @@ static int abis_nm_rx_statechg_rep(struct msgb *mb)
|
||||
|
||||
new_state = *nm_state;
|
||||
|
||||
abis_nm_tlv_parse(&tp, bts, foh->data, oh->length-sizeof(*foh));
|
||||
abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
|
||||
if (TLVP_PRESENT(&tp, NM_ATT_OPER_STATE)) {
|
||||
new_state.operational = *TLVP_VAL(&tp, NM_ATT_OPER_STATE);
|
||||
DEBUGPC(DNM, "OP_STATE=%s ", nm_opstate_name(new_state.operational));
|
||||
@@ -744,25 +805,19 @@ static int abis_nm_rx_statechg_rep(struct msgb *mb)
|
||||
new_state.availability = *TLVP_VAL(&tp, NM_ATT_AVAIL_STATUS);
|
||||
DEBUGPC(DNM, "AVAIL=%s(%02x) ", nm_avail_name(new_state.availability),
|
||||
new_state.availability);
|
||||
} else
|
||||
new_state.availability = 0xff;
|
||||
}
|
||||
if (TLVP_PRESENT(&tp, NM_ATT_ADM_STATE)) {
|
||||
new_state.administrative = *TLVP_VAL(&tp, NM_ATT_ADM_STATE);
|
||||
DEBUGPC(DNM, "ADM=%2s ", nm_adm_name(new_state.administrative));
|
||||
}
|
||||
DEBUGPC(DNM, "\n");
|
||||
|
||||
if ((new_state.administrative != 0 && nm_state->administrative == 0) ||
|
||||
new_state.operational != nm_state->operational ||
|
||||
new_state.availability != nm_state->availability) {
|
||||
if (memcmp(&new_state, nm_state, sizeof(new_state))) {
|
||||
/* Update the operational state of a given object in our in-memory data
|
||||
* structures and send an event to the higher layer */
|
||||
void *obj = objclass2obj(bts, foh->obj_class, &foh->obj_inst);
|
||||
rc = nm_state_event(EVT_STATECHG_OPER, foh->obj_class, obj, nm_state, &new_state);
|
||||
nm_state->operational = new_state.operational;
|
||||
nm_state->availability = new_state.availability;
|
||||
if (nm_state->administrative == 0)
|
||||
nm_state->administrative = new_state.administrative;
|
||||
*nm_state = new_state;
|
||||
}
|
||||
#if 0
|
||||
if (op_state == 1) {
|
||||
@@ -784,7 +839,7 @@ static int rx_fail_evt_rep(struct msgb *mb)
|
||||
|
||||
DEBUGPC(DNM, "Failure Event Report ");
|
||||
|
||||
abis_nm_tlv_parse(&tp, mb->trx->bts, foh->data, oh->length-sizeof(*foh));
|
||||
abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
|
||||
|
||||
if (TLVP_PRESENT(&tp, NM_ATT_EVENT_TYPE))
|
||||
DEBUGPC(DNM, "Type=%s ", event_type_name(*TLVP_VAL(&tp, NM_ATT_EVENT_TYPE)));
|
||||
@@ -856,21 +911,29 @@ static int abis_nm_rx_sw_act_req(struct msgb *mb)
|
||||
const u_int8_t *sw_config;
|
||||
int sw_config_len;
|
||||
int file_id_len;
|
||||
int nack = 0;
|
||||
int ret;
|
||||
|
||||
debugp_foh(foh);
|
||||
|
||||
DEBUGPC(DNM, "SW Activate Request: ");
|
||||
|
||||
DEBUGP(DNM, "Software Activate Request, ACKing and Activating\n");
|
||||
if (foh->obj_class >= 0xf0 && foh->obj_class <= 0xf3) {
|
||||
DEBUGPC(DNM, "NACKing for GPRS obj_class 0x%02x\n", foh->obj_class);
|
||||
nack = 1;
|
||||
} else
|
||||
DEBUGPC(DNM, "ACKing and Activating\n");
|
||||
|
||||
ret = abis_nm_sw_act_req_ack(mb->trx->bts, foh->obj_class,
|
||||
foh->obj_inst.bts_nr,
|
||||
foh->obj_inst.trx_nr,
|
||||
foh->obj_inst.ts_nr, 0,
|
||||
foh->obj_inst.ts_nr, nack,
|
||||
foh->data, oh->length-sizeof(*foh));
|
||||
|
||||
abis_nm_tlv_parse(&tp, mb->trx->bts, foh->data, oh->length-sizeof(*foh));
|
||||
if (nack)
|
||||
return ret;
|
||||
|
||||
abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
|
||||
sw_config = TLVP_VAL(&tp, NM_ATT_SW_CONFIG);
|
||||
sw_config_len = TLVP_LEN(&tp, NM_ATT_SW_CONFIG);
|
||||
if (!TLVP_PRESENT(&tp, NM_ATT_SW_CONFIG)) {
|
||||
@@ -904,7 +967,7 @@ static int abis_nm_rx_chg_adm_state_ack(struct msgb *mb)
|
||||
struct tlv_parsed tp;
|
||||
u_int8_t adm_state;
|
||||
|
||||
abis_nm_tlv_parse(&tp, mb->trx->bts, foh->data, oh->length-sizeof(*foh));
|
||||
abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
|
||||
if (!TLVP_PRESENT(&tp, NM_ATT_ADM_STATE))
|
||||
return -EINVAL;
|
||||
|
||||
@@ -920,7 +983,7 @@ static int abis_nm_rx_lmt_event(struct msgb *mb)
|
||||
struct tlv_parsed tp;
|
||||
|
||||
DEBUGP(DNM, "LMT Event ");
|
||||
abis_nm_tlv_parse(&tp, mb->trx->bts, foh->data, oh->length-sizeof(*foh));
|
||||
abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
|
||||
if (TLVP_PRESENT(&tp, NM_ATT_BS11_LMT_LOGON_SESSION) &&
|
||||
TLVP_LEN(&tp, NM_ATT_BS11_LMT_LOGON_SESSION) >= 1) {
|
||||
u_int8_t onoff = *TLVP_VAL(&tp, NM_ATT_BS11_LMT_LOGON_SESSION);
|
||||
@@ -966,7 +1029,7 @@ static int abis_nm_rcvmsg_fom(struct msgb *mb)
|
||||
else
|
||||
DEBUGPC(DNM, "NACK 0x%02x ", mt);
|
||||
|
||||
abis_nm_tlv_parse(&tp, mb->trx->bts, foh->data, oh->length-sizeof(*foh));
|
||||
abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
|
||||
if (TLVP_PRESENT(&tp, NM_ATT_NACK_CAUSES))
|
||||
DEBUGPC(DNM, "CAUSE=%s\n",
|
||||
nack_cause_name(*TLVP_VAL(&tp, NM_ATT_NACK_CAUSES)));
|
||||
@@ -980,11 +1043,13 @@ static int abis_nm_rcvmsg_fom(struct msgb *mb)
|
||||
/* check if last message is to be acked */
|
||||
if (is_ack_nack(nmh->last_msgtype)) {
|
||||
if (mt == MT_ACK(nmh->last_msgtype)) {
|
||||
DEBUGP(DNM, "received ACK (0x%x)\n", foh->msg_type);
|
||||
fprintf(stderr, "received ACK (0x%x)\n",
|
||||
foh->msg_type);
|
||||
/* we got our ACK, continue sending the next msg */
|
||||
} else if (mt == MT_NACK(nmh->last_msgtype)) {
|
||||
/* we got a NACK, signal this to the caller */
|
||||
DEBUGP(DNM, "received NACK (0x%x)\n", foh->msg_type);
|
||||
fprintf(stderr, "received NACK (0x%x)\n",
|
||||
foh->msg_type);
|
||||
/* FIXME: somehow signal this to the caller */
|
||||
} else {
|
||||
/* really strange things happen */
|
||||
@@ -1006,12 +1071,6 @@ static int abis_nm_rcvmsg_fom(struct msgb *mb)
|
||||
case NM_MT_CONN_MDROP_LINK_ACK:
|
||||
DEBUGP(DNM, "CONN MDROP LINK ACK\n");
|
||||
break;
|
||||
case NM_MT_IPACC_RESTART_ACK:
|
||||
dispatch_signal(SS_NM, S_NM_IPACC_RESTART_ACK, NULL);
|
||||
break;
|
||||
case NM_MT_IPACC_RESTART_NACK:
|
||||
dispatch_signal(SS_NM, S_NM_IPACC_RESTART_NACK, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1157,22 +1216,6 @@ struct abis_nm_sw {
|
||||
|
||||
static struct abis_nm_sw g_sw;
|
||||
|
||||
static void sw_add_file_id_and_ver(struct abis_nm_sw *sw, struct msgb *msg)
|
||||
{
|
||||
if (sw->bts->type == GSM_BTS_TYPE_NANOBTS) {
|
||||
msgb_v_put(msg, NM_ATT_SW_DESCR);
|
||||
msgb_tl16v_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id);
|
||||
msgb_tl16v_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len,
|
||||
sw->file_version);
|
||||
} else if (sw->bts->type == GSM_BTS_TYPE_BS11) {
|
||||
msgb_tlv_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id);
|
||||
msgb_tlv_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len,
|
||||
sw->file_version);
|
||||
} else {
|
||||
LOGP(DNM, LOGL_ERROR, "Please implement this for the BTS.\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* 6.2.1 / 8.3.1: Load Data Initiate */
|
||||
static int sw_load_init(struct abis_nm_sw *sw)
|
||||
{
|
||||
@@ -1184,8 +1227,11 @@ static int sw_load_init(struct abis_nm_sw *sw)
|
||||
fill_om_fom_hdr(oh, len, NM_MT_LOAD_INIT, sw->obj_class,
|
||||
sw->obj_instance[0], sw->obj_instance[1],
|
||||
sw->obj_instance[2]);
|
||||
|
||||
sw_add_file_id_and_ver(sw, msg);
|
||||
|
||||
/* FIXME: this is BS11 specific format */
|
||||
msgb_tlv_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id);
|
||||
msgb_tlv_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len,
|
||||
sw->file_version);
|
||||
msgb_tv_put(msg, NM_ATT_WINDOW_SIZE, sw->window_size);
|
||||
|
||||
return abis_nm_sendmsg(sw->bts, msg);
|
||||
@@ -1243,24 +1289,7 @@ static int sw_load_segment(struct abis_nm_sw *sw)
|
||||
/* we only now know the exact length for the OM hdr */
|
||||
len = strlen(line_buf)+2;
|
||||
break;
|
||||
case GSM_BTS_TYPE_NANOBTS: {
|
||||
static_assert(sizeof(seg_buf) >= IPACC_SEGMENT_SIZE, buffer_big_enough);
|
||||
len = read(sw->fd, &seg_buf, IPACC_SEGMENT_SIZE);
|
||||
if (len < 0) {
|
||||
perror("read failed");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (len != IPACC_SEGMENT_SIZE)
|
||||
sw->last_seg = 1;
|
||||
|
||||
++sw->seg_in_window;
|
||||
msgb_tl16v_put(msg, NM_ATT_IPACC_FILE_DATA, len, (const u_int8_t *) seg_buf);
|
||||
len += 3;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOGP(DNM, LOGL_ERROR, "sw_load_segment needs implementation for the BTS.\n");
|
||||
/* FIXME: Other BTS types */
|
||||
return -1;
|
||||
}
|
||||
@@ -1284,7 +1313,11 @@ static int sw_load_end(struct abis_nm_sw *sw)
|
||||
sw->obj_instance[0], sw->obj_instance[1],
|
||||
sw->obj_instance[2]);
|
||||
|
||||
sw_add_file_id_and_ver(sw, msg);
|
||||
/* FIXME: this is BS11 specific format */
|
||||
msgb_tlv_put(msg, NM_ATT_FILE_ID, sw->file_id_len, sw->file_id);
|
||||
msgb_tlv_put(msg, NM_ATT_FILE_VERSION, sw->file_version_len,
|
||||
sw->file_version);
|
||||
|
||||
return abis_nm_sendmsg(sw->bts, msg);
|
||||
}
|
||||
|
||||
@@ -1308,59 +1341,6 @@ static int sw_activate(struct abis_nm_sw *sw)
|
||||
return abis_nm_sendmsg(sw->bts, msg);
|
||||
}
|
||||
|
||||
struct sdp_firmware {
|
||||
char magic[4];
|
||||
char more_magic[4];
|
||||
unsigned int header_length;
|
||||
unsigned int file_length;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
static int parse_sdp_header(struct abis_nm_sw *sw)
|
||||
{
|
||||
struct sdp_firmware firmware_header;
|
||||
int rc;
|
||||
struct stat stat;
|
||||
|
||||
rc = read(sw->fd, &firmware_header, sizeof(firmware_header));
|
||||
if (rc != sizeof(firmware_header)) {
|
||||
LOGP(DNM, LOGL_ERROR, "Could not read SDP file header.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strncmp(firmware_header.magic, " SDP", 4) != 0) {
|
||||
LOGP(DNM, LOGL_ERROR, "The magic number1 is wrong.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (firmware_header.more_magic[0] != 0x10 ||
|
||||
firmware_header.more_magic[1] != 0x02 ||
|
||||
firmware_header.more_magic[2] != 0x00 ||
|
||||
firmware_header.more_magic[3] != 0x00) {
|
||||
LOGP(DNM, LOGL_ERROR, "The more magic number is wrong.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (fstat(sw->fd, &stat) == -1) {
|
||||
LOGP(DNM, LOGL_ERROR, "Could not stat the file.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ntohl(firmware_header.file_length) != stat.st_size) {
|
||||
LOGP(DNM, LOGL_ERROR, "The filesizes do not match.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* go back to the start as we checked the whole filesize.. */
|
||||
lseek(sw->fd, 0l, SEEK_SET);
|
||||
LOGP(DNM, LOGL_NOTICE, "The ipaccess SDP header is not fully understood.\n"
|
||||
"There might be checksums in the file that are not\n"
|
||||
"verified and incomplete firmware might be flashed.\n"
|
||||
"There is absolutely no WARRANTY that flashing will\n"
|
||||
"work.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sw_open_file(struct abis_nm_sw *sw, const char *fname)
|
||||
{
|
||||
char file_id[12+1];
|
||||
@@ -1392,19 +1372,6 @@ static int sw_open_file(struct abis_nm_sw *sw, const char *fname)
|
||||
/* rewind to start of file */
|
||||
rewind(sw->stream);
|
||||
break;
|
||||
case GSM_BTS_TYPE_NANOBTS:
|
||||
/* TODO: extract that from the filename or content */
|
||||
rc = parse_sdp_header(sw);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Could not parse the ipaccess SDP header\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy((char *)sw->file_id, "id");
|
||||
sw->file_id_len = 3;
|
||||
strcpy((char *)sw->file_version, "version");
|
||||
sw->file_version_len = 8;
|
||||
break;
|
||||
default:
|
||||
/* We don't know how to treat them yet */
|
||||
close(sw->fd);
|
||||
@@ -1503,12 +1470,6 @@ static int abis_nm_rcvmsg_sw(struct msgb *mb)
|
||||
rc = sw_load_end(sw);
|
||||
}
|
||||
break;
|
||||
case NM_MT_LOAD_ABORT:
|
||||
if (sw->cbfn)
|
||||
sw->cbfn(GSM_HOOK_NM_SWLOAD,
|
||||
NM_MT_LOAD_ABORT, mb,
|
||||
sw->cb_data, NULL);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SW_STATE_WAIT_ENDACK:
|
||||
@@ -1522,7 +1483,6 @@ static int abis_nm_rcvmsg_sw(struct msgb *mb)
|
||||
sw->cbfn(GSM_HOOK_NM_SWLOAD,
|
||||
NM_MT_LOAD_END_ACK, mb,
|
||||
sw->cb_data, NULL);
|
||||
rc = 0;
|
||||
break;
|
||||
case NM_MT_LOAD_END_NACK:
|
||||
if (sw->forced) {
|
||||
@@ -1599,26 +1559,10 @@ int abis_nm_software_load(struct gsm_bts *bts, const char *fname,
|
||||
return -EBUSY;
|
||||
|
||||
sw->bts = bts;
|
||||
|
||||
switch (bts->type) {
|
||||
case GSM_BTS_TYPE_BS11:
|
||||
sw->obj_class = NM_OC_SITE_MANAGER;
|
||||
sw->obj_instance[0] = 0xff;
|
||||
sw->obj_instance[1] = 0xff;
|
||||
sw->obj_instance[2] = 0xff;
|
||||
break;
|
||||
case GSM_BTS_TYPE_NANOBTS:
|
||||
sw->obj_class = NM_OC_BASEB_TRANSC;
|
||||
sw->obj_instance[0] = 0x00;
|
||||
sw->obj_instance[1] = 0x00;
|
||||
sw->obj_instance[2] = 0xff;
|
||||
break;
|
||||
case GSM_BTS_TYPE_UNKNOWN:
|
||||
default:
|
||||
LOGPC(DNM, LOGL_ERROR, "Software Load not properly implemented.\n");
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
sw->obj_class = NM_OC_SITE_MANAGER;
|
||||
sw->obj_instance[0] = 0xff;
|
||||
sw->obj_instance[1] = 0xff;
|
||||
sw->obj_instance[2] = 0xff;
|
||||
sw->window_size = win_size;
|
||||
sw->state = SW_STATE_WAIT_INITACK;
|
||||
sw->cbfn = cbfn;
|
||||
@@ -1646,10 +1590,7 @@ int abis_nm_software_load_status(struct gsm_bts *bts)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (sw->stream)
|
||||
percent = (ftell(sw->stream) * 100) / st.st_size;
|
||||
else
|
||||
percent = (lseek(sw->fd, 0, SEEK_CUR) * 100) / st.st_size;
|
||||
percent = (ftell(sw->stream) * 100) / st.st_size;
|
||||
return percent;
|
||||
}
|
||||
|
||||
@@ -2340,18 +2281,10 @@ int abis_nm_bs11_get_cclk(struct gsm_bts *bts)
|
||||
}
|
||||
|
||||
//static const u_int8_t bs11_logon_c7[] = { 0x07, 0xd9, 0x01, 0x11, 0x0d, 0x10, 0x20 };
|
||||
static const u_int8_t bs11_logon_c8[] = { 0x02 };
|
||||
static const u_int8_t bs11_logon_c9[] = "FACTORY";
|
||||
|
||||
int abis_nm_bs11_factory_logon(struct gsm_bts *bts, int on)
|
||||
{
|
||||
return abis_nm_bs11_logon(bts, 0x02, "FACTORY", on);
|
||||
}
|
||||
|
||||
int abis_nm_bs11_infield_logon(struct gsm_bts *bts, int on)
|
||||
{
|
||||
return abis_nm_bs11_logon(bts, 0x03, "FIELD ", on);
|
||||
}
|
||||
|
||||
int abis_nm_bs11_logon(struct gsm_bts *bts, u_int8_t level, const char *name, int on)
|
||||
{
|
||||
struct abis_om_hdr *oh;
|
||||
struct msgb *msg = nm_msgb_alloc();
|
||||
@@ -2362,15 +2295,15 @@ int abis_nm_bs11_logon(struct gsm_bts *bts, u_int8_t level, const char *name, in
|
||||
oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
|
||||
if (on) {
|
||||
u_int8_t len = 3*2 + sizeof(bdt)
|
||||
+ 1 + strlen(name);
|
||||
+ sizeof(bs11_logon_c8) + sizeof(bs11_logon_c9);
|
||||
fill_om_fom_hdr(oh, len, NM_MT_BS11_LMT_LOGON,
|
||||
NM_OC_BS11_BTSE, 0xff, 0xff, 0xff);
|
||||
msgb_tlv_put(msg, NM_ATT_BS11_LMT_LOGIN_TIME,
|
||||
sizeof(bdt), (u_int8_t *) &bdt);
|
||||
msgb_tlv_put(msg, NM_ATT_BS11_LMT_USER_ACC_LEV,
|
||||
1, &level);
|
||||
sizeof(bs11_logon_c8), bs11_logon_c8);
|
||||
msgb_tlv_put(msg, NM_ATT_BS11_LMT_USER_NAME,
|
||||
strlen(name), (u_int8_t *)name);
|
||||
sizeof(bs11_logon_c9), bs11_logon_c9);
|
||||
} else {
|
||||
fill_om_fom_hdr(oh, 0, NM_MT_BS11_LMT_LOGOFF,
|
||||
NM_OC_BS11_BTSE, 0xff, 0xff, 0xff);
|
||||
@@ -2418,27 +2351,6 @@ int abis_nm_bs11_set_pll_locked(struct gsm_bts *bts, int locked)
|
||||
return abis_nm_sendmsg(bts, msg);
|
||||
}
|
||||
|
||||
/* Set the calibration value of the PLL (work value/set value)
|
||||
* It depends on the login which one is changed */
|
||||
int abis_nm_bs11_set_pll(struct gsm_bts *bts, int value)
|
||||
{
|
||||
struct abis_om_hdr *oh;
|
||||
struct msgb *msg;
|
||||
u_int8_t tlv_value[2];
|
||||
|
||||
msg = nm_msgb_alloc();
|
||||
oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
|
||||
fill_om_fom_hdr(oh, 3, NM_MT_BS11_SET_ATTR, NM_OC_BS11,
|
||||
BS11_OBJ_TRX1, 0x00, 0x00);
|
||||
|
||||
tlv_value[0] = value>>8;
|
||||
tlv_value[1] = value&0xff;
|
||||
|
||||
msgb_tlv_put(msg, NM_ATT_BS11_PLL, 2, tlv_value);
|
||||
|
||||
return abis_nm_sendmsg(bts, msg);
|
||||
}
|
||||
|
||||
int abis_nm_bs11_get_state(struct gsm_bts *bts)
|
||||
{
|
||||
return __simple_cmd(bts, NM_MT_BS11_GET_STATE);
|
||||
@@ -2685,15 +2597,14 @@ static int abis_nm_rx_ipacc(struct msgb *msg)
|
||||
struct abis_om_fom_hdr *foh;
|
||||
u_int8_t idstrlen = oh->data[0];
|
||||
struct tlv_parsed tp;
|
||||
struct ipacc_ack_signal_data signal;
|
||||
|
||||
if (strncmp((char *)&oh->data[1], ipaccess_magic, idstrlen)) {
|
||||
LOGP(DNM, LOGL_ERROR, "id string is not com.ipaccess !?!\n");
|
||||
DEBUGP(DNM, "id string is not com.ipaccess !?!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
foh = (struct abis_om_fom_hdr *) (oh->data + 1 + idstrlen);
|
||||
abis_nm_tlv_parse(&tp, msg->trx->bts, foh->data, oh->length-sizeof(*foh));
|
||||
abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
|
||||
|
||||
debugp_foh(foh);
|
||||
|
||||
@@ -2716,7 +2627,7 @@ static int abis_nm_rx_ipacc(struct msgb *msg)
|
||||
DEBUGPC(DNM, "\n");
|
||||
break;
|
||||
case NM_MT_IPACC_RSL_CONNECT_NACK:
|
||||
LOGP(DNM, LOGL_ERROR, "RSL CONNECT NACK ");
|
||||
DEBUGPC(DNM, "RSL CONNECT NACK ");
|
||||
if (TLVP_PRESENT(&tp, NM_ATT_NACK_CAUSES))
|
||||
DEBUGPC(DNM, " CAUSE=%s\n",
|
||||
nack_cause_name(*TLVP_VAL(&tp, NM_ATT_NACK_CAUSES)));
|
||||
@@ -2728,35 +2639,35 @@ static int abis_nm_rx_ipacc(struct msgb *msg)
|
||||
/* FIXME: decode and show the actual attributes */
|
||||
break;
|
||||
case NM_MT_IPACC_SET_NVATTR_NACK:
|
||||
LOGP(DNM, LOGL_ERROR, "SET NVATTR NACK ");
|
||||
DEBUGPC(DNM, "SET NVATTR NACK ");
|
||||
if (TLVP_PRESENT(&tp, NM_ATT_NACK_CAUSES))
|
||||
LOGPC(DNM, LOGL_ERROR, " CAUSE=%s\n",
|
||||
DEBUGPC(DNM, " CAUSE=%s\n",
|
||||
nack_cause_name(*TLVP_VAL(&tp, NM_ATT_NACK_CAUSES)));
|
||||
else
|
||||
LOGPC(DNM, LOGL_ERROR, "\n");
|
||||
DEBUGPC(DNM, "\n");
|
||||
break;
|
||||
case NM_MT_IPACC_GET_NVATTR_ACK:
|
||||
DEBUGPC(DNM, "GET NVATTR ACK\n");
|
||||
/* FIXME: decode and show the actual attributes */
|
||||
break;
|
||||
case NM_MT_IPACC_GET_NVATTR_NACK:
|
||||
LOGPC(DNM, LOGL_ERROR, "GET NVATTR NACK ");
|
||||
DEBUGPC(DNM, "GET NVATTR NACK ");
|
||||
if (TLVP_PRESENT(&tp, NM_ATT_NACK_CAUSES))
|
||||
LOGPC(DNM, LOGL_ERROR, " CAUSE=%s\n",
|
||||
DEBUGPC(DNM, " CAUSE=%s\n",
|
||||
nack_cause_name(*TLVP_VAL(&tp, NM_ATT_NACK_CAUSES)));
|
||||
else
|
||||
LOGPC(DNM, LOGL_ERROR, "\n");
|
||||
DEBUGPC(DNM, "\n");
|
||||
break;
|
||||
case NM_MT_IPACC_SET_ATTR_ACK:
|
||||
DEBUGPC(DNM, "SET ATTR ACK\n");
|
||||
break;
|
||||
case NM_MT_IPACC_SET_ATTR_NACK:
|
||||
LOGPC(DNM, LOGL_ERROR, "SET ATTR NACK ");
|
||||
DEBUGPC(DNM, "SET ATTR NACK ");
|
||||
if (TLVP_PRESENT(&tp, NM_ATT_NACK_CAUSES))
|
||||
LOGPC(DNM, LOGL_ERROR, " CAUSE=%s\n",
|
||||
DEBUGPC(DNM, " CAUSE=%s\n",
|
||||
nack_cause_name(*TLVP_VAL(&tp, NM_ATT_NACK_CAUSES)));
|
||||
else
|
||||
LOGPC(DNM, LOGL_ERROR, "\n");
|
||||
DEBUGPC(DNM, "\n");
|
||||
break;
|
||||
default:
|
||||
DEBUGPC(DNM, "unknown\n");
|
||||
@@ -2768,14 +2679,7 @@ static int abis_nm_rx_ipacc(struct msgb *msg)
|
||||
case NM_MT_IPACC_RSL_CONNECT_NACK:
|
||||
case NM_MT_IPACC_SET_NVATTR_NACK:
|
||||
case NM_MT_IPACC_GET_NVATTR_NACK:
|
||||
signal.bts = msg->trx->bts;
|
||||
signal.msg_type = foh->msg_type;
|
||||
dispatch_signal(SS_NM, S_NM_IPACC_NACK, &signal);
|
||||
break;
|
||||
case NM_MT_IPACC_SET_NVATTR_ACK:
|
||||
signal.bts = msg->trx->bts;
|
||||
signal.msg_type = foh->msg_type;
|
||||
dispatch_signal(SS_NM, S_NM_IPACC_ACK, &signal);
|
||||
dispatch_signal(SS_NM, S_NM_IPACC_NACK, &foh->msg_type);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -2822,11 +2726,11 @@ int abis_nm_ipaccess_msg(struct gsm_bts *bts, u_int8_t msg_type,
|
||||
}
|
||||
|
||||
/* set some attributes in NVRAM */
|
||||
int abis_nm_ipaccess_set_nvattr(struct gsm_bts_trx *trx, u_int8_t *attr,
|
||||
int abis_nm_ipaccess_set_nvattr(struct gsm_bts *bts, u_int8_t *attr,
|
||||
int attr_len)
|
||||
{
|
||||
return abis_nm_ipaccess_msg(trx->bts, NM_MT_IPACC_SET_NVATTR,
|
||||
NM_OC_BASEB_TRANSC, 0, trx->nr, 0xff, attr,
|
||||
return abis_nm_ipaccess_msg(bts, NM_MT_IPACC_SET_NVATTR,
|
||||
NM_OC_BASEB_TRANSC, 0, 0, 0xff, attr,
|
||||
attr_len);
|
||||
}
|
||||
|
||||
@@ -2873,19 +2777,11 @@ int abis_nm_ipaccess_set_attr(struct gsm_bts *bts, u_int8_t obj_class,
|
||||
attr, attr_len);
|
||||
}
|
||||
|
||||
void abis_nm_ipaccess_cgi(u_int8_t *buf, struct gsm_bts *bts)
|
||||
{
|
||||
/* we simply reuse the GSM48 function and overwrite the RAC
|
||||
* with the Cell ID */
|
||||
gsm48_ra_id_by_bts(buf, bts);
|
||||
*((u_int16_t *)(buf + 5)) = htons(bts->cell_identity);
|
||||
}
|
||||
|
||||
void gsm_trx_lock_rf(struct gsm_bts_trx *trx, int locked)
|
||||
{
|
||||
int new_state = locked ? NM_STATE_LOCKED : NM_STATE_UNLOCKED;
|
||||
|
||||
trx->nm_state.administrative = new_state;
|
||||
trx->rf_locked = locked;
|
||||
if (!trx->bts || !trx->bts->oml_link)
|
||||
return;
|
||||
|
||||
@@ -3000,3 +2896,5 @@ int ipac_parse_bcch_info(struct ipac_bcch_info *binf, u_int8_t *buf)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* GSM Radio Signalling Link messages on the A-bis interface
|
||||
* 3GPP TS 08.58 version 8.6.0 Release 1999 / ETSI TS 100 596 V8.6.0 */
|
||||
|
||||
/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
|
||||
/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
@@ -30,23 +30,104 @@
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/gsm_04_08.h>
|
||||
#include <osmocore/gsm_utils.h>
|
||||
#include <openbsc/gsm_utils.h>
|
||||
#include <openbsc/abis_rsl.h>
|
||||
#include <openbsc/chan_alloc.h>
|
||||
#include <openbsc/bsc_rll.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <osmocore/tlv.h>
|
||||
#include <openbsc/tlv.h>
|
||||
#include <openbsc/paging.h>
|
||||
#include <openbsc/signal.h>
|
||||
#include <openbsc/meas_rep.h>
|
||||
#include <openbsc/rtp_proxy.h>
|
||||
#include <osmocore/rsl.h>
|
||||
|
||||
#define RSL_ALLOC_SIZE 1024
|
||||
#define RSL_ALLOC_HEADROOM 128
|
||||
|
||||
#define MAX(a, b) (a) >= (b) ? (a) : (b)
|
||||
|
||||
static const struct tlv_definition rsl_att_tlvdef = {
|
||||
.def = {
|
||||
[RSL_IE_CHAN_NR] = { TLV_TYPE_TV },
|
||||
[RSL_IE_LINK_IDENT] = { TLV_TYPE_TV },
|
||||
[RSL_IE_ACT_TYPE] = { TLV_TYPE_TV },
|
||||
[RSL_IE_BS_POWER] = { TLV_TYPE_TV },
|
||||
[RSL_IE_CHAN_IDENT] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_CHAN_MODE] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_ENCR_INFO] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_FRAME_NUMBER] = { TLV_TYPE_FIXED, 2 },
|
||||
[RSL_IE_HANDO_REF] = { TLV_TYPE_TV },
|
||||
[RSL_IE_L1_INFO] = { TLV_TYPE_FIXED, 2 },
|
||||
[RSL_IE_L3_INFO] = { TLV_TYPE_TL16V },
|
||||
[RSL_IE_MS_IDENTITY] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_MS_POWER] = { TLV_TYPE_TV },
|
||||
[RSL_IE_PAGING_GROUP] = { TLV_TYPE_TV },
|
||||
[RSL_IE_PAGING_LOAD] = { TLV_TYPE_FIXED, 2 },
|
||||
[RSL_IE_PYHS_CONTEXT] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_ACCESS_DELAY] = { TLV_TYPE_TV },
|
||||
[RSL_IE_RACH_LOAD] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_REQ_REFERENCE] = { TLV_TYPE_FIXED, 3 },
|
||||
[RSL_IE_RELEASE_MODE] = { TLV_TYPE_TV },
|
||||
[RSL_IE_RESOURCE_INFO] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_RLM_CAUSE] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_STARTNG_TIME] = { TLV_TYPE_FIXED, 2 },
|
||||
[RSL_IE_TIMING_ADVANCE] = { TLV_TYPE_TV },
|
||||
[RSL_IE_UPLINK_MEAS] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_CAUSE] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_MEAS_RES_NR] = { TLV_TYPE_TV },
|
||||
[RSL_IE_MSG_ID] = { TLV_TYPE_TV },
|
||||
[RSL_IE_SYSINFO_TYPE] = { TLV_TYPE_TV },
|
||||
[RSL_IE_MS_POWER_PARAM] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_BS_POWER_PARAM] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_PREPROC_PARAM] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_PREPROC_MEAS] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_IMM_ASS_INFO] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_SMSCB_INFO] = { TLV_TYPE_FIXED, 23 },
|
||||
[RSL_IE_MS_TIMING_OFFSET] = { TLV_TYPE_TV },
|
||||
[RSL_IE_ERR_MSG] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_FULL_BCCH_INFO] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_CHAN_NEEDED] = { TLV_TYPE_TV },
|
||||
[RSL_IE_CB_CMD_TYPE] = { TLV_TYPE_TV },
|
||||
[RSL_IE_SMSCB_MSG] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_FULL_IMM_ASS_INFO] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_SACCH_INFO] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_CBCH_LOAD_INFO] = { TLV_TYPE_TV },
|
||||
[RSL_IE_SMSCB_CHAN_INDICATOR] = { TLV_TYPE_TV },
|
||||
[RSL_IE_GROUP_CALL_REF] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_CHAN_DESC] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_NCH_DRX_INFO] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_CMD_INDICATOR] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_EMLPP_PRIO] = { TLV_TYPE_TV },
|
||||
[RSL_IE_UIC] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_MAIN_CHAN_REF] = { TLV_TYPE_TV },
|
||||
[RSL_IE_MR_CONFIG] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_MR_CONTROL] = { TLV_TYPE_TV },
|
||||
[RSL_IE_SUP_CODEC_TYPES] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_CODEC_CONFIG] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_RTD] = { TLV_TYPE_TV },
|
||||
[RSL_IE_TFO_STATUS] = { TLV_TYPE_TV },
|
||||
[RSL_IE_LLP_APDU] = { TLV_TYPE_TLV },
|
||||
[RSL_IE_SIEMENS_MRPCI] = { TLV_TYPE_TV },
|
||||
[RSL_IE_IPAC_PROXY_UDP] = { TLV_TYPE_FIXED, 2 },
|
||||
[RSL_IE_IPAC_BSCMPL_TOUT] = { TLV_TYPE_TV },
|
||||
[RSL_IE_IPAC_REMOTE_IP] = { TLV_TYPE_FIXED, 4 },
|
||||
[RSL_IE_IPAC_REMOTE_PORT] = { TLV_TYPE_FIXED, 2 },
|
||||
[RSL_IE_IPAC_RTP_PAYLOAD] = { TLV_TYPE_TV },
|
||||
[RSL_IE_IPAC_LOCAL_PORT] = { TLV_TYPE_FIXED, 2 },
|
||||
[RSL_IE_IPAC_SPEECH_MODE] = { TLV_TYPE_TV },
|
||||
[RSL_IE_IPAC_LOCAL_IP] = { TLV_TYPE_FIXED, 4 },
|
||||
[RSL_IE_IPAC_CONN_ID] = { TLV_TYPE_FIXED, 2 },
|
||||
[RSL_IE_IPAC_RTP_CSD_FMT] = { TLV_TYPE_TV },
|
||||
[RSL_IE_IPAC_RTP_JIT_BUF] = { TLV_TYPE_FIXED, 2 },
|
||||
[RSL_IE_IPAC_RTP_COMPR] = { TLV_TYPE_TV },
|
||||
[RSL_IE_IPAC_RTP_PAYLOAD2] = { TLV_TYPE_TV },
|
||||
[RSL_IE_IPAC_RTP_MPLEX] = { TLV_TYPE_FIXED, 8 },
|
||||
[RSL_IE_IPAC_RTP_MPLEX_ID] = { TLV_TYPE_TV },
|
||||
},
|
||||
};
|
||||
#define rsl_tlv_parse(dec, buf, len) \
|
||||
tlv_parse(dec, &rsl_att_tlvdef, buf, len, 0, 0)
|
||||
|
||||
static u_int8_t mdisc_by_msgtype(u_int8_t msg_type)
|
||||
{
|
||||
/* mask off the transparent bit ? */
|
||||
@@ -74,6 +155,44 @@ static inline void init_dchan_hdr(struct abis_rsl_dchan_hdr *dh,
|
||||
dh->ie_chan = RSL_IE_CHAN_NR;
|
||||
}
|
||||
|
||||
static inline void init_llm_hdr(struct abis_rsl_rll_hdr *dh,
|
||||
u_int8_t msg_type)
|
||||
{
|
||||
/* dh->c.msg_discr = mdisc_by_msgtype(msg_type); */
|
||||
dh->c.msg_discr = ABIS_RSL_MDISC_RLL;
|
||||
dh->c.msg_type = msg_type;
|
||||
dh->ie_chan = RSL_IE_CHAN_NR;
|
||||
dh->ie_link_id = RSL_IE_LINK_IDENT;
|
||||
}
|
||||
|
||||
|
||||
/* encode channel number as per Section 9.3.1 */
|
||||
u_int8_t rsl_enc_chan_nr(u_int8_t type, u_int8_t subch, u_int8_t timeslot)
|
||||
{
|
||||
u_int8_t ret;
|
||||
|
||||
ret = (timeslot & 0x07) | type;
|
||||
|
||||
switch (type) {
|
||||
case RSL_CHAN_Lm_ACCHs:
|
||||
subch &= 0x01;
|
||||
break;
|
||||
case RSL_CHAN_SDCCH4_ACCH:
|
||||
subch &= 0x07;
|
||||
break;
|
||||
case RSL_CHAN_SDCCH8_ACCH:
|
||||
subch &= 0x07;
|
||||
break;
|
||||
default:
|
||||
/* no subchannels allowed */
|
||||
subch = 0x00;
|
||||
break;
|
||||
}
|
||||
ret |= (subch << 3);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* determine logical channel based on TRX and channel number IE */
|
||||
struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, u_int8_t chan_nr)
|
||||
{
|
||||
@@ -118,8 +237,6 @@ struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, u_int8_t chan_nr)
|
||||
}
|
||||
|
||||
lchan = &ts->lchan[lch_idx];
|
||||
debug_set_context(BSC_CTX_LCHAN, lchan);
|
||||
debug_set_context(BSC_CTX_SUBSCR, lchan->subscr);
|
||||
|
||||
return lchan;
|
||||
}
|
||||
@@ -216,14 +333,57 @@ static int build_encr_info(u_int8_t *out, struct gsm_lchan *lchan)
|
||||
return lchan->encr.key_len + 1;
|
||||
}
|
||||
|
||||
static void print_rsl_cause(int lvl, const u_int8_t *cause_v, u_int8_t cause_len)
|
||||
|
||||
static const char *rsl_err_vals[0xff] = {
|
||||
[RSL_ERR_RADIO_IF_FAIL] = "Radio Interface Failure",
|
||||
[RSL_ERR_RADIO_LINK_FAIL] = "Radio Link Failure",
|
||||
[RSL_ERR_HANDOVER_ACC_FAIL] = "Handover Access Failure",
|
||||
[RSL_ERR_TALKER_ACC_FAIL] = "Talker Access Failure",
|
||||
[RSL_ERR_OM_INTERVENTION] = "O&M Intervention",
|
||||
[RSL_ERR_NORMAL_UNSPEC] = "Normal event, unspecified",
|
||||
[RSL_ERR_T_MSRFPCI_EXP] = "Siemens: T_MSRFPCI Expired",
|
||||
[RSL_ERR_EQUIPMENT_FAIL] = "Equipment Failure",
|
||||
[RSL_ERR_RR_UNAVAIL] = "Radio Resource not available",
|
||||
[RSL_ERR_TERR_CH_FAIL] = "Terrestrial Channel Failure",
|
||||
[RSL_ERR_CCCH_OVERLOAD] = "CCCH Overload",
|
||||
[RSL_ERR_ACCH_OVERLOAD] = "ACCH Overload",
|
||||
[RSL_ERR_PROCESSOR_OVERLOAD] = "Processor Overload",
|
||||
[RSL_ERR_RES_UNAVAIL] = "Resource not available, unspecified",
|
||||
[RSL_ERR_TRANSC_UNAVAIL] = "Transcoding not available",
|
||||
[RSL_ERR_SERV_OPT_UNAVAIL] = "Service or Option not available",
|
||||
[RSL_ERR_ENCR_UNIMPL] = "Encryption algorithm not implemented",
|
||||
[RSL_ERR_SERV_OPT_UNIMPL] = "Service or Option not implemented",
|
||||
[RSL_ERR_RCH_ALR_ACTV_ALLOC] = "Radio channel already activated",
|
||||
[RSL_ERR_INVALID_MESSAGE] = "Invalid Message, unspecified",
|
||||
[RSL_ERR_MSG_DISCR] = "Message Discriminator Error",
|
||||
[RSL_ERR_MSG_TYPE] = "Message Type Error",
|
||||
[RSL_ERR_MSG_SEQ] = "Message Sequence Error",
|
||||
[RSL_ERR_IE_ERROR] = "General IE error",
|
||||
[RSL_ERR_MAND_IE_ERROR] = "Mandatory IE error",
|
||||
[RSL_ERR_OPT_IE_ERROR] = "Optional IE error",
|
||||
[RSL_ERR_IE_NONEXIST] = "IE non-existent",
|
||||
[RSL_ERR_IE_LENGTH] = "IE length error",
|
||||
[RSL_ERR_IE_CONTENT] = "IE content error",
|
||||
[RSL_ERR_PROTO] = "Protocol error, unspecified",
|
||||
[RSL_ERR_INTERWORKING] = "Interworking error, unspecified",
|
||||
};
|
||||
|
||||
static const char *rsl_err_name(u_int8_t err)
|
||||
{
|
||||
if (rsl_err_vals[err])
|
||||
return rsl_err_vals[err];
|
||||
else
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static void print_rsl_cause(const u_int8_t *cause_v, u_int8_t cause_len)
|
||||
{
|
||||
int i;
|
||||
|
||||
LOGPC(DRSL, lvl, "CAUSE=0x%02x(%s) ",
|
||||
DEBUGPC(DRSL, "CAUSE=0x%02x(%s) ",
|
||||
cause_v[0], rsl_err_name(cause_v[0]));
|
||||
for (i = 1; i < cause_len-1; i++)
|
||||
LOGPC(DRSL, lvl, "%02x ", cause_v[i]);
|
||||
DEBUGPC(DRSL, "%02x ", cause_v[i]);
|
||||
}
|
||||
|
||||
/* Send a BCCH_INFO message as per Chapter 8.5.1 */
|
||||
@@ -563,7 +723,8 @@ int rsl_deact_sacch(struct gsm_lchan *lchan)
|
||||
msg->lchan = lchan;
|
||||
msg->trx = lchan->ts->trx;
|
||||
|
||||
DEBUGP(DRSL, "%s DEACTivate SACCH CMD\n", gsm_lchan_name(lchan));
|
||||
DEBUGP(DRSL, "DEACTivate SACCH CMD channel=%s chan_nr=0x%02x\n",
|
||||
gsm_ts_name(lchan->ts), dh->chan_nr);
|
||||
|
||||
return abis_rsl_sendmsg(msg);
|
||||
}
|
||||
@@ -581,7 +742,8 @@ int rsl_rf_chan_release(struct gsm_lchan *lchan)
|
||||
msg->lchan = lchan;
|
||||
msg->trx = lchan->ts->trx;
|
||||
|
||||
DEBUGP(DRSL, "%s RF Channel Release CMD\n", gsm_lchan_name(lchan));
|
||||
DEBUGP(DRSL, "RF Channel Release CMD channel=%s chan_nr=0x%02x\n",
|
||||
gsm_ts_name(lchan->ts), dh->chan_nr);
|
||||
|
||||
/* BTS will respond by RF CHAN REL ACK */
|
||||
return abis_rsl_sendmsg(msg);
|
||||
@@ -674,8 +836,8 @@ int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
|
||||
dh->chan_nr = lchan2chan_nr(lchan);
|
||||
msgb_tv_put(msg, RSL_IE_SIEMENS_MRPCI, *(u_int8_t *)mrpci);
|
||||
|
||||
DEBUGP(DRSL, "%s TX Siemens MRPCI 0x%02x\n",
|
||||
gsm_lchan_name(lchan), *(u_int8_t *)mrpci);
|
||||
DEBUGP(DRSL, "channel=%s chan_nr=0x%02x TX Siemens MRPCI 0x%02x\n",
|
||||
gsm_ts_name(lchan->ts), dh->chan_nr, *(u_int8_t *)mrpci);
|
||||
|
||||
msg->trx = lchan->ts->trx;
|
||||
|
||||
@@ -687,13 +849,27 @@ int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci)
|
||||
/* Chapter 8.3.1 */
|
||||
int rsl_data_request(struct msgb *msg, u_int8_t link_id)
|
||||
{
|
||||
u_int8_t l3_len = msg->tail - (u_int8_t *)msgb_l3(msg);
|
||||
struct abis_rsl_rll_hdr *rh;
|
||||
|
||||
if (msg->lchan == NULL) {
|
||||
LOGP(DRSL, LOGL_ERROR, "cannot send DATA REQUEST to unknown lchan\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, lchan2chan_nr(msg->lchan),
|
||||
link_id, 1);
|
||||
if (msg->lchan->use_count <= 0) {
|
||||
DEBUGP(DRSL, "BUG: Trying to send data on unused lchan\n");
|
||||
}
|
||||
|
||||
/* First push the L3 IE tag and length */
|
||||
msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
|
||||
|
||||
/* Then push the RSL header */
|
||||
rh = (struct abis_rsl_rll_hdr *) msgb_push(msg, sizeof(*rh));
|
||||
init_llm_hdr(rh, RSL_MT_DATA_REQ);
|
||||
rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
|
||||
rh->chan_nr = lchan2chan_nr(msg->lchan);
|
||||
rh->link_id = link_id;
|
||||
|
||||
msg->trx = msg->lchan->ts->trx;
|
||||
|
||||
@@ -704,10 +880,15 @@ int rsl_data_request(struct msgb *msg, u_int8_t link_id)
|
||||
/* Chapter 8.3.1 */
|
||||
int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id)
|
||||
{
|
||||
struct msgb *msg;
|
||||
struct msgb *msg = rsl_msgb_alloc();
|
||||
struct abis_rsl_rll_hdr *rh;
|
||||
|
||||
rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
|
||||
init_llm_hdr(rh, RSL_MT_EST_REQ);
|
||||
//rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
|
||||
rh->chan_nr = lchan2chan_nr(lchan);
|
||||
rh->link_id = link_id;
|
||||
|
||||
msg = rsl_rll_simple(RSL_MT_EST_REQ, lchan2chan_nr(lchan),
|
||||
link_id, 0);
|
||||
msg->trx = lchan->ts->trx;
|
||||
|
||||
return abis_rsl_sendmsg(msg);
|
||||
@@ -720,16 +901,16 @@ int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id)
|
||||
lchan_free() */
|
||||
int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id)
|
||||
{
|
||||
struct msgb *msg = rsl_msgb_alloc();
|
||||
struct abis_rsl_rll_hdr *rh;
|
||||
|
||||
struct msgb *msg;
|
||||
|
||||
msg = rsl_rll_simple(RSL_MT_REL_REQ, lchan2chan_nr(lchan),
|
||||
link_id, 0);
|
||||
rh = (struct abis_rsl_rll_hdr *) msgb_put(msg, sizeof(*rh));
|
||||
init_llm_hdr(rh, RSL_MT_REL_REQ);
|
||||
//rh->c.msg_discr |= ABIS_RSL_MDISC_TRANSP;
|
||||
rh->chan_nr = lchan2chan_nr(lchan);
|
||||
rh->link_id = link_id;
|
||||
msgb_tv_put(msg, RSL_IE_RELEASE_MODE, 0); /* normal release */
|
||||
|
||||
lchan->state = LCHAN_S_REL_REQ;
|
||||
/* FIXME: start some timer in case we don't receive a REL ACK ? */
|
||||
|
||||
msg->trx = lchan->ts->trx;
|
||||
|
||||
return abis_rsl_sendmsg(msg);
|
||||
@@ -745,10 +926,6 @@ static int rsl_rx_chan_act_ack(struct msgb *msg)
|
||||
if (rslh->ie_chan != RSL_IE_CHAN_NR)
|
||||
return -EINVAL;
|
||||
|
||||
if (msg->lchan->state != LCHAN_S_ACT_REQ)
|
||||
LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %s\n",
|
||||
gsm_lchan_name(msg->lchan),
|
||||
gsm_lchans_name(msg->lchan->state));
|
||||
msg->lchan->state = LCHAN_S_ACTIVE;
|
||||
|
||||
dispatch_signal(SS_LCHAN, S_LCHAN_ACTIVATE_ACK, msg->lchan);
|
||||
@@ -762,24 +939,16 @@ static int rsl_rx_chan_act_nack(struct msgb *msg)
|
||||
struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
|
||||
struct tlv_parsed tp;
|
||||
|
||||
LOGP(DRSL, LOGL_ERROR, "%s CHANNEL ACTIVATE NACK",
|
||||
gsm_lchan_name(msg->lchan));
|
||||
|
||||
/* BTS has rejected channel activation ?!? */
|
||||
if (dh->ie_chan != RSL_IE_CHAN_NR)
|
||||
return -EINVAL;
|
||||
|
||||
rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
|
||||
if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) {
|
||||
const u_int8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE);
|
||||
print_rsl_cause(LOGL_ERROR, cause,
|
||||
if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
|
||||
print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
|
||||
TLVP_LEN(&tp, RSL_IE_CAUSE));
|
||||
if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC)
|
||||
msg->lchan->state = LCHAN_S_NONE;
|
||||
} else
|
||||
msg->lchan->state = LCHAN_S_NONE;
|
||||
|
||||
LOGPC(DRSL, LOGL_ERROR, "\n");
|
||||
|
||||
msg->lchan->state = LCHAN_S_NONE;
|
||||
|
||||
dispatch_signal(SS_LCHAN, S_LCHAN_ACTIVATE_NACK, msg->lchan);
|
||||
|
||||
@@ -794,16 +963,14 @@ static int rsl_rx_conn_fail(struct msgb *msg)
|
||||
struct tlv_parsed tp;
|
||||
|
||||
/* FIXME: print which channel */
|
||||
LOGP(DRSL, LOGL_NOTICE, "%s CONNECTION FAIL: RELEASING ",
|
||||
gsm_lchan_name(msg->lchan));
|
||||
LOGP(DRSL, LOGL_NOTICE, "CONNECTION FAIL: RELEASING\n");
|
||||
|
||||
rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
|
||||
|
||||
if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
|
||||
print_rsl_cause(LOGL_NOTICE, TLVP_VAL(&tp, RSL_IE_CAUSE),
|
||||
print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
|
||||
TLVP_LEN(&tp, RSL_IE_CAUSE));
|
||||
|
||||
LOGPC(DRSL, LOGL_NOTICE, "\n");
|
||||
/* FIXME: only free it after channel release ACK */
|
||||
return rsl_rf_chan_release(msg->lchan);
|
||||
}
|
||||
@@ -853,8 +1020,8 @@ static void print_meas_rep(struct gsm_meas_rep *mr)
|
||||
return;
|
||||
for (i = 0; i < mr->num_cell; i++) {
|
||||
struct gsm_meas_rep_cell *mrc = &mr->cell[i];
|
||||
DEBUGP(DMEAS, "IDX=%u ARFCN=%u BSIC=%u => %d dBm\n",
|
||||
mrc->neigh_idx, mrc->arfcn, mrc->bsic, rxlev2dbm(mrc->rxlev));
|
||||
DEBUGP(DMEAS, "ARFCN=%u BSIC=%u => %d dBm\n", mrc->arfcn, mrc->bsic,
|
||||
rxlev2dbm(mrc->rxlev));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -869,11 +1036,8 @@ static int rsl_rx_meas_res(struct msgb *msg)
|
||||
|
||||
/* check if this channel is actually active */
|
||||
/* FIXME: maybe this check should be way more generic/centralized */
|
||||
if (msg->lchan->state != LCHAN_S_ACTIVE) {
|
||||
LOGP(DRSL, LOGL_NOTICE, "%s: MEAS RES for inactive channel\n",
|
||||
gsm_lchan_name(msg->lchan));
|
||||
if (msg->lchan->state != LCHAN_S_ACTIVE)
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(mr, 0, sizeof(*mr));
|
||||
mr->lchan = msg->lchan;
|
||||
@@ -934,7 +1098,7 @@ static int rsl_rx_hando_det(struct msgb *msg)
|
||||
struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
|
||||
struct tlv_parsed tp;
|
||||
|
||||
DEBUGP(DRSL, "%s HANDOVER DETECT ", gsm_lchan_name(msg->lchan));
|
||||
DEBUGP(DRSL, "HANDOVER DETECT ");
|
||||
|
||||
rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh));
|
||||
|
||||
@@ -956,14 +1120,18 @@ static int abis_rsl_rx_dchan(struct msgb *msg)
|
||||
char *ts_name;
|
||||
|
||||
msg->lchan = lchan_lookup(msg->trx, rslh->chan_nr);
|
||||
ts_name = gsm_lchan_name(msg->lchan);
|
||||
ts_name = gsm_ts_name(msg->lchan->ts);
|
||||
|
||||
if (rslh->c.msg_type != RSL_MT_MEAS_RES)
|
||||
DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ", ts_name, rslh->chan_nr);
|
||||
|
||||
switch (rslh->c.msg_type) {
|
||||
case RSL_MT_CHAN_ACTIV_ACK:
|
||||
DEBUGP(DRSL, "%s CHANNEL ACTIVATE ACK\n", ts_name);
|
||||
DEBUGPC(DRSL, "CHANNEL ACTIVATE ACK\n");
|
||||
rc = rsl_rx_chan_act_ack(msg);
|
||||
break;
|
||||
case RSL_MT_CHAN_ACTIV_NACK:
|
||||
DEBUGPC(DRSL, "CHANNEL ACTIVATE NACK\n");
|
||||
rc = rsl_rx_chan_act_nack(msg);
|
||||
break;
|
||||
case RSL_MT_CONN_FAIL:
|
||||
@@ -976,31 +1144,27 @@ static int abis_rsl_rx_dchan(struct msgb *msg)
|
||||
rc = rsl_rx_hando_det(msg);
|
||||
break;
|
||||
case RSL_MT_RF_CHAN_REL_ACK:
|
||||
DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", ts_name);
|
||||
if (msg->lchan->state != LCHAN_S_REL_REQ)
|
||||
LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
|
||||
gsm_lchan_name(msg->lchan),
|
||||
gsm_lchans_name(msg->lchan->state));
|
||||
DEBUGPC(DRSL, "RF CHANNEL RELEASE ACK\n");
|
||||
msg->lchan->state = LCHAN_S_NONE;
|
||||
lchan_free(msg->lchan);
|
||||
break;
|
||||
case RSL_MT_MODE_MODIFY_ACK:
|
||||
DEBUGP(DRSL, "%s CHANNEL MODE MODIFY ACK\n", ts_name);
|
||||
DEBUGPC(DRSL, "CHANNEL MODE MODIFY ACK\n");
|
||||
break;
|
||||
case RSL_MT_MODE_MODIFY_NACK:
|
||||
LOGP(DRSL, LOGL_ERROR, "%s CHANNEL MODE MODIFY NACK\n", ts_name);
|
||||
DEBUGPC(DRSL, "CHANNEL MODE MODIFY NACK\n");
|
||||
break;
|
||||
case RSL_MT_IPAC_PDCH_ACT_ACK:
|
||||
DEBUGPC(DRSL, "%s IPAC PDCH ACT ACK\n", ts_name);
|
||||
DEBUGPC(DRSL, "IPAC PDCH ACT ACK\n");
|
||||
break;
|
||||
case RSL_MT_IPAC_PDCH_ACT_NACK:
|
||||
LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH ACT NACK\n", ts_name);
|
||||
DEBUGPC(DRSL, "IPAC PDCH ACT NACK\n");
|
||||
break;
|
||||
case RSL_MT_IPAC_PDCH_DEACT_ACK:
|
||||
DEBUGP(DRSL, "%s IPAC PDCH DEACT ACK\n", ts_name);
|
||||
DEBUGPC(DRSL, "IPAC PDCH DEACT ACK\n");
|
||||
break;
|
||||
case RSL_MT_IPAC_PDCH_DEACT_NACK:
|
||||
LOGP(DRSL, LOGL_ERROR, "%s IPAC PDCH DEACT NACK\n", ts_name);
|
||||
DEBUGPC(DRSL, "IPAC PDCH DEACT NACK\n");
|
||||
break;
|
||||
case RSL_MT_PHY_CONTEXT_CONF:
|
||||
case RSL_MT_PREPROC_MEAS_RES:
|
||||
@@ -1010,12 +1174,12 @@ static int abis_rsl_rx_dchan(struct msgb *msg)
|
||||
case RSL_MT_MR_CODEC_MOD_ACK:
|
||||
case RSL_MT_MR_CODEC_MOD_NACK:
|
||||
case RSL_MT_MR_CODEC_MOD_PER:
|
||||
LOGP(DRSL, LOGL_NOTICE, "%s Unimplemented Abis RSL DChan "
|
||||
"msg 0x%02x\n", ts_name, rslh->c.msg_type);
|
||||
DEBUGPC(DRSL, "Unimplemented Abis RSL DChan msg 0x%02x\n",
|
||||
rslh->c.msg_type);
|
||||
break;
|
||||
default:
|
||||
LOGP(DRSL, LOGL_NOTICE, "%s unknown Abis RSL DChan msg 0x%02x\n",
|
||||
ts_name, rslh->c.msg_type);
|
||||
DEBUGPC(DRSL, "unknown Abis RSL DChan msg 0x%02x\n",
|
||||
rslh->c.msg_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -1027,12 +1191,12 @@ static int rsl_rx_error_rep(struct msgb *msg)
|
||||
struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
|
||||
struct tlv_parsed tp;
|
||||
|
||||
LOGP(DRSL, LOGL_ERROR, "%s ERROR REPORT ", gsm_trx_name(msg->trx));
|
||||
LOGP(DRSL, LOGL_ERROR, "ERROR REPORT ");
|
||||
|
||||
rsl_tlv_parse(&tp, rslh->data, msgb_l2len(msg)-sizeof(*rslh));
|
||||
|
||||
if (TLVP_PRESENT(&tp, RSL_IE_CAUSE))
|
||||
print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE),
|
||||
print_rsl_cause(TLVP_VAL(&tp, RSL_IE_CAUSE),
|
||||
TLVP_LEN(&tp, RSL_IE_CAUSE));
|
||||
|
||||
LOGPC(DRSL, LOGL_ERROR, "\n");
|
||||
@@ -1051,16 +1215,15 @@ static int abis_rsl_rx_trx(struct msgb *msg)
|
||||
break;
|
||||
case RSL_MT_RF_RES_IND:
|
||||
/* interference on idle channels of TRX */
|
||||
//DEBUGP(DRSL, "%s RF Resource Indication\n", gsm_trx_name(msg->trx));
|
||||
//DEBUGP(DRSL, "TRX: RF Interference Indication\n");
|
||||
break;
|
||||
case RSL_MT_OVERLOAD:
|
||||
/* indicate CCCH / ACCH / processor overload */
|
||||
LOGP(DRSL, LOGL_ERROR, "%s CCCH/ACCH/CPU Overload\n",
|
||||
gsm_trx_name(msg->trx));
|
||||
LOGP(DRSL, LOGL_ERROR, "TRX: CCCH/ACCH/CPU Overload\n");
|
||||
break;
|
||||
default:
|
||||
LOGP(DRSL, LOGL_NOTICE, "%s Unknown Abis RSL TRX message "
|
||||
"type 0x%02x\n", gsm_trx_name(msg->trx), rslh->msg_type);
|
||||
DEBUGP(DRSL, "Unknown Abis RSL TRX message type 0x%02x\n",
|
||||
rslh->msg_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
return rc;
|
||||
@@ -1106,24 +1269,18 @@ static int rsl_rx_chan_rqd(struct msgb *msg)
|
||||
lctype = get_ctype_by_chreq(bts, rqd_ref->ra, bts->network->neci);
|
||||
chreq_reason = get_reason_by_chreq(bts, rqd_ref->ra, bts->network->neci);
|
||||
|
||||
counter_inc(bts->network->stats.chreq.total);
|
||||
bts->network->stats.chreq.total++;
|
||||
|
||||
/* check availability / allocate channel */
|
||||
lchan = lchan_alloc(bts, lctype);
|
||||
if (!lchan) {
|
||||
LOGP(DRSL, LOGL_NOTICE, "BTS %d CHAN RQD: no resources for %s 0x%x\n",
|
||||
msg->lchan->ts->trx->bts->nr, gsm_lchant_name(lctype), rqd_ref->ra);
|
||||
counter_inc(bts->network->stats.chreq.no_channel);
|
||||
DEBUGP(DRSL, "CHAN RQD: no resources for %s 0x%x\n",
|
||||
gsm_lchan_name(lctype), rqd_ref->ra);
|
||||
bts->network->stats.chreq.no_channel++;
|
||||
/* FIXME: send some kind of reject ?!? */
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (lchan->state != LCHAN_S_NONE)
|
||||
LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel "
|
||||
"in state %s\n", gsm_lchan_name(lchan),
|
||||
gsm_lchans_name(lchan->state));
|
||||
lchan->state = LCHAN_S_ACT_REQ;
|
||||
|
||||
ts_number = lchan->ts->nr;
|
||||
arfcn = lchan->ts->trx->arfcn;
|
||||
subch = lchan->nr;
|
||||
@@ -1151,9 +1308,10 @@ static int rsl_rx_chan_rqd(struct msgb *msg)
|
||||
ia.timing_advance = rqd_ta;
|
||||
ia.mob_alloc_len = 0;
|
||||
|
||||
DEBUGP(DRSL, "%s Activating ARFCN(%u) SS(%u) lctype %s "
|
||||
"r=%s ra=0x%02x\n", gsm_lchan_name(lchan), arfcn, subch,
|
||||
gsm_lchant_name(lchan->type), gsm_chreq_name(chreq_reason),
|
||||
DEBUGP(DRSL, "Activating ARFCN(%u) TS(%u) SS(%u) lctype %s "
|
||||
"chan_nr=0x%02x r=%s ra=0x%02x\n",
|
||||
arfcn, ts_number, subch, gsm_lchan_name(lchan->type),
|
||||
ia.chan_desc.chan_nr, gsm_chreq_name(chreq_reason),
|
||||
rqd_ref->ra);
|
||||
|
||||
/* Start timer T3101 to wait for GSM48_MT_RR_PAG_RESP */
|
||||
@@ -1232,12 +1390,10 @@ static int rsl_rx_rll_err_ind(struct msgb *msg)
|
||||
struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
|
||||
u_int8_t *rlm_cause = rllh->data;
|
||||
|
||||
LOGP(DRLL, LOGL_ERROR, "%s ERROR INDICATION cause=%s\n",
|
||||
gsm_lchan_name(msg->lchan),
|
||||
get_value_string(rsl_rlm_cause_strs, rlm_cause[1]));
|
||||
LOGP(DRLL, LOGL_ERROR, "ERROR INDICATION cause=0x%02x\n", rlm_cause[1]);
|
||||
|
||||
rll_indication(msg->lchan, rllh->link_id, BSC_RLLR_IND_ERR_IND);
|
||||
|
||||
|
||||
if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED)
|
||||
return rsl_rf_chan_release(msg->lchan);
|
||||
|
||||
@@ -1258,8 +1414,9 @@ static int abis_rsl_rx_rll(struct msgb *msg)
|
||||
u_int8_t sapi = rllh->link_id & 7;
|
||||
|
||||
msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
|
||||
ts_name = gsm_lchan_name(msg->lchan);
|
||||
DEBUGP(DRLL, "%s SAPI=%u ", ts_name, sapi);
|
||||
ts_name = gsm_ts_name(msg->lchan->ts);
|
||||
DEBUGP(DRLL, "channel=%s chan_nr=0x%02x sapi=%u ", ts_name,
|
||||
rllh->chan_nr, sapi);
|
||||
|
||||
switch (rllh->c.msg_type) {
|
||||
case RSL_MT_DATA_IND:
|
||||
@@ -1328,31 +1485,11 @@ static u_int8_t ipa_smod_s_for_lchan(struct gsm_lchan *lchan)
|
||||
{
|
||||
switch (lchan->tch_mode) {
|
||||
case GSM48_CMODE_SPEECH_V1:
|
||||
switch (lchan->type) {
|
||||
case GSM_LCHAN_TCH_F:
|
||||
return 0x00;
|
||||
case GSM_LCHAN_TCH_H:
|
||||
return 0x03;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0x00;
|
||||
case GSM48_CMODE_SPEECH_EFR:
|
||||
switch (lchan->type) {
|
||||
case GSM_LCHAN_TCH_F:
|
||||
return 0x01;
|
||||
/* there's no half-rate EFR */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0x01;
|
||||
case GSM48_CMODE_SPEECH_AMR:
|
||||
switch (lchan->type) {
|
||||
case GSM_LCHAN_TCH_F:
|
||||
return 0x02;
|
||||
case GSM_LCHAN_TCH_H:
|
||||
return 0x05;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0x02;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1429,8 +1566,9 @@ int rsl_ipacc_crcx(struct gsm_lchan *lchan)
|
||||
lchan->abis_ip.speech_mode = 0x10 | ipa_smod_s_for_lchan(lchan);
|
||||
msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
|
||||
|
||||
DEBUGP(DRSL, "%s IPAC_BIND speech_mode=0x%02x\n",
|
||||
gsm_lchan_name(lchan), lchan->abis_ip.speech_mode);
|
||||
DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_BIND "
|
||||
"speech_mode=0x%02x\n", gsm_ts_name(lchan->ts),
|
||||
dh->chan_nr, lchan->abis_ip.speech_mode);
|
||||
|
||||
msg->trx = lchan->ts->trx;
|
||||
|
||||
@@ -1459,8 +1597,9 @@ int rsl_ipacc_mdcx(struct gsm_lchan *lchan, u_int32_t ip, u_int16_t port,
|
||||
lchan->abis_ip.speech_mode = 0x00 | ipa_smod_s_for_lchan(lchan);
|
||||
|
||||
ia.s_addr = htonl(ip);
|
||||
DEBUGP(DRSL, "%s IPAC_MDCX IP=%s PORT=%d RTP_PAYLOAD2=%d CONN_ID=%d "
|
||||
"speech_mode=0x%02x\n", gsm_lchan_name(lchan), inet_ntoa(ia), port,
|
||||
DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_MDCX "
|
||||
"IP=%s PORT=%d RTP_PAYLOAD2=%d CONN_ID=%d speech_mode=0x%02x\n",
|
||||
gsm_ts_name(lchan->ts), dh->chan_nr, inet_ntoa(ia), port,
|
||||
rtp_payload2, lchan->abis_ip.conn_id, lchan->abis_ip.speech_mode);
|
||||
|
||||
msgb_tv16_put(msg, RSL_IE_IPAC_CONN_ID, lchan->abis_ip.conn_id);
|
||||
@@ -1501,7 +1640,8 @@ int rsl_ipacc_pdch_activate(struct gsm_lchan *lchan)
|
||||
dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
|
||||
dh->chan_nr = lchan2chan_nr(lchan);
|
||||
|
||||
DEBUGP(DRSL, "%s IPAC_PDCH_ACT\n", gsm_lchan_name(lchan));
|
||||
DEBUGP(DRSL, "channel=%s chan_nr=0x%02x IPAC_PDCH_ACT\n",
|
||||
gsm_ts_name(lchan->ts), dh->chan_nr);
|
||||
|
||||
msg->trx = lchan->ts->trx;
|
||||
|
||||
@@ -1582,7 +1722,7 @@ static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
|
||||
rsl_tlv_parse(&tv, dh->data, msgb_l2len(msg)-sizeof(*dh));
|
||||
|
||||
if (TLVP_PRESENT(&tv, RSL_IE_CAUSE))
|
||||
print_rsl_cause(LOGL_DEBUG, TLVP_VAL(&tv, RSL_IE_CAUSE),
|
||||
print_rsl_cause(TLVP_VAL(&tv, RSL_IE_CAUSE),
|
||||
TLVP_LEN(&tv, RSL_IE_CAUSE));
|
||||
|
||||
/* the BTS tells us a RTP stream has been disconnected */
|
||||
@@ -1599,38 +1739,38 @@ static int abis_rsl_rx_ipacc_dlcx_ind(struct msgb *msg)
|
||||
static int abis_rsl_rx_ipacc(struct msgb *msg)
|
||||
{
|
||||
struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
|
||||
char *ts_name;
|
||||
int rc = 0;
|
||||
|
||||
msg->lchan = lchan_lookup(msg->trx, rllh->chan_nr);
|
||||
ts_name = gsm_lchan_name(msg->lchan);
|
||||
DEBUGP(DRSL, "channel=%s chan_nr=0x%02x ",
|
||||
gsm_ts_name(msg->lchan->ts), rllh->chan_nr);
|
||||
|
||||
switch (rllh->c.msg_type) {
|
||||
case RSL_MT_IPAC_CRCX_ACK:
|
||||
DEBUGP(DRSL, "%s IPAC_CRCX_ACK ", ts_name);
|
||||
DEBUGPC(DRSL, "IPAC_CRCX_ACK ");
|
||||
rc = abis_rsl_rx_ipacc_crcx_ack(msg);
|
||||
break;
|
||||
case RSL_MT_IPAC_CRCX_NACK:
|
||||
/* somehow the BTS was unable to bind the lchan to its local
|
||||
* port?!? */
|
||||
LOGP(DRSL, LOGL_ERROR, "%s IPAC_CRCX_NACK\n", ts_name);
|
||||
DEBUGPC(DRSL, "IPAC_CRCX_NACK ");
|
||||
break;
|
||||
case RSL_MT_IPAC_MDCX_ACK:
|
||||
/* the BTS tells us that a connect operation was successful */
|
||||
DEBUGP(DRSL, "%s IPAC_MDCX_ACK ", ts_name);
|
||||
DEBUGPC(DRSL, "IPAC_MDCX_ACK ");
|
||||
rc = abis_rsl_rx_ipacc_mdcx_ack(msg);
|
||||
break;
|
||||
case RSL_MT_IPAC_MDCX_NACK:
|
||||
/* somehow the BTS was unable to connect the lchan to a remote
|
||||
* port */
|
||||
LOGP(DRSL, LOGL_ERROR, "%s IPAC_MDCX_NACK\n", ts_name);
|
||||
DEBUGPC(DRSL, "IPAC_MDCX_NACK ");
|
||||
break;
|
||||
case RSL_MT_IPAC_DLCX_IND:
|
||||
DEBUGP(DRSL, "%s IPAC_DLCX_IND ", ts_name);
|
||||
DEBUGPC(DRSL, "IPAC_DLCX_IND ");
|
||||
rc = abis_rsl_rx_ipacc_dlcx_ind(msg);
|
||||
break;
|
||||
default:
|
||||
LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x\n",
|
||||
LOGP(DRSL, LOGL_NOTICE, "Unknown ip.access msg_type 0x%02x",
|
||||
rllh->c.msg_type);
|
||||
break;
|
||||
}
|
||||
@@ -1643,9 +1783,21 @@ static int abis_rsl_rx_ipacc(struct msgb *msg)
|
||||
/* Entry-point where L2 RSL from BTS enters */
|
||||
int abis_rsl_rcvmsg(struct msgb *msg)
|
||||
{
|
||||
struct abis_rsl_common_hdr *rslh = msgb_l2(msg) ;
|
||||
struct abis_rsl_common_hdr *rslh;
|
||||
int rc = 0;
|
||||
|
||||
if (!msg) {
|
||||
DEBUGP(DRSL, "Empty RSL msg?..\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (msgb_l2len(msg) < sizeof(*rslh)) {
|
||||
DEBUGP(DRSL, "Truncated RSL message with l2len: %u\n", msgb_l2len(msg));
|
||||
return -1;
|
||||
}
|
||||
|
||||
rslh = msgb_l2(msg);
|
||||
|
||||
switch (rslh->msg_discr & 0xfe) {
|
||||
case ABIS_RSL_MDISC_RLL:
|
||||
rc = abis_rsl_rx_rll(msg);
|
||||
@@ -1675,6 +1827,45 @@ int abis_rsl_rcvmsg(struct msgb *msg)
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* Section 3.3.2.3 TS 05.02. I think this looks like a table */
|
||||
int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf)
|
||||
{
|
||||
switch (ccch_conf) {
|
||||
case RSL_BCCH_CCCH_CONF_1_NC:
|
||||
return 1;
|
||||
case RSL_BCCH_CCCH_CONF_1_C:
|
||||
return 1;
|
||||
case RSL_BCCH_CCCH_CONF_2_NC:
|
||||
return 2;
|
||||
case RSL_BCCH_CCCH_CONF_3_NC:
|
||||
return 3;
|
||||
case RSL_BCCH_CCCH_CONF_4_NC:
|
||||
return 4;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Section 3.3.2.3 TS 05.02 */
|
||||
int rsl_ccch_conf_to_bs_ccch_sdcch_comb(int ccch_conf)
|
||||
{
|
||||
switch (ccch_conf) {
|
||||
case RSL_BCCH_CCCH_CONF_1_NC:
|
||||
return 0;
|
||||
case RSL_BCCH_CCCH_CONF_1_C:
|
||||
return 1;
|
||||
case RSL_BCCH_CCCH_CONF_2_NC:
|
||||
return 0;
|
||||
case RSL_BCCH_CCCH_CONF_3_NC:
|
||||
return 0;
|
||||
case RSL_BCCH_CCCH_CONF_4_NC:
|
||||
return 0;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* From Table 10.5.33 of GSM 04.08 */
|
||||
int rsl_number_of_paging_subchannels(struct gsm_bts *bts)
|
||||
{
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <osmocore/bitvec.h>
|
||||
#include <openbsc/bitvec.h>
|
||||
|
||||
#define BITNUM_FROM_COMP(byte, bit) ((byte*8)+bit)
|
||||
|
||||
@@ -36,7 +36,7 @@ static inline unsigned int bytenum_from_bitnum(unsigned int bitnum)
|
||||
}
|
||||
|
||||
/* convert ZERO/ONE/L/H to a bitmask at given pos in a byte */
|
||||
static uint8_t bitval2mask(enum bit_value bit, uint8_t bitnum)
|
||||
static u_int8_t bitval2mask(enum bit_value bit, u_int8_t bitnum)
|
||||
{
|
||||
int bitval;
|
||||
|
||||
@@ -60,11 +60,11 @@ static uint8_t bitval2mask(enum bit_value bit, uint8_t bitnum)
|
||||
}
|
||||
|
||||
/* check if the bit is 0 or 1 for a given position inside a bitvec */
|
||||
enum bit_value bitvec_get_bit_pos(const struct bitvec *bv, unsigned int bitnr)
|
||||
enum bit_value bitvec_get_bit_pos(struct bitvec *bv, unsigned int bitnr)
|
||||
{
|
||||
unsigned int bytenum = bytenum_from_bitnum(bitnr);
|
||||
unsigned int bitnum = 7 - (bitnr % 8);
|
||||
uint8_t bitval;
|
||||
u_int8_t bitval;
|
||||
|
||||
if (bytenum >= bv->data_len)
|
||||
return -EINVAL;
|
||||
@@ -78,7 +78,7 @@ enum bit_value bitvec_get_bit_pos(const struct bitvec *bv, unsigned int bitnr)
|
||||
}
|
||||
|
||||
/* get the Nth set bit inside the bit vector */
|
||||
unsigned int bitvec_get_nth_set_bit(const struct bitvec *bv, unsigned int n)
|
||||
unsigned int bitvec_get_nth_set_bit(struct bitvec *bv, unsigned int n)
|
||||
{
|
||||
unsigned int i, k = 0;
|
||||
|
||||
@@ -99,7 +99,7 @@ int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnr,
|
||||
{
|
||||
unsigned int bytenum = bytenum_from_bitnum(bitnr);
|
||||
unsigned int bitnum = 7 - (bitnr % 8);
|
||||
uint8_t bitval;
|
||||
u_int8_t bitval;
|
||||
|
||||
if (bytenum >= bv->data_len)
|
||||
return -EINVAL;
|
||||
@@ -36,10 +36,10 @@
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/abis_nm.h>
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/tlv.h>
|
||||
#include <openbsc/msgb.h>
|
||||
#include <openbsc/tlv.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <osmocore/select.h>
|
||||
#include <openbsc/select.h>
|
||||
#include <openbsc/rs232.h>
|
||||
|
||||
/* state of our bs11_config application */
|
||||
@@ -51,7 +51,7 @@ enum bs11cfg_state {
|
||||
STATE_QUERY,
|
||||
};
|
||||
static enum bs11cfg_state bs11cfg_state = STATE_NONE;
|
||||
static char *command, *value;
|
||||
static char *command;
|
||||
struct timer_list status_timer;
|
||||
|
||||
static const u_int8_t obj_li_attr[] = {
|
||||
@@ -71,13 +71,6 @@ static const char *trx1_password = "1111111111";
|
||||
|
||||
static const u_int8_t too_fast[] = { 0x12, 0x80, 0x00, 0x00, 0x02, 0x02 };
|
||||
|
||||
static struct debug_target *stderr_target;
|
||||
|
||||
/* dummy function to keep gsm_data.c happy */
|
||||
struct counter *counter_alloc(const char *name)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int handle_serial_msg(struct msgb *rx_msg);
|
||||
|
||||
@@ -540,21 +533,6 @@ static int handle_state_resp(enum abis_bs11_phase state)
|
||||
sleep(1);
|
||||
abis_nm_bs11_factory_logon(g_bts, 0);
|
||||
command = NULL;
|
||||
} else if (!strcmp(command, "pll-setvalue")) {
|
||||
abis_nm_bs11_set_pll(g_bts, atoi(value));
|
||||
sleep(1);
|
||||
abis_nm_bs11_factory_logon(g_bts, 0);
|
||||
command = NULL;
|
||||
} else if (!strcmp(command, "pll-workvalue")) {
|
||||
/* To set the work value we need to login as FIELD */
|
||||
abis_nm_bs11_factory_logon(g_bts, 0);
|
||||
sleep(1);
|
||||
abis_nm_bs11_infield_logon(g_bts, 1);
|
||||
sleep(1);
|
||||
abis_nm_bs11_set_pll(g_bts, atoi(value));
|
||||
sleep(1);
|
||||
abis_nm_bs11_infield_logon(g_bts, 0);
|
||||
command = NULL;
|
||||
} else if (!strcmp(command, "oml-tei")) {
|
||||
abis_nm_bs11_conn_oml_tei(g_bts, 0, 1, 0xff, TEI_OML);
|
||||
command = NULL;
|
||||
@@ -649,7 +627,7 @@ int handle_serial_msg(struct msgb *rx_msg)
|
||||
exit(0);
|
||||
break;
|
||||
case NM_MT_BS11_GET_STATE_ACK:
|
||||
rc = abis_nm_tlv_parse(&tp, g_bts, foh->data, oh->length-sizeof(*foh));
|
||||
rc = abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
|
||||
print_state(&tp);
|
||||
if (TLVP_PRESENT(&tp, NM_ATT_BS11_BTS_STATE) &&
|
||||
TLVP_LEN(&tp, NM_ATT_BS11_BTS_STATE) >= 1)
|
||||
@@ -657,7 +635,7 @@ int handle_serial_msg(struct msgb *rx_msg)
|
||||
break;
|
||||
case NM_MT_GET_ATTR_RESP:
|
||||
printf("\n%sATTRIBUTES:\n", obj_name(foh));
|
||||
abis_nm_tlv_parse(&tp, g_bts, foh->data, oh->length-sizeof(*foh));
|
||||
abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
|
||||
rc = print_attr(&tp);
|
||||
//hexdump(foh->data, oh->length-sizeof(*foh));
|
||||
break;
|
||||
@@ -721,27 +699,25 @@ static void print_help(void)
|
||||
printf("\t-p --port </dev/ttyXXX>\t\tSpecify serial port\n");
|
||||
printf("\t-s --software <file>\t\tSpecify Software file\n");
|
||||
printf("\t-S --safety <file>\t\tSpecify Safety Load file\n");
|
||||
printf("\t-d --delay <ms>\t\t\tSpecify delay in milliseconds\n");
|
||||
printf("\t-d --delay <ms>\t\tSpecify delay in milliseconds\n");
|
||||
printf("\t-D --disconnect\t\t\tDisconnect BTS from BSC\n");
|
||||
printf("\t-w --win-size <num>\t\tSpecify Window Size\n");
|
||||
printf("\t-f --forced\t\t\tForce Software Load\n");
|
||||
printf("\nSupported commands:\n");
|
||||
printf("\tquery\t\t\tQuery the BS-11 about serial number and configuration\n");
|
||||
printf("\tdisconnect\t\tDisconnect A-bis link (go into administrative state)\n");
|
||||
printf("\tresconnect\t\tReconnect A-bis link (go into normal state)\n");
|
||||
printf("\trestart\t\t\tRestart the BTS\n");
|
||||
printf("\tsoftware\t\tDownload Software (only in administrative state)\n");
|
||||
printf("\tcreate-trx1\t\tCreate objects for TRX1 (Danger: Your BS-11 might overheat)\n");
|
||||
printf("\tdelete-trx1\t\tDelete objects for TRX1\n");
|
||||
printf("\tpll-e1-locked\t\tSet the PLL to be locked to E1 clock\n");
|
||||
printf("\tpll-standalone\t\tSet the PLL to be in standalone mode\n");
|
||||
printf("\tpll-setvalue <value>\tSet the PLL set value\n");
|
||||
printf("\tpll-workvalue <value>\tSet the PLL work value\n");
|
||||
printf("\toml-tei\t\t\tSet OML E1 TS and TEI\n");
|
||||
printf("\tbport0-star\t\tSet BPORT0 line config to star\n");
|
||||
printf("\tquery\t\tQuery the BS-11 about serial number and configuration\n");
|
||||
printf("\tdisconnect\tDisconnect A-bis link (go into administrative state)\n");
|
||||
printf("\tresconnect\tReconnect A-bis link (go into normal state)\n");
|
||||
printf("\trestart\t\tRestart the BTS\n");
|
||||
printf("\tsoftware\tDownload Software (only in administrative state)\n");
|
||||
printf("\tcreate-trx1\tCreate objects for TRX1 (Danger: Your BS-11 might overheat)\n");
|
||||
printf("\tdelete-trx1\tDelete objects for TRX1\n");
|
||||
printf("\tpll-e1-locked\tSet the PLL to be locked to E1 clock\n");
|
||||
printf("\tpll-standalone\tSet the PLL to be in standalone mode\n");
|
||||
printf("\toml-tei\tSet OML E1 TS and TEI\n");
|
||||
printf("\tbport0-star\tSet BPORT0 line config to star\n");
|
||||
printf("\tbport0-multiport\tSet BPORT0 line config to multiport\n");
|
||||
printf("\tcreate-bport1\t\tCreate BPORT1 object\n");
|
||||
printf("\tdelete-bport1\t\tDelete BPORT1 object\n");
|
||||
printf("\tcreate-bport1\tCreate BPORT1 object\n");
|
||||
printf("\tdelete-bport1\tDelete BPORT1 object\n");
|
||||
}
|
||||
|
||||
static void handle_options(int argc, char **argv)
|
||||
@@ -778,7 +754,7 @@ static void handle_options(int argc, char **argv)
|
||||
serial_port = optarg;
|
||||
break;
|
||||
case 'b':
|
||||
debug_parse_category_mask(stderr_target, optarg);
|
||||
debug_parse_category_mask(optarg);
|
||||
break;
|
||||
case 's':
|
||||
fname_software = optarg;
|
||||
@@ -808,9 +784,6 @@ static void handle_options(int argc, char **argv)
|
||||
}
|
||||
if (optind < argc)
|
||||
command = argv[optind];
|
||||
if (optind+1 < argc)
|
||||
value = argv[optind+1];
|
||||
|
||||
}
|
||||
|
||||
static int num_sigint;
|
||||
@@ -834,12 +807,7 @@ int main(int argc, char **argv)
|
||||
struct gsm_network *gsmnet;
|
||||
int rc;
|
||||
|
||||
debug_init();
|
||||
stderr_target = debug_target_create_stderr();
|
||||
debug_add_target(stderr_target);
|
||||
debug_set_all_filter(stderr_target, 1);
|
||||
handle_options(argc, argv);
|
||||
bts_model_bs11_init();
|
||||
|
||||
gsmnet = gsm_network_init(1, 1, NULL);
|
||||
if (!gsmnet) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* A hackish minimal BSC (+MSC +HLR) implementation */
|
||||
|
||||
/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
|
||||
/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
@@ -31,23 +31,17 @@
|
||||
#include <getopt.h>
|
||||
|
||||
#include <openbsc/db.h>
|
||||
#include <osmocore/select.h>
|
||||
#include <openbsc/select.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/e1_input.h>
|
||||
#include <osmocore/talloc.h>
|
||||
#include <openbsc/talloc.h>
|
||||
#include <openbsc/signal.h>
|
||||
|
||||
/* MCC and MNC for the Location Area Identifier */
|
||||
static struct debug_target *stderr_target;
|
||||
struct gsm_network *bsc_gsmnet = 0;
|
||||
static const char *database_name = "hlr.sqlite3";
|
||||
static const char *config_file = "openbsc.cfg";
|
||||
|
||||
|
||||
/* timer to store statistics */
|
||||
#define DB_SYNC_INTERVAL 60, 0
|
||||
static struct timer_list db_sync_timer;
|
||||
|
||||
extern int bsc_bootstrap_network(int (*mmc_rev)(struct gsm_network *, int, void *),
|
||||
const char *cfg_file);
|
||||
extern int bsc_shutdown_net(struct gsm_network *net);
|
||||
@@ -111,10 +105,10 @@ static void handle_options(int argc, char** argv)
|
||||
print_help();
|
||||
exit(0);
|
||||
case 's':
|
||||
debug_set_use_color(stderr_target, 0);
|
||||
debug_use_color(0);
|
||||
break;
|
||||
case 'd':
|
||||
debug_parse_category_mask(stderr_target, optarg);
|
||||
debug_parse_category_mask(optarg);
|
||||
break;
|
||||
case 'l':
|
||||
database_name = strdup(optarg);
|
||||
@@ -126,7 +120,7 @@ static void handle_options(int argc, char** argv)
|
||||
create_pcap_file(optarg);
|
||||
break;
|
||||
case 'T':
|
||||
debug_set_print_timestamp(stderr_target, 1);
|
||||
debug_timestamp(1);
|
||||
break;
|
||||
case 'P':
|
||||
ipacc_rtp_direct = 0;
|
||||
@@ -138,7 +132,6 @@ static void handle_options(int argc, char** argv)
|
||||
}
|
||||
}
|
||||
|
||||
extern void *tall_vty_ctx;
|
||||
static void signal_handler(int signal)
|
||||
{
|
||||
fprintf(stdout, "signal %u received\n", signal);
|
||||
@@ -154,53 +147,22 @@ static void signal_handler(int signal)
|
||||
/* in case of abort, we want to obtain a talloc report
|
||||
* and then return to the caller, who will abort the process */
|
||||
case SIGUSR1:
|
||||
talloc_report(tall_vty_ctx, stderr);
|
||||
talloc_report_full(tall_bsc_ctx, stderr);
|
||||
break;
|
||||
case SIGUSR2:
|
||||
talloc_report_full(tall_vty_ctx, stderr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* timer handling */
|
||||
static int _db_store_counter(struct counter *counter, void *data)
|
||||
{
|
||||
return db_store_counter(counter);
|
||||
}
|
||||
|
||||
static void db_sync_timer_cb(void *data)
|
||||
{
|
||||
/* store counters to database and re-schedule */
|
||||
counters_for_each(_db_store_counter, NULL);
|
||||
bsc_schedule_timer(&db_sync_timer, DB_SYNC_INTERVAL);
|
||||
}
|
||||
|
||||
extern int bts_model_unknown_init(void);
|
||||
extern int bts_model_bs11_init(void);
|
||||
extern int bts_model_nanobts_init(void);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int rc;
|
||||
|
||||
debug_init();
|
||||
tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
|
||||
talloc_ctx_init();
|
||||
on_dso_load_token();
|
||||
on_dso_load_rrlp();
|
||||
on_dso_load_ho_dec();
|
||||
stderr_target = debug_target_create_stderr();
|
||||
debug_add_target(stderr_target);
|
||||
|
||||
bts_model_unknown_init();
|
||||
bts_model_bs11_init();
|
||||
bts_model_nanobts_init();
|
||||
|
||||
/* enable filters */
|
||||
debug_set_all_filter(stderr_target, 1);
|
||||
|
||||
/* parse options */
|
||||
handle_options(argc, argv);
|
||||
@@ -220,11 +182,6 @@ int main(int argc, char **argv)
|
||||
}
|
||||
printf("DB: Database prepared.\n");
|
||||
|
||||
/* setup the timer */
|
||||
db_sync_timer.cb = db_sync_timer_cb;
|
||||
db_sync_timer.data = NULL;
|
||||
bsc_schedule_timer(&db_sync_timer, DB_SYNC_INTERVAL);
|
||||
|
||||
rc = bsc_bootstrap_network(mncc_recv, config_file);
|
||||
if (rc < 0)
|
||||
exit(1);
|
||||
@@ -232,12 +189,10 @@ int main(int argc, char **argv)
|
||||
signal(SIGINT, &signal_handler);
|
||||
signal(SIGABRT, &signal_handler);
|
||||
signal(SIGUSR1, &signal_handler);
|
||||
signal(SIGUSR2, &signal_handler);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
while (1) {
|
||||
bsc_upqueue(bsc_gsmnet);
|
||||
debug_reset_context();
|
||||
bsc_select_main(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <osmocore/gsm_utils.h>
|
||||
#include <openbsc/gsm_utils.h>
|
||||
#include <openbsc/gsm_04_08.h>
|
||||
#include <openbsc/abis_rsl.h>
|
||||
#include <openbsc/abis_nm.h>
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <openbsc/system_information.h>
|
||||
#include <openbsc/paging.h>
|
||||
#include <openbsc/signal.h>
|
||||
#include <osmocore/talloc.h>
|
||||
#include <openbsc/talloc.h>
|
||||
|
||||
/* global pointer to the gsm network data structure */
|
||||
extern struct gsm_network *bsc_gsmnet;
|
||||
@@ -330,7 +330,6 @@ static unsigned char nanobts_attr_bts[] = {
|
||||
NM_ATT_NY1, 10, /* 10 retransmissions of physical config */
|
||||
NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
|
||||
NM_ATT_BSIC, HARDCODED_BSIC,
|
||||
NM_ATT_IPACC_CGI, 0, 7, 0x00, 0xf1, 0x10, 0x00, 0x01, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static unsigned char nanobts_attr_radio[] = {
|
||||
@@ -338,66 +337,6 @@ static unsigned char nanobts_attr_radio[] = {
|
||||
NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
|
||||
};
|
||||
|
||||
static unsigned char nanobts_attr_nse[] = {
|
||||
NM_ATT_IPACC_NSEI, 0, 2, 0x03, 0x9d, /* NSEI 925 */
|
||||
NM_ATT_IPACC_NS_CFG, 0, 7, 3, /* (un)blocking timer (Tns-block) */
|
||||
3, /* (un)blocking retries */
|
||||
3, /* reset timer (Tns-reset) */
|
||||
3, /* reset retries */
|
||||
30, /* test timer (Tns-test) */
|
||||
3, /* alive timer (Tns-alive) */
|
||||
10, /* alive retrires */
|
||||
NM_ATT_IPACC_BSSGP_CFG, 0, 11,
|
||||
3, /* blockimg timer (T1) */
|
||||
3, /* blocking retries */
|
||||
3, /* unblocking retries */
|
||||
3, /* reset timer */
|
||||
3, /* reset retries */
|
||||
10, /* suspend timer (T3) in 100ms */
|
||||
3, /* suspend retries */
|
||||
10, /* resume timer (T4) in 100ms */
|
||||
3, /* resume retries */
|
||||
10, /* capability update timer (T5) */
|
||||
3, /* capability update retries */
|
||||
};
|
||||
|
||||
static unsigned char nanobts_attr_cell[] = {
|
||||
NM_ATT_IPACC_RAC, 0, 1, 1, /* routing area code */
|
||||
NM_ATT_IPACC_GPRS_PAGING_CFG, 0, 2,
|
||||
5, /* repeat time (50ms) */
|
||||
3, /* repeat count */
|
||||
NM_ATT_IPACC_BVCI, 0, 2, 0x03, 0x9d, /* BVCI 925 */
|
||||
NM_ATT_IPACC_RLC_CFG, 0, 9,
|
||||
20, /* T3142 */
|
||||
5, /* T3169 */
|
||||
5, /* T3191 */
|
||||
200, /* T3193 */
|
||||
5, /* T3195 */
|
||||
10, /* N3101 */
|
||||
4, /* N3103 */
|
||||
8, /* N3105 */
|
||||
15, /* RLC CV countdown */
|
||||
NM_ATT_IPACC_CODING_SCHEMES, 0, 2, 0x0f, 0x00,
|
||||
NM_ATT_IPACC_RLC_CFG_2, 0, 5,
|
||||
0x00, 250,
|
||||
0x00, 250,
|
||||
2, /* MCS2 */
|
||||
#if 0
|
||||
/* EDGE model only, breaks older models.
|
||||
* Should inquire the BTS capabilities */
|
||||
NM_ATT_IPACC_RLC_CFG_3, 0, 1,
|
||||
2, /* MCS2 */
|
||||
#endif
|
||||
};
|
||||
|
||||
static unsigned char nanobts_attr_nsvc0[] = {
|
||||
NM_ATT_IPACC_NSVCI, 0, 2, 0x03, 0x9d, /* 925 */
|
||||
NM_ATT_IPACC_NS_LINK_CFG, 0, 8,
|
||||
0x59, 0xd8, /* remote udp port (23000) */
|
||||
192, 168, 100, 11, /* remote ip address */
|
||||
0x59, 0xd8, /* local udp port (23000) */
|
||||
};
|
||||
|
||||
/* Callback function to be called whenever we get a GSM 12.21 state change event */
|
||||
int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
|
||||
struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
|
||||
@@ -405,7 +344,6 @@ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
|
||||
struct gsm_bts *bts;
|
||||
struct gsm_bts_trx *trx;
|
||||
struct gsm_bts_trx_ts *ts;
|
||||
struct gsm_bts_gprs_nsvc *nsvc;
|
||||
|
||||
/* This event-driven BTS setup is currently only required on nanoBTS */
|
||||
|
||||
@@ -417,15 +355,16 @@ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
|
||||
switch (obj_class) {
|
||||
case NM_OC_SITE_MANAGER:
|
||||
bts = container_of(obj, struct gsm_bts, site_mgr);
|
||||
if ((new_state->operational == 2 &&
|
||||
new_state->availability == NM_AVSTATE_OK) ||
|
||||
(new_state->operational == 1 &&
|
||||
new_state->availability == NM_AVSTATE_OFF_LINE))
|
||||
if (new_state->operational == 2 &&
|
||||
new_state->availability == NM_AVSTATE_OK) {
|
||||
printf("STARTING SITE MANAGER\n");
|
||||
abis_nm_opstart(bts, obj_class, 0xff, 0xff, 0xff);
|
||||
}
|
||||
break;
|
||||
case NM_OC_BTS:
|
||||
bts = obj;
|
||||
if (new_state->availability == NM_AVSTATE_DEPENDENCY) {
|
||||
printf("STARTING BTS...\n");
|
||||
patch_nm_tables(bts);
|
||||
abis_nm_set_bts_attr(bts, nanobts_attr_bts,
|
||||
sizeof(nanobts_attr_bts));
|
||||
@@ -441,6 +380,7 @@ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
|
||||
trx = ts->trx;
|
||||
if (new_state->operational == 1 &&
|
||||
new_state->availability == NM_AVSTATE_DEPENDENCY) {
|
||||
printf("STARTING OC Channel...\n");
|
||||
patch_nm_tables(trx->bts);
|
||||
enum abis_nm_chan_comb ccomb =
|
||||
abis_nm_chcomb4pchan(ts->pchan);
|
||||
@@ -459,53 +399,6 @@ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
|
||||
abis_nm_opstart(trx->bts, obj_class, trx->bts->bts_nr,
|
||||
trx->nr, 0xff);
|
||||
break;
|
||||
case NM_OC_GPRS_NSE:
|
||||
bts = container_of(obj, struct gsm_bts, gprs.nse);
|
||||
if (!bts->gprs.enabled)
|
||||
break;
|
||||
if (new_state->availability == 5) {
|
||||
abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
|
||||
0xff, 0xff, nanobts_attr_nse,
|
||||
sizeof(nanobts_attr_nse));
|
||||
abis_nm_opstart(bts, obj_class, bts->bts_nr,
|
||||
0xff, 0xff);
|
||||
abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr,
|
||||
0xff, 0xff, NM_STATE_UNLOCKED);
|
||||
}
|
||||
break;
|
||||
case NM_OC_GPRS_CELL:
|
||||
bts = container_of(obj, struct gsm_bts, gprs.cell);
|
||||
if (!bts->gprs.enabled)
|
||||
break;
|
||||
if (new_state->availability == 5) {
|
||||
abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
|
||||
0, 0xff, nanobts_attr_cell,
|
||||
sizeof(nanobts_attr_cell));
|
||||
abis_nm_opstart(bts, obj_class, bts->bts_nr,
|
||||
0, 0xff);
|
||||
abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr,
|
||||
0, 0xff, NM_STATE_UNLOCKED);
|
||||
}
|
||||
break;
|
||||
case NM_OC_GPRS_NSVC:
|
||||
nsvc = obj;
|
||||
bts = nsvc->bts;
|
||||
if (!bts->gprs.enabled)
|
||||
break;
|
||||
/* We skip NSVC1 since we only use NSVC0 */
|
||||
if (nsvc->id == 1)
|
||||
break;
|
||||
if (new_state->availability == NM_AVSTATE_OFF_LINE) {
|
||||
abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
|
||||
nsvc->id, 0xff,
|
||||
nanobts_attr_nsvc0,
|
||||
sizeof(nanobts_attr_nsvc0));
|
||||
abis_nm_opstart(bts, obj_class, bts->bts_nr,
|
||||
nsvc->id, 0xff);
|
||||
abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr,
|
||||
nsvc->id, 0xff,
|
||||
NM_STATE_UNLOCKED);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -519,8 +412,6 @@ static int sw_activ_rep(struct msgb *mb)
|
||||
struct gsm_bts *bts = mb->trx->bts;
|
||||
struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
|
||||
|
||||
if (!trx)
|
||||
return -EINVAL;
|
||||
|
||||
switch (foh->obj_class) {
|
||||
case NM_OC_BASEB_TRANSC:
|
||||
@@ -542,7 +433,8 @@ static int sw_activ_rep(struct msgb *mb)
|
||||
* This code is here to make sure that on start
|
||||
* a TRX remains locked.
|
||||
*/
|
||||
int rc_state = trx->nm_state.administrative;
|
||||
int rc_state = trx->rf_locked ?
|
||||
NM_STATE_LOCKED : NM_STATE_UNLOCKED;
|
||||
/* Patch ARFCN into radio attribute */
|
||||
nanobts_attr_radio[5] &= 0xf0;
|
||||
nanobts_attr_radio[5] |= trx->arfcn >> 8;
|
||||
@@ -798,14 +690,14 @@ static int set_system_infos(struct gsm_bts_trx *trx)
|
||||
DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
|
||||
rsl_bcch_info(trx, i, si_tmp, sizeof(si_tmp));
|
||||
}
|
||||
if (bts->gprs.enabled) {
|
||||
i = 13;
|
||||
rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_13);
|
||||
if (rc < 0)
|
||||
goto err_out;
|
||||
DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
|
||||
rsl_bcch_info(trx, RSL_SYSTEM_INFO_13, si_tmp, rc);
|
||||
}
|
||||
#ifdef GPRS
|
||||
i = 13
|
||||
rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_13);
|
||||
if (rc < 0)
|
||||
goto err_out;
|
||||
DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
|
||||
rsl_bcch_info(trx, RSL_SYSTEM_INFO_13, si_tmp, rc);
|
||||
#endif
|
||||
}
|
||||
|
||||
i = 5;
|
||||
@@ -854,46 +746,19 @@ static void patch_nm_tables(struct gsm_bts *bts)
|
||||
|
||||
/* patch BSIC */
|
||||
bs11_attr_bts[1] = bts->bsic;
|
||||
nanobts_attr_bts[sizeof(nanobts_attr_bts)-11] = bts->bsic;
|
||||
|
||||
/* patch CGI */
|
||||
abis_nm_ipaccess_cgi(nanobts_attr_bts+sizeof(nanobts_attr_bts)-7, bts);
|
||||
nanobts_attr_bts[sizeof(nanobts_attr_bts)-1] = bts->bsic;
|
||||
|
||||
/* patch the power reduction */
|
||||
bs11_attr_radio[5] = bts->c0->max_power_red / 2;
|
||||
nanobts_attr_radio[1] = bts->c0->max_power_red / 2;
|
||||
|
||||
/* patch NSEI */
|
||||
nanobts_attr_nse[3] = bts->gprs.nse.nsei >> 8;
|
||||
nanobts_attr_nse[4] = bts->gprs.nse.nsei & 0xff;
|
||||
|
||||
/* patch NSVCI */
|
||||
nanobts_attr_nsvc0[3] = bts->gprs.nsvc[0].nsvci >> 8;
|
||||
nanobts_attr_nsvc0[4] = bts->gprs.nsvc[0].nsvci & 0xff;
|
||||
|
||||
/* patch IP address as SGSN IP */
|
||||
*(u_int16_t *)(nanobts_attr_nsvc0+8) =
|
||||
htons(bts->gprs.nsvc[0].remote_port);
|
||||
*(u_int32_t *)(nanobts_attr_nsvc0+10) =
|
||||
htonl(bts->gprs.nsvc[0].remote_ip);
|
||||
*(u_int16_t *)(nanobts_attr_nsvc0+14) =
|
||||
htons(bts->gprs.nsvc[0].local_port);
|
||||
|
||||
/* patch BVCI */
|
||||
nanobts_attr_cell[12] = bts->gprs.cell.bvci >> 8;
|
||||
nanobts_attr_cell[13] = bts->gprs.cell.bvci & 0xff;
|
||||
/* patch RAC */
|
||||
nanobts_attr_cell[3] = bts->gprs.rac;
|
||||
|
||||
}
|
||||
|
||||
static void bootstrap_rsl(struct gsm_bts_trx *trx)
|
||||
{
|
||||
LOGP(DRSL, LOGL_NOTICE, "bootstrapping RSL for BTS/TRX (%u/%u) "
|
||||
"on ARFCN %u using MCC=%u MNC=%u LAC=%u CID=%u BSIC=%u TSC=%u\n",
|
||||
trx->bts->nr, trx->nr, trx->arfcn, bsc_gsmnet->country_code,
|
||||
bsc_gsmnet->network_code, trx->bts->location_area_code,
|
||||
trx->bts->cell_identity, trx->bts->bsic, trx->bts->tsc);
|
||||
"using MCC=%u MNC=%u BSIC=%u TSC=%u\n",
|
||||
trx->bts->nr, trx->nr, bsc_gsmnet->country_code,
|
||||
bsc_gsmnet->network_code, trx->bts->bsic, trx->bts->tsc);
|
||||
set_system_infos(trx);
|
||||
}
|
||||
|
||||
@@ -937,10 +802,8 @@ static int bootstrap_bts(struct gsm_bts *bts)
|
||||
}
|
||||
break;
|
||||
case GSM_BAND_900:
|
||||
if (bts->c0->arfcn < 1 ||
|
||||
(bts->c0->arfcn > 124 && bts->c0->arfcn < 955) ||
|
||||
bts->c0->arfcn > 1023) {
|
||||
LOGP(DNM, LOGL_ERROR, "GSM900 channel must be between 1-124, 955-1023.\n");
|
||||
if (bts->c0->arfcn < 1 || bts->c0->arfcn > 124) {
|
||||
LOGP(DNM, LOGL_ERROR, "GSM900 channel must be between 1-124.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
@@ -964,6 +827,11 @@ static int bootstrap_bts(struct gsm_bts *bts)
|
||||
/* T3212 is set from vty/config */
|
||||
|
||||
/* some defaults for our system information */
|
||||
bts->si_common.rach_control.re = 1; /* no re-establishment */
|
||||
bts->si_common.rach_control.tx_integer = 5; /* 8 slots spread */
|
||||
bts->si_common.rach_control.max_trans = 3; /* 7 retransmissions */
|
||||
bts->si_common.rach_control.t2 = 4; /* no emergency calls */
|
||||
|
||||
bts->si_common.cell_options.radio_link_timeout = 2; /* 12 */
|
||||
bts->si_common.cell_options.dtx = 2; /* MS shall not use upplink DTX */
|
||||
bts->si_common.cell_options.pwrc = 0; /* PWRC not set */
|
||||
|
||||
1237
openbsc/src/bsc_mgcp.c
Normal file
1237
openbsc/src/bsc_mgcp.c
Normal file
File diff suppressed because it is too large
Load Diff
72
openbsc/src/bsc_msc.c
Normal file
72
openbsc/src/bsc_msc.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/* Routines to talk to the MSC using the IPA Protocol */
|
||||
/*
|
||||
* (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2010 by on-waves.com
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openbsc/bsc_msc.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int connect_to_msc(struct bsc_fd *fd, const char *ip, int port)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
int on = 1, ret;
|
||||
|
||||
printf("Attempting to connect MSC at %s:%d\n", ip, port);
|
||||
|
||||
fd->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
fd->when = BSC_FD_READ;
|
||||
fd->data = NULL;
|
||||
fd->priv_nr = 1;
|
||||
|
||||
if (fd->fd < 0) {
|
||||
perror("Creating TCP socket failed");
|
||||
return fd->fd;
|
||||
}
|
||||
|
||||
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(port);
|
||||
inet_aton(ip, &sin.sin_addr);
|
||||
|
||||
setsockopt(fd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
||||
ret = connect(fd->fd, (struct sockaddr *) &sin, sizeof(sin));
|
||||
|
||||
if (ret < 0) {
|
||||
perror("Connection failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = bsc_register_fd(fd);
|
||||
if (ret < 0) {
|
||||
perror("Registering the fd failed");
|
||||
close(fd->fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
809
openbsc/src/bsc_msc_ip.c
Normal file
809
openbsc/src/bsc_msc_ip.c
Normal file
@@ -0,0 +1,809 @@
|
||||
/* A hackish minimal BSC (+MSC +HLR) implementation */
|
||||
|
||||
/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009 by on-waves.com
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <getopt.h>
|
||||
|
||||
#include <openbsc/select.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/e1_input.h>
|
||||
#include <openbsc/talloc.h>
|
||||
#include <openbsc/select.h>
|
||||
#include <openbsc/ipaccess.h>
|
||||
#include <openbsc/bssap.h>
|
||||
#include <openbsc/paging.h>
|
||||
#include <openbsc/signal.h>
|
||||
#include <openbsc/chan_alloc.h>
|
||||
#include <openbsc/bsc_msc.h>
|
||||
|
||||
#include <sccp/sccp.h>
|
||||
|
||||
/* SCCP helper */
|
||||
#define SCCP_IT_TIMER 60
|
||||
|
||||
/* MCC and MNC for the Location Area Identifier */
|
||||
struct gsm_network *bsc_gsmnet = 0;
|
||||
static const char *config_file = "openbsc.cfg";
|
||||
static char *msc_address = "127.0.0.1";
|
||||
static struct bsc_fd msc_connection;
|
||||
static struct in_addr local_addr;
|
||||
extern int ipacc_rtp_direct;
|
||||
|
||||
extern int bsc_bootstrap_network(int (*layer4)(struct gsm_network *, int, void *), const char *cfg_file);
|
||||
extern int bsc_shutdown_net(struct gsm_network *net);
|
||||
|
||||
struct bss_sccp_connection_data *bss_sccp_create_data()
|
||||
{
|
||||
struct bss_sccp_connection_data *data;
|
||||
|
||||
data = _talloc_zero(tall_bsc_ctx,
|
||||
sizeof(struct bss_sccp_connection_data),
|
||||
"bsc<->msc");
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
||||
INIT_LLIST_HEAD(&data->sccp_queue);
|
||||
INIT_LLIST_HEAD(&data->gsm_queue);
|
||||
return data;
|
||||
}
|
||||
|
||||
void bss_sccp_free_data(struct bss_sccp_connection_data *data)
|
||||
{
|
||||
bsc_del_timer(&data->T10);
|
||||
bsc_del_timer(&data->sccp_it);
|
||||
bsc_free_queued(data->sccp);
|
||||
bts_free_queued(data);
|
||||
talloc_free(data);
|
||||
}
|
||||
|
||||
static void sccp_it_fired(void *_data)
|
||||
{
|
||||
struct bss_sccp_connection_data *data =
|
||||
(struct bss_sccp_connection_data *) _data;
|
||||
|
||||
sccp_connection_send_it(data->sccp);
|
||||
bsc_schedule_timer(&data->sccp_it, SCCP_IT_TIMER, 0);
|
||||
}
|
||||
|
||||
|
||||
/* GSM subscriber drop-ins */
|
||||
extern struct llist_head *subscr_bsc_active_subscriber(void);
|
||||
struct gsm_subscriber *find_subscriber(u_int8_t type, const char *mi_string)
|
||||
{
|
||||
struct gsm_subscriber *subscr;
|
||||
u_int32_t tmsi = GSM_RESERVED_TMSI;
|
||||
if (type == GSM_MI_TYPE_TMSI) {
|
||||
tmsi = tmsi_from_string(mi_string);
|
||||
if (tmsi == GSM_RESERVED_TMSI) {
|
||||
DEBUGP(DMSC, "The TMSI is the reserved one.\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
llist_for_each_entry(subscr, subscr_bsc_active_subscriber(), entry) {
|
||||
if (type == GSM_MI_TYPE_TMSI && tmsi == subscr->tmsi) {
|
||||
return subscr_get(subscr);
|
||||
} else if (type == GSM_MI_TYPE_IMSI && strcmp(mi_string, subscr->imsi) == 0) {
|
||||
return subscr_get(subscr);
|
||||
}
|
||||
}
|
||||
|
||||
DEBUGP(DMSC, "No subscriber has been found.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* SCCP handling */
|
||||
void msc_outgoing_sccp_data(struct sccp_connection *conn, struct msgb *msg, unsigned int len)
|
||||
{
|
||||
struct bssmap_header *bs;
|
||||
|
||||
if (len < 1) {
|
||||
DEBUGP(DMSC, "The header is too short.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (msg->l3h[0]) {
|
||||
case BSSAP_MSG_BSS_MANAGEMENT:
|
||||
msg->l4h = &msg->l3h[sizeof(*bs)];
|
||||
msg->lchan = sccp_get_lchan(conn->data_ctx);
|
||||
bssmap_rcvmsg_dt1(conn, msg, len - sizeof(*bs));
|
||||
break;
|
||||
case BSSAP_MSG_DTAP:
|
||||
dtap_rcvmsg(sccp_get_lchan(conn->data_ctx), msg, len);
|
||||
break;
|
||||
default:
|
||||
DEBUGPC(DMSC, "Unimplemented msg type: %d\n", msg->l3h[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void msc_outgoing_sccp_state(struct sccp_connection *conn, int old_state)
|
||||
{
|
||||
if (conn->connection_state >= SCCP_CONNECTION_STATE_RELEASE_COMPLETE) {
|
||||
DEBUGP(DMSC, "Freeing sccp conn: %p state: %d\n", conn, conn->connection_state);
|
||||
if (sccp_get_lchan(conn->data_ctx) != NULL) {
|
||||
struct gsm_lchan *lchan = sccp_get_lchan(conn->data_ctx);
|
||||
|
||||
DEBUGP(DMSC, "ERROR: The lchan is still associated\n.");
|
||||
|
||||
lchan->msc_data = NULL;
|
||||
put_lchan(lchan);
|
||||
}
|
||||
|
||||
bss_sccp_free_data((struct bss_sccp_connection_data *)conn->data_ctx);
|
||||
sccp_connection_free(conn);
|
||||
return;
|
||||
} else if (conn->connection_state == SCCP_CONNECTION_STATE_ESTABLISHED) {
|
||||
struct bss_sccp_connection_data *con_data;
|
||||
|
||||
DEBUGP(DMSC, "Connection established: %p\n", conn);
|
||||
|
||||
/* start the inactivity test timer */
|
||||
con_data = (struct bss_sccp_connection_data *) conn->data_ctx;
|
||||
con_data->sccp_it.cb = sccp_it_fired;
|
||||
con_data->sccp_it.data = con_data;
|
||||
bsc_schedule_timer(&con_data->sccp_it, SCCP_IT_TIMER, 0);
|
||||
|
||||
bsc_send_queued(conn);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* General COMPLETE LAYER3 INFORMATION handling for
|
||||
* PAGING RESPONSE, LOCATION UPDATING REQUEST, CM REESTABLISHMENT REQUEST,
|
||||
* CM SERVICE REQUEST, IMSI DETACH, IMMEDIATE SETUP.
|
||||
*
|
||||
* IMMEDIATE SETUP is coming from GROUP CC that is not yet
|
||||
* supported...
|
||||
*/
|
||||
int open_sccp_connection(struct msgb *layer3)
|
||||
{
|
||||
struct bss_sccp_connection_data *con_data;
|
||||
struct sccp_connection *sccp_connection;
|
||||
struct msgb *data;
|
||||
|
||||
DEBUGP(DMSC, "Opening new layer3 connection\n");
|
||||
sccp_connection = sccp_connection_socket();
|
||||
if (!sccp_connection) {
|
||||
DEBUGP(DMSC, "Failed to allocate memory.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
data = bssmap_create_layer3(layer3);
|
||||
if (!data) {
|
||||
DEBUGP(DMSC, "Failed to allocate complete layer3.\n");
|
||||
sccp_connection_free(sccp_connection);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
con_data = bss_sccp_create_data();
|
||||
if (!con_data) {
|
||||
DEBUGP(DMSC, "Failed to allocate bss<->msc data.\n");
|
||||
sccp_connection_free(sccp_connection);
|
||||
msgb_free(data);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* initialize the bridge */
|
||||
con_data->lchan = layer3->lchan;
|
||||
con_data->sccp = sccp_connection;
|
||||
|
||||
sccp_connection->state_cb = msc_outgoing_sccp_state;
|
||||
sccp_connection->data_cb = msc_outgoing_sccp_data;
|
||||
sccp_connection->data_ctx = con_data;
|
||||
layer3->lchan->msc_data = con_data;
|
||||
|
||||
/* FIXME: Use transaction for this */
|
||||
use_lchan(layer3->lchan);
|
||||
sccp_connection_connect(sccp_connection, &sccp_ssn_bssap, data);
|
||||
msgb_free(data);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* figure out if this is the inial layer3 message */
|
||||
static int send_dtap_or_open_connection(struct msgb *msg)
|
||||
{
|
||||
if (msg->lchan->msc_data) {
|
||||
struct msgb *dtap = dtap_create_msg(msg, 0);
|
||||
if (!dtap) {
|
||||
DEBUGP(DMSC, "Creating a DTAP message failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
bsc_queue_connection_write(lchan_get_sccp(msg->lchan), dtap);
|
||||
return 1;
|
||||
} else {
|
||||
return open_sccp_connection(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Receive a PAGING RESPONSE message from the MS */
|
||||
static int handle_paging_response(struct msgb *msg)
|
||||
{
|
||||
struct gsm_subscriber *subscr;
|
||||
char mi_string[GSM48_MI_SIZE];
|
||||
u_int8_t mi_type;
|
||||
|
||||
gsm48_paging_extract_mi(msg, mi_string, &mi_type);
|
||||
DEBUGP(DMSC, "PAGING RESPONSE: mi_type=0x%02x MI(%s)\n",
|
||||
mi_type, mi_string);
|
||||
|
||||
subscr = find_subscriber(mi_type, mi_string);
|
||||
if (!subscr)
|
||||
return -EINVAL;
|
||||
|
||||
/* force the paging to stop at every bts */
|
||||
subscr->lac = GSM_LAC_RESERVED_ALL_BTS;
|
||||
if (gsm48_handle_paging_resp(msg, subscr) != 0) {
|
||||
DEBUGP(DMSC, "Paging failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* open a new transaction and SCCP connection */
|
||||
return send_dtap_or_open_connection(msg);
|
||||
}
|
||||
|
||||
/* Receive a CIPHER MODE COMPLETE from the MS */
|
||||
static int handle_cipher_m_complete(struct msgb *msg)
|
||||
{
|
||||
struct msgb *resp;
|
||||
|
||||
DEBUGP(DMSC, "CIPHER MODE COMPLETE from MS, forwarding to MSC\n");
|
||||
resp = bssmap_create_cipher_complete(msg);
|
||||
if (!resp) {
|
||||
DEBUGP(DMSC, "Creating MSC response failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* handled this message */
|
||||
bts_unblock_queue(msg->lchan->msc_data);
|
||||
bsc_queue_connection_write(lchan_get_sccp(msg->lchan), resp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Receive a ASSIGNMENT COMPLETE */
|
||||
static int handle_ass_compl(struct msgb *msg)
|
||||
{
|
||||
struct gsm_lchan *old_chan;
|
||||
struct gsm48_hdr *gh = msgb_l3(msg);
|
||||
|
||||
DEBUGP(DMSC, "ASSIGNMENT COMPLETE from MS, forwarding to MSC\n");
|
||||
|
||||
if (!msg->lchan->msc_data) {
|
||||
DEBUGP(DMSC, "No MSC data\n");
|
||||
put_lchan(msg->lchan);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (msg->lchan->msc_data->secondary_lchan != msg->lchan) {
|
||||
LOGP(DMSC, LOGL_NOTICE, "Wrong assignment complete.\n");
|
||||
put_lchan(msg->lchan);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (msgb_l3len(msg) - sizeof(*gh) != 1) {
|
||||
DEBUGP(DMSC, "assignment failure invalid: %d\n",
|
||||
msgb_l3len(msg) - sizeof(*gh));
|
||||
put_lchan(msg->lchan);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* swap the channels and release the old */
|
||||
old_chan = msg->lchan->msc_data->lchan;
|
||||
msg->lchan->msc_data->lchan = msg->lchan;
|
||||
msg->lchan->msc_data->secondary_lchan = NULL;
|
||||
old_chan->msc_data = NULL;
|
||||
|
||||
/* give up the old channel to not do a SACCH deactivate */
|
||||
subscr_put(old_chan->subscr);
|
||||
old_chan->subscr = NULL;
|
||||
put_lchan(old_chan);
|
||||
|
||||
/* activate audio on it... */
|
||||
if (is_ipaccess_bts(msg->lchan->ts->trx->bts) && msg->lchan->tch_mode != GSM48_CMODE_SIGN)
|
||||
rsl_ipacc_crcx(msg->lchan);
|
||||
|
||||
gsm0808_send_assignment_compl(msg->lchan, gh->data[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive a ASSIGNMENT FAILURE. If the message is failed
|
||||
* to be parsed the T10 timer will send the failure.
|
||||
*/
|
||||
static int handle_ass_fail(struct msgb *msg)
|
||||
{
|
||||
struct gsm48_hdr *gh = msgb_l3(msg);
|
||||
|
||||
DEBUGP(DMSC, "ASSIGNMENT FAILURE from MS, forwarding to MSC\n");
|
||||
if (!msg->lchan->msc_data) {
|
||||
DEBUGP(DMSC, "No MSC data\n");
|
||||
put_lchan(msg->lchan);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (msg->lchan->msc_data->secondary_lchan != msg->lchan) {
|
||||
LOGP(DMSC, LOGL_NOTICE, "Wrong assignment complete.\n");
|
||||
put_lchan(msg->lchan);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (msgb_l3len(msg) - sizeof(*gh) != 1) {
|
||||
DEBUGP(DMSC, "assignment failure invalid: %d\n",
|
||||
msgb_l3len(msg) - sizeof(*gh));
|
||||
put_lchan(msg->lchan);
|
||||
return -1;
|
||||
}
|
||||
|
||||
gsm0808_send_assignment_failure(msg->lchan,
|
||||
GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, &gh->data[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive a GSM04.08 MODIFY ACK. Actually we have to check
|
||||
* the content to see if this was a success or not.
|
||||
*/
|
||||
static int handle_modify_ack(struct msgb *msg)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* modify RSL */
|
||||
rc = gsm48_rx_rr_modif_ack(msg);
|
||||
if (rc < 0)
|
||||
gsm0808_send_assignment_failure(msg->lchan,
|
||||
GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE, NULL);
|
||||
else
|
||||
gsm0808_send_assignment_compl(msg->lchan, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Receive a GSM 04.08 Radio Resource (RR) message */
|
||||
static int gsm0408_rcv_rr(struct msgb *msg)
|
||||
{
|
||||
struct gsm48_hdr *gh = msgb_l3(msg);
|
||||
int rc = 0;
|
||||
|
||||
switch (gh->msg_type) {
|
||||
case GSM48_MT_RR_PAG_RESP:
|
||||
rc = handle_paging_response(msg);
|
||||
break;
|
||||
case GSM48_MT_RR_MEAS_REP:
|
||||
/* ignore measurement for now */
|
||||
rc = -1;
|
||||
break;
|
||||
case GSM48_MT_RR_CIPH_M_COMPL:
|
||||
rc = handle_cipher_m_complete(msg);
|
||||
break;
|
||||
case GSM48_MT_RR_ASS_COMPL:
|
||||
rc = handle_ass_compl(msg);
|
||||
break;
|
||||
case GSM48_MT_RR_ASS_FAIL:
|
||||
rc = handle_ass_fail(msg);
|
||||
break;
|
||||
case GSM48_MT_RR_CHAN_MODE_MODIF_ACK:
|
||||
rc = handle_modify_ack(msg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Receive a GSM 04.08 Mobility Management (MM) message */
|
||||
static int gsm0408_rcv_mm(struct msgb *msg)
|
||||
{
|
||||
struct gsm48_hdr *gh = msgb_l3(msg);
|
||||
int rc = 0;
|
||||
|
||||
switch (gh->msg_type & 0xbf) {
|
||||
case GSM48_MT_MM_LOC_UPD_REQUEST:
|
||||
case GSM48_MT_MM_CM_REEST_REQ:
|
||||
case GSM48_MT_MM_CM_SERV_REQ:
|
||||
case GSM48_MT_MM_IMSI_DETACH_IND:
|
||||
rc = send_dtap_or_open_connection(msg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id)
|
||||
{
|
||||
struct gsm48_hdr *gh = msgb_l3(msg);
|
||||
u_int8_t pdisc = gh->proto_discr & 0x0f;
|
||||
int rc = 0;
|
||||
|
||||
switch (pdisc) {
|
||||
case GSM48_PDISC_RR:
|
||||
rc = gsm0408_rcv_rr(msg);
|
||||
break;
|
||||
case GSM48_PDISC_MM:
|
||||
rc = gsm0408_rcv_mm(msg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* if we have a sccp connection and didn't handle the message
|
||||
* forward it to the MSC using DTAP
|
||||
*/
|
||||
if (rc == 0 && msg->lchan->msc_data && lchan_get_sccp(msg->lchan)) {
|
||||
struct msgb *dtap = dtap_create_msg(msg, link_id);
|
||||
if (!dtap) {
|
||||
DEBUGP(DMSC, "Creating a DTAP message failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
bsc_queue_connection_write(lchan_get_sccp(msg->lchan), dtap);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* handle ipaccess signals */
|
||||
static int handle_abisip_signal(unsigned int subsys, unsigned int signal,
|
||||
void *handler_data, void *signal_data)
|
||||
{
|
||||
struct gsm_lchan *lchan = signal_data;
|
||||
struct gsm_bts_trx_ts *ts;
|
||||
int rc;
|
||||
|
||||
if (subsys != SS_ABISIP)
|
||||
return 0;
|
||||
|
||||
ts = lchan->ts;
|
||||
|
||||
switch (signal) {
|
||||
case S_ABISIP_CRCX_ACK:
|
||||
/* we can ask it to connect now */
|
||||
if (lchan->msc_data) {
|
||||
DEBUGP(DMSC, "Connecting BTS to port: %d conn: %d\n",
|
||||
lchan->msc_data->rtp_port, lchan->abis_ip.conn_id);
|
||||
|
||||
int rtp_payload = ts->trx->bts->network->rtp_payload;
|
||||
if (rtp_payload == 0)
|
||||
rtp_payload = lchan->abis_ip.rtp_payload2;
|
||||
|
||||
rc = rsl_ipacc_mdcx(lchan, ntohl(local_addr.s_addr),
|
||||
lchan->msc_data->rtp_port,
|
||||
rtp_payload);
|
||||
if (rc < 0) {
|
||||
DEBUGP(DMSC, "Failed to send connect: %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case S_ABISIP_DLCX_IND:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_usage()
|
||||
{
|
||||
printf("Usage: bsc_hack\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* SCCP handling
|
||||
*/
|
||||
static int msc_sccp_write_ipa(struct msgb *msg, void *data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DEBUGP(DMSC, "Sending SCCP to MSC: %u\n", msgb_l2len(msg));
|
||||
ipaccess_prepend_header(msg, IPAC_PROTO_SCCP);
|
||||
|
||||
|
||||
DEBUGP(DMI, "MSC TX %s\n", hexdump(msg->l2h, msgb_l2len(msg)));
|
||||
ret = write(msc_connection.fd, msg->data, msg->len);
|
||||
|
||||
if (ret <= 0) {
|
||||
perror("MSC: Failed to send SCCP");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msc_sccp_accept(struct sccp_connection *connection, void *data)
|
||||
{
|
||||
DEBUGP(DMSC, "Rejecting incoming SCCP connection.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int msc_sccp_read(struct msgb *msgb, unsigned int length, void *data)
|
||||
{
|
||||
struct bssmap_header *bs;
|
||||
|
||||
DEBUGP(DMSC, "Incoming SCCP message ftom MSC: %s\n", hexdump(msgb->l3h, length));
|
||||
|
||||
if (length < sizeof(*bs)) {
|
||||
DEBUGP(DMSC, "The header is too short.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
bs = (struct bssmap_header *) msgb->l3h;
|
||||
if (bs->length < length - sizeof(*bs))
|
||||
return -1;
|
||||
|
||||
switch (bs->type) {
|
||||
case BSSAP_MSG_BSS_MANAGEMENT:
|
||||
msgb->l4h = &msgb->l3h[sizeof(*bs)];
|
||||
bssmap_rcvmsg_udt(bsc_gsmnet, msgb, length - sizeof(*bs));
|
||||
break;
|
||||
default:
|
||||
DEBUGPC(DMSC, "Unimplemented msg type: %d\n", bs->type);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* network initialisation
|
||||
*/
|
||||
static void initialize_if_needed(void)
|
||||
{
|
||||
if (!bsc_gsmnet) {
|
||||
int rc;
|
||||
struct msgb *msg;
|
||||
|
||||
fprintf(stderr, "Bootstraping the network. Sending GSM08.08 reset.\n");
|
||||
rc = bsc_bootstrap_network(NULL, config_file);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Bootstrapping the network failed. exiting.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/* send a gsm 08.08 reset message from here */
|
||||
msg = bssmap_create_reset();
|
||||
if (!msg) {
|
||||
DEBUGP(DMSC, "Failed to create the reset message.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sccp_write(msg, &sccp_ssn_bssap, &sccp_ssn_bssap, 0);
|
||||
msgb_free(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* callback with IP access data
|
||||
*/
|
||||
static int ipaccess_a_fd_cb(struct bsc_fd *bfd, unsigned int what)
|
||||
{
|
||||
int error;
|
||||
struct msgb *msg = ipaccess_read_msg(bfd, &error);
|
||||
struct ipaccess_head *hh;
|
||||
|
||||
if (!msg) {
|
||||
if (error == 0) {
|
||||
fprintf(stderr, "The connection to the MSC was lost, exiting\n");
|
||||
exit(-2);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Failed to parse ip access message: %d\n", error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
DEBUGP(DMSC, "From MSC: %s proto: %d\n", hexdump(msg->data, msg->len), msg->l2h[0]);
|
||||
|
||||
/* handle base message handling */
|
||||
hh = (struct ipaccess_head *) msg->data;
|
||||
ipaccess_rcvmsg_base(msg, bfd);
|
||||
|
||||
/* initialize the networking. This includes sending a GSM08.08 message */
|
||||
if (hh->proto == IPAC_PROTO_IPACCESS && msg->l2h[0] == IPAC_MSGT_ID_ACK)
|
||||
initialize_if_needed();
|
||||
else if (hh->proto == IPAC_PROTO_SCCP)
|
||||
sccp_system_incoming(msg);
|
||||
|
||||
msgb_free(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_help()
|
||||
{
|
||||
printf(" Some useful help...\n");
|
||||
printf(" -h --help this text\n");
|
||||
printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
|
||||
printf(" -s --disable-color\n");
|
||||
printf(" -c --config-file filename The config file to use.\n");
|
||||
printf(" -m --msc=IP. The address of the MSC.\n");
|
||||
printf(" -l --local=IP. The local address of the MGCP.\n");
|
||||
}
|
||||
|
||||
static void handle_options(int argc, char** argv)
|
||||
{
|
||||
while (1) {
|
||||
int option_index = 0, c;
|
||||
static struct option long_options[] = {
|
||||
{"help", 0, 0, 'h'},
|
||||
{"debug", 1, 0, 'd'},
|
||||
{"config-file", 1, 0, 'c'},
|
||||
{"disable-color", 0, 0, 's'},
|
||||
{"timestamp", 0, 0, 'T'},
|
||||
{"rtp-proxy", 0, 0, 'P'},
|
||||
{"msc", 1, 0, 'm'},
|
||||
{"local", 1, 0, 'l'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long(argc, argv, "hd:sTPc:m:l:",
|
||||
long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'h':
|
||||
print_usage();
|
||||
print_help();
|
||||
exit(0);
|
||||
case 's':
|
||||
debug_use_color(0);
|
||||
break;
|
||||
case 'd':
|
||||
debug_parse_category_mask(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
config_file = strdup(optarg);
|
||||
break;
|
||||
case 'T':
|
||||
debug_timestamp(1);
|
||||
break;
|
||||
case 'P':
|
||||
ipacc_rtp_direct = 0;
|
||||
break;
|
||||
case 'm':
|
||||
msc_address = strdup(optarg);
|
||||
break;
|
||||
case 'l':
|
||||
inet_aton(optarg, &local_addr);
|
||||
break;
|
||||
default:
|
||||
/* ignore */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void signal_handler(int signal)
|
||||
{
|
||||
fprintf(stdout, "signal %u received\n", signal);
|
||||
|
||||
switch (signal) {
|
||||
case SIGINT:
|
||||
bsc_shutdown_net(bsc_gsmnet);
|
||||
sleep(3);
|
||||
exit(0);
|
||||
break;
|
||||
case SIGABRT:
|
||||
/* in case of abort, we want to obtain a talloc report
|
||||
* and then return to the caller, who will abort the process */
|
||||
case SIGUSR1:
|
||||
talloc_report_full(tall_bsc_ctx, stderr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_mode()
|
||||
{
|
||||
static const u_int8_t assignment_req[] = { 0x01, 0x0b, 0x03, 0x01, 0x0b, 0x25, 0x01, 0x00, 0x01 };
|
||||
struct gsm_lchan lchan;
|
||||
struct sccp_connection conn;
|
||||
struct bss_sccp_connection_data data;
|
||||
|
||||
struct gsm_bts_trx_ts trx_ts;
|
||||
struct gsm_bts_trx trx;
|
||||
struct gsm_bts bts;
|
||||
int rc;
|
||||
|
||||
/* initialize */
|
||||
fprintf(stderr, "Bootstraping the network. Sending GSM08.08 reset.\n");
|
||||
rc = bsc_bootstrap_network(NULL, config_file);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Bootstrapping the network failed. exiting.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
bts.network = bsc_gsmnet;
|
||||
trx.bts = &bts;
|
||||
trx_ts.trx = &trx;
|
||||
lchan.ts = &trx_ts;
|
||||
|
||||
/* create fake data connection */
|
||||
data.lchan = &lchan;
|
||||
data.sccp = &conn;
|
||||
lchan.msc_data = &data;
|
||||
conn.data_ctx = &data;
|
||||
|
||||
|
||||
struct msgb *msg = msgb_alloc(400, "test-msg");
|
||||
msg->lchan = &lchan;
|
||||
|
||||
msg->l4h = msgb_put(msg, ARRAY_SIZE(assignment_req));
|
||||
memcpy(msg->l4h, assignment_req, ARRAY_SIZE(assignment_req));
|
||||
bssmap_rcvmsg_dt1(&conn, msg, ARRAY_SIZE(assignment_req));
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int rc;
|
||||
|
||||
tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
|
||||
|
||||
/* parse options */
|
||||
handle_options(argc, argv);
|
||||
|
||||
/* seed the PRNG */
|
||||
srand(time(NULL));
|
||||
|
||||
/* initialize sccp */
|
||||
sccp_system_init(msc_sccp_write_ipa, NULL);
|
||||
sccp_connection_set_incoming(&sccp_ssn_bssap, msc_sccp_accept, NULL);
|
||||
sccp_set_read(&sccp_ssn_bssap, msc_sccp_read, NULL);
|
||||
|
||||
/* initialize ipaccess handling */
|
||||
register_signal_handler(SS_ABISIP, handle_abisip_signal, NULL);
|
||||
|
||||
msc_connection.cb = ipaccess_a_fd_cb;
|
||||
rc = connect_to_msc(&msc_connection, msc_address, 5000);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Opening the MSC connection failed.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
signal(SIGINT, &signal_handler);
|
||||
signal(SIGABRT, &signal_handler);
|
||||
signal(SIGUSR1, &signal_handler);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
while (1) {
|
||||
bsc_select_main(0);
|
||||
}
|
||||
}
|
||||
@@ -24,9 +24,9 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include <openbsc/debug.h>
|
||||
#include <osmocore/talloc.h>
|
||||
#include <osmocore/timer.h>
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <openbsc/talloc.h>
|
||||
#include <openbsc/timer.h>
|
||||
#include <openbsc/linuxlist.h>
|
||||
#include <openbsc/bsc_rll.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/chan_alloc.h>
|
||||
|
||||
1299
openbsc/src/bssap.c
Normal file
1299
openbsc/src/bssap.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,84 +0,0 @@
|
||||
/* ip.access nanoBTS specific code */
|
||||
|
||||
/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <osmocore/tlv.h>
|
||||
#include <openbsc/abis_nm.h>
|
||||
|
||||
static struct gsm_bts_model model_nanobts = {
|
||||
.type = GSM_BTS_TYPE_NANOBTS,
|
||||
.nm_att_tlvdef = {
|
||||
.def = {
|
||||
/* ip.access specifics */
|
||||
[NM_ATT_IPACC_DST_IP] = { TLV_TYPE_FIXED, 4 },
|
||||
[NM_ATT_IPACC_DST_IP_PORT] = { TLV_TYPE_FIXED, 2 },
|
||||
[NM_ATT_IPACC_STREAM_ID] = { TLV_TYPE_TV, },
|
||||
[NM_ATT_IPACC_FREQ_CTRL] = { TLV_TYPE_TV, },
|
||||
[NM_ATT_IPACC_SEC_OML_CFG] = { TLV_TYPE_FIXED, 6 },
|
||||
[NM_ATT_IPACC_IP_IF_CFG] = { TLV_TYPE_FIXED, 8 },
|
||||
[NM_ATT_IPACC_IP_GW_CFG] = { TLV_TYPE_FIXED, 12 },
|
||||
[NM_ATT_IPACC_IN_SERV_TIME] = { TLV_TYPE_FIXED, 4 },
|
||||
[NM_ATT_IPACC_LOCATION] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_PAGING_CFG] = { TLV_TYPE_FIXED, 2 },
|
||||
[NM_ATT_IPACC_UNIT_ID] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_UNIT_NAME] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_SNMP_CFG] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_PRIM_OML_CFG_LIST] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_NV_FLAGS] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_FREQ_CTRL] = { TLV_TYPE_FIXED, 2 },
|
||||
[NM_ATT_IPACC_PRIM_OML_FB_TOUT] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_CUR_SW_CFG] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_TIMING_BUS] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_CGI] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_RAC] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_OBJ_VERSION] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_GPRS_PAGING_CFG]= { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_NSEI] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_BVCI] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_NSVCI] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_NS_CFG] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_BSSGP_CFG] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_NS_LINK_CFG] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_RLC_CFG] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_ALM_THRESH_LIST]= { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_MONIT_VAL_LIST] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_TIB_CONTROL] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_SUPP_FEATURES] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_CODING_SCHEMES] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_RLC_CFG_2] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_HEARTB_TOUT] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_UPTIME] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_RLC_CFG_3] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_SSL_CFG] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_SEC_POSSIBLE] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_IML_SSL_STATE] = { TLV_TYPE_TL16V },
|
||||
[NM_ATT_IPACC_REVOC_DATE] = { TLV_TYPE_TL16V },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
int bts_model_nanobts_init(void)
|
||||
{
|
||||
return gsm_bts_model_register(&model_nanobts);
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/* Siemens BS-11 specific code */
|
||||
|
||||
/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <osmocore/tlv.h>
|
||||
#include <openbsc/abis_nm.h>
|
||||
|
||||
static struct gsm_bts_model model_bs11 = {
|
||||
.type = GSM_BTS_TYPE_BS11,
|
||||
.nm_att_tlvdef = {
|
||||
.def = {
|
||||
[NM_ATT_AVAIL_STATUS] = { TLV_TYPE_TLV },
|
||||
/* BS11 specifics */
|
||||
[NM_ATT_BS11_ESN_FW_CODE_NO] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_ESN_HW_CODE_NO] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_ESN_PCB_SERIAL] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_BOOT_SW_VERS] = { TLV_TYPE_TLV },
|
||||
[0xd5] = { TLV_TYPE_TLV },
|
||||
[0xa8] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_PASSWORD] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_TXPWR] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_RSSI_OFFS] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_LINE_CFG] = { TLV_TYPE_TV },
|
||||
[NM_ATT_BS11_L1_PROT_TYPE] = { TLV_TYPE_TV },
|
||||
[NM_ATT_BS11_BIT_ERR_THESH] = { TLV_TYPE_FIXED, 2 },
|
||||
[NM_ATT_BS11_DIVERSITY] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_LMT_LOGON_SESSION]={ TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_LMT_LOGIN_TIME] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_LMT_USER_ACC_LEV] ={ TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_LMT_USER_NAME] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_BTS_STATE] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_E1_STATE] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_PLL_MODE] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_PLL] = { TLV_TYPE_TLV },
|
||||
[NM_ATT_BS11_CCLK_ACCURACY] = { TLV_TYPE_TV },
|
||||
[NM_ATT_BS11_CCLK_TYPE] = { TLV_TYPE_TV },
|
||||
[0x95] = { TLV_TYPE_FIXED, 2 },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
int bts_model_bs11_init(void)
|
||||
{
|
||||
return gsm_bts_model_register(&model_bs11);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user