mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
				synced 2025-11-02 21:13:44 +00:00 
			
		
		
		
	Compare commits
	
		
			7 Commits
		
	
	
		
			on-waves/0
			...
			on-waves/0
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					2727909dba | ||
| 
						 | 
					ad9856ec15 | ||
| 
						 | 
					9d53a8ad2a | ||
| 
						 | 
					058956e8ee | ||
| 
						 | 
					a34bb9167f | ||
| 
						 | 
					b8ac7ffd7c | ||
| 
						 | 
					b13cf829da | 
							
								
								
									
										25
									
								
								libosmocore/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								libosmocore/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,25 +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
 | 
			
		||||
 | 
			
		||||
.tarball-version
 | 
			
		||||
.version
 | 
			
		||||
@@ -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,14 +0,0 @@
 | 
			
		||||
AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6
 | 
			
		||||
ACLOCAL_AMFLAGS = -I m4
 | 
			
		||||
 | 
			
		||||
INCLUDES = $(all_includes) -I$(top_srcdir)/include
 | 
			
		||||
SUBDIRS = include src tests
 | 
			
		||||
 | 
			
		||||
pkgconfigdir = $(libdir)/pkgconfig
 | 
			
		||||
pkgconfig_DATA = libosmocore.pc
 | 
			
		||||
 | 
			
		||||
BUILT_SOURCES = $(top_srcdir)/.version
 | 
			
		||||
$(top_srcdir)/.version:
 | 
			
		||||
	echo $(VERSION) > $@-t && mv $@-t $@
 | 
			
		||||
dist-hook:
 | 
			
		||||
	echo $(VERSION) > $(distdir)/.tarball-version
 | 
			
		||||
@@ -1,56 +0,0 @@
 | 
			
		||||
AC_INIT([libosmocore],
 | 
			
		||||
	m4_esyscmd([./git-version-gen .tarball-version]),
 | 
			
		||||
	[openbsc-devel@lists.openbsc.org])
 | 
			
		||||
 | 
			
		||||
AM_INIT_AUTOMAKE([dist-bzip2])
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
LT_INIT
 | 
			
		||||
AC_PROG_LIBTOOL
 | 
			
		||||
 | 
			
		||||
AC_CONFIG_MACRO_DIR([m4])
 | 
			
		||||
 | 
			
		||||
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,151 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
# Print a version string.
 | 
			
		||||
scriptversion=2010-01-28.01
 | 
			
		||||
 | 
			
		||||
# Copyright (C) 2007-2010 Free Software Foundation, Inc.
 | 
			
		||||
#
 | 
			
		||||
# 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 3 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, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
# This script is derived from GIT-VERSION-GEN from GIT: http://git.or.cz/.
 | 
			
		||||
# It may be run two ways:
 | 
			
		||||
# - from a git repository in which the "git describe" command below
 | 
			
		||||
#   produces useful output (thus requiring at least one signed tag)
 | 
			
		||||
# - from a non-git-repo directory containing a .tarball-version file, which
 | 
			
		||||
#   presumes this script is invoked like "./git-version-gen .tarball-version".
 | 
			
		||||
 | 
			
		||||
# In order to use intra-version strings in your project, you will need two
 | 
			
		||||
# separate generated version string files:
 | 
			
		||||
#
 | 
			
		||||
# .tarball-version - present only in a distribution tarball, and not in
 | 
			
		||||
#   a checked-out repository.  Created with contents that were learned at
 | 
			
		||||
#   the last time autoconf was run, and used by git-version-gen.  Must not
 | 
			
		||||
#   be present in either $(srcdir) or $(builddir) for git-version-gen to
 | 
			
		||||
#   give accurate answers during normal development with a checked out tree,
 | 
			
		||||
#   but must be present in a tarball when there is no version control system.
 | 
			
		||||
#   Therefore, it cannot be used in any dependencies.  GNUmakefile has
 | 
			
		||||
#   hooks to force a reconfigure at distribution time to get the value
 | 
			
		||||
#   correct, without penalizing normal development with extra reconfigures.
 | 
			
		||||
#
 | 
			
		||||
# .version - present in a checked-out repository and in a distribution
 | 
			
		||||
#   tarball.  Usable in dependencies, particularly for files that don't
 | 
			
		||||
#   want to depend on config.h but do want to track version changes.
 | 
			
		||||
#   Delete this file prior to any autoconf run where you want to rebuild
 | 
			
		||||
#   files to pick up a version string change; and leave it stale to
 | 
			
		||||
#   minimize rebuild time after unrelated changes to configure sources.
 | 
			
		||||
#
 | 
			
		||||
# It is probably wise to add these two files to .gitignore, so that you
 | 
			
		||||
# don't accidentally commit either generated file.
 | 
			
		||||
#
 | 
			
		||||
# Use the following line in your configure.ac, so that $(VERSION) will
 | 
			
		||||
# automatically be up-to-date each time configure is run (and note that
 | 
			
		||||
# since configure.ac no longer includes a version string, Makefile rules
 | 
			
		||||
# should not depend on configure.ac for version updates).
 | 
			
		||||
#
 | 
			
		||||
# AC_INIT([GNU project],
 | 
			
		||||
#         m4_esyscmd([build-aux/git-version-gen .tarball-version]),
 | 
			
		||||
#         [bug-project@example])
 | 
			
		||||
#
 | 
			
		||||
# Then use the following lines in your Makefile.am, so that .version
 | 
			
		||||
# will be present for dependencies, and so that .tarball-version will
 | 
			
		||||
# exist in distribution tarballs.
 | 
			
		||||
#
 | 
			
		||||
# BUILT_SOURCES = $(top_srcdir)/.version
 | 
			
		||||
# $(top_srcdir)/.version:
 | 
			
		||||
#	echo $(VERSION) > $@-t && mv $@-t $@
 | 
			
		||||
# dist-hook:
 | 
			
		||||
#	echo $(VERSION) > $(distdir)/.tarball-version
 | 
			
		||||
 | 
			
		||||
case $# in
 | 
			
		||||
    1) ;;
 | 
			
		||||
    *) echo 1>&2 "Usage: $0 \$srcdir/.tarball-version"; exit 1;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
tarball_version_file=$1
 | 
			
		||||
nl='
 | 
			
		||||
'
 | 
			
		||||
 | 
			
		||||
# First see if there is a tarball-only version file.
 | 
			
		||||
# then try "git describe", then default.
 | 
			
		||||
if test -f $tarball_version_file
 | 
			
		||||
then
 | 
			
		||||
    v=`cat $tarball_version_file` || exit 1
 | 
			
		||||
    case $v in
 | 
			
		||||
	*$nl*) v= ;; # reject multi-line output
 | 
			
		||||
	[0-9]*) ;;
 | 
			
		||||
	*) v= ;;
 | 
			
		||||
    esac
 | 
			
		||||
    test -z "$v" \
 | 
			
		||||
	&& echo "$0: WARNING: $tarball_version_file seems to be damaged" 1>&2
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if test -n "$v"
 | 
			
		||||
then
 | 
			
		||||
    : # use $v
 | 
			
		||||
elif
 | 
			
		||||
       v=`git describe --abbrev=4 --match='v*' HEAD 2>/dev/null \
 | 
			
		||||
	  || git describe --abbrev=4 HEAD 2>/dev/null` \
 | 
			
		||||
    && case $v in
 | 
			
		||||
	 [0-9]*) ;;
 | 
			
		||||
	 v[0-9]*) ;;
 | 
			
		||||
	 *) (exit 1) ;;
 | 
			
		||||
       esac
 | 
			
		||||
then
 | 
			
		||||
    # Is this a new git that lists number of commits since the last
 | 
			
		||||
    # tag or the previous older version that did not?
 | 
			
		||||
    #   Newer: v6.10-77-g0f8faeb
 | 
			
		||||
    #   Older: v6.10-g0f8faeb
 | 
			
		||||
    case $v in
 | 
			
		||||
	*-*-*) : git describe is okay three part flavor ;;
 | 
			
		||||
	*-*)
 | 
			
		||||
	    : git describe is older two part flavor
 | 
			
		||||
	    # Recreate the number of commits and rewrite such that the
 | 
			
		||||
	    # result is the same as if we were using the newer version
 | 
			
		||||
	    # of git describe.
 | 
			
		||||
	    vtag=`echo "$v" | sed 's/-.*//'`
 | 
			
		||||
	    numcommits=`git rev-list "$vtag"..HEAD | wc -l`
 | 
			
		||||
	    v=`echo "$v" | sed "s/\(.*\)-\(.*\)/\1-$numcommits-\2/"`;
 | 
			
		||||
	    ;;
 | 
			
		||||
    esac
 | 
			
		||||
 | 
			
		||||
    # Change the first '-' to a '.', so version-comparing tools work properly.
 | 
			
		||||
    # Remove the "g" in git describe's output string, to save a byte.
 | 
			
		||||
    v=`echo "$v" | sed 's/-/./;s/\(.*\)-g/\1-/'`;
 | 
			
		||||
else
 | 
			
		||||
    v=UNKNOWN
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
v=`echo "$v" |sed 's/^v//'`
 | 
			
		||||
 | 
			
		||||
# Don't declare a version "dirty" merely because a time stamp has changed.
 | 
			
		||||
git status > /dev/null 2>&1
 | 
			
		||||
 | 
			
		||||
dirty=`sh -c 'git diff-index --name-only HEAD' 2>/dev/null` || dirty=
 | 
			
		||||
case "$dirty" in
 | 
			
		||||
    '') ;;
 | 
			
		||||
    *) # Append the suffix only if there isn't one already.
 | 
			
		||||
	case $v in
 | 
			
		||||
	  *-dirty) ;;
 | 
			
		||||
	  *) v="$v-dirty" ;;
 | 
			
		||||
	esac ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
# Omit the trailing newline, so that m4_esyscmd can use the result directly.
 | 
			
		||||
echo "$v" | tr -d '\012'
 | 
			
		||||
 | 
			
		||||
# Local variables:
 | 
			
		||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
 | 
			
		||||
# time-stamp-start: "scriptversion="
 | 
			
		||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
 | 
			
		||||
# time-stamp-end: "$"
 | 
			
		||||
# End:
 | 
			
		||||
@@ -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 logging.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;
 | 
			
		||||
const char *gsm48_cc_state_name(uint8_t state);
 | 
			
		||||
const char *gsm48_cc_msg_name(uint8_t msgtype);
 | 
			
		||||
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,130 +0,0 @@
 | 
			
		||||
#ifndef _OSMOCORE_LOGGING_H
 | 
			
		||||
#define _OSMOCORE_LOGGING_H
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <osmocore/linuxlist.h>
 | 
			
		||||
 | 
			
		||||
#define LOG_MAX_CATEGORY	32
 | 
			
		||||
#define LOG_MAX_CTX		8
 | 
			
		||||
#define LOG_MAX_FILTERS	8
 | 
			
		||||
 | 
			
		||||
#define DEBUG
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
#define DEBUGP(ss, fmt, args...) logp(ss, __FILE__, __LINE__, 0, fmt, ## args)
 | 
			
		||||
#define DEBUGPC(ss, fmt, args...) logp(ss, __FILE__, __LINE__, 1, fmt, ## args)
 | 
			
		||||
#else
 | 
			
		||||
#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 logp(unsigned int subsys, char *file, int line, int cont, const char *format, ...) __attribute__ ((format (printf, 5, 6)));
 | 
			
		||||
 | 
			
		||||
/* new logging interface */
 | 
			
		||||
#define LOGP(ss, level, fmt, args...) \
 | 
			
		||||
	logp2(ss, level, __FILE__, __LINE__, 0, fmt, ##args)
 | 
			
		||||
#define LOGPC(ss, level, fmt, args...) \
 | 
			
		||||
	logp2(ss, level, __FILE__, __LINE__, 1, fmt, ##args)
 | 
			
		||||
 | 
			
		||||
/* different levels */
 | 
			
		||||
#define LOGL_DEBUG	1	/* debugging information */
 | 
			
		||||
#define LOGL_INFO	3
 | 
			
		||||
#define LOGL_NOTICE	5	/* abnormal/unexpected condition */
 | 
			
		||||
#define LOGL_ERROR	7	/* error condition, requires user action */
 | 
			
		||||
#define LOGL_FATAL	8	/* fatal, program aborted */
 | 
			
		||||
 | 
			
		||||
#define LOG_FILTER_ALL	0x0001
 | 
			
		||||
 | 
			
		||||
struct log_category {
 | 
			
		||||
	uint8_t loglevel;
 | 
			
		||||
	uint8_t enabled;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct log_info_cat {
 | 
			
		||||
	const char *name;
 | 
			
		||||
	const char *color;
 | 
			
		||||
	const char *description;
 | 
			
		||||
	uint8_t loglevel;
 | 
			
		||||
	uint8_t enabled;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* log context information, passed to filter */
 | 
			
		||||
struct log_context {
 | 
			
		||||
	void *ctx[LOG_MAX_CTX+1];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct log_target;
 | 
			
		||||
 | 
			
		||||
typedef int log_filter(const struct log_context *ctx,
 | 
			
		||||
		       struct log_target *target);
 | 
			
		||||
 | 
			
		||||
struct log_info {
 | 
			
		||||
	/* filter callback function */
 | 
			
		||||
	log_filter *filter_fn;
 | 
			
		||||
 | 
			
		||||
	/* per-category information */
 | 
			
		||||
	const struct log_info_cat *cat;
 | 
			
		||||
	unsigned int num_cat;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct log_target {
 | 
			
		||||
        struct llist_head entry;
 | 
			
		||||
 | 
			
		||||
	int filter_map;
 | 
			
		||||
	void *filter_data[LOG_MAX_FILTERS+1];
 | 
			
		||||
 | 
			
		||||
	struct log_category categories[LOG_MAX_CATEGORY+1];
 | 
			
		||||
	uint8_t loglevel;
 | 
			
		||||
	int use_color:1;
 | 
			
		||||
	int print_timestamp:1;
 | 
			
		||||
 | 
			
		||||
	union {
 | 
			
		||||
		struct {
 | 
			
		||||
			FILE *out;
 | 
			
		||||
		} tgt_stdout;
 | 
			
		||||
 | 
			
		||||
		struct {
 | 
			
		||||
			int priority;
 | 
			
		||||
		} tgt_syslog;
 | 
			
		||||
 | 
			
		||||
		struct {
 | 
			
		||||
			void *vty;
 | 
			
		||||
		} tgt_vty;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
        void (*output) (struct log_target *target, const char *string);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* use the above macros */
 | 
			
		||||
void logp2(unsigned int subsys, unsigned int level, char *file,
 | 
			
		||||
	   int line, int cont, const char *format, ...)
 | 
			
		||||
				__attribute__ ((format (printf, 6, 7)));
 | 
			
		||||
void log_init(const struct log_info *cat);
 | 
			
		||||
 | 
			
		||||
/* context management */
 | 
			
		||||
void log_reset_context(void);
 | 
			
		||||
int log_set_context(uint8_t ctx, void *value);
 | 
			
		||||
 | 
			
		||||
/* filter on the targets */
 | 
			
		||||
void log_set_all_filter(struct log_target *target, int);
 | 
			
		||||
 | 
			
		||||
void log_set_use_color(struct log_target *target, int);
 | 
			
		||||
void log_set_print_timestamp(struct log_target *target, int);
 | 
			
		||||
void log_set_log_level(struct log_target *target, int log_level);
 | 
			
		||||
void log_parse_category_mask(struct log_target *target, const char* mask);
 | 
			
		||||
int log_parse_level(const char *lvl);
 | 
			
		||||
int log_parse_category(const char *category);
 | 
			
		||||
void log_set_category_filter(struct log_target *target, int category,
 | 
			
		||||
			       int enable, int level);
 | 
			
		||||
 | 
			
		||||
/* management of the targets */
 | 
			
		||||
struct log_target *log_target_create(void);
 | 
			
		||||
struct log_target *log_target_create_stderr(void);
 | 
			
		||||
void log_add_target(struct log_target *target);
 | 
			
		||||
void log_del_target(struct log_target *target);
 | 
			
		||||
 | 
			
		||||
#endif /* _OSMOCORE_LOGGING_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,32 +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);
 | 
			
		||||
 | 
			
		||||
const char *rsl_err_name(uint8_t err);
 | 
			
		||||
const char *rsl_rlm_cause_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,45 +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.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
#ifndef write_queue_h
 | 
			
		||||
#define write_queue_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);
 | 
			
		||||
void write_queue_clear(struct write_queue *queue);
 | 
			
		||||
int write_queue_enqueue(struct write_queue *queue, struct msgb *data);
 | 
			
		||||
int write_queue_bfd_cb(struct bsc_fd *fd, unsigned int what);
 | 
			
		||||
 | 
			
		||||
#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 +0,0 @@
 | 
			
		||||
Dummply placeholder.
 | 
			
		||||
@@ -1,17 +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 \
 | 
			
		||||
			 logging.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,263 +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-2010 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 struct value_string 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" },
 | 
			
		||||
	{ 0,					NULL },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* FIXME: convert to value_string */
 | 
			
		||||
static 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_state_name(uint8_t state)
 | 
			
		||||
{
 | 
			
		||||
	if (state < ARRAY_SIZE(cc_state_names))
 | 
			
		||||
		return cc_state_names[state];
 | 
			
		||||
 | 
			
		||||
	return "invalid";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct value_string cc_msg_names[] = {
 | 
			
		||||
	{ GSM48_MT_CC_ALERTING,		"ALERTING" },
 | 
			
		||||
	{ GSM48_MT_CC_CALL_PROC,	"CALL_PROC" },
 | 
			
		||||
	{ GSM48_MT_CC_PROGRESS,		"PROGRESS" },
 | 
			
		||||
	{ GSM48_MT_CC_ESTAB,		"ESTAB" },
 | 
			
		||||
	{ GSM48_MT_CC_SETUP,		"SETUP" },
 | 
			
		||||
	{ GSM48_MT_CC_ESTAB_CONF,	"ESTAB_CONF" },
 | 
			
		||||
	{ GSM48_MT_CC_CONNECT,		"CONNECT" },
 | 
			
		||||
	{ GSM48_MT_CC_CALL_CONF,	"CALL_CONF" },
 | 
			
		||||
	{ GSM48_MT_CC_START_CC,		"START_CC" },
 | 
			
		||||
	{ GSM48_MT_CC_RECALL,		"RECALL" },
 | 
			
		||||
	{ GSM48_MT_CC_EMERG_SETUP,	"EMERG_SETUP" },
 | 
			
		||||
	{ GSM48_MT_CC_CONNECT_ACK,	"CONNECT_ACK" },
 | 
			
		||||
	{ GSM48_MT_CC_USER_INFO,	"USER_INFO" },
 | 
			
		||||
	{ GSM48_MT_CC_MODIFY_REJECT,	"MODIFY_REJECT" },
 | 
			
		||||
	{ GSM48_MT_CC_MODIFY,		"MODIFY" },
 | 
			
		||||
	{ GSM48_MT_CC_HOLD,		"HOLD" },
 | 
			
		||||
	{ GSM48_MT_CC_HOLD_ACK,		"HOLD_ACK" },
 | 
			
		||||
	{ GSM48_MT_CC_HOLD_REJ,		"HOLD_REJ" },
 | 
			
		||||
	{ GSM48_MT_CC_RETR,		"RETR" },
 | 
			
		||||
	{ GSM48_MT_CC_RETR_ACK,		"RETR_ACK" },
 | 
			
		||||
	{ GSM48_MT_CC_RETR_REJ,		"RETR_REJ" },
 | 
			
		||||
	{ GSM48_MT_CC_MODIFY_COMPL,	"MODIFY_COMPL" },
 | 
			
		||||
	{ GSM48_MT_CC_DISCONNECT,	"DISCONNECT" },
 | 
			
		||||
	{ GSM48_MT_CC_RELEASE_COMPL,	"RELEASE_COMPL" },
 | 
			
		||||
	{ GSM48_MT_CC_RELEASE,		"RELEASE" },
 | 
			
		||||
	{ GSM48_MT_CC_STOP_DTMF,	"STOP_DTMF" },
 | 
			
		||||
	{ GSM48_MT_CC_STOP_DTMF_ACK,	"STOP_DTMF_ACK" },
 | 
			
		||||
	{ GSM48_MT_CC_STATUS_ENQ,	"STATUS_ENQ" },
 | 
			
		||||
	{ GSM48_MT_CC_START_DTMF,	"START_DTMF" },
 | 
			
		||||
	{ GSM48_MT_CC_START_DTMF_ACK,	"START_DTMF_ACK" },
 | 
			
		||||
	{ GSM48_MT_CC_START_DTMF_REJ,	"START_DTMF_REJ" },
 | 
			
		||||
	{ GSM48_MT_CC_CONG_CTRL,	"CONG_CTRL" },
 | 
			
		||||
	{ GSM48_MT_CC_FACILITY,		"FACILITY" },
 | 
			
		||||
	{ GSM48_MT_CC_STATUS,		"STATUS" },
 | 
			
		||||
	{ GSM48_MT_CC_NOTIFY,		"NOTFIY" },
 | 
			
		||||
	{ 0,				NULL }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const char *gsm48_cc_msg_name(uint8_t msgtype)
 | 
			
		||||
{
 | 
			
		||||
	return get_value_string(cc_msg_names, msgtype);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *rr_cause_name(uint8_t cause)
 | 
			
		||||
{
 | 
			
		||||
	return get_value_string(rr_cause_names, cause);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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,345 +0,0 @@
 | 
			
		||||
/* Debugging/Logging support code */
 | 
			
		||||
 | 
			
		||||
/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
 | 
			
		||||
 * (C) 2008 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 <stdarg.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <strings.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
#include <osmocore/talloc.h>
 | 
			
		||||
#include <osmocore/utils.h>
 | 
			
		||||
#include <osmocore/logging.h>
 | 
			
		||||
 | 
			
		||||
static const struct log_info *log_info;
 | 
			
		||||
 | 
			
		||||
static struct log_context log_context;
 | 
			
		||||
static void *tall_log_ctx = NULL;
 | 
			
		||||
static LLIST_HEAD(target_list);
 | 
			
		||||
 | 
			
		||||
static const struct value_string loglevel_strs[] = {
 | 
			
		||||
	{ 0,		"EVERYTHING" },
 | 
			
		||||
	{ LOGL_DEBUG,	"DEBUG" },
 | 
			
		||||
	{ LOGL_INFO,	"INFO" },
 | 
			
		||||
	{ LOGL_NOTICE,	"NOTICE" },
 | 
			
		||||
	{ LOGL_ERROR,	"ERROR" },
 | 
			
		||||
	{ LOGL_FATAL,	"FATAL" },
 | 
			
		||||
	{ 0, NULL },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int log_parse_level(const char *lvl)
 | 
			
		||||
{
 | 
			
		||||
	return get_string_value(loglevel_strs, lvl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int log_parse_category(const char *category)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < log_info->num_cat; ++i) {
 | 
			
		||||
		if (!strcasecmp(log_info->cat[i].name+1, category))
 | 
			
		||||
			return i;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return -EINVAL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Parse the category mask.
 | 
			
		||||
 * The format can be this: category1:category2:category3
 | 
			
		||||
 * or category1,2:category2,3:...
 | 
			
		||||
 */
 | 
			
		||||
void log_parse_category_mask(struct log_target* target, const char *_mask)
 | 
			
		||||
{
 | 
			
		||||
	int i = 0;
 | 
			
		||||
	char *mask = strdup(_mask);
 | 
			
		||||
	char *category_token = NULL;
 | 
			
		||||
 | 
			
		||||
	/* Disable everything to enable it afterwards */
 | 
			
		||||
	for (i = 0; i < ARRAY_SIZE(target->categories); ++i)
 | 
			
		||||
		target->categories[i].enabled = 0;
 | 
			
		||||
 | 
			
		||||
	category_token = strtok(mask, ":");
 | 
			
		||||
	do {
 | 
			
		||||
		for (i = 0; i < log_info->num_cat; ++i) {
 | 
			
		||||
			char* colon = strstr(category_token, ",");
 | 
			
		||||
			int length = strlen(category_token);
 | 
			
		||||
 | 
			
		||||
			if (colon)
 | 
			
		||||
			    length = colon - category_token;
 | 
			
		||||
 | 
			
		||||
			if (strncasecmp(log_info->cat[i].name, category_token,
 | 
			
		||||
					length) == 0) {
 | 
			
		||||
				int level = 0;
 | 
			
		||||
 | 
			
		||||
				if (colon)
 | 
			
		||||
					level = atoi(colon+1);
 | 
			
		||||
 | 
			
		||||
				target->categories[i].enabled = 1;
 | 
			
		||||
				target->categories[i].loglevel = level;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} while ((category_token = strtok(NULL, ":")));
 | 
			
		||||
 | 
			
		||||
	free(mask);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char* color(int subsys)
 | 
			
		||||
{
 | 
			
		||||
	if (subsys < log_info->num_cat)
 | 
			
		||||
		return log_info->cat[subsys].color;
 | 
			
		||||
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _output(struct log_target *target, unsigned int subsys,
 | 
			
		||||
		    char *file, int line, int cont, const char *format,
 | 
			
		||||
		    va_list ap)
 | 
			
		||||
{
 | 
			
		||||
	char col[30];
 | 
			
		||||
	char sub[30];
 | 
			
		||||
	char tim[30];
 | 
			
		||||
	char buf[4096];
 | 
			
		||||
	char final[4096];
 | 
			
		||||
 | 
			
		||||
	/* prepare the data */
 | 
			
		||||
	col[0] = '\0';
 | 
			
		||||
	sub[0] = '\0';
 | 
			
		||||
	tim[0] = '\0';
 | 
			
		||||
	buf[0] = '\0';
 | 
			
		||||
 | 
			
		||||
	/* are we using color */
 | 
			
		||||
	if (target->use_color) {
 | 
			
		||||
		const char *c = color(subsys);
 | 
			
		||||
		if (c) {
 | 
			
		||||
			snprintf(col, sizeof(col), "%s", color(subsys));
 | 
			
		||||
			col[sizeof(col)-1] = '\0';
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	vsnprintf(buf, sizeof(buf), format, ap);
 | 
			
		||||
	buf[sizeof(buf)-1] = '\0';
 | 
			
		||||
 | 
			
		||||
	if (!cont) {
 | 
			
		||||
		if (target->print_timestamp) {
 | 
			
		||||
			char *timestr;
 | 
			
		||||
			time_t tm;
 | 
			
		||||
			tm = time(NULL);
 | 
			
		||||
			timestr = ctime(&tm);
 | 
			
		||||
			timestr[strlen(timestr)-1] = '\0';
 | 
			
		||||
			snprintf(tim, sizeof(tim), "%s ", timestr);
 | 
			
		||||
			tim[sizeof(tim)-1] = '\0';
 | 
			
		||||
		}
 | 
			
		||||
		snprintf(sub, sizeof(sub), "<%4.4x> %s:%d ", subsys, file, line);
 | 
			
		||||
		sub[sizeof(sub)-1] = '\0';
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	snprintf(final, sizeof(final), "%s%s%s%s\033[0;m", col, tim, sub, buf);
 | 
			
		||||
	final[sizeof(final)-1] = '\0';
 | 
			
		||||
	target->output(target, final);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void _logp(unsigned int subsys, int level, char *file, int line,
 | 
			
		||||
		  int cont, const char *format, va_list ap)
 | 
			
		||||
{
 | 
			
		||||
	struct log_target *tar;
 | 
			
		||||
 | 
			
		||||
	llist_for_each_entry(tar, &target_list, entry) {
 | 
			
		||||
		struct log_category *category;
 | 
			
		||||
		int output = 0;
 | 
			
		||||
 | 
			
		||||
		category = &tar->categories[subsys];
 | 
			
		||||
		/* subsystem is not supposed to be logged */
 | 
			
		||||
		if (!category->enabled)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		/* Check the global log level */
 | 
			
		||||
		if (tar->loglevel != 0 && level < tar->loglevel)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		/* Check the category log level */
 | 
			
		||||
		if (tar->loglevel == 0 && category->loglevel != 0 &&
 | 
			
		||||
		    level < category->loglevel)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		/* Apply filters here... if that becomes messy we will
 | 
			
		||||
		 * need to put filters in a list and each filter will
 | 
			
		||||
		 * say stop, continue, output */
 | 
			
		||||
		if ((tar->filter_map & LOG_FILTER_ALL) != 0)
 | 
			
		||||
			output = 1;
 | 
			
		||||
		else if (log_info->filter_fn)
 | 
			
		||||
			output = log_info->filter_fn(&log_context,
 | 
			
		||||
						       tar);
 | 
			
		||||
 | 
			
		||||
		if (output) {
 | 
			
		||||
			/* FIXME: copying the va_list is an ugly
 | 
			
		||||
			 * workaround against a bug hidden somewhere in
 | 
			
		||||
			 * _output.  If we do not copy here, the first
 | 
			
		||||
			 * call to _output() will corrupt the va_list
 | 
			
		||||
			 * contents, and any further _output() calls
 | 
			
		||||
			 * with the same va_list will segfault */
 | 
			
		||||
			va_list bp;
 | 
			
		||||
			va_copy(bp, ap);
 | 
			
		||||
			_output(tar, subsys, file, line, cont, format, bp);
 | 
			
		||||
			va_end(bp);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void logp(unsigned int subsys, char *file, int line, int cont,
 | 
			
		||||
	  const char *format, ...)
 | 
			
		||||
{
 | 
			
		||||
	va_list ap;
 | 
			
		||||
 | 
			
		||||
	va_start(ap, format);
 | 
			
		||||
	_logp(subsys, LOGL_DEBUG, file, line, cont, format, ap);
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void logp2(unsigned int subsys, unsigned int level, char *file, int line, int cont, const char *format, ...)
 | 
			
		||||
{
 | 
			
		||||
	va_list ap;
 | 
			
		||||
 | 
			
		||||
	va_start(ap, format);
 | 
			
		||||
	_logp(subsys, level, file, line, cont, format, ap);
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char hexd_buff[4096];
 | 
			
		||||
 | 
			
		||||
char *hexdump(const unsigned char *buf, int len)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	char *cur = hexd_buff;
 | 
			
		||||
 | 
			
		||||
	hexd_buff[0] = 0;
 | 
			
		||||
	for (i = 0; i < len; i++) {
 | 
			
		||||
		int len_remain = sizeof(hexd_buff) - (cur - hexd_buff);
 | 
			
		||||
		int rc = snprintf(cur, len_remain, "%02x ", buf[i]);
 | 
			
		||||
		if (rc <= 0)
 | 
			
		||||
			break;
 | 
			
		||||
		cur += rc;
 | 
			
		||||
	}
 | 
			
		||||
	hexd_buff[sizeof(hexd_buff)-1] = 0;
 | 
			
		||||
	return hexd_buff;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void log_add_target(struct log_target *target)
 | 
			
		||||
{
 | 
			
		||||
	llist_add_tail(&target->entry, &target_list);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void log_del_target(struct log_target *target)
 | 
			
		||||
{
 | 
			
		||||
	llist_del(&target->entry);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void log_reset_context(void)
 | 
			
		||||
{
 | 
			
		||||
	memset(&log_context, 0, sizeof(log_context));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int log_set_context(uint8_t ctx_nr, void *value)
 | 
			
		||||
{
 | 
			
		||||
	if (ctx_nr > LOG_MAX_CTX)
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
 | 
			
		||||
	log_context.ctx[ctx_nr] = value;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void log_set_all_filter(struct log_target *target, int all)
 | 
			
		||||
{
 | 
			
		||||
	if (all)
 | 
			
		||||
		target->filter_map |= LOG_FILTER_ALL;
 | 
			
		||||
	else
 | 
			
		||||
		target->filter_map &= ~LOG_FILTER_ALL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void log_set_use_color(struct log_target *target, int use_color)
 | 
			
		||||
{
 | 
			
		||||
	target->use_color = use_color;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void log_set_print_timestamp(struct log_target *target, int print_timestamp)
 | 
			
		||||
{
 | 
			
		||||
	target->print_timestamp = print_timestamp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void log_set_log_level(struct log_target *target, int log_level)
 | 
			
		||||
{
 | 
			
		||||
	target->loglevel = log_level;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void log_set_category_filter(struct log_target *target, int category,
 | 
			
		||||
			       int enable, int level)
 | 
			
		||||
{
 | 
			
		||||
	if (category >= log_info->num_cat)
 | 
			
		||||
		return;
 | 
			
		||||
	target->categories[category].enabled = !!enable;
 | 
			
		||||
	target->categories[category].loglevel = level;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void _stderr_output(struct log_target *target, const char *log)
 | 
			
		||||
{
 | 
			
		||||
	fprintf(target->tgt_stdout.out, "%s", log);
 | 
			
		||||
	fflush(target->tgt_stdout.out);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct log_target *log_target_create(void)
 | 
			
		||||
{
 | 
			
		||||
	struct log_target *target;
 | 
			
		||||
 | 
			
		||||
	target = talloc_zero(tall_log_ctx, struct log_target);
 | 
			
		||||
	if (!target)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	INIT_LLIST_HEAD(&target->entry);
 | 
			
		||||
	memcpy(target->categories, log_info->cat,
 | 
			
		||||
		sizeof(struct log_category)*log_info->num_cat);
 | 
			
		||||
	target->use_color = 1;
 | 
			
		||||
	target->print_timestamp = 0;
 | 
			
		||||
	target->loglevel = 0;
 | 
			
		||||
	return target;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct log_target *log_target_create_stderr(void)
 | 
			
		||||
{
 | 
			
		||||
	struct log_target *target;
 | 
			
		||||
 | 
			
		||||
	target = log_target_create();
 | 
			
		||||
	if (!target)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	target->tgt_stdout.out = stderr;
 | 
			
		||||
	target->output = _stderr_output;
 | 
			
		||||
	return target;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void log_init(const struct log_info *cat)
 | 
			
		||||
{
 | 
			
		||||
	tall_log_ctx = talloc_named_const(NULL, 1, "logging");
 | 
			
		||||
	log_info = cat;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,329 +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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct value_string rsl_err_vals[] = {
 | 
			
		||||
	{ 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" },
 | 
			
		||||
	{ 0,				NULL }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const char *rsl_err_name(uint8_t err)
 | 
			
		||||
{
 | 
			
		||||
	return get_value_string(rsl_err_vals, err);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static 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_rlm_cause_name(uint8_t err)
 | 
			
		||||
{
 | 
			
		||||
	return get_value_string(rsl_rlm_cause_strs, 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)
 | 
			
		||||
{
 | 
			
		||||
	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,66 +0,0 @@
 | 
			
		||||
/* utility routines for keeping some statistics */
 | 
			
		||||
 | 
			
		||||
/* (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.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
#include <osmocore/linuxlist.h>
 | 
			
		||||
#include <osmocore/talloc.h>
 | 
			
		||||
#include <osmocore/statistics.h>
 | 
			
		||||
 | 
			
		||||
static LLIST_HEAD(counters);
 | 
			
		||||
 | 
			
		||||
void *tall_ctr_ctx;
 | 
			
		||||
 | 
			
		||||
struct counter *counter_alloc(const char *name)
 | 
			
		||||
{
 | 
			
		||||
	struct counter *ctr = talloc_zero(tall_ctr_ctx, struct counter);
 | 
			
		||||
 | 
			
		||||
	if (!ctr)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	ctr->name = name;
 | 
			
		||||
	llist_add_tail(&ctr->list, &counters);
 | 
			
		||||
 | 
			
		||||
	return ctr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void counter_free(struct counter *ctr)
 | 
			
		||||
{
 | 
			
		||||
	llist_del(&ctr->list);
 | 
			
		||||
	talloc_free(ctr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int counters_for_each(int (*handle_counter)(struct counter *, void *), void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct counter *ctr;
 | 
			
		||||
	int rc = 0;
 | 
			
		||||
 | 
			
		||||
	llist_for_each_entry(ctr, &counters, list) {
 | 
			
		||||
		rc = handle_counter(ctr, data);
 | 
			
		||||
		if (rc < 0)
 | 
			
		||||
			return rc;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return rc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1,50 +0,0 @@
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#include <osmocore/utils.h>
 | 
			
		||||
 | 
			
		||||
static char namebuf[255];
 | 
			
		||||
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;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	snprintf(namebuf, sizeof(namebuf), "unknown 0x%x", val);
 | 
			
		||||
	return namebuf;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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,85 +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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void write_queue_clear(struct write_queue *queue)
 | 
			
		||||
{
 | 
			
		||||
	while (!llist_empty(&queue->msg_queue)) {
 | 
			
		||||
		struct msgb *msg = msgb_dequeue(&queue->msg_queue);
 | 
			
		||||
		msgb_free(msg);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	queue->current_length = 0;
 | 
			
		||||
	queue->bfd.when &= ~BSC_FD_WRITE;
 | 
			
		||||
}
 | 
			
		||||
@@ -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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								openbsc/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								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?
 | 
			
		||||
 | 
			
		||||
@@ -23,9 +19,6 @@ install-sh
 | 
			
		||||
missing
 | 
			
		||||
stamp-h1
 | 
			
		||||
 | 
			
		||||
# git-version-gen magic
 | 
			
		||||
.tarball-version
 | 
			
		||||
.version
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# apps and app data
 | 
			
		||||
@@ -33,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,10 +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
 | 
			
		||||
 | 
			
		||||
BUILT_SOURCES = $(top_srcdir)/.version
 | 
			
		||||
$(top_srcdir)/.version:
 | 
			
		||||
	echo $(VERSION) > $@-t && mv $@-t $@
 | 
			
		||||
dist-hook:
 | 
			
		||||
	echo $(VERSION) > $(distdir)/.tarball-version
 | 
			
		||||
#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,6 +1,7 @@
 | 
			
		||||
dnl Process this file with autoconf to produce a configure script
 | 
			
		||||
AC_INIT(openbsc, 0.3.99.17onwaves)
 | 
			
		||||
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
 | 
			
		||||
AC_INIT
 | 
			
		||||
 | 
			
		||||
AM_INIT_AUTOMAKE(openbsc, 0.3.4onwaves)
 | 
			
		||||
 | 
			
		||||
dnl kernel style compile messages
 | 
			
		||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 | 
			
		||||
@@ -15,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 >= 0.1.11)
 | 
			
		||||
 | 
			
		||||
dnl checks for header files
 | 
			
		||||
AC_HEADER_STDC
 | 
			
		||||
 | 
			
		||||
@@ -39,7 +38,6 @@ AM_CONFIG_HEADER(bscconfig.h)
 | 
			
		||||
 | 
			
		||||
AC_OUTPUT(
 | 
			
		||||
    openbsc.pc
 | 
			
		||||
    libsccp.pc
 | 
			
		||||
    include/openbsc/Makefile
 | 
			
		||||
    include/vty/Makefile
 | 
			
		||||
    include/sccp/Makefile
 | 
			
		||||
@@ -47,9 +45,10 @@ AC_OUTPUT(
 | 
			
		||||
    src/Makefile
 | 
			
		||||
    tests/Makefile
 | 
			
		||||
    tests/debug/Makefile
 | 
			
		||||
    tests/timer/Makefile
 | 
			
		||||
    tests/sms/Makefile
 | 
			
		||||
    tests/gsm0408/Makefile
 | 
			
		||||
    tests/db/Makefile
 | 
			
		||||
    tests/channel/Makefile
 | 
			
		||||
    tests/sccp/Makefile
 | 
			
		||||
    tests/bsc-nat/Makefile
 | 
			
		||||
    Makefile)
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@ rsip_resp = """200 321321332\r\n"""
 | 
			
		||||
audit_packet = """AUEP %d 13@mgw MGCP 1.0\r\n"""
 | 
			
		||||
crcx_packet = """CRCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nL: p:20, a:GSM-EFR, nt:IN\r\nM: recvonly\r\n"""
 | 
			
		||||
dlcx_packet = """DLCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nI: %d\r\n"""
 | 
			
		||||
mdcx_packet = """MDCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nI: %d\r\nL: p:20, a:GSM-EFR, nt:IN\r\nM: recvonly\r\n\r\nv=0\r\no=- 258696477 0 IN IP4 172.16.1.107\r\ns=-\r\nc=IN IP4 172.16.1.107\r\nt=0 0\r\nm=audio 6666 RTP/AVP 127\r\na=rtpmap:127 GSM-EFR/8000/1\r\na=ptime:20\r\na=recvonly\r\nm=image 4402 udptl t38\r\na=T38FaxVersion:0\r\na=T38MaxBitRate:14400\r\n"""
 | 
			
		||||
mdcx_packet = """MDCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nI: %d\r\nL: p:20, a:GSM-EFR, nt:IN\r\nM: recvonly\r\n\r\nv=0\r\no=- 258696477 0 IN IP4 172.16.1.107\r\ns=-\r\nc=IN IP4 172.16.1.107\r\nt=0 0\r\nm=audio 4400 RTP/AVP 127\r\na=rtpmap:127 GSM-EFR/8000/1\r\na=ptime:20\r\na=recvonly\r\nm=image 4402 udptl t38\r\na=T38FaxVersion:0\r\na=T38MaxBitRate:14400\r\n"""
 | 
			
		||||
 | 
			
		||||
def hexdump(src, length=8):
 | 
			
		||||
    """Recipe is from http://code.activestate.com/recipes/142812/"""
 | 
			
		||||
@@ -25,24 +25,15 @@ def hexdump(src, length=8):
 | 
			
		||||
 | 
			
		||||
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
 | 
			
		||||
server_socket.bind(("127.0.0.1", MGCP_CALLAGENT_PORT))
 | 
			
		||||
server_socket.setblocking(1)
 | 
			
		||||
server_socket.setblocking(0)
 | 
			
		||||
 | 
			
		||||
last_ci = 1
 | 
			
		||||
def send_and_receive(packet):
 | 
			
		||||
    global last_ci
 | 
			
		||||
 | 
			
		||||
def send_receive(packet):
 | 
			
		||||
    server_socket.sendto(packet, ("127.0.0.1", MGCP_GATEWAY_PORT))
 | 
			
		||||
    try:
 | 
			
		||||
        data, addr = server_socket.recvfrom(4096)
 | 
			
		||||
 | 
			
		||||
        # attempt to store the CI of the response
 | 
			
		||||
        list = data.split("\n")
 | 
			
		||||
        for item in list:
 | 
			
		||||
           if item.startswith("I: "):
 | 
			
		||||
               last_ci = int(item[3:])
 | 
			
		||||
 | 
			
		||||
        print hexdump(data), addr
 | 
			
		||||
    except socket.error, e:
 | 
			
		||||
        print e
 | 
			
		||||
    except socket.error:
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
def generate_tid():
 | 
			
		||||
@@ -51,10 +42,13 @@ def generate_tid():
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
i = 1
 | 
			
		||||
while True:
 | 
			
		||||
    send_and_receive(audit_packet % generate_tid())
 | 
			
		||||
    send_and_receive(crcx_packet % generate_tid() )
 | 
			
		||||
    send_and_receive(mdcx_packet % (generate_tid(), last_ci))
 | 
			
		||||
    send_and_receive(dlcx_packet % (generate_tid(), last_ci))
 | 
			
		||||
    send_receive(rsip_resp)
 | 
			
		||||
    send_receive(audit_packet)
 | 
			
		||||
    send_receive(crcx_packet % generate_tid() )
 | 
			
		||||
    send_receive(mdcx_packet % (generate_tid(), i))
 | 
			
		||||
    send_receive(dlcx_packet % (generate_tid(), i))
 | 
			
		||||
    i = i + 1
 | 
			
		||||
 | 
			
		||||
    time.sleep(3)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,151 +0,0 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
# Print a version string.
 | 
			
		||||
scriptversion=2010-01-28.01
 | 
			
		||||
 | 
			
		||||
# Copyright (C) 2007-2010 Free Software Foundation, Inc.
 | 
			
		||||
#
 | 
			
		||||
# 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 3 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, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
# This script is derived from GIT-VERSION-GEN from GIT: http://git.or.cz/.
 | 
			
		||||
# It may be run two ways:
 | 
			
		||||
# - from a git repository in which the "git describe" command below
 | 
			
		||||
#   produces useful output (thus requiring at least one signed tag)
 | 
			
		||||
# - from a non-git-repo directory containing a .tarball-version file, which
 | 
			
		||||
#   presumes this script is invoked like "./git-version-gen .tarball-version".
 | 
			
		||||
 | 
			
		||||
# In order to use intra-version strings in your project, you will need two
 | 
			
		||||
# separate generated version string files:
 | 
			
		||||
#
 | 
			
		||||
# .tarball-version - present only in a distribution tarball, and not in
 | 
			
		||||
#   a checked-out repository.  Created with contents that were learned at
 | 
			
		||||
#   the last time autoconf was run, and used by git-version-gen.  Must not
 | 
			
		||||
#   be present in either $(srcdir) or $(builddir) for git-version-gen to
 | 
			
		||||
#   give accurate answers during normal development with a checked out tree,
 | 
			
		||||
#   but must be present in a tarball when there is no version control system.
 | 
			
		||||
#   Therefore, it cannot be used in any dependencies.  GNUmakefile has
 | 
			
		||||
#   hooks to force a reconfigure at distribution time to get the value
 | 
			
		||||
#   correct, without penalizing normal development with extra reconfigures.
 | 
			
		||||
#
 | 
			
		||||
# .version - present in a checked-out repository and in a distribution
 | 
			
		||||
#   tarball.  Usable in dependencies, particularly for files that don't
 | 
			
		||||
#   want to depend on config.h but do want to track version changes.
 | 
			
		||||
#   Delete this file prior to any autoconf run where you want to rebuild
 | 
			
		||||
#   files to pick up a version string change; and leave it stale to
 | 
			
		||||
#   minimize rebuild time after unrelated changes to configure sources.
 | 
			
		||||
#
 | 
			
		||||
# It is probably wise to add these two files to .gitignore, so that you
 | 
			
		||||
# don't accidentally commit either generated file.
 | 
			
		||||
#
 | 
			
		||||
# Use the following line in your configure.ac, so that $(VERSION) will
 | 
			
		||||
# automatically be up-to-date each time configure is run (and note that
 | 
			
		||||
# since configure.ac no longer includes a version string, Makefile rules
 | 
			
		||||
# should not depend on configure.ac for version updates).
 | 
			
		||||
#
 | 
			
		||||
# AC_INIT([GNU project],
 | 
			
		||||
#         m4_esyscmd([build-aux/git-version-gen .tarball-version]),
 | 
			
		||||
#         [bug-project@example])
 | 
			
		||||
#
 | 
			
		||||
# Then use the following lines in your Makefile.am, so that .version
 | 
			
		||||
# will be present for dependencies, and so that .tarball-version will
 | 
			
		||||
# exist in distribution tarballs.
 | 
			
		||||
#
 | 
			
		||||
# BUILT_SOURCES = $(top_srcdir)/.version
 | 
			
		||||
# $(top_srcdir)/.version:
 | 
			
		||||
#	echo $(VERSION) > $@-t && mv $@-t $@
 | 
			
		||||
# dist-hook:
 | 
			
		||||
#	echo $(VERSION) > $(distdir)/.tarball-version
 | 
			
		||||
 | 
			
		||||
case $# in
 | 
			
		||||
    1) ;;
 | 
			
		||||
    *) echo 1>&2 "Usage: $0 \$srcdir/.tarball-version"; exit 1;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
tarball_version_file=$1
 | 
			
		||||
nl='
 | 
			
		||||
'
 | 
			
		||||
 | 
			
		||||
# First see if there is a tarball-only version file.
 | 
			
		||||
# then try "git describe", then default.
 | 
			
		||||
if test -f $tarball_version_file
 | 
			
		||||
then
 | 
			
		||||
    v=`cat $tarball_version_file` || exit 1
 | 
			
		||||
    case $v in
 | 
			
		||||
	*$nl*) v= ;; # reject multi-line output
 | 
			
		||||
	[0-9]*) ;;
 | 
			
		||||
	*) v= ;;
 | 
			
		||||
    esac
 | 
			
		||||
    test -z "$v" \
 | 
			
		||||
	&& echo "$0: WARNING: $tarball_version_file seems to be damaged" 1>&2
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if test -n "$v"
 | 
			
		||||
then
 | 
			
		||||
    : # use $v
 | 
			
		||||
elif test -d ./../.git \
 | 
			
		||||
    && v=`git describe --abbrev=4 --match='v*' HEAD 2>/dev/null \
 | 
			
		||||
	  || git describe --abbrev=4 HEAD 2>/dev/null` \
 | 
			
		||||
    && case $v in
 | 
			
		||||
	 [0-9]*) ;;
 | 
			
		||||
	 v[0-9]*) ;;
 | 
			
		||||
	 *) (exit 1) ;;
 | 
			
		||||
       esac
 | 
			
		||||
then
 | 
			
		||||
    # Is this a new git that lists number of commits since the last
 | 
			
		||||
    # tag or the previous older version that did not?
 | 
			
		||||
    #   Newer: v6.10-77-g0f8faeb
 | 
			
		||||
    #   Older: v6.10-g0f8faeb
 | 
			
		||||
    case $v in
 | 
			
		||||
	*-*-*) : git describe is okay three part flavor ;;
 | 
			
		||||
	*-*)
 | 
			
		||||
	    : git describe is older two part flavor
 | 
			
		||||
	    # Recreate the number of commits and rewrite such that the
 | 
			
		||||
	    # result is the same as if we were using the newer version
 | 
			
		||||
	    # of git describe.
 | 
			
		||||
	    vtag=`echo "$v" | sed 's/-.*//'`
 | 
			
		||||
	    numcommits=`git rev-list "$vtag"..HEAD | wc -l`
 | 
			
		||||
	    v=`echo "$v" | sed "s/\(.*\)-\(.*\)/\1-$numcommits-\2/"`;
 | 
			
		||||
	    ;;
 | 
			
		||||
    esac
 | 
			
		||||
 | 
			
		||||
    # Change the first '-' to a '.', so version-comparing tools work properly.
 | 
			
		||||
    # Remove the "g" in git describe's output string, to save a byte.
 | 
			
		||||
    v=`echo "$v" | sed 's/-/./;s/\(.*\)-g/\1-/'`;
 | 
			
		||||
else
 | 
			
		||||
    v=UNKNOWN
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
v=`echo "$v" |sed 's/^v//'`
 | 
			
		||||
 | 
			
		||||
# Don't declare a version "dirty" merely because a time stamp has changed.
 | 
			
		||||
git status > /dev/null 2>&1
 | 
			
		||||
 | 
			
		||||
dirty=`sh -c 'git diff-index --name-only HEAD' 2>/dev/null` || dirty=
 | 
			
		||||
case "$dirty" in
 | 
			
		||||
    '') ;;
 | 
			
		||||
    *) # Append the suffix only if there isn't one already.
 | 
			
		||||
	case $v in
 | 
			
		||||
	  *-dirty) ;;
 | 
			
		||||
	  *) v="$v-dirty" ;;
 | 
			
		||||
	esac ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
# Omit the trailing newline, so that m4_esyscmd can use the result directly.
 | 
			
		||||
echo "$v" | tr -d '\012'
 | 
			
		||||
 | 
			
		||||
# Local variables:
 | 
			
		||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
 | 
			
		||||
# time-stamp-start: "scriptversion="
 | 
			
		||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
 | 
			
		||||
# time-stamp-end: "$"
 | 
			
		||||
# End:
 | 
			
		||||
@@ -1,12 +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 \
 | 
			
		||||
		 vty.h bssap.h bsc_msc.h bsc_nat.h bsc_msc_rf.h
 | 
			
		||||
 | 
			
		||||
openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.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,
 | 
			
		||||
@@ -92,7 +747,7 @@ int abis_nm_sw_act_req_ack(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i1,
 | 
			
		||||
int abis_nm_raw_msg(struct gsm_bts *bts, int len, u_int8_t *msg);
 | 
			
		||||
int abis_nm_event_reports(struct gsm_bts *bts, int on);
 | 
			
		||||
int abis_nm_reset_resource(struct gsm_bts *bts);
 | 
			
		||||
int abis_nm_software_load(struct gsm_bts *bts, int trx_nr, const char *fname,
 | 
			
		||||
int abis_nm_software_load(struct gsm_bts *bts, const char *fname,
 | 
			
		||||
			  u_int8_t win_size, int forced,
 | 
			
		||||
			  gsm_cbfn *cbfn, void *cb_data);
 | 
			
		||||
int abis_nm_software_load_status(struct gsm_bts *bts);
 | 
			
		||||
@@ -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,15 +798,14 @@ 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_trx *trx);
 | 
			
		||||
int abis_nm_ipaccess_restart(struct gsm_bts *bts);
 | 
			
		||||
int abis_nm_ipaccess_set_attr(struct gsm_bts *bts, u_int8_t obj_class,
 | 
			
		||||
				u_int8_t bts_nr, u_int8_t trx_nr, u_int8_t ts_nr,
 | 
			
		||||
				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);
 | 
			
		||||
 | 
			
		||||
@@ -164,10 +815,8 @@ enum nm_evt {
 | 
			
		||||
	EVT_STATECHG_ADM,
 | 
			
		||||
};
 | 
			
		||||
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,
 | 
			
		||||
		   struct abis_om_obj_inst *obj_inst);
 | 
			
		||||
		   struct gsm_nm_state *old_state, struct gsm_nm_state *new_state); 
 | 
			
		||||
 | 
			
		||||
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 */
 | 
			
		||||
@@ -59,7 +539,7 @@ int rsl_ipacc_crcx(struct gsm_lchan *lchan);
 | 
			
		||||
int rsl_ipacc_mdcx(struct gsm_lchan *lchan, u_int32_t ip,
 | 
			
		||||
		   u_int16_t port, u_int8_t rtp_payload2);
 | 
			
		||||
int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan);
 | 
			
		||||
int rsl_ipacc_pdch_activate(struct gsm_lchan *lchan, int act);
 | 
			
		||||
int rsl_ipacc_pdch_activate(struct gsm_lchan *lchan);
 | 
			
		||||
 | 
			
		||||
int abis_rsl_rcvmsg(struct msgb *msg);
 | 
			
		||||
 | 
			
		||||
@@ -68,16 +548,12 @@ unsigned int get_paging_group(u_int64_t imsi, unsigned int bs_cc_chans,
 | 
			
		||||
unsigned int n_pag_blocks(int bs_ccch_sdcch_comb, unsigned int bs_ag_blks_res);
 | 
			
		||||
u_int64_t str_to_imsi(const char *imsi_str);
 | 
			
		||||
u_int8_t lchan2chan_nr(const struct gsm_lchan *lchan);
 | 
			
		||||
int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id, u_int8_t release_reason);
 | 
			
		||||
 | 
			
		||||
int rsl_lchan_set_state(struct gsm_lchan *lchan, int);
 | 
			
		||||
 | 
			
		||||
int rsl_lchan_set_state(struct gsm_lchan *lchan, int);
 | 
			
		||||
int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id);
 | 
			
		||||
 | 
			
		||||
/* to be provided by external code */
 | 
			
		||||
int abis_rsl_sendmsg(struct msgb *msg);
 | 
			
		||||
int rsl_deact_sacch(struct gsm_lchan *lchan);
 | 
			
		||||
int rsl_lchan_rll_release(struct gsm_lchan *lchan, u_int8_t link_id);
 | 
			
		||||
int rsl_chan_release(struct gsm_lchan *lchan);
 | 
			
		||||
 | 
			
		||||
/* BCCH related code */
 | 
			
		||||
int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf);
 | 
			
		||||
 
 | 
			
		||||
@@ -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,6 +0,0 @@
 | 
			
		||||
/* GSM 08.08 like API for OpenBSC */
 | 
			
		||||
 | 
			
		||||
#include "gsm_data.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int gsm0808_submit_dtap(struct gsm_subscriber_connection *conn, struct msgb *msg, int link_id);
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
/* 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
 | 
			
		||||
 * (C) 2010 by on-waves.com
 | 
			
		||||
 * All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
@@ -23,29 +23,8 @@
 | 
			
		||||
#ifndef BSC_MSC_H
 | 
			
		||||
#define BSC_MSC_H
 | 
			
		||||
 | 
			
		||||
#include <osmocore/write_queue.h>
 | 
			
		||||
#include <osmocore/timer.h>
 | 
			
		||||
#include "select.h"
 | 
			
		||||
 | 
			
		||||
struct bsc_msc_connection {
 | 
			
		||||
	struct write_queue write_queue;
 | 
			
		||||
	int is_connected;
 | 
			
		||||
	int is_authenticated;
 | 
			
		||||
	const char *ip;
 | 
			
		||||
	int port;
 | 
			
		||||
	int prio;
 | 
			
		||||
 | 
			
		||||
	void (*connection_loss) (struct bsc_msc_connection *);
 | 
			
		||||
	void (*connected) (struct bsc_msc_connection *);
 | 
			
		||||
	struct timer_list reconnect_timer;
 | 
			
		||||
	struct timer_list timeout_timer;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct bsc_msc_connection *bsc_msc_create(const char *ip, int port, int prio);
 | 
			
		||||
int bsc_msc_connect(struct bsc_msc_connection *);
 | 
			
		||||
void bsc_msc_schedule_connect(struct bsc_msc_connection *);
 | 
			
		||||
 | 
			
		||||
void bsc_msc_lost(struct bsc_msc_connection *);
 | 
			
		||||
 | 
			
		||||
struct msgb *bsc_msc_id_get_resp(const char *token);
 | 
			
		||||
int connect_to_msc(struct bsc_fd *fd, const char *ip, int port);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +0,0 @@
 | 
			
		||||
#ifndef BSC_MSC_RF
 | 
			
		||||
#define BSC_MSC_RF
 | 
			
		||||
 | 
			
		||||
#include <osmocore/write_queue.h>
 | 
			
		||||
 | 
			
		||||
struct gsm_network;
 | 
			
		||||
 | 
			
		||||
struct bsc_msc_rf {
 | 
			
		||||
	struct bsc_fd listen;
 | 
			
		||||
	struct gsm_network *gsm_network;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct bsc_msc_rf_conn {
 | 
			
		||||
	struct write_queue queue;
 | 
			
		||||
	struct gsm_network *gsm_network;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct bsc_msc_rf *bsc_msc_rf_create(const char *path, struct gsm_network *net);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
 | 
			
		||||
 * (C) 2010 by On-Waves
 | 
			
		||||
 * (C) 2010 by on-waves.com
 | 
			
		||||
 * All Rights Reserved
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
@@ -22,317 +22,12 @@
 | 
			
		||||
#ifndef BSC_NAT_H
 | 
			
		||||
#define BSC_NAT_H
 | 
			
		||||
 | 
			
		||||
#include "mgcp.h"
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sccp/sccp_types.h>
 | 
			
		||||
 | 
			
		||||
#include <osmocore/select.h>
 | 
			
		||||
#include <osmocore/msgb.h>
 | 
			
		||||
#include <osmocore/timer.h>
 | 
			
		||||
#include <osmocore/write_queue.h>
 | 
			
		||||
#include <osmocore/statistics.h>
 | 
			
		||||
 | 
			
		||||
#include <regex.h>
 | 
			
		||||
 | 
			
		||||
#define DIR_BSC 1
 | 
			
		||||
#define DIR_MSC 2
 | 
			
		||||
 | 
			
		||||
#define NAT_IPAC_PROTO_MGCP	0xfc
 | 
			
		||||
 | 
			
		||||
struct bsc_nat;
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
	NAT_CON_TYPE_NONE,
 | 
			
		||||
	NAT_CON_TYPE_LU,
 | 
			
		||||
	NAT_CON_TYPE_CM_SERV_REQ,
 | 
			
		||||
	NAT_CON_TYPE_PAG_RESP,
 | 
			
		||||
	NAT_CON_TYPE_LOCAL_REJECT,
 | 
			
		||||
	NAT_CON_TYPE_OTHER,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * For the NAT we will need to analyze and later patch
 | 
			
		||||
 * the received message. This would require us to parse
 | 
			
		||||
 * the IPA and SCCP header twice. Instead of doing this
 | 
			
		||||
 * we will have one analyze structure and have the patching
 | 
			
		||||
 * and filter operate on the same structure.
 | 
			
		||||
 */
 | 
			
		||||
struct bsc_nat_parsed {
 | 
			
		||||
	/* ip access prototype */
 | 
			
		||||
	int ipa_proto;
 | 
			
		||||
 | 
			
		||||
	/* source local reference */
 | 
			
		||||
	struct sccp_source_reference *src_local_ref;
 | 
			
		||||
 | 
			
		||||
	/* destination local reference */
 | 
			
		||||
	struct sccp_source_reference *dest_local_ref;
 | 
			
		||||
 | 
			
		||||
	/* called ssn number */
 | 
			
		||||
	int called_ssn;
 | 
			
		||||
 | 
			
		||||
	/* calling ssn number */
 | 
			
		||||
	int calling_ssn;
 | 
			
		||||
 | 
			
		||||
	/* sccp message type */
 | 
			
		||||
	int sccp_type;
 | 
			
		||||
 | 
			
		||||
	/* bssap type, e.g. 0 for BSS Management */
 | 
			
		||||
	int bssap;
 | 
			
		||||
 | 
			
		||||
	/* the gsm0808 message type */
 | 
			
		||||
	int gsm_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Per BSC data structure
 | 
			
		||||
 */
 | 
			
		||||
struct bsc_connection {
 | 
			
		||||
	struct llist_head list_entry;
 | 
			
		||||
 | 
			
		||||
	/* do we know anything about this BSC? */
 | 
			
		||||
	int authenticated;
 | 
			
		||||
 | 
			
		||||
	/* the fd we use to communicate */
 | 
			
		||||
	struct write_queue write_queue;
 | 
			
		||||
 | 
			
		||||
	/* the BSS associated */
 | 
			
		||||
	struct bsc_config *cfg;
 | 
			
		||||
 | 
			
		||||
	/* a timeout node */
 | 
			
		||||
	struct timer_list id_timeout;
 | 
			
		||||
 | 
			
		||||
	/* pong timeout */
 | 
			
		||||
	struct timer_list ping_timeout;
 | 
			
		||||
	struct timer_list pong_timeout;
 | 
			
		||||
 | 
			
		||||
	/* a back pointer */
 | 
			
		||||
	struct bsc_nat *nat;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Per SCCP source local reference patch table. It needs to
 | 
			
		||||
 * be updated on new SCCP connections, connection confirm and reject,
 | 
			
		||||
 * and on the loss of the BSC connection.
 | 
			
		||||
 */
 | 
			
		||||
struct sccp_connections {
 | 
			
		||||
	struct llist_head list_entry;
 | 
			
		||||
 | 
			
		||||
	struct bsc_connection *bsc;
 | 
			
		||||
 | 
			
		||||
	struct sccp_source_reference real_ref;
 | 
			
		||||
	struct sccp_source_reference patched_ref;
 | 
			
		||||
	struct sccp_source_reference remote_ref;
 | 
			
		||||
	int has_remote_ref;
 | 
			
		||||
 | 
			
		||||
	/* status */
 | 
			
		||||
	int con_type;
 | 
			
		||||
	int con_local;
 | 
			
		||||
 | 
			
		||||
	/* GSM audio handling. That is 32 * multiplex + ts */
 | 
			
		||||
	int crcx;
 | 
			
		||||
	int msc_timeslot;
 | 
			
		||||
	int bsc_timeslot;
 | 
			
		||||
 | 
			
		||||
	/* timeout handling */
 | 
			
		||||
	struct timespec creation_time;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Stats per BSC
 | 
			
		||||
 */
 | 
			
		||||
struct bsc_config_stats {
 | 
			
		||||
	struct {
 | 
			
		||||
		struct counter *conn;
 | 
			
		||||
		struct counter *calls;
 | 
			
		||||
	} sccp;
 | 
			
		||||
 | 
			
		||||
	struct {
 | 
			
		||||
		struct counter *reconn;
 | 
			
		||||
	} net;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * One BSC entry in the config
 | 
			
		||||
 */
 | 
			
		||||
struct bsc_config {
 | 
			
		||||
	struct llist_head entry;
 | 
			
		||||
 | 
			
		||||
	char *token;
 | 
			
		||||
	unsigned int lac;
 | 
			
		||||
	int nr;
 | 
			
		||||
 | 
			
		||||
	char *description;
 | 
			
		||||
 | 
			
		||||
	/* imsi white and blacklist */
 | 
			
		||||
	char *acc_lst_name;
 | 
			
		||||
 | 
			
		||||
	int forbid_paging;
 | 
			
		||||
 | 
			
		||||
	/* backpointer */
 | 
			
		||||
	struct bsc_nat *nat;
 | 
			
		||||
 | 
			
		||||
	struct bsc_config_stats stats;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * BSCs point of view of endpoints
 | 
			
		||||
 */
 | 
			
		||||
struct bsc_endpoint {
 | 
			
		||||
	/* the pending transaction id */
 | 
			
		||||
	char *transaction_id;
 | 
			
		||||
	/* the bsc we are talking to */
 | 
			
		||||
	struct bsc_connection *bsc;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Statistic for the nat.
 | 
			
		||||
 */
 | 
			
		||||
struct bsc_nat_statistics {
 | 
			
		||||
	struct {
 | 
			
		||||
		struct counter *conn;
 | 
			
		||||
		struct counter *calls;
 | 
			
		||||
	} sccp;
 | 
			
		||||
 | 
			
		||||
	struct {
 | 
			
		||||
		struct counter *reconn;
 | 
			
		||||
                struct counter *auth_fail;
 | 
			
		||||
	} bsc;
 | 
			
		||||
 | 
			
		||||
	struct {
 | 
			
		||||
		struct counter *reconn;
 | 
			
		||||
	} msc;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct bsc_nat_acc_lst {
 | 
			
		||||
	struct llist_head list;
 | 
			
		||||
 | 
			
		||||
	/* the name of the list */
 | 
			
		||||
	const char *name;
 | 
			
		||||
	struct llist_head fltr_list;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct bsc_nat_acc_lst_entry {
 | 
			
		||||
	struct llist_head list;
 | 
			
		||||
 | 
			
		||||
	/* the filter */
 | 
			
		||||
	char *imsi_allow;
 | 
			
		||||
	regex_t imsi_allow_re;
 | 
			
		||||
	char *imsi_deny;
 | 
			
		||||
	regex_t imsi_deny_re;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * the structure of the "nat" network
 | 
			
		||||
 */
 | 
			
		||||
struct bsc_nat {
 | 
			
		||||
	/* active SCCP connections that need patching */
 | 
			
		||||
	struct llist_head sccp_connections;
 | 
			
		||||
 | 
			
		||||
	/* active BSC connections that need patching */
 | 
			
		||||
	struct llist_head bsc_connections;
 | 
			
		||||
 | 
			
		||||
	/* access lists */
 | 
			
		||||
	struct llist_head access_lists;
 | 
			
		||||
 | 
			
		||||
	/* known BSC's */
 | 
			
		||||
	struct llist_head bsc_configs;
 | 
			
		||||
	int num_bsc;
 | 
			
		||||
	int bsc_ip_tos;
 | 
			
		||||
 | 
			
		||||
	/* MGCP config */
 | 
			
		||||
	struct mgcp_config *mgcp_cfg;
 | 
			
		||||
	struct write_queue mgcp_queue;
 | 
			
		||||
	u_int8_t mgcp_msg[4096];
 | 
			
		||||
	int mgcp_length;
 | 
			
		||||
 | 
			
		||||
	/* msc things */
 | 
			
		||||
	char *msc_ip;
 | 
			
		||||
	int msc_port;
 | 
			
		||||
	int first_contact;
 | 
			
		||||
	struct bsc_msc_connection *msc_con;
 | 
			
		||||
	char *token;
 | 
			
		||||
 | 
			
		||||
	/* timeouts */
 | 
			
		||||
	int auth_timeout;
 | 
			
		||||
	int ping_timeout;
 | 
			
		||||
	int pong_timeout;
 | 
			
		||||
 | 
			
		||||
	struct bsc_endpoint *bsc_endpoints;
 | 
			
		||||
 | 
			
		||||
	/* filter */
 | 
			
		||||
	char *acc_lst_name;
 | 
			
		||||
 | 
			
		||||
	/* statistics */
 | 
			
		||||
	struct bsc_nat_statistics stats;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* create and init the structures */
 | 
			
		||||
struct bsc_config *bsc_config_alloc(struct bsc_nat *nat, const char *token, unsigned int lac);
 | 
			
		||||
struct bsc_config *bsc_config_num(struct bsc_nat *nat, int num);
 | 
			
		||||
struct bsc_nat *bsc_nat_alloc(void);
 | 
			
		||||
struct bsc_connection *bsc_connection_alloc(struct bsc_nat *nat);
 | 
			
		||||
void bsc_nat_set_msc_ip(struct bsc_nat *bsc, const char *ip);
 | 
			
		||||
 | 
			
		||||
void sccp_connection_destroy(struct sccp_connections *);
 | 
			
		||||
void bsc_close_connection(struct bsc_connection *);
 | 
			
		||||
 | 
			
		||||
const char *bsc_con_type_to_string(int type);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * parse the given message into the above structure
 | 
			
		||||
 */
 | 
			
		||||
struct bsc_nat_parsed *bsc_nat_parse(struct msgb *msg);
 | 
			
		||||
#include "msgb.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * filter based on IP Access header in both directions
 | 
			
		||||
 */
 | 
			
		||||
int bsc_nat_filter_ipa(int direction, struct msgb *msg, struct bsc_nat_parsed *parsed);
 | 
			
		||||
int bsc_nat_vty_init(struct bsc_nat *nat);
 | 
			
		||||
struct bsc_connection *bsc_nat_find_bsc(struct bsc_nat *nat, struct msgb *msg, int *_lac);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Content filtering.
 | 
			
		||||
 */
 | 
			
		||||
int bsc_nat_filter_sccp_cr(struct bsc_connection *bsc, struct msgb *msg,
 | 
			
		||||
			   struct bsc_nat_parsed *, int *con_type);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SCCP patching and handling
 | 
			
		||||
 */
 | 
			
		||||
struct sccp_connections *create_sccp_src_ref(struct bsc_connection *bsc, struct bsc_nat_parsed *parsed);
 | 
			
		||||
int update_sccp_src_ref(struct sccp_connections *sccp, struct bsc_nat_parsed *parsed);
 | 
			
		||||
void remove_sccp_src_ref(struct bsc_connection *bsc, struct msgb *msg, struct bsc_nat_parsed *parsed);
 | 
			
		||||
struct sccp_connections *patch_sccp_src_ref_to_bsc(struct msgb *, struct bsc_nat_parsed *, struct bsc_nat *);
 | 
			
		||||
struct sccp_connections *patch_sccp_src_ref_to_msc(struct msgb *, struct bsc_nat_parsed *, struct bsc_connection *);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * MGCP/Audio handling
 | 
			
		||||
 */
 | 
			
		||||
int bsc_write_mgcp(struct bsc_connection *bsc, const u_int8_t *data, unsigned int length);
 | 
			
		||||
int bsc_mgcp_assign(struct sccp_connections *, struct msgb *msg);
 | 
			
		||||
void bsc_mgcp_init(struct sccp_connections *);
 | 
			
		||||
void bsc_mgcp_dlcx(struct sccp_connections *);
 | 
			
		||||
void bsc_mgcp_free_endpoints(struct bsc_nat *nat);
 | 
			
		||||
int bsc_mgcp_nat_init(struct bsc_nat *nat);
 | 
			
		||||
 | 
			
		||||
struct sccp_connections *bsc_mgcp_find_con(struct bsc_nat *, int endpoint_number);
 | 
			
		||||
struct msgb *bsc_mgcp_rewrite(char *input, int length, const char *ip, int port);
 | 
			
		||||
void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg);
 | 
			
		||||
 | 
			
		||||
void bsc_mgcp_clear_endpoints_for(struct bsc_connection *bsc);
 | 
			
		||||
int bsc_mgcp_parse_response(const char *str, int *code, char transaction[60]);
 | 
			
		||||
int bsc_mgcp_extract_ci(const char *resp);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int bsc_write(struct bsc_connection *bsc, struct msgb *msg, int id);
 | 
			
		||||
 | 
			
		||||
/* IMSI allow/deny handling */
 | 
			
		||||
void bsc_parse_reg(void *ctx, regex_t *reg, char **imsi, int argc, const char **argv);
 | 
			
		||||
struct bsc_nat_acc_lst *bsc_nat_acc_lst_find(struct bsc_nat *nat, const char *name);
 | 
			
		||||
struct bsc_nat_acc_lst *bsc_nat_acc_lst_get(struct bsc_nat *nat, const char *name);
 | 
			
		||||
void bsc_nat_acc_lst_delete(struct bsc_nat_acc_lst *lst);
 | 
			
		||||
 | 
			
		||||
struct bsc_nat_acc_lst_entry *bsc_nat_acc_lst_entry_create(struct bsc_nat_acc_lst *);
 | 
			
		||||
int bsc_nat_filter_ipa(struct msgb *msg);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include <osmocore/msgb.h>
 | 
			
		||||
#include <openbsc/msgb.h>
 | 
			
		||||
#include <openbsc/gsm_data.h>
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
@@ -326,6 +326,7 @@ 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*);
 | 
			
		||||
 
 | 
			
		||||
@@ -27,20 +27,20 @@
 | 
			
		||||
 * Refcounting for the lchan. If the refcount drops to zero
 | 
			
		||||
 * the channel will send a RSL release request.
 | 
			
		||||
 */
 | 
			
		||||
#define use_subscr_con(con) \
 | 
			
		||||
	do {	(con)->use_count++; \
 | 
			
		||||
		DEBUGP(DREF, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) increases usage to: %d\n", \
 | 
			
		||||
			(con)->lchan->ts->trx->bts->nr, (con)->lchan->ts->trx->nr, (con)->lchan->ts->nr, \
 | 
			
		||||
			(con)->lchan->nr, (con)->use_count); \
 | 
			
		||||
#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_subscr_con(con, reason) \
 | 
			
		||||
	do { (con)->use_count--; \
 | 
			
		||||
		DEBUGP(DREF, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) decreases usage to: %d\n", \
 | 
			
		||||
			(con)->lchan->ts->trx->bts->nr, (con)->lchan->ts->trx->nr, (con)->lchan->ts->nr, \
 | 
			
		||||
			(con)->lchan->nr, (con)->use_count); \
 | 
			
		||||
	    if ((con)->use_count <= 0) \
 | 
			
		||||
		_lchan_release((con)->lchan, reason); \
 | 
			
		||||
#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);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -63,27 +63,12 @@ struct gsm_lchan *lchan_find(struct gsm_bts *bts, struct gsm_subscriber *subscr)
 | 
			
		||||
struct gsm_lchan *lchan_for_subscr(struct gsm_subscriber *subscr);
 | 
			
		||||
 | 
			
		||||
/* Allocate a logical channel (SDCCH, TCH, ...) */
 | 
			
		||||
struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type, int allow_bigger);
 | 
			
		||||
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);
 | 
			
		||||
void lchan_reset(struct gsm_lchan *lchan);
 | 
			
		||||
 | 
			
		||||
/* internal.. do not use */
 | 
			
		||||
int _lchan_release(struct gsm_lchan *lchan, u_int8_t release_reason);
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
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, unsigned long long min_id);
 | 
			
		||||
struct gsm_sms *db_sms_get_unsent_by_subscr(struct gsm_network *net, unsigned long long min_subscr_id);
 | 
			
		||||
struct gsm_sms *db_sms_get_unsent(struct gsm_network *net, int min_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,58 @@
 | 
			
		||||
#ifndef _DEBUG_H
 | 
			
		||||
#define _DEBUG_H
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <osmocore/linuxlist.h>
 | 
			
		||||
 | 
			
		||||
#define DEBUG
 | 
			
		||||
#include <osmocore/logging.h>
 | 
			
		||||
 | 
			
		||||
/* 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,
 | 
			
		||||
	DNAT,
 | 
			
		||||
	Debug_LastEntry,
 | 
			
		||||
};
 | 
			
		||||
#define DRLL		0x0001
 | 
			
		||||
#define DCC		0x0002
 | 
			
		||||
#define DMM		0x0004
 | 
			
		||||
#define DRR		0x0008
 | 
			
		||||
#define DRSL		0x0010
 | 
			
		||||
#define DNM		0x0020
 | 
			
		||||
 | 
			
		||||
/* context */
 | 
			
		||||
#define BSC_CTX_LCHAN	0
 | 
			
		||||
#define BSC_CTX_SUBSCR	1
 | 
			
		||||
#define BSC_CTX_BTS	2
 | 
			
		||||
#define BSC_CTX_SCCP	3
 | 
			
		||||
#define DMNCC		0x0080
 | 
			
		||||
#define DSMS		0x0100
 | 
			
		||||
#define DPAG		0x0200
 | 
			
		||||
#define DMEAS		0x0400
 | 
			
		||||
 | 
			
		||||
/* target */
 | 
			
		||||
#define DMI		0x1000
 | 
			
		||||
#define DMIB		0x2000
 | 
			
		||||
#define DMUX		0x4000
 | 
			
		||||
#define DINP		0x8000
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
	//DEBUG_FILTER_ALL = 1 << 0,
 | 
			
		||||
	LOG_FILTER_IMSI = 1 << 1,
 | 
			
		||||
};
 | 
			
		||||
#define DSCCP		0x10000
 | 
			
		||||
#define DMSC		0x20000
 | 
			
		||||
 | 
			
		||||
void log_set_imsi_filter(struct log_target *target, const char *imsi);
 | 
			
		||||
#define DMGCP		0x40000
 | 
			
		||||
 | 
			
		||||
extern const struct log_info log_info;
 | 
			
		||||
#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 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...) 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 */
 | 
			
		||||
#define LOGL_INFO	3
 | 
			
		||||
#define LOGL_NOTICE	5	/* abnormal/unexpected condition */
 | 
			
		||||
#define LOGL_ERROR	7	/* error condition, requires user action */
 | 
			
		||||
#define LOGL_FATAL	8	/* fatal, program aborted */
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
@@ -66,8 +66,6 @@ struct e1inp_ts {
 | 
			
		||||
		struct {
 | 
			
		||||
			/* list of all signalling links on this TS */
 | 
			
		||||
			struct llist_head sign_links;
 | 
			
		||||
			/* delay for the queue */
 | 
			
		||||
			int delay;
 | 
			
		||||
			/* timer when to dequeue next frame */
 | 
			
		||||
			struct timer_list tx_timer;
 | 
			
		||||
		} sign;
 | 
			
		||||
@@ -95,7 +93,6 @@ struct e1inp_driver {
 | 
			
		||||
	struct llist_head list;
 | 
			
		||||
	const char *name;
 | 
			
		||||
	int (*want_write)(struct e1inp_ts *ts);
 | 
			
		||||
	int default_delay;
 | 
			
		||||
};	
 | 
			
		||||
 | 
			
		||||
struct e1inp_line {
 | 
			
		||||
 
 | 
			
		||||
@@ -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,15 +750,19 @@ struct gsm_trans;
 | 
			
		||||
void gsm0408_allow_everyone(int allow);
 | 
			
		||||
 | 
			
		||||
int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id);
 | 
			
		||||
enum gsm_chan_t get_ctype_by_chreq(struct gsm_network *bts, u_int8_t ra);
 | 
			
		||||
enum gsm_chreq_reason_t get_reason_by_chreq(u_int8_t ra, int neci);
 | 
			
		||||
void gsm_net_update_ctype(struct gsm_network *net);
 | 
			
		||||
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);
 | 
			
		||||
int gsm48_send_rr_ciph_mode(struct gsm_lchan *lchan, int want_imeisv);
 | 
			
		||||
@@ -44,16 +782,15 @@ 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_extract_mi(uint8_t *classmark2, int length, char *mi_string, uint8_t *mi_type);
 | 
			
		||||
int gsm48_paging_extract_mi(struct gsm48_pag_resp *pag, int length, char *mi_string, u_int8_t *mi_type);
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
int gsm48_lchan_modify(struct gsm_lchan *lchan, u_int8_t lchan_mode);
 | 
			
		||||
int gsm48_rx_rr_modif_ack(struct msgb *msg);
 | 
			
		||||
int gsm48_parse_meas_rep(struct gsm_meas_rep *rep, struct msgb *msg);
 | 
			
		||||
 | 
			
		||||
struct msgb *gsm48_create_mm_serv_rej(enum gsm48_reject_value value);
 | 
			
		||||
struct msgb *gsm48_create_loc_upd_rej(uint8_t cause);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -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 {
 | 
			
		||||
@@ -25,7 +205,7 @@ struct msgb;
 | 
			
		||||
 | 
			
		||||
int gsm0411_rcv_sms(struct msgb *msg, u_int8_t link_id);
 | 
			
		||||
 | 
			
		||||
int gsm411_send_sms_lchan(struct gsm_subscriber_connection *conn, struct gsm_sms *sms);
 | 
			
		||||
int gsm411_send_sms_lchan(struct gsm_lchan *lchan, struct gsm_sms *sms);
 | 
			
		||||
 | 
			
		||||
struct gsm_sms *sms_alloc(void);
 | 
			
		||||
void sms_free(struct gsm_sms *sms);
 | 
			
		||||
 
 | 
			
		||||
@@ -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,7 +3,20 @@
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
struct bsc_msc_connection;
 | 
			
		||||
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,
 | 
			
		||||
@@ -42,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
 | 
			
		||||
@@ -75,42 +87,18 @@ enum gsm_paging_event {
 | 
			
		||||
	GSM_PAGING_OOM,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum bts_gprs_mode {
 | 
			
		||||
	BTS_GPRS_NONE = 0,
 | 
			
		||||
	BTS_GPRS_GPRS = 1,
 | 
			
		||||
	BTS_GPRS_EGPRS = 2,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct msgb;
 | 
			
		||||
typedef int gsm_cbfn(unsigned int hooknum,
 | 
			
		||||
		     unsigned int event,
 | 
			
		||||
		     struct msgb *msg,
 | 
			
		||||
		     void *data, void *param);
 | 
			
		||||
 | 
			
		||||
/* communications link with a BTS */
 | 
			
		||||
struct gsm_bts_link {
 | 
			
		||||
	struct gsm_bts *bts;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct sccp_connection;
 | 
			
		||||
 | 
			
		||||
/* 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 gsm_lchan;
 | 
			
		||||
struct gsm_subscriber;
 | 
			
		||||
struct gsm_mncc;
 | 
			
		||||
@@ -129,7 +117,6 @@ struct bss_sccp_connection_data {
 | 
			
		||||
        struct timer_list T10;
 | 
			
		||||
 | 
			
		||||
	/* for SCCP ... */
 | 
			
		||||
	struct timer_list sccp_cc_timeout;
 | 
			
		||||
	struct timer_list sccp_it;
 | 
			
		||||
 | 
			
		||||
	/* audio handling */
 | 
			
		||||
@@ -142,9 +129,6 @@ struct bss_sccp_connection_data {
 | 
			
		||||
 | 
			
		||||
	struct llist_head sccp_queue;
 | 
			
		||||
	unsigned int sccp_queue_size;
 | 
			
		||||
 | 
			
		||||
	/* Active connections */
 | 
			
		||||
	struct llist_head active_connections;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define GSM0808_T10_VALUE	6, 0
 | 
			
		||||
@@ -199,35 +183,10 @@ 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_REL_ERR,	/* channel is in an error state */
 | 
			
		||||
	LCHAN_S_INACTIVE,	/* channel is set inactive */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* the per subscriber data for lchan */
 | 
			
		||||
struct gsm_subscriber_connection {
 | 
			
		||||
	/* To whom we are allocated at the moment */
 | 
			
		||||
	struct gsm_subscriber *subscr;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Operations that have a state and might be pending
 | 
			
		||||
	 */
 | 
			
		||||
	struct gsm_loc_updating_operation *loc_operation;
 | 
			
		||||
 | 
			
		||||
	/* use count. how many users use this channel */
 | 
			
		||||
	unsigned int use_count;
 | 
			
		||||
	int hand_off;
 | 
			
		||||
 | 
			
		||||
	/* Are we part of a special "silent" call */
 | 
			
		||||
	int silent_call;
 | 
			
		||||
 | 
			
		||||
	/* back pointers */
 | 
			
		||||
	struct gsm_lchan *lchan;
 | 
			
		||||
	struct gsm_bts *bts;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct gsm_lchan {
 | 
			
		||||
	/* The TS that we're part of */
 | 
			
		||||
	struct gsm_bts_trx_ts *ts;
 | 
			
		||||
@@ -251,22 +210,31 @@ struct gsm_lchan {
 | 
			
		||||
		u_int8_t key[MAX_A5_KEY_LEN];
 | 
			
		||||
	} encr;
 | 
			
		||||
 | 
			
		||||
	struct timer_list T3101;
 | 
			
		||||
	struct timer_list T3111;
 | 
			
		||||
	struct timer_list error_timer;
 | 
			
		||||
 | 
			
		||||
	/* AMR bits */
 | 
			
		||||
	struct gsm48_multi_rate_conf mr_conf;
 | 
			
		||||
	
 | 
			
		||||
	/* To whom we are allocated at the moment */
 | 
			
		||||
	struct gsm_subscriber *subscr;
 | 
			
		||||
 | 
			
		||||
	struct timer_list T3101;
 | 
			
		||||
 | 
			
		||||
	/* Established data link layer services */
 | 
			
		||||
	u_int8_t sapis[8];
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Operations that have a state and might be pending
 | 
			
		||||
	 */
 | 
			
		||||
	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;
 | 
			
		||||
 | 
			
		||||
	/* cache of last measurement reports on this lchan */
 | 
			
		||||
	struct gsm_meas_rep meas_rep[6];
 | 
			
		||||
	int meas_rep_idx;
 | 
			
		||||
@@ -284,14 +252,6 @@ struct gsm_lchan {
 | 
			
		||||
		u_int8_t speech_mode;
 | 
			
		||||
		struct rtp_socket *rtp_socket;
 | 
			
		||||
	} abis_ip;
 | 
			
		||||
 | 
			
		||||
	struct gsm_subscriber_connection conn;
 | 
			
		||||
 | 
			
		||||
	/* release reason */
 | 
			
		||||
	u_int8_t release_reason;
 | 
			
		||||
 | 
			
		||||
	/* timestamp */
 | 
			
		||||
	struct timeval alloc_time;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct gsm_e1_subslot {
 | 
			
		||||
@@ -303,7 +263,7 @@ struct gsm_e1_subslot {
 | 
			
		||||
	u_int8_t	e1_ts_ss;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define TS_F_PDCH_MODE	0x1000
 | 
			
		||||
#define BTS_TRX_F_ACTIVATED	0x0001
 | 
			
		||||
/* One Timeslot in a TRX */
 | 
			
		||||
struct gsm_bts_trx_ts {
 | 
			
		||||
	struct gsm_bts_trx *trx;
 | 
			
		||||
@@ -357,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 {
 | 
			
		||||
@@ -365,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 
 | 
			
		||||
 */
 | 
			
		||||
@@ -404,13 +358,10 @@ struct gsm_paging_request {
 | 
			
		||||
struct gsm_bts_paging_state {
 | 
			
		||||
	/* pending requests */
 | 
			
		||||
	struct llist_head pending_requests;
 | 
			
		||||
	struct gsm_paging_request *last_request;
 | 
			
		||||
	struct gsm_bts *bts;
 | 
			
		||||
 | 
			
		||||
	struct timer_list work_timer;
 | 
			
		||||
	struct timer_list credit_timer;
 | 
			
		||||
 | 
			
		||||
	/* free chans needed */
 | 
			
		||||
	int free_chans_need;
 | 
			
		||||
 | 
			
		||||
	/* load */
 | 
			
		||||
	u_int16_t available_slots;
 | 
			
		||||
@@ -423,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;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -448,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? */
 | 
			
		||||
@@ -515,24 +461,14 @@ struct gsm_bts {
 | 
			
		||||
 | 
			
		||||
	/* Not entirely sure how ip.access specific this is */
 | 
			
		||||
	struct {
 | 
			
		||||
		enum bts_gprs_mode mode;
 | 
			
		||||
		struct {
 | 
			
		||||
			struct gsm_nm_state nm_state;
 | 
			
		||||
			u_int16_t nsei;
 | 
			
		||||
			uint8_t timer[7];
 | 
			
		||||
		} nse;
 | 
			
		||||
		struct {
 | 
			
		||||
			struct gsm_nm_state nm_state;
 | 
			
		||||
			u_int16_t bvci;
 | 
			
		||||
			uint8_t timer[11];
 | 
			
		||||
		} cell;
 | 
			
		||||
		struct gsm_bts_gprs_nsvc nsvc[2];
 | 
			
		||||
		u_int8_t rac;
 | 
			
		||||
	} gprs;
 | 
			
		||||
 | 
			
		||||
	/* RACH NM values */
 | 
			
		||||
	int rach_b_thresh;
 | 
			
		||||
	int rach_ldavg_slots;
 | 
			
		||||
	
 | 
			
		||||
	/* transceivers */
 | 
			
		||||
	int num_trx;
 | 
			
		||||
@@ -542,52 +478,44 @@ 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;
 | 
			
		||||
	struct {
 | 
			
		||||
		struct counter *rf_fail;
 | 
			
		||||
		struct counter *rll_err;
 | 
			
		||||
	} chan;
 | 
			
		||||
	struct {
 | 
			
		||||
		struct counter *oml_fail;
 | 
			
		||||
		struct counter *rsl_fail;
 | 
			
		||||
	} bts;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum gsm_auth_policy {
 | 
			
		||||
@@ -668,23 +596,9 @@ struct gsm_network {
 | 
			
		||||
		enum rrlp_mode mode;
 | 
			
		||||
	} rrlp;
 | 
			
		||||
 | 
			
		||||
	enum gsm_chan_t ctype_by_chreq[16];
 | 
			
		||||
 | 
			
		||||
	/* Use a TCH for handling requests of type paging any */
 | 
			
		||||
	int pag_any_tch;
 | 
			
		||||
 | 
			
		||||
	/* a hack for On Waves. It must be signed */
 | 
			
		||||
	int32_t core_country_code;
 | 
			
		||||
	int32_t core_network_code;
 | 
			
		||||
 | 
			
		||||
	/* a simple token for this network... */
 | 
			
		||||
	char *bsc_token;
 | 
			
		||||
	char *msc_ip;
 | 
			
		||||
	int msc_port;
 | 
			
		||||
	int msc_prio;
 | 
			
		||||
	struct bsc_msc_connection *msc_con;
 | 
			
		||||
	int ping_timeout;
 | 
			
		||||
	int pong_timeout;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define SMS_HDR_SIZE	128
 | 
			
		||||
@@ -709,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);
 | 
			
		||||
 | 
			
		||||
@@ -727,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,
 | 
			
		||||
@@ -744,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;
 | 
			
		||||
 | 
			
		||||
@@ -781,15 +692,8 @@ const char *gsm_auth_policy_name(enum gsm_auth_policy policy);
 | 
			
		||||
enum rrlp_mode rrlp_mode_parse(const char *arg);
 | 
			
		||||
const char *rrlp_mode_name(enum rrlp_mode mode);
 | 
			
		||||
 | 
			
		||||
enum bts_gprs_mode bts_gprs_mode_parse(const char *arg);
 | 
			
		||||
const char *bts_gprs_mode_name(enum bts_gprs_mode mode);
 | 
			
		||||
 | 
			
		||||
void gsm_trx_lock_rf(struct gsm_bts_trx *trx, int locked);
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
@@ -88,8 +88,6 @@ 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;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,8 @@
 | 
			
		||||
/* Generic BTS - VTY code tries to allocate this BTS before type is known */
 | 
			
		||||
 | 
			
		||||
/* (C) 2010 by Daniel Willmann <daniel@totalueberwachung.de>
 | 
			
		||||
/* 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
 | 
			
		||||
 *
 | 
			
		||||
@@ -20,21 +22,20 @@
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef GSM_UTILS_H
 | 
			
		||||
#define GSM_UTILS_H
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
#include <openbsc/gsm_data.h>
 | 
			
		||||
#include <osmocore/tlv.h>
 | 
			
		||||
#include <openbsc/abis_nm.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);
 | 
			
		||||
 | 
			
		||||
static struct gsm_bts_model model_unknown = {
 | 
			
		||||
	.type = GSM_BTS_TYPE_UNKNOWN,
 | 
			
		||||
	.nm_att_tlvdef = {
 | 
			
		||||
		.def = {
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
};
 | 
			
		||||
int ms_pwr_ctl_lvl(enum gsm_band band, unsigned int dbm);
 | 
			
		||||
int ms_pwr_dbm(enum gsm_band band, u_int8_t lvl);
 | 
			
		||||
 | 
			
		||||
int bts_model_unknown_init(void)
 | 
			
		||||
{
 | 
			
		||||
	return gsm_bts_model_register(&model_unknown);
 | 
			
		||||
}
 | 
			
		||||
/* 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,61 +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);
 | 
			
		||||
 | 
			
		||||
int ipaccess_drop_oml(struct gsm_bts *bts);
 | 
			
		||||
int ipaccess_drop_rsl(struct gsm_bts_trx *trx);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 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,14 +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
 | 
			
		||||
@@ -48,94 +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);
 | 
			
		||||
typedef int (*mgcp_reset)(struct mgcp_config *cfg);
 | 
			
		||||
 | 
			
		||||
struct mgcp_config {
 | 
			
		||||
	/* common configuration */
 | 
			
		||||
	int source_port;
 | 
			
		||||
	char *local_ip;
 | 
			
		||||
	char *source_addr;
 | 
			
		||||
	char *bts_ip;
 | 
			
		||||
	char *call_agent_addr;
 | 
			
		||||
 | 
			
		||||
	/* default endpoint data */
 | 
			
		||||
	struct in_addr bts_in;
 | 
			
		||||
	char *audio_name;
 | 
			
		||||
	int audio_payload;
 | 
			
		||||
	int audio_loop;
 | 
			
		||||
	int early_bind;
 | 
			
		||||
	int rtp_base_port;
 | 
			
		||||
	int endp_tos;
 | 
			
		||||
 | 
			
		||||
	/* only used in forward mode */
 | 
			
		||||
	char *forward_ip;
 | 
			
		||||
	int forward_port;
 | 
			
		||||
 | 
			
		||||
	unsigned int last_call_id;
 | 
			
		||||
 | 
			
		||||
	/* endpoint configuration */
 | 
			
		||||
	unsigned int number_endpoints;
 | 
			
		||||
	struct mgcp_endpoint *endpoints;
 | 
			
		||||
 | 
			
		||||
	/* spec handling */
 | 
			
		||||
	int force_realloc;
 | 
			
		||||
 | 
			
		||||
	/* callback functionality */
 | 
			
		||||
	mgcp_change change_cb;
 | 
			
		||||
	mgcp_policy policy_cb;
 | 
			
		||||
	mgcp_reset reset_cb;
 | 
			
		||||
	void *data;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* 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_response_with_data(int code, const char *msg, const char *trans, const char *data);
 | 
			
		||||
 | 
			
		||||
/* adc helper */
 | 
			
		||||
static inline int mgcp_timeslot_to_endpoint(int multiplex, int timeslot)
 | 
			
		||||
{
 | 
			
		||||
	if (timeslot == 0)
 | 
			
		||||
		timeslot = 1;
 | 
			
		||||
	return timeslot + (31 * multiplex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1,78 +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;
 | 
			
		||||
 | 
			
		||||
	/* statistics */
 | 
			
		||||
	unsigned int in_bts;
 | 
			
		||||
	unsigned int in_remote;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define ENDPOINT_NUMBER(endp) abs(endp - endp->cfg->endpoints)
 | 
			
		||||
 | 
			
		||||
struct mgcp_msg_ptr {
 | 
			
		||||
	unsigned int start;
 | 
			
		||||
	unsigned int length;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int mgcp_analyze_header(struct mgcp_config *cfg, struct msgb *msg,
 | 
			
		||||
			struct mgcp_msg_ptr *ptr, int size,
 | 
			
		||||
			const char **transaction_id, struct mgcp_endpoint **endp);
 | 
			
		||||
int mgcp_send_dummy(struct mgcp_endpoint *endp);
 | 
			
		||||
 | 
			
		||||
#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);
 | 
			
		||||
@@ -43,7 +43,4 @@ void paging_request_stop(struct gsm_bts *bts, struct gsm_subscriber *subscr,
 | 
			
		||||
/* update paging load */
 | 
			
		||||
void paging_update_buffer_space(struct gsm_bts *bts, u_int16_t);
 | 
			
		||||
 | 
			
		||||
/* pending paging requests */
 | 
			
		||||
unsigned int paging_pending_requests_nr(struct gsm_bts *bts);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -71,7 +71,6 @@ enum gprs_nmo {
 | 
			
		||||
	GPRS_NMO_III	= 2,	/* no paging coordination */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* TS 04.60 12.24 */
 | 
			
		||||
struct gprs_cell_options {
 | 
			
		||||
	enum gprs_nmo nmo;
 | 
			
		||||
	/* T3168: wait for packet uplink assignment message */
 | 
			
		||||
@@ -80,16 +79,6 @@ struct gprs_cell_options {
 | 
			
		||||
	u_int32_t t3192;	/* in milliseconds */
 | 
			
		||||
	u_int32_t drx_timer_max;/* in seconds */
 | 
			
		||||
	u_int32_t bs_cv_max;
 | 
			
		||||
 | 
			
		||||
	u_int8_t ext_info_present;
 | 
			
		||||
	struct {
 | 
			
		||||
		u_int8_t egprs_supported;
 | 
			
		||||
			u_int8_t use_egprs_p_ch_req;
 | 
			
		||||
			u_int8_t bep_period;
 | 
			
		||||
		u_int8_t pfc_supported;
 | 
			
		||||
		u_int8_t dtm_supported;
 | 
			
		||||
		u_int8_t bss_paging_coordination;
 | 
			
		||||
	} ext_info;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* TS 04.60 Table 12.9.2 */
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -42,13 +41,11 @@ enum signal_subsystems {
 | 
			
		||||
	SS_SUBSCR,
 | 
			
		||||
	SS_SCALL,
 | 
			
		||||
	SS_GLOBAL,
 | 
			
		||||
	SS_CHALLOC,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* SS_PAGING signals */
 | 
			
		||||
enum signal_paging {
 | 
			
		||||
	S_PAGING_SUCCEEDED,
 | 
			
		||||
	S_PAGING_EXPIRED,
 | 
			
		||||
	S_PAGING_COMPLETED,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* SS_SMS signals */
 | 
			
		||||
@@ -72,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 */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -94,12 +88,6 @@ enum signal_lchan {
 | 
			
		||||
	S_LCHAN_MEAS_REP,		/* 08.58 Measurement Report */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* SS_CHALLOC signals */
 | 
			
		||||
enum signal_challoc {
 | 
			
		||||
	S_CHALLOC_ALLOC_FAIL,	/* allocation of lchan has failed */
 | 
			
		||||
	S_CHALLOC_FREED,	/* lchan has been successfully freed */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* SS_SUBSCR signals */
 | 
			
		||||
enum signal_subscr {
 | 
			
		||||
	S_SUBSCR_ATTACHED,
 | 
			
		||||
@@ -118,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;
 | 
			
		||||
@@ -132,15 +123,12 @@ struct scall_signal_data {
 | 
			
		||||
	void *data;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct ipacc_ack_signal_data {
 | 
			
		||||
	struct gsm_bts_trx *trx;
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
struct challoc_signal_data {
 | 
			
		||||
	struct gsm_bts *bts;
 | 
			
		||||
	struct gsm_lchan *lchan;
 | 
			
		||||
	enum gsm_chan_t type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#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 <openbsc/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 log_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 */
 | 
			
		||||
@@ -20,8 +20,8 @@ struct gsm_trans {
 | 
			
		||||
	/* To whom we belong, unique identifier of remote MM entity */
 | 
			
		||||
	struct gsm_subscriber *subscr;
 | 
			
		||||
 | 
			
		||||
	/* The associated connection we are using to transmit messages */
 | 
			
		||||
	struct gsm_subscriber_connection *conn;
 | 
			
		||||
	/* The LCHAN that we're currently using to transmit messages */
 | 
			
		||||
	struct gsm_lchan *lchan;
 | 
			
		||||
 | 
			
		||||
	/* reference from MNCC or other application */
 | 
			
		||||
	u_int32_t callref;
 | 
			
		||||
@@ -71,6 +71,6 @@ int trans_assign_trans_id(struct gsm_subscriber *subscr,
 | 
			
		||||
 | 
			
		||||
/* update all transactions to use a different LCHAN, e.g.
 | 
			
		||||
 * after handover has succeeded */
 | 
			
		||||
int trans_lchan_change(struct gsm_subscriber_connection *conn_old,
 | 
			
		||||
		       struct gsm_subscriber_connection *conn_new);
 | 
			
		||||
int trans_lchan_change(struct gsm_lchan *lchan_old,
 | 
			
		||||
		       struct gsm_lchan *lchan_new);
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -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,10 +0,0 @@
 | 
			
		||||
#ifndef OPENBSC_VTY_H
 | 
			
		||||
#define OPENBSC_VTY_H
 | 
			
		||||
 | 
			
		||||
struct gsm_network;
 | 
			
		||||
struct vty;
 | 
			
		||||
 | 
			
		||||
void openbsc_vty_add_cmds(void);
 | 
			
		||||
void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -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 {
 | 
			
		||||
@@ -94,7 +94,7 @@ struct sccp_connection {
 | 
			
		||||
 *   call sccp_system_incoming for incoming data (from the network)
 | 
			
		||||
 *   sccp will call outgoing whenever outgoing data exists
 | 
			
		||||
 */
 | 
			
		||||
int sccp_system_init(void (*outgoing)(struct msgb *data, void *ctx), void *context);
 | 
			
		||||
int sccp_system_init(int (*outgoing)(struct msgb *data, void *ctx), void *context);
 | 
			
		||||
int sccp_system_incoming(struct msgb *data);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -105,11 +105,6 @@ int sccp_connection_send_it(struct sccp_connection *connection);
 | 
			
		||||
int sccp_connection_close(struct sccp_connection *connection, int cause);
 | 
			
		||||
int sccp_connection_free(struct sccp_connection *connection);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * internal.. 
 | 
			
		||||
 */
 | 
			
		||||
int sccp_connection_force_free(struct sccp_connection *conn);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a new socket. Set your callbacks and then call bind to open
 | 
			
		||||
 * the connection.
 | 
			
		||||
@@ -148,11 +143,6 @@ extern const struct sockaddr_sccp sccp_ssn_bssap;
 | 
			
		||||
u_int32_t sccp_src_ref_to_int(struct sccp_source_reference *ref);
 | 
			
		||||
struct sccp_source_reference sccp_src_ref_from_int(u_int32_t);
 | 
			
		||||
 | 
			
		||||
struct msgb *sccp_create_refuse(struct sccp_source_reference *src_ref, int cause, uint8_t *data, int length);
 | 
			
		||||
struct msgb *sccp_create_cc(struct sccp_source_reference *src_ref, struct sccp_source_reference *dst_ref);
 | 
			
		||||
struct msgb *sccp_create_rlsd(struct sccp_source_reference *src_ref, struct sccp_source_reference *dst_ref, int cause);
 | 
			
		||||
struct msgb *sccp_create_dt1(struct sccp_source_reference *dst_ref, uint8_t *data, uint8_t len);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Below this are helper functions and structs for parsing SCCP messages
 | 
			
		||||
 */
 | 
			
		||||
 
 | 
			
		||||
@@ -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));
 | 
			
		||||
 | 
			
		||||
@@ -411,10 +391,4 @@ struct sccp_data_it {
 | 
			
		||||
	u_int8_t			credit;
 | 
			
		||||
} __attribute__((packed));
 | 
			
		||||
 | 
			
		||||
struct sccp_proto_err {
 | 
			
		||||
	u_int8_t			type;
 | 
			
		||||
	struct sccp_source_reference	destination_local_reference;
 | 
			
		||||
	u_int8_t			error_cause;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@
 | 
			
		||||
/* Create a new buffer.  Memory will be allocated in chunks of the given
 | 
			
		||||
   size.  If the argument is 0, the library will supply a reasonable
 | 
			
		||||
   default size suitable for buffering socket I/O. */
 | 
			
		||||
struct buffer *buffer_new(void *ctx, size_t);
 | 
			
		||||
struct buffer *buffer_new(size_t);
 | 
			
		||||
 | 
			
		||||
/* Free all data in the buffer. */
 | 
			
		||||
void buffer_reset(struct buffer *);
 | 
			
		||||
 
 | 
			
		||||
@@ -107,8 +107,6 @@ enum node_type {
 | 
			
		||||
	TS_NODE,
 | 
			
		||||
	SUBSCR_NODE,
 | 
			
		||||
	MGCP_NODE,
 | 
			
		||||
	NAT_NODE,
 | 
			
		||||
	BSC_NODE,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Node which has some commands and prompt string and configuration
 | 
			
		||||
@@ -358,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,29 +1,23 @@
 | 
			
		||||
INCLUDES = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
 | 
			
		||||
AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS)
 | 
			
		||||
AM_LDFLAGS = $(LIBOSMOCORE_LIBS)
 | 
			
		||||
INCLUDES = $(all_includes) -I$(top_srcdir)/include
 | 
			
		||||
AM_CFLAGS=-Wall
 | 
			
		||||
 | 
			
		||||
sbin_PROGRAMS = bsc_hack bs11_config ipaccess-find ipaccess-config \
 | 
			
		||||
                isdnsync bsc_mgcp ipaccess-proxy \
 | 
			
		||||
                bsc_msc_ip bsc_nat
 | 
			
		||||
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 meas_rep.c telnet_interface.c bsc_version.c bsc_api.c vty_interface_cmds.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 \
 | 
			
		||||
		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
 | 
			
		||||
                handover_logic.c handover_decision.c meas_rep.c
 | 
			
		||||
 | 
			
		||||
libvty_a_SOURCES = vty/buffer.c vty/command.c vty/vector.c vty/vty.c
 | 
			
		||||
 | 
			
		||||
@@ -32,28 +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_rf.c
 | 
			
		||||
		bsc_msc.c
 | 
			
		||||
bsc_msc_ip_LDADD = libbsc.a libvty.a libsccp.a
 | 
			
		||||
 | 
			
		||||
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_find_SOURCES = ipaccess/ipaccess-find.c
 | 
			
		||||
ipaccess_find_SOURCES = ipaccess-find.c select.c timer.c
 | 
			
		||||
 | 
			
		||||
ipaccess_config_SOURCES = ipaccess/ipaccess-config.c ipaccess/ipaccess-firmware.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 vty_interface_cmds.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 nat/bsc_sccp.c \
 | 
			
		||||
		  nat/bsc_nat_utils.c nat/bsc_nat_vty.c nat/bsc_mgcp_utils.c \
 | 
			
		||||
		  mgcp/mgcp_protocol.c mgcp/mgcp_network.c mgcp/mgcp_vty.c \
 | 
			
		||||
		  bsc_msc.c bssap.c
 | 
			
		||||
bsc_nat_LDADD = libvty.a libbsc.a libsccp.a -lrt
 | 
			
		||||
bsc_nat_SOURCES = nat/bsc_nat.c nat/bsc_filter.c bsc_msc.c
 | 
			
		||||
bsc_nat_LDADD = libbsc.a libsccp.a
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,7 +1,7 @@
 | 
			
		||||
/* GSM Radio Signalling Link messages on the A-bis interface
 | 
			
		||||
/* 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];
 | 
			
		||||
	log_set_context(BSC_CTX_LCHAN, lchan);
 | 
			
		||||
	log_set_context(BSC_CTX_SUBSCR, lchan->conn.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]);
 | 
			
		||||
	for (i = 1; i < cause_len-1; i++) 
 | 
			
		||||
		DEBUGPC(DRSL, "%02x ", cause_v[i]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Send a BCCH_INFO message as per Chapter 8.5.1 */
 | 
			
		||||
@@ -245,7 +405,7 @@ int rsl_bcch_info(struct gsm_bts_trx *trx, u_int8_t type,
 | 
			
		||||
	return abis_rsl_sendmsg(msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int rsl_sacch_filling(struct gsm_bts_trx *trx, u_int8_t type,
 | 
			
		||||
int rsl_sacch_filling(struct gsm_bts_trx *trx, u_int8_t type, 
 | 
			
		||||
		      const u_int8_t *data, int len)
 | 
			
		||||
{
 | 
			
		||||
	struct abis_rsl_common_hdr *ch;
 | 
			
		||||
@@ -416,7 +576,7 @@ int rsl_chan_activate(struct gsm_bts_trx *trx, u_int8_t chan_nr,
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int rsl_chan_activate_lchan(struct gsm_lchan *lchan, u_int8_t act_type,
 | 
			
		||||
int rsl_chan_activate_lchan(struct gsm_lchan *lchan, u_int8_t act_type, 
 | 
			
		||||
			    u_int8_t ta, u_int8_t ho_ref)
 | 
			
		||||
{
 | 
			
		||||
	struct abis_rsl_dchan_hdr *dh;
 | 
			
		||||
@@ -563,38 +723,18 @@ 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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void error_timeout_cb(void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct gsm_lchan *lchan = data;
 | 
			
		||||
	if (lchan->state != LCHAN_S_REL_ERR) {
 | 
			
		||||
		LOGP(DRSL, LOGL_ERROR, "%s error timeout but not in error state: %d\n",
 | 
			
		||||
		     gsm_lchan_name(lchan), lchan->state);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* go back to the none state */
 | 
			
		||||
	LOGP(DRSL, LOGL_NOTICE, "%s is back in operation.\n", gsm_lchan_name(lchan));
 | 
			
		||||
	rsl_lchan_set_state(lchan, LCHAN_S_NONE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Chapter 8.4.14 / 4.7: Tell BTS to release the radio channel */
 | 
			
		||||
static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error)
 | 
			
		||||
int rsl_rf_chan_release(struct gsm_lchan *lchan)
 | 
			
		||||
{
 | 
			
		||||
	struct abis_rsl_dchan_hdr *dh;
 | 
			
		||||
	struct msgb *msg;
 | 
			
		||||
	struct msgb *msg = rsl_msgb_alloc();
 | 
			
		||||
 | 
			
		||||
	if (lchan->state == LCHAN_S_REL_ERR) {
 | 
			
		||||
		LOGP(DRSL, LOGL_NOTICE, "%s is in error state not sending release.\n",
 | 
			
		||||
		     gsm_lchan_name(lchan));
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	msg = rsl_msgb_alloc();
 | 
			
		||||
	dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
 | 
			
		||||
	init_dchan_hdr(dh, RSL_MT_RF_CHAN_REL);
 | 
			
		||||
	dh->chan_nr = lchan2chan_nr(lchan);
 | 
			
		||||
@@ -602,20 +742,8 @@ static int rsl_rf_chan_release(struct gsm_lchan *lchan, int error)
 | 
			
		||||
	msg->lchan = lchan;
 | 
			
		||||
	msg->trx = lchan->ts->trx;
 | 
			
		||||
 | 
			
		||||
	DEBUGP(DRSL, "%s RF Channel Release CMD due error %d\n", gsm_lchan_name(lchan), error);
 | 
			
		||||
 | 
			
		||||
	if (error) {
 | 
			
		||||
		/*
 | 
			
		||||
		 * the nanoBTS sends RLL release indications after the channel release. This can
 | 
			
		||||
		 * be a problem when we have reassigned the channel to someone else and then can
 | 
			
		||||
		 * not figure out who used this channel.
 | 
			
		||||
		 */
 | 
			
		||||
		rsl_lchan_set_state(lchan, LCHAN_S_REL_ERR);
 | 
			
		||||
		lchan->error_timer.data = lchan;
 | 
			
		||||
		lchan->error_timer.cb = error_timeout_cb;
 | 
			
		||||
		bsc_schedule_timer(&lchan->error_timer,
 | 
			
		||||
				   msg->trx->bts->network->T3111 + 2, 0);
 | 
			
		||||
	}
 | 
			
		||||
	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);
 | 
			
		||||
@@ -708,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;
 | 
			
		||||
 | 
			
		||||
@@ -721,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;
 | 
			
		||||
 | 
			
		||||
@@ -738,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);
 | 
			
		||||
@@ -752,29 +899,23 @@ int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id)
 | 
			
		||||
   RELEASE CONFIRM, which we in turn use to trigger RSL CHANNEL RELEASE,
 | 
			
		||||
   which in turn is acknowledged by RSL CHANNEL RELEASE ACK, which calls
 | 
			
		||||
   lchan_free() */
 | 
			
		||||
int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id, u_int8_t reason)
 | 
			
		||||
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);
 | 
			
		||||
        /* 0 is normal release, 1 is local end */
 | 
			
		||||
	msgb_tv_put(msg, RSL_IE_RELEASE_MODE, reason);
 | 
			
		||||
 | 
			
		||||
	/* FIXME: start some timer in case we don't receive a REL ACK ? */
 | 
			
		||||
	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 */
 | 
			
		||||
 | 
			
		||||
	msg->trx = lchan->ts->trx;
 | 
			
		||||
 | 
			
		||||
	return abis_rsl_sendmsg(msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int rsl_lchan_set_state(struct gsm_lchan *lchan, int state)
 | 
			
		||||
{
 | 
			
		||||
	lchan->state = state;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Chapter 8.4.2: Channel Activate Acknowledge */
 | 
			
		||||
static int rsl_rx_chan_act_ack(struct msgb *msg)
 | 
			
		||||
{
 | 
			
		||||
@@ -785,11 +926,7 @@ 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));
 | 
			
		||||
	rsl_lchan_set_state(msg->lchan, LCHAN_S_ACTIVE);
 | 
			
		||||
	msg->lchan->state = LCHAN_S_ACTIVE;
 | 
			
		||||
 | 
			
		||||
	dispatch_signal(SS_LCHAN, S_LCHAN_ACTIVATE_ACK, msg->lchan);
 | 
			
		||||
 | 
			
		||||
@@ -802,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)
 | 
			
		||||
			rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
 | 
			
		||||
	} else
 | 
			
		||||
		rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
 | 
			
		||||
 | 
			
		||||
	LOGPC(DRSL, LOGL_ERROR, "\n");
 | 
			
		||||
	msg->lchan->state = LCHAN_S_NONE;
 | 
			
		||||
 | 
			
		||||
	dispatch_signal(SS_LCHAN, S_LCHAN_ACTIVATE_NACK, msg->lchan);
 | 
			
		||||
 | 
			
		||||
@@ -834,19 +963,16 @@ 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 */
 | 
			
		||||
	counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rf_fail);
 | 
			
		||||
	return rsl_rf_chan_release(msg->lchan, 1);
 | 
			
		||||
	return rsl_rf_chan_release(msg->lchan);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void print_meas_rep_uni(struct gsm_meas_rep_unidir *mru,
 | 
			
		||||
@@ -894,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));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -910,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_DEBUG, "%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;
 | 
			
		||||
@@ -975,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));
 | 
			
		||||
 | 
			
		||||
@@ -997,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:
 | 
			
		||||
@@ -1017,36 +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 && msg->lchan->state != LCHAN_S_REL_ERR)
 | 
			
		||||
			LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state %s\n",
 | 
			
		||||
				gsm_lchan_name(msg->lchan),
 | 
			
		||||
				gsm_lchans_name(msg->lchan->state));
 | 
			
		||||
		bsc_del_timer(&msg->lchan->T3111);
 | 
			
		||||
		/* we have an error timer pending to release that */
 | 
			
		||||
		if (msg->lchan->state != LCHAN_S_REL_ERR)
 | 
			
		||||
			rsl_lchan_set_state(msg->lchan, LCHAN_S_NONE);
 | 
			
		||||
		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);
 | 
			
		||||
		msg->lchan->ts->flags |= TS_F_PDCH_MODE;
 | 
			
		||||
		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);
 | 
			
		||||
		msg->lchan->ts->flags &= ~TS_F_PDCH_MODE;
 | 
			
		||||
		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:
 | 
			
		||||
@@ -1056,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;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -1073,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");
 | 
			
		||||
@@ -1097,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));
 | 
			
		||||
		/* indicate CCCH / ACCH / processor overload */ 
 | 
			
		||||
		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;
 | 
			
		||||
@@ -1117,15 +1234,7 @@ static void t3101_expired(void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct gsm_lchan *lchan = data;
 | 
			
		||||
 | 
			
		||||
	rsl_rf_chan_release(lchan, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* If T3111 expires, we will send the RF Channel Request */
 | 
			
		||||
static void t3111_expired(void *data)
 | 
			
		||||
{
 | 
			
		||||
	struct gsm_lchan *lchan = data;
 | 
			
		||||
 | 
			
		||||
	rsl_rf_chan_release(lchan, 0);
 | 
			
		||||
	rsl_rf_chan_release(lchan);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* MS has requested a channel on the RACH */
 | 
			
		||||
@@ -1140,7 +1249,6 @@ static int rsl_rx_chan_rqd(struct msgb *msg)
 | 
			
		||||
	struct gsm_lchan *lchan;
 | 
			
		||||
	u_int8_t rqd_ta;
 | 
			
		||||
	int ret;
 | 
			
		||||
	int is_lu;
 | 
			
		||||
 | 
			
		||||
	u_int16_t arfcn;
 | 
			
		||||
	u_int8_t ts_number, subch;
 | 
			
		||||
@@ -1158,33 +1266,21 @@ static int rsl_rx_chan_rqd(struct msgb *msg)
 | 
			
		||||
 | 
			
		||||
	/* determine channel type (SDCCH/TCH_F/TCH_H) based on
 | 
			
		||||
	 * request reference RA */
 | 
			
		||||
	lctype = get_ctype_by_chreq(bts->network, rqd_ref->ra);
 | 
			
		||||
	chreq_reason = get_reason_by_chreq(rqd_ref->ra, bts->network->neci);
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * We want LOCATION UPDATES to succeed and will assign a TCH
 | 
			
		||||
	 * if we have no SDCCH available.
 | 
			
		||||
	 */
 | 
			
		||||
	is_lu = !!(chreq_reason == GSM_CHREQ_REASON_LOCATION_UPD);
 | 
			
		||||
	bts->network->stats.chreq.total++;
 | 
			
		||||
 | 
			
		||||
	/* check availability / allocate channel */
 | 
			
		||||
	lchan = lchan_alloc(bts, lctype, is_lu);
 | 
			
		||||
	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));
 | 
			
		||||
	rsl_lchan_set_state(lchan, LCHAN_S_ACT_REQ);
 | 
			
		||||
 | 
			
		||||
	ts_number = lchan->ts->nr;
 | 
			
		||||
	arfcn = lchan->ts->trx->arfcn;
 | 
			
		||||
	subch = lchan->nr;
 | 
			
		||||
@@ -1212,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 */
 | 
			
		||||
@@ -1240,10 +1337,6 @@ static int rsl_rx_ccch_load(struct msgb *msg)
 | 
			
		||||
	switch (rslh->data[0]) {
 | 
			
		||||
	case RSL_IE_PAGING_LOAD:
 | 
			
		||||
		pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
 | 
			
		||||
		if (is_ipaccess_bts(msg->trx->bts) && pg_buf_space == 0xffff) {
 | 
			
		||||
			/* paging load below configured threshold, use 50 as default */
 | 
			
		||||
			pg_buf_space = 50;
 | 
			
		||||
		}
 | 
			
		||||
		paging_update_buffer_space(msg->trx->bts, pg_buf_space);
 | 
			
		||||
		break;
 | 
			
		||||
	case RSL_IE_RACH_LOAD:
 | 
			
		||||
@@ -1297,47 +1390,17 @@ 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),
 | 
			
		||||
		rsl_rlm_cause_name(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) {
 | 
			
		||||
		counter_inc(msg->lchan->ts->trx->bts->network->stats.chan.rll_err);
 | 
			
		||||
		return rsl_rf_chan_release(msg->lchan, 1);
 | 
			
		||||
	}
 | 
			
		||||
		
 | 
			
		||||
	if (rlm_cause[1] == RLL_CAUSE_T200_EXPIRED)
 | 
			
		||||
		return rsl_rf_chan_release(msg->lchan);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void rsl_handle_release(struct gsm_lchan *lchan)
 | 
			
		||||
{
 | 
			
		||||
	int sapi;
 | 
			
		||||
	struct gsm_bts *bts;
 | 
			
		||||
 | 
			
		||||
	/* maybe we have only brought down one RLL */
 | 
			
		||||
	if (lchan->state != LCHAN_S_REL_REQ)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	for (sapi = 0; sapi < ARRAY_SIZE(lchan->sapis); ++sapi) {
 | 
			
		||||
		if (lchan->sapis[sapi] == LCHAN_SAPI_UNUSED)
 | 
			
		||||
			continue;
 | 
			
		||||
		LOGP(DRSL, LOGL_NOTICE, "%s waiting for SAPI=%d to be released.\n",
 | 
			
		||||
		     gsm_lchan_name(lchan), sapi);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/* wait a bit to send the RF Channel Release */
 | 
			
		||||
	lchan->T3111.cb = t3111_expired;
 | 
			
		||||
	lchan->T3111.data = lchan;
 | 
			
		||||
	bts = lchan->ts->trx->bts;
 | 
			
		||||
	bsc_schedule_timer(&lchan->T3111, bts->network->T3111, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*	ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST
 | 
			
		||||
/*	ESTABLISH INDICATION, LOCATION AREA UPDATE REQUEST 
 | 
			
		||||
	0x02, 0x06,
 | 
			
		||||
	0x01, 0x20,
 | 
			
		||||
	0x02, 0x00,
 | 
			
		||||
@@ -1351,13 +1414,14 @@ 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:
 | 
			
		||||
		DEBUGPC(DRLL, "DATA INDICATION\n");
 | 
			
		||||
		if (msgb_l2len(msg) >
 | 
			
		||||
		if (msgb_l2len(msg) > 
 | 
			
		||||
		    sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
 | 
			
		||||
		    rllh->data[0] == RSL_IE_L3_INFO) {
 | 
			
		||||
			msg->l3h = &rllh->data[3];
 | 
			
		||||
@@ -1369,7 +1433,7 @@ static int abis_rsl_rx_rll(struct msgb *msg)
 | 
			
		||||
		/* lchan is established, stop T3101 */
 | 
			
		||||
		msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_MS;
 | 
			
		||||
		bsc_del_timer(&msg->lchan->T3101);
 | 
			
		||||
		if (msgb_l2len(msg) >
 | 
			
		||||
		if (msgb_l2len(msg) > 
 | 
			
		||||
		    sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
 | 
			
		||||
		    rllh->data[0] == RSL_IE_L3_INFO) {
 | 
			
		||||
			msg->l3h = &rllh->data[3];
 | 
			
		||||
@@ -1388,16 +1452,20 @@ static int abis_rsl_rx_rll(struct msgb *msg)
 | 
			
		||||
		msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
 | 
			
		||||
		rll_indication(msg->lchan, rllh->link_id,
 | 
			
		||||
				  BSC_RLLR_IND_REL_IND);
 | 
			
		||||
		rsl_handle_release(msg->lchan);
 | 
			
		||||
		rsl_lchan_rll_release(msg->lchan, rllh->link_id);
 | 
			
		||||
		/* we can now releae the channel on the BTS/Abis side */
 | 
			
		||||
		/* FIXME: officially we need to start T3111 and wait for
 | 
			
		||||
		 * some grace period */
 | 
			
		||||
		rsl_rf_chan_release(msg->lchan);
 | 
			
		||||
		break;
 | 
			
		||||
	case RSL_MT_REL_CONF:
 | 
			
		||||
		/* BTS informs us of having received UA from MS,
 | 
			
		||||
		 * in response to DISC that we've sent earlier */
 | 
			
		||||
		DEBUGPC(DRLL, "RELEASE CONFIRMATION\n");
 | 
			
		||||
		msg->lchan->sapis[rllh->link_id & 0x7] = LCHAN_SAPI_UNUSED;
 | 
			
		||||
		rsl_handle_release(msg->lchan);
 | 
			
		||||
		rsl_lchan_rll_release(msg->lchan, rllh->link_id);
 | 
			
		||||
		/* we can now releae the channel on the BTS/Abis side */
 | 
			
		||||
		/* FIXME: officially we need to start T3111 and wait for
 | 
			
		||||
		 * some grace period */
 | 
			
		||||
		rsl_rf_chan_release(msg->lchan);
 | 
			
		||||
		break;
 | 
			
		||||
	case RSL_MT_ERROR_IND:
 | 
			
		||||
		rc = rsl_rx_rll_err_ind(msg);
 | 
			
		||||
@@ -1498,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;
 | 
			
		||||
 | 
			
		||||
@@ -1528,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);
 | 
			
		||||
@@ -1560,24 +1630,18 @@ int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan)
 | 
			
		||||
	return rc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int rsl_ipacc_pdch_activate(struct gsm_lchan *lchan, int act)
 | 
			
		||||
int rsl_ipacc_pdch_activate(struct gsm_lchan *lchan)
 | 
			
		||||
{
 | 
			
		||||
	struct msgb *msg = rsl_msgb_alloc();
 | 
			
		||||
	struct abis_rsl_dchan_hdr *dh;
 | 
			
		||||
	u_int8_t msg_type;
 | 
			
		||||
 | 
			
		||||
	if (act)
 | 
			
		||||
		msg_type = RSL_MT_IPAC_PDCH_ACT;
 | 
			
		||||
	else
 | 
			
		||||
		msg_type = RSL_MT_IPAC_PDCH_DEACT;
 | 
			
		||||
 | 
			
		||||
	dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
 | 
			
		||||
	init_dchan_hdr(dh, msg_type);
 | 
			
		||||
	init_dchan_hdr(dh, RSL_MT_IPAC_PDCH_ACT);
 | 
			
		||||
	dh->c.msg_discr = ABIS_RSL_MDISC_DED_CHAN;
 | 
			
		||||
	dh->chan_nr = lchan2chan_nr(lchan);
 | 
			
		||||
 | 
			
		||||
	DEBUGP(DRSL, "%s IPAC_PDCH_%sACT\n", gsm_lchan_name(lchan),
 | 
			
		||||
		act ? "" : "DE");
 | 
			
		||||
	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;
 | 
			
		||||
 | 
			
		||||
@@ -1658,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 */
 | 
			
		||||
@@ -1675,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;
 | 
			
		||||
	}
 | 
			
		||||
@@ -1763,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)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user