9
0
Fork 0

Import layer1 from osmocomBB (WIP: NOT COMPLETE)

The goal is to touch the code as less as possible.

The following files still had to be modified:
* The Makefiles to integrate it into nuttx
* The layer1's main.c was converted to command-line only:
  No more keyboard and GUI handling.

TODO:
* Finish importing the layer1
* See how to avoid duplication with misc/tools/osmocon/ headers
* Makefile: use $(TOPDIR) if necessary instead of always using ../
  ../ could be used some time only
* Kconfig for -DCONFIG_* ?
* GTA02 support

Signed-off-by: Denis 'GNUtoo' Carikli <GNUtoo@no-log.org>
This commit is contained in:
Denis 'GNUtoo' Carikli 2015-04-05 23:24:42 +02:00
parent 55a5cab48f
commit a2ce02f920
182 changed files with 17253 additions and 117 deletions

View File

@ -42,3 +42,7 @@ endmenu
menu "System Libraries and NSH Add-Ons"
source "$APPSDIR/system/Kconfig"
endmenu
menu "OsmocomBB (GPL)"
source "$APPSDIR/osmocomBB/Kconfig"
endmenu

View File

@ -49,7 +49,7 @@ TOPDIR ?= $(APPDIR)/import
CONFIGURED_APPS =
SUBDIRS = examples graphics interpreters modbus builtin import nshlib
SUBDIRS += netutils platform system
SUBDIRS += netutils platform system osmocomBB
# The list of configured directories is derived from NuttX configuration
# file: The selected applications are enabled settings in the configuration
@ -65,6 +65,7 @@ SUBDIRS += netutils platform system
include builtin/Make.defs
include examples/Make.defs
include osmocomBB/Make.defs
include graphics/Make.defs
include interpreters/Make.defs
include modbus/Make.defs

View File

@ -18,7 +18,6 @@ source "$APPSDIR/examples/djoystick/Kconfig"
source "$APPSDIR/examples/elf/Kconfig"
source "$APPSDIR/examples/ftpc/Kconfig"
source "$APPSDIR/examples/ftpd/Kconfig"
source "$APPSDIR/examples/hello/Kconfig"
source "$APPSDIR/examples/helloxx/Kconfig"
source "$APPSDIR/examples/json/Kconfig"
source "$APPSDIR/examples/hidkbd/Kconfig"

View File

@ -98,10 +98,6 @@ ifeq ($(CONFIG_EXAMPLES_FTPD),y)
CONFIGURED_APPS += examples/ftpd
endif
ifeq ($(CONFIG_EXAMPLES_HELLO),y)
CONFIGURED_APPS += examples/hello
endif
ifeq ($(CONFIG_EXAMPLES_HELLOXX),y)
CONFIGURED_APPS += examples/helloxx
endif

View File

@ -38,7 +38,7 @@
# Sub-directories
SUBDIRS = adc ajoystick bastest bridge buttons can cc3000 cpuhog cxxtest
SUBDIRS += dhcpd discover djoystick elf flash_test ftpc ftpd hello helloxx
SUBDIRS += dhcpd discover djoystick elf flash_test ftpc ftpd helloxx
SUBDIRS += hidkbd igmp i2schar json keypadtest lcdrw ltdc mm modbus mount
SUBDIRS += mtdpart mtdrwb netpkt nettest nrf24l01_term nsh null nx nxterm
SUBDIRS += nxffs nxflat nxhello nximage nxlines nxtext ostest pashello pipe
@ -55,7 +55,7 @@ CNTXTDIRS = pwm
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
CNTXTDIRS += adc ajoystick bridge can cc3000 cpuhog cxxtest dhcpd discover
CNTXTDIRS += djoystick flash_test ftpd hello helloxx i2schar json keypadtest
CNTXTDIRS += djoystick flash_test ftpd helloxx i2schar json keypadtest
CNTXTDIRS += ltdc modbus lcdrw mtdpart mtdrwb netpkt nettest nx nxhello
CNTXTDIRS += nximage nxlines nxtext nrf24l01_term ostest random relays
CNTXTDIRS += qencoder serialblasters lcd serialrx smart_test tcpecho telnetd

View File

@ -1,11 +0,0 @@
/Make.dep
/.depend
/.built
/*.asm
/*.obj
/*.rel
/*.lst
/*.sym
/*.adb
/*.lib
/*.src

View File

@ -1,22 +0,0 @@
#
# For a description of the syntax of this configuration file,
# see misc/tools/kconfig-language.txt.
#
config EXAMPLES_HELLO
bool "\"Hello, World!\" example"
default n
---help---
Enable the \"Hello, World!\" example
if EXAMPLES_HELLO
config EXAMPLES_HELLO_PROGNAME
string "Program name"
default "hello"
depends on BUILD_KERNEL
---help---
This is the name of the program that will be use when the NSH ELF
program is installed.
endif

View File

@ -1,67 +0,0 @@
/****************************************************************************
* examples/hello/hello_main.c
*
* Copyright (C) 2008, 2011-2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdio.h>
/****************************************************************************
* Definitions
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* hello_main
****************************************************************************/
#ifdef CONFIG_BUILD_KERNEL
int main(int argc, FAR char *argv[])
#else
int hello_main(int argc, char *argv[])
#endif
{
printf("Hello, World!!\n");
return 0;
}

339
apps/osmocomBB/COPYING Normal file
View File

@ -0,0 +1,339 @@
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.

6
apps/osmocomBB/Kconfig Normal file
View File

@ -0,0 +1,6 @@
#
# For a description of the syntax of this configuration file,
# see misc/tools/kconfig-language.txt.
#
source "$APPSDIR/osmocomBB/layer1/Kconfig"

39
apps/osmocomBB/Make.defs Normal file
View File

@ -0,0 +1,39 @@
############################################################################
# apps/examples/Make.defs
# Adds selected applications to apps/ build
#
# Copyright (C) 2012 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
ifeq ($(CONFIG_OSMOCOMBB_LAYER1),y)
CONFIGURED_APPS += osmocomBB/layer1
endif

78
apps/osmocomBB/Makefile Normal file
View File

@ -0,0 +1,78 @@
############################################################################
# apps/examples/Makefile
#
# Copyright (C) 2011-2014 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
# 3. Neither the name NuttX nor the names of its contributors may be
# used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
############################################################################
-include $(TOPDIR)/.config # Current configuration
# Sub-directories
SUBDIRS = layer1
# Sub-directories that might need context setup. Directories may need
# context setup for a variety of reasons, but the most common is because
# the example may be built as an NSH built-in function.
CNTXTDIRS =
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
CNTXTDIRS += layer1
endif
all: nothing
.PHONY: nothing context depend clean distclean
define SDIR_template
$(1)_$(2):
$(Q) $(MAKE) -C $(1) $(2) TOPDIR="$(TOPDIR)" APPDIR="$(APPDIR)"
endef
$(foreach SDIR, $(CNTXTDIRS), $(eval $(call SDIR_template,$(SDIR),context)))
$(foreach SDIR, $(SUBDIRS), $(eval $(call SDIR_template,$(SDIR),depend)))
$(foreach SDIR, $(SUBDIRS), $(eval $(call SDIR_template,$(SDIR),clean)))
$(foreach SDIR, $(SUBDIRS), $(eval $(call SDIR_template,$(SDIR),distclean)))
nothing:
install:
context: $(foreach SDIR, $(CNTXTDIRS), $(SDIR)_context)
depend: $(foreach SDIR, $(SUBDIRS), $(SDIR)_depend)
clean: $(foreach SDIR, $(SUBDIRS), $(SDIR)_clean)
distclean: $(foreach SDIR, $(SUBDIRS), $(SDIR)_distclean)
-include Make.dep

23
apps/osmocomBB/README.txt Normal file
View File

@ -0,0 +1,23 @@
nuttx osmocomBB
common src/target/firmware
include include/
Modified:
---------
nuttx osmocomBB
layer1/main.c apps/layer1/main.c
board/*/init.c apps/layer1/board/init.c
Deleted:
--------
osmocomBB/include/keypad.h -> Useless: we want to use nuttx's keypad infrastructure instead
osmocomBB/include/stdint.h -> To use nuttx's one
osmocomBB/include/memory.h -> To use compat.h instead
Already in nuttx:
-----------------
osmocomBB nuttx apps
msgb.h, linuxlist.h:
src/shared/libosmocore/include/osmocom/core/ misc/tools/osmocon/ apps/osmocomBB/libosmocore/include/osmocom/core

View File

@ -0,0 +1,19 @@
/* (C) 2014 by Denis 'GNUtoo' Carikli <GNUtoo@no-log.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.
*
*/

View File

@ -0,0 +1,32 @@
/* (C) 2014 by Denis 'GNUtoo' Carikli <GNUtoo@no-log.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 NUTTX_OSMOCOMBB_COMPAT_H
#define NUTTX_OSMOCOMBB_COMPAT_H
#define readb(a) getreg8(a)
#define readw(a) getreg16(a)
#define readl(a) getreg32(a)
#define writeb(v,a) putreg8(v,a)
#define writew(v,a) putreg16(v,a)
#define writel(v,a) putreg32(v,a)
#endif /* NUTTX_OSMOCOMBB_COMPAT_H */

View File

@ -0,0 +1,3 @@
#ifndef NUTTX_OSMOCOMBB_COMPAT_DUMMY_H
#define NUTTX_OSMOCOMBB_COMPAT_DUMMY_H
#endif /* NUTTX_OSMOCOMBB_COMPAT_DUMMY_H */

View File

@ -0,0 +1,303 @@
/* Messages to be sent between the different layers */
/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
* (C) 2010 by Holger Hans Peter Freyther
*
* 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 __L1CTL_PROTO_H__
#define __L1CTL_PROTO_H__
enum {
_L1CTL_NONE = 0,
L1CTL_FBSB_REQ,
L1CTL_FBSB_CONF,
L1CTL_DATA_IND,
L1CTL_RACH_REQ,
L1CTL_DM_EST_REQ,
L1CTL_DATA_REQ,
L1CTL_RESET_IND,
L1CTL_PM_REQ, /* power measurement */
L1CTL_PM_CONF, /* power measurement */
L1CTL_ECHO_REQ,
L1CTL_ECHO_CONF,
L1CTL_RACH_CONF,
L1CTL_RESET_REQ,
L1CTL_RESET_CONF,
L1CTL_DATA_CONF,
L1CTL_CCCH_MODE_REQ,
L1CTL_CCCH_MODE_CONF,
L1CTL_DM_REL_REQ,
L1CTL_PARAM_REQ,
L1CTL_DM_FREQ_REQ,
L1CTL_CRYPTO_REQ,
L1CTL_SIM_REQ,
L1CTL_SIM_CONF,
L1CTL_TCH_MODE_REQ,
L1CTL_TCH_MODE_CONF,
L1CTL_NEIGH_PM_REQ,
L1CTL_NEIGH_PM_IND,
L1CTL_TRAFFIC_REQ,
L1CTL_TRAFFIC_CONF,
L1CTL_TRAFFIC_IND,
};
enum ccch_mode {
CCCH_MODE_NONE = 0,
CCCH_MODE_NON_COMBINED,
CCCH_MODE_COMBINED,
};
enum neigh_mode {
NEIGH_MODE_NONE = 0,
NEIGH_MODE_PM,
NEIGH_MODE_SB,
};
#define TRAFFIC_DATA_LEN 40
/*
* NOTE: struct size. We do add manual padding out of the believe
* that it will avoid some unaligned access.
*/
/* there are no more messages in a sequence */
#define L1CTL_F_DONE 0x01
struct l1ctl_hdr {
uint8_t msg_type;
uint8_t flags;
uint8_t padding[2];
uint8_t data[0];
} __attribute__((packed));
/*
* downlink info ... down from the BTS..
*/
struct l1ctl_info_dl {
/* GSM 08.58 channel number (9.3.1) */
uint8_t chan_nr;
/* GSM 08.58 link identifier (9.3.2) */
uint8_t link_id;
/* the ARFCN and the band. FIXME: what about MAIO? */
uint16_t band_arfcn;
uint32_t frame_nr;
uint8_t rx_level; /* 0 .. 63 in typical GSM notation (dBm+110) */
uint8_t snr; /* Signal/Noise Ration (dB) */
uint8_t num_biterr;
uint8_t fire_crc;
uint8_t payload[0];
} __attribute__((packed));
/* new CCCH was found. This is following the header */
struct l1ctl_fbsb_conf {
int16_t initial_freq_err;
uint8_t result;
uint8_t bsic;
/* FIXME: contents of cell_info ? */
} __attribute__((packed));
/* CCCH mode was changed */
struct l1ctl_ccch_mode_conf {
uint8_t ccch_mode; /* enum ccch_mode */
uint8_t padding[3];
} __attribute__((packed));
/* TCH mode was changed */
struct l1ctl_tch_mode_conf {
uint8_t tch_mode; /* enum tch_mode */
uint8_t audio_mode;
uint8_t padding[2];
} __attribute__((packed));
/* data on the CCCH was found. This is following the header */
struct l1ctl_data_ind {
uint8_t data[23];
} __attribute__((packed));
/* traffic from the network */
struct l1ctl_traffic_ind {
uint8_t data[TRAFFIC_DATA_LEN];
} __attribute__((packed));
/*
* uplink info
*/
struct l1ctl_info_ul {
/* GSM 08.58 channel number (9.3.1) */
uint8_t chan_nr;
/* GSM 08.58 link identifier (9.3.2) */
uint8_t link_id;
uint8_t padding[2];
uint8_t payload[0];
} __attribute__((packed));
/*
* msg for FBSB_REQ
* the l1_info_ul header is in front
*/
struct l1ctl_fbsb_req {
uint16_t band_arfcn;
uint16_t timeout; /* in TDMA frames */
uint16_t freq_err_thresh1;
uint16_t freq_err_thresh2;
uint8_t num_freqerr_avg;
uint8_t flags; /* L1CTL_FBSB_F_* */
uint8_t sync_info_idx;
uint8_t ccch_mode; /* enum ccch_mode */
uint8_t rxlev_exp; /* expected signal level */
} __attribute__((packed));
#define L1CTL_FBSB_F_FB0 (1 << 0)
#define L1CTL_FBSB_F_FB1 (1 << 1)
#define L1CTL_FBSB_F_SB (1 << 2)
#define L1CTL_FBSB_F_FB01SB (L1CTL_FBSB_F_FB0|L1CTL_FBSB_F_FB1|L1CTL_FBSB_F_SB)
/*
* msg for CCCH_MODE_REQ
* the l1_info_ul header is in front
*/
struct l1ctl_ccch_mode_req {
uint8_t ccch_mode; /* enum ccch_mode */
uint8_t padding[3];
} __attribute__((packed));
/*
* msg for TCH_MODE_REQ
* the l1_info_ul header is in front
*/
struct l1ctl_tch_mode_req {
uint8_t tch_mode; /* enum gsm48_chan_mode */
#define AUDIO_TX_MICROPHONE (1<<0)
#define AUDIO_TX_TRAFFIC_REQ (1<<1)
#define AUDIO_RX_SPEAKER (1<<2)
#define AUDIO_RX_TRAFFIC_IND (1<<3)
uint8_t audio_mode;
uint8_t padding[2];
} __attribute__((packed));
/* the l1_info_ul header is in front */
struct l1ctl_rach_req {
uint8_t ra;
uint8_t combined;
uint16_t offset;
} __attribute__((packed));
/* the l1_info_ul header is in front */
struct l1ctl_par_req {
int8_t ta;
uint8_t tx_power;
uint8_t padding[2];
} __attribute__((packed));
struct l1ctl_h0 {
uint16_t band_arfcn;
} __attribute__((packed));
struct l1ctl_h1 {
uint8_t hsn;
uint8_t maio;
uint8_t n;
uint8_t _padding[1];
uint16_t ma[64];
} __attribute__((packed));
struct l1ctl_dm_est_req {
uint8_t tsc;
uint8_t h;
union {
struct l1ctl_h0 h0;
struct l1ctl_h1 h1;
};
uint8_t tch_mode;
uint8_t audio_mode;
} __attribute__((packed));
struct l1ctl_dm_freq_req {
uint16_t fn;
uint8_t tsc;
uint8_t h;
union {
struct l1ctl_h0 h0;
struct l1ctl_h1 h1;
};
} __attribute__((packed));
struct l1ctl_crypto_req {
uint8_t algo;
uint8_t key[0];
} __attribute__((packed));
struct l1ctl_pm_req {
uint8_t type;
uint8_t padding[3];
union {
struct {
uint16_t band_arfcn_from;
uint16_t band_arfcn_to;
} range;
};
} __attribute__((packed));
/* a single L1CTL_PM response */
struct l1ctl_pm_conf {
uint16_t band_arfcn;
uint8_t pm[2];
} __attribute__((packed));
enum l1ctl_reset_type {
L1CTL_RES_T_BOOT, /* only _IND */
L1CTL_RES_T_FULL,
L1CTL_RES_T_SCHED,
};
/* argument to L1CTL_RESET_REQ and L1CTL_RESET_IND */
struct l1ctl_reset {
uint8_t type;
uint8_t pad[3];
} __attribute__((packed));
struct l1ctl_neigh_pm_req {
uint8_t n;
uint8_t padding[1];
uint16_t band_arfcn[64];
uint8_t tn[64];
} __attribute__((packed));
/* neighbour cell measurement results */
struct l1ctl_neigh_pm_ind {
uint16_t band_arfcn;
uint8_t pm[2];
uint8_t tn;
uint8_t padding;
} __attribute__((packed));
/* traffic data to network */
struct l1ctl_traffic_req {
uint8_t data[TRAFFIC_DATA_LEN];
} __attribute__((packed));
#endif /* __L1CTL_PROTO_H__ */

View File

@ -0,0 +1,24 @@
#ifndef _OSMOCORE_RSL_H
#define _OSMOCORE_RSL_H
#include <stdint.h>
#include <osmocom/core/utils.h>
#include <osmocom/gsm/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);
const struct value_string rsl_rlm_cause_strs[];
const char *rsl_err_name(uint8_t err);
/* Section 3.3.2.3 TS 05.02. I think this looks like a table */
int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf);
#endif /* _OSMOCORE_RSL_H */

View File

@ -0,0 +1,17 @@
#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);
#endif

View File

@ -0,0 +1,22 @@
#
# For a description of the syntax of this configuration file,
# see misc/tools/kconfig-language.txt.
#
config OSMOCOMBB_LAYER1
bool "Layer1 GSM application"
default n
---help---
Layer1 GSM application
if OSMOCOMBB_LAYER1
config OSMOCOMBB_LAYER1_PROGNAME
string "Program name"
default "layer1"
depends on BUILD_KERNEL
---help---
This is the name of the program that will be use when the NSH ELF
program is installed.
endif

View File

@ -1,7 +1,7 @@
############################################################################
# apps/examples/hello/Makefile
# osmocomBB/Makefile
#
# Copyright (C) 2008, 2010-2013 Gregory Nutt. All rights reserved.
# Copyright (C) 2007-2008, 2010-2012 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
@ -37,22 +37,45 @@
-include $(TOPDIR)/Make.defs
include $(APPDIR)/Make.defs
# Hello, World! built-in application info
# osmocomBB GSM layer1 built-in application info
APPNAME = hello
APPNAME = layer1
PRIORITY = SCHED_PRIORITY_DEFAULT
STACKSIZE = 2048
# Hello, World! Example
# osmocomBB GSM layer1
ASRCS =
CSRCS =
MAINSRC = hello_main.c
CSRCS += \
../osmocomBB/calypso/misc.c \
ifeq ($(CONFIG_ARCH_BOARD_COMPALE86),y)
CSRCS += ../osmocomBB/board/compal_e86/init.c
endif
ifeq ($(CONFIG_ARCH_BOARD_COMPALE88),y)
CSRCS += ../osmocomBB/board/compal_e88/init.c
endif
ifeq ($(CONFIG_ARCH_BOARD_COMPALE99),y)
CSRCS += ../osmocomBB/board/compal_e99/init.c
endif
MAINSRC = layer1_main.c
AOBJS = $(ASRCS:.S=$(OBJEXT))
COBJS = $(CSRCS:.c=$(OBJEXT))
MAINOBJ = $(MAINSRC:.c=$(OBJEXT))
CFLAGS += -I../compat/include/
CFLAGS += -I../compat/include/dummy/
CFLAGS += -I../osmocomBB/include/
CFLAGS += -I../libosmocore/include/
CFLAGS += -I../include/
CFLAGS += -I../../../nuttx/include
CFLAGS += -I$(TOPDIR)/include/
CFLAGS += -I$(TOPDIR)/../misc/tools
SRCS = $(ASRCS) $(CSRCS) $(MAINSRC)
OBJS = $(AOBJS) $(COBJS)
@ -76,8 +99,8 @@ else
INSTALL_DIR = $(BIN_DIR)
endif
CONFIG_EXAMPLES_HELLO_PROGNAME ?= hello$(EXEEXT)
PROGNAME = $(CONFIG_EXAMPLES_HELLO_PROGNAME)
CONFIG_OSMOCOMBB_LAYER1_PROGNAME ?= layer1$(EXEEXT)
PROGNAME = $(CONFIG_OSMOCOMBB_LAYER1_PROGNAME)
ROOTDEPPATH = --dep-path .

View File

@ -0,0 +1,118 @@
/* main program of Free Software for Calypso Phone */
/* (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 <compat.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <rffe.h>
#include <board.h>
#include <abb/twl3025.h>
#include <rf/trf6151.h>
#include <calypso/clock.h>
#include <calypso/tpu.h>
#include <calypso/tsp.h>
#include <calypso/irq.h>
#include <calypso/misc.h>
#include <calypso/sim.h>
#include <layer1/sync.h>
#include <layer1/async.h>
#include <layer1/tpu_window.h>
#include <layer1/l23_api.h>
const char *hr = "======================================================================\n";
void board_io_init(void);
/* MAIN program **************************************************************/
#ifdef CONFIG_BUILD_KERNEL
int main(int argc, FAR char *argv[])
#else
int layer1_main(int argc, char *argv[])
#endif
{
uint8_t atr[20];
uint8_t atrLength = 0;
board_io_init();
/* Initialize DMA controller */
dma_init();
/* Initialize ABB driver (uses SPI) */
twl3025_init();
puts("\n\nOsmocomBB Layer 1 (Nuttx version)\n");
puts(hr);
/* Dump device identification */
dump_dev_id();
puts(hr);
/* Dump clock config after PLL set */
calypso_clk_dump();
puts(hr);
#if 0
/* initialize SIM */
calypso_sim_init();
#endif
puts("Power up simcard:\n");
memset(atr,0,sizeof(atr));
#if 0
atrLength = calypso_sim_powerup(atr);
layer1_init();
tpu_frame_irq_en(1, 1);
while (1) {
l1a_compl_execute();
osmo_timers_update();
sim_handler();
l1a_l23_handler();
}
/* NOT REACHED */
twl3025_power_off();
#endif
return 0;
}
static int afcout = 0;
static void tspact_toggle(uint8_t num)
{
printf("TSPACT%u toggle\n", num);
tsp_act_toggle((1 << num));
tpu_enq_sleep();
tpu_enable(1);
tpu_wait_idle();
}

View File

@ -0,0 +1,104 @@
nobase_include_HEADERS = \
osmocom/codec/codec.h \
osmocom/core/application.h \
osmocom/core/backtrace.h \
osmocom/core/bits.h \
osmocom/core/bitvec.h \
osmocom/core/conv.h \
osmocom/core/crc16.h \
osmocom/core/crc16gen.h \
osmocom/core/crc32gen.h \
osmocom/core/crc64gen.h \
osmocom/core/crc8gen.h \
osmocom/core/crcgen.h \
osmocom/core/gsmtap.h \
osmocom/core/gsmtap_util.h \
osmocom/core/linuxlist.h \
osmocom/core/linuxrbtree.h \
osmocom/core/logging.h \
osmocom/core/msgb.h \
osmocom/core/panic.h \
osmocom/core/prim.h \
osmocom/core/process.h \
osmocom/core/rate_ctr.h \
osmocom/core/select.h \
osmocom/core/signal.h \
osmocom/core/socket.h \
osmocom/core/statistics.h \
osmocom/core/timer.h \
osmocom/core/utils.h \
osmocom/core/write_queue.h \
osmocom/crypt/auth.h \
osmocom/crypt/gprs_cipher.h \
osmocom/gprs/gprs_bssgp.h \
osmocom/gprs/gprs_bssgp_bss.h \
osmocom/gprs/gprs_msgb.h \
osmocom/gprs/gprs_ns.h \
osmocom/gprs/gprs_ns_frgre.h \
osmocom/gprs/protocol/gsm_08_16.h \
osmocom/gprs/protocol/gsm_08_18.h \
osmocom/gsm/a5.h \
osmocom/gsm/abis_nm.h \
osmocom/gsm/comp128.h \
osmocom/gsm/gan.h \
osmocom/gsm/gsm0411_smc.h \
osmocom/gsm/gsm0411_smr.h \
osmocom/gsm/gsm0411_utils.h \
osmocom/gsm/gsm0480.h \
osmocom/gsm/gsm0502.h \
osmocom/gsm/gsm0808.h \
osmocom/gsm/gsm48.h \
osmocom/gsm/gsm48_ie.h \
osmocom/gsm/gsm_utils.h \
osmocom/gsm/lapd_core.h \
osmocom/gsm/lapdm.h \
osmocom/gsm/mncc.h \
osmocom/gsm/prim.h \
osmocom/gsm/protocol/gsm_03_41.h \
osmocom/gsm/protocol/gsm_04_08.h \
osmocom/gsm/protocol/gsm_04_11.h \
osmocom/gsm/protocol/gsm_04_12.h \
osmocom/gsm/protocol/gsm_04_80.h \
osmocom/gsm/protocol/gsm_08_08.h \
osmocom/gsm/protocol/gsm_08_58.h \
osmocom/gsm/protocol/gsm_12_21.h \
osmocom/gsm/protocol/gsm_44_318.h \
osmocom/gsm/protocol/ipaccess.h \
osmocom/gsm/rsl.h \
osmocom/gsm/rxlev_stat.h \
osmocom/gsm/sysinfo.h \
osmocom/gsm/tlv.h
if ENABLE_PLUGIN
nobase_include_HEADERS += osmocom/core/plugin.h
endif
if ENABLE_TALLOC
nobase_include_HEADERS += osmocom/core/talloc.h
endif
if ENABLE_MSGFILE
nobase_include_HEADERS += osmocom/core/msgfile.h
endif
if ENABLE_SERIAL
nobase_include_HEADERS += osmocom/core/serial.h
endif
if ENABLE_VTY
nobase_include_HEADERS += \
osmocom/vty/buffer.h \
osmocom/vty/command.h \
osmocom/vty/logging.h \
osmocom/vty/misc.h \
osmocom/vty/telnet_interface.h \
osmocom/vty/vector.h \
osmocom/vty/vty.h
endif
noinst_HEADERS = osmocom/core/timer_compat.h
osmocom/core/crc%gen.h: osmocom/core/crcXXgen.h.tpl
$(AM_V_GEN)$(MKDIR_P) $(dir $@)
$(AM_V_GEN)sed -e's/XX/$*/g' $< > $@

View File

@ -0,0 +1,20 @@
#ifndef _OSMOCOM_CODEC_H
#define _OSMOCOM_CODEC_H
#include <stdint.h>
extern const uint16_t gsm610_bitorder[]; /* FR */
extern const uint16_t gsm620_unvoiced_bitorder[]; /* HR unvoiced */
extern const uint16_t gsm620_voiced_bitorder[]; /* HR voiced */
extern const uint16_t gsm660_bitorder[]; /* EFR */
extern const uint16_t gsm690_12_2_bitorder[]; /* AMR 12.2 kbits */
extern const uint16_t gsm690_10_2_bitorder[]; /* AMR 10.2 kbits */
extern const uint16_t gsm690_7_95_bitorder[]; /* AMR 7.95 kbits */
extern const uint16_t gsm690_7_4_bitorder[]; /* AMR 7.4 kbits */
extern const uint16_t gsm690_6_7_bitorder[]; /* AMR 6.7 kbits */
extern const uint16_t gsm690_5_9_bitorder[]; /* AMR 5.9 kbits */
extern const uint16_t gsm690_5_15_bitorder[]; /* AMR 5.15 kbits */
extern const uint16_t gsm690_4_75_bitorder[]; /* AMR 4.75 kbits */
#endif /* _OSMOCOM_CODEC_H */

View File

@ -0,0 +1,23 @@
#ifndef OSMO_APPLICATION_H
#define OSMO_APPLICATION_H
/*!
* \file application.h
* \brief Routines for helping with the osmocom application setup.
*/
/*! \brief information containing the available logging subsystems */
struct log_info;
/*! \brief one instance of a logging target (file, stderr, ...) */
struct log_target;
/*! \brief the default logging target, logging to stderr */
extern struct log_target *osmo_stderr_target;
void osmo_init_ignore_signals(void);
int osmo_init_logging(const struct log_info *);
int osmo_daemonize(void);
#endif

View File

@ -0,0 +1,7 @@
#ifndef _OSMO_BACKTRACE_H_
#define _OSMO_BACKTRACE_H_
void osmo_generate_backtrace(void);
void osmo_log_backtrace(int subsys, int level);
#endif

View File

@ -0,0 +1,78 @@
#ifndef _OSMO_BITS_H
#define _OSMO_BITS_H
#include <stdint.h>
/*! \defgroup bits soft, unpacked and packed bits
* @{
*/
/*! \file bits.h
* \brief Osmocom bit level support code
*/
typedef int8_t sbit_t; /*!< \brief soft bit (-127...127) */
typedef uint8_t ubit_t; /*!< \brief unpacked bit (0 or 1) */
typedef uint8_t pbit_t; /*!< \brief packed bis (8 bits in a byte) */
/*
NOTE on the endianess of pbit_t:
Bits in a pbit_t are ordered MSB first, i.e. 0x80 is the first bit.
Bit i in a pbit_t array is array[i/8] & (1<<(7-i%8))
*/
/*! \brief determine how many bytes we would need for \a num_bits packed bits
* \param[in] num_bits Number of packed bits
*/
static inline unsigned int osmo_pbit_bytesize(unsigned int num_bits)
{
unsigned int pbit_bytesize = num_bits / 8;
if (num_bits % 8)
pbit_bytesize++;
return pbit_bytesize;
}
int osmo_ubit2pbit(pbit_t *out, const ubit_t *in, unsigned int num_bits);
int osmo_pbit2ubit(ubit_t *out, const pbit_t *in, unsigned int num_bits);
int osmo_ubit2pbit_ext(pbit_t *out, unsigned int out_ofs,
const ubit_t *in, unsigned int in_ofs,
unsigned int num_bits, int lsb_mode);
int osmo_pbit2ubit_ext(ubit_t *out, unsigned int out_ofs,
const pbit_t *in, unsigned int in_ofs,
unsigned int num_bits, int lsb_mode);
/* BIT REVERSAL */
/*! \brief bit-reversal mode for osmo_bit_reversal() */
enum osmo_br_mode {
/*! \brief reverse all bits in a 32bit dword */
OSMO_BR_BITS_IN_DWORD = 31,
/*! \brief reverse byte order in a 32bit dword */
OSMO_BR_BYTES_IN_DWORD = 24,
/*! \brief reverse bits of each byte in a 32bit dword */
OSMO_BR_BITS_IN_BYTE = 7,
/*! \brief swap the two 16bit words in a 32bit dword */
OSMO_BR_WORD_SWAP = 16,
};
/*! \brief generic bit reversal function */
uint32_t osmo_bit_reversal(uint32_t x, enum osmo_br_mode k);
/* \brief reverse the bits within each byte of a 32bit word */
uint32_t osmo_revbytebits_32(uint32_t x);
/* \brief reverse the bits within a byte */
uint32_t osmo_revbytebits_8(uint8_t x);
/* \brief reverse the bits of each byte in a given buffer */
void osmo_revbytebits_buf(uint8_t *buf, int len);
/*! @} */
#endif /* _OSMO_BITS_H */

View File

@ -0,0 +1,70 @@
#ifndef _BITVEC_H
#define _BITVEC_H
/* bit vector utility routines */
/* (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.
*
*/
/*! \defgroup bitvec Bit vectors
* @{
*/
/*! \file bitvec.h
* \brief Osmocom bit vector abstraction
*/
#include <stdint.h>
/*! \brief A single GSM bit
*
* In GSM mac blocks, every bit can be 0 or 1, or L or H. L/H are
* defined relative to the 0x2b padding pattern */
enum bit_value {
ZERO = 0, /*!< \brief A zero (0) bit */
ONE = 1, /*!< \brief A one (1) bit */
L = 2, /*!< \brief A CSN.1 "L" bit */
H = 3, /*!< \brief A CSN.1 "H" bit */
};
/*! \brief structure describing a bit vector */
struct bitvec {
unsigned int cur_bit; /*!< \brief curser to the next unused bit */
unsigned int data_len; /*!< \brief length of data array in bytes */
uint8_t *data; /*!< \brief pointer to data array */
};
enum bit_value bitvec_get_bit_pos(const struct bitvec *bv, unsigned int bitnr);
enum bit_value bitvec_get_bit_pos_high(const struct bitvec *bv,
unsigned int bitnr);
unsigned int bitvec_get_nth_set_bit(const struct bitvec *bv, unsigned int n);
int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnum,
enum bit_value bit);
int bitvec_set_bit(struct bitvec *bv, enum bit_value bit);
int bitvec_get_bit_high(struct bitvec *bv);
int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, int count);
int bitvec_set_uint(struct bitvec *bv, unsigned int in, int count);
int bitvec_get_uint(struct bitvec *bv, int num_bits);
int bitvec_find_bit_pos(const struct bitvec *bv, unsigned int n, enum bit_value val);
int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit);
/*! @} */
#endif /* _BITVEC_H */

View File

@ -0,0 +1,146 @@
/*
* conv.h
*
* Copyright (C) 2011 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.
*/
/*! \defgroup conv Convolutional encoding and decoding routines
* @{
*/
/*! \file conv.h
* \file Osmocom convolutional encoder and decoder
*/
#ifndef __OSMO_CONV_H__
#define __OSMO_CONV_H__
#include <stdint.h>
#include <osmocom/core/bits.h>
/*! \brief possibe termination types
*
* The termination type will determine which state the encoder/decoder
* can start/end with. This is mostly taken care of in the high level API
* call. So if you use the low level API, you must take care of making the
* proper calls yourself.
*/
enum osmo_conv_term {
CONV_TERM_FLUSH = 0, /*!< \brief Flush encoder state */
CONV_TERM_TRUNCATION, /*!< \brief Direct truncation */
CONV_TERM_TAIL_BITING, /*!< \brief Tail biting */
};
/*! \brief structure describing a given convolutional code
*
* The only required fields are N,K and the next_output/next_state arrays. The
* other can be left to default value of zero depending on what the code does.
* If 'len' is left at 0 then only the low level API can be used.
*/
struct osmo_conv_code {
int N; /*!< \brief Inverse of code rate */
int K; /*!< \brief Constraint length */
int len; /*!< \brief # of data bits */
enum osmo_conv_term term; /*!< \brief Termination type */
const uint8_t (*next_output)[2];/*!< \brief Next output array */
const uint8_t (*next_state)[2]; /*!< \brief Next state array */
const uint8_t *next_term_output;/*!< \brief Flush termination output */
const uint8_t *next_term_state; /*!< \brief Flush termination state */
const int *puncture; /*!< \brief Punctured bits indexes */
};
/* Common */
int osmo_conv_get_input_length(const struct osmo_conv_code *code, int len);
int osmo_conv_get_output_length(const struct osmo_conv_code *code, int len);
/* Encoding */
/* Low level API */
/*! \brief convolutional encoder state */
struct osmo_conv_encoder {
const struct osmo_conv_code *code; /*!< \brief for which code? */
int i_idx; /*!< \brief Next input bit index */
int p_idx; /*!< \brief Current puncture index */
uint8_t state; /*!< \brief Current state */
};
void osmo_conv_encode_init(struct osmo_conv_encoder *encoder,
const struct osmo_conv_code *code);
void osmo_conv_encode_load_state(struct osmo_conv_encoder *encoder,
const ubit_t *input);
int osmo_conv_encode_raw(struct osmo_conv_encoder *encoder,
const ubit_t *input, ubit_t *output, int n);
int osmo_conv_encode_flush(struct osmo_conv_encoder *encoder, ubit_t *output);
/* All-in-one */
int osmo_conv_encode(const struct osmo_conv_code *code,
const ubit_t *input, ubit_t *output);
/* Decoding */
/* Low level API */
/*! \brief convolutional decoder state */
struct osmo_conv_decoder {
const struct osmo_conv_code *code; /*!< \brief for which code? */
int n_states; /*!< \brief number of states */
int len; /*!< \brief Max o_idx (excl. termination) */
int o_idx; /*!< \brief output index */
int p_idx; /*!< \brief puncture index */
unsigned int *ae; /*!< \brief accumulated error */
unsigned int *ae_next; /*!< \brief next accumulated error (tmp in scan) */
uint8_t *state_history; /*!< \brief state history [len][n_states] */
};
void osmo_conv_decode_init(struct osmo_conv_decoder *decoder,
const struct osmo_conv_code *code,
int len, int start_state);
void osmo_conv_decode_reset(struct osmo_conv_decoder *decoder, int start_state);
void osmo_conv_decode_rewind(struct osmo_conv_decoder *decoder);
void osmo_conv_decode_deinit(struct osmo_conv_decoder *decoder);
int osmo_conv_decode_scan(struct osmo_conv_decoder *decoder,
const sbit_t *input, int n);
int osmo_conv_decode_flush(struct osmo_conv_decoder *decoder,
const sbit_t *input);
int osmo_conv_decode_get_output(struct osmo_conv_decoder *decoder,
ubit_t *output, int has_flush, int end_state);
/* All-in-one */
int osmo_conv_decode(const struct osmo_conv_code *code,
const sbit_t *input, ubit_t *output);
/*! @} */
#endif /* __OSMO_CONV_H__ */

View File

@ -0,0 +1,34 @@
/*
* This was copied from the linux kernel and adjusted for our types.
*/
/*
* crc16.h - CRC-16 routine
*
* Implements the standard CRC-16:
* Width 16
* Poly 0x8005 (x^16 + x^15 + x^2 + 1)
* Init 0
*
* Copyright (c) 2005 Ben Gardner <bgardner@wabtec.com>
*
* This source code is licensed under the GNU General Public License,
* Version 2. See the file COPYING for more details.
*/
#ifndef __CRC16_H
#define __CRC16_H
#include <stdint.h>
#include <sys/types.h>
extern uint16_t const osmo_crc16_table[256];
extern uint16_t osmo_crc16(uint16_t crc, const uint8_t *buffer, size_t len);
static inline uint16_t osmo_crc16_byte(uint16_t crc, const uint8_t data)
{
return (crc >> 8) ^ osmo_crc16_table[(crc ^ data) & 0xff];
}
#endif /* __CRC16_H */

View File

@ -0,0 +1,59 @@
/*
* crcXXgen.h
*
* Copyright (C) 2011 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.
*/
#ifndef __OSMO_CRCXXGEN_H__
#define __OSMO_CRCXXGEN_H__
/*! \addtogroup crcgen
* @{
*/
/*! \file crcXXgen.h
* \file Osmocom generic CRC routines (for max XX bits poly) header
*/
#include <stdint.h>
#include <osmocom/core/bits.h>
/*! \brief structure describing a given CRC code of max XX bits */
struct osmo_crcXXgen_code {
int bits; /*!< \brief Actual number of bits of the CRC */
uintXX_t poly; /*!< \brief Polynom (normal representation, MSB omitted */
uintXX_t init; /*!< \brief Initialization value of the CRC state */
uintXX_t remainder; /*!< \brief Remainder of the CRC (final XOR) */
};
uintXX_t osmo_crcXXgen_compute_bits(const struct osmo_crcXXgen_code *code,
const ubit_t *in, int len);
int osmo_crcXXgen_check_bits(const struct osmo_crcXXgen_code *code,
const ubit_t *in, int len, const ubit_t *crc_bits);
void osmo_crcXXgen_set_bits(const struct osmo_crcXXgen_code *code,
const ubit_t *in, int len, ubit_t *crc_bits);
/*! @} */
#endif /* __OSMO_CRCXXGEN_H__ */
/* vim: set syntax=c: */

View File

@ -0,0 +1,41 @@
/*
* crcgen.h
*
* Copyright (C) 2011 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.
*/
#ifndef __OSMO_CRCGEN_H__
#define __OSMO_CRCGEN_H__
/*! \defgroup crcgen Osmocom generic CRC routines
* @{
*/
/*! \file crcgen.h
* \file Osmocom generic CRC routines global header
*/
#include <osmocom/core/crc8gen.h>
#include <osmocom/core/crc16gen.h>
#include <osmocom/core/crc32gen.h>
#include <osmocom/core/crc64gen.h>
/*! @} */
#endif /* __OSMO_CRCGEN_H__ */

View File

@ -0,0 +1,166 @@
#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>
/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
/* The GSMTAP format definition is maintained in libosmocore,
* specifically the latest version can always be obtained from
* http://cgit.osmocom.org/cgit/libosmocore/tree/include/osmocom/core/gsmtap.h
*
* If you want to introduce new protocol/burst/channel types or extend
* GSMTAP in any way, please contact the GSMTAP maintainer at either the
* public openbsc@lists.osmocom.org mailing list, or privately at
* Harald Welte <laforge@gnumonks.org>.
*
* Your cooperation ensures that all projects will use the same GSMTAP
* definitions and remain compatible with each other.
*/
#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_TYPE_SIM 0x04
#define GSMTAP_TYPE_TETRA_I1 0x05 /* tetra air interface */
#define GSMTAP_TYPE_TETRA_I1_BURST 0x06 /* tetra air interface */
#define GSMTAP_TYPE_WMX_BURST 0x07 /* WiMAX burst */
#define GSMTAP_TYPE_GB_LLC 0x08 /* GPRS Gb interface: LLC */
#define GSMTAP_TYPE_GB_SNDCP 0x09 /* GPRS Gb interface: SNDCP */
#define GSMTAP_TYPE_GMR1_UM 0x0a /* GMR-1 L2 packets */
#define GSMTAP_TYPE_UMTS_RLC_MAC 0x0b
#define GSMTAP_TYPE_UMTS_RRC 0x0c
/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
/* sub-types for TYPE_UM_BURST */
#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
/* WiMAX bursts */
#define GSMTAP_BURST_CDMA_CODE 0x10 /* WiMAX CDMA Code Attribute burst */
#define GSMTAP_BURST_FCH 0x11 /* WiMAX FCH burst */
#define GSMTAP_BURST_FFB 0x12 /* WiMAX Fast Feedback burst */
#define GSMTAP_BURST_PDU 0x13 /* WiMAX PDU burst */
#define GSMTAP_BURST_HACK 0x14 /* WiMAX HARQ ACK burst */
#define GSMTAP_BURST_PHY_ATTRIBUTES 0x15 /* WiMAX PHY Attributes burst */
/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
/* sub-types for TYPE_UM */
#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_PACCH 0x0b
#define GSMTAP_CHANNEL_CBCH52 0x0c
#define GSMTAP_CHANNEL_PDCH 0x0d
#define GSMTAP_CHANNEL_PTCCH 0x0e
#define GSMTAP_CHANNEL_CBCH51 0x0f
/* GPRS Coding Scheme CS1..4 */
#define GSMTAP_GPRS_CS_BASE 0x20
#define GSMTAP_GPRS_CS(N) (GSMTAP_GPRS_CS_BASE + N)
/* (E) GPRS Coding Scheme MCS0..9 */
#define GSMTAP_GPRS_MCS_BASE 0x30
#define GSMTAP_GPRS_MCS(N) (GSMTAP_GPRS_MCS_BASE + N)
#define GSMTAP_CHANNEL_ACCH 0x80
/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
/* sub-types for TYPE_TETRA_AIR */
#define GSMTAP_TETRA_BSCH 0x01
#define GSMTAP_TETRA_AACH 0x02
#define GSMTAP_TETRA_SCH_HU 0x03
#define GSMTAP_TETRA_SCH_HD 0x04
#define GSMTAP_TETRA_SCH_F 0x05
#define GSMTAP_TETRA_BNCH 0x06
#define GSMTAP_TETRA_STCH 0x07
#define GSMTAP_TETRA_TCH_F 0x08
/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
/* sub-types for TYPE_GMR1_UM */
#define GSMTAP_GMR1_UNKNOWN 0x00
#define GSMTAP_GMR1_BCCH 0x01
#define GSMTAP_GMR1_CCCH 0x02 /* either AGCH or PCH */
#define GSMTAP_GMR1_PCH 0x03
#define GSMTAP_GMR1_AGCH 0x04
#define GSMTAP_GMR1_BACH 0x05
#define GSMTAP_GMR1_RACH 0x06
#define GSMTAP_GMR1_CBCH 0x07
#define GSMTAP_GMR1_SDCCH 0x08
#define GSMTAP_GMR1_TACCH 0x09
#define GSMTAP_GMR1_GBCH 0x0a
#define GSMTAP_GMR1_SACCH 0x01 /* to be combined with _TCH{6,9} */
#define GSMTAP_GMR1_FACCH 0x02 /* to be combines with _TCH{3,6,9} */
#define GSMTAP_GMR1_DKAB 0x03 /* to be combined with _TCH3 */
#define GSMTAP_GMR1_TCH3 0x10
#define GSMTAP_GMR1_TCH6 0x14
#define GSMTAP_GMR1_TCH9 0x18
/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
#define GSMTAP_UMTS_CH_PCCH 0x01
#define GSMTAP_UMTS_CH_CCCH 0x02
#define GSMTAP_UMTS_CH_DCCH 0x03
/* flags for the ARFCN */
#define GSMTAP_ARFCN_F_PCS 0x8000
#define GSMTAP_ARFCN_F_UPLINK 0x4000
#define GSMTAP_ARFCN_MASK 0x3fff
/* IANA-assigned well-known UDP port for GSMTAP messages */
#define GSMTAP_UDP_PORT 4729
/* ====== DO NOT MAKE UNAPPROVED MODIFICATIONS HERE ===== */
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 */

View File

@ -0,0 +1,57 @@
#ifndef _GSMTAP_UTIL_H
#define _GSMTAP_UTIL_H
#include <stdint.h>
#include <osmocom/core/write_queue.h>
#include <osmocom/core/select.h>
/*! \defgroup gsmtap GSMTAP
* @{
*/
/*! \file gsmtap_util.h */
uint8_t chantype_rsl2gsmtap(uint8_t rsl_chantype, uint8_t rsl_link_id);
struct msgb *gsmtap_makemsg_ex(uint8_t type, uint16_t arfcn, uint8_t ts, uint8_t chan_type,
uint8_t ss, uint32_t fn, int8_t signal_dbm,
uint8_t snr, const uint8_t *data, unsigned int len);
struct msgb *gsmtap_makemsg(uint16_t arfcn, uint8_t ts, uint8_t chan_type,
uint8_t ss, uint32_t fn, int8_t signal_dbm,
uint8_t snr, const uint8_t *data, unsigned int len);
/*! \brief one gsmtap instance */
struct gsmtap_inst {
int ofd_wq_mode; /*!< \brief wait queue mode? */
struct osmo_wqueue wq; /*!< \brief the wait queue */
struct osmo_fd sink_ofd;/*!< \brief file descriptor */
};
/*! \brief obtain the file descriptor associated with a gsmtap instance */
static inline int gsmtap_inst_fd(struct gsmtap_inst *gti)
{
return gti->wq.bfd.fd;
}
int gsmtap_source_init_fd(const char *host, uint16_t port);
int gsmtap_source_add_sink_fd(int gsmtap_fd);
struct gsmtap_inst *gsmtap_source_init(const char *host, uint16_t port,
int ofd_wq_mode);
int gsmtap_source_add_sink(struct gsmtap_inst *gti);
int gsmtap_sendmsg(struct gsmtap_inst *gti, struct msgb *msg);
int gsmtap_send_ex(struct gsmtap_inst *gti, uint8_t type, uint16_t arfcn, uint8_t ts,
uint8_t chan_type, uint8_t ss, uint32_t fn,
int8_t signal_dbm, uint8_t snr, const uint8_t *data,
unsigned int len);
int gsmtap_send(struct gsmtap_inst *gti, uint16_t arfcn, uint8_t ts,
uint8_t chan_type, uint8_t ss, uint32_t fn,
int8_t signal_dbm, uint8_t snr, const uint8_t *data,
unsigned int len);
#endif /* _GSMTAP_UTIL_H */

View File

@ -0,0 +1,360 @@
#ifndef _LINUX_LLIST_H
#define _LINUX_LLIST_H
#include <stddef.h>
#ifndef inline
#define inline __inline__
#endif
static inline void prefetch(__attribute__((unused)) const void *x) {;}
/**
* container_of - cast a member of a structure out to the containing structure
*
* @ptr: the pointer to the member.
* @type: the type of the container struct this is embedded in.
* @member: the name of the member within the struct.
*
*/
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (typeof( ((type *)0)->member ) *)(ptr); \
(type *)( (char *)__mptr - offsetof(type, member) );})
/*
* These are non-NULL pointers that will result in page faults
* under normal circumstances, used to verify that nobody uses
* non-initialized llist entries.
*/
#define LLIST_POISON1 ((void *) 0x00100100)
#define LLIST_POISON2 ((void *) 0x00200200)
/*
* Simple doubly linked llist implementation.
*
* Some of the internal functions ("__xxx") are useful when
* manipulating whole llists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
*/
struct llist_head {
struct llist_head *next, *prev;
};
#define LLIST_HEAD_INIT(name) { &(name), &(name) }
#define LLIST_HEAD(name) \
struct llist_head name = LLIST_HEAD_INIT(name)
#define INIT_LLIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal llist manipulation where we know
* the prev/next entries already!
*/
static inline void __llist_add(struct llist_head *_new,
struct llist_head *prev,
struct llist_head *next)
{
next->prev = _new;
_new->next = next;
_new->prev = prev;
prev->next = _new;
}
/**
* llist_add - add a new entry
* @new: new entry to be added
* @head: llist head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void llist_add(struct llist_head *_new, struct llist_head *head)
{
__llist_add(_new, head, head->next);
}
/**
* llist_add_tail - add a new entry
* @new: new entry to be added
* @head: llist head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void llist_add_tail(struct llist_head *_new, struct llist_head *head)
{
__llist_add(_new, head->prev, head);
}
/*
* Delete a llist entry by making the prev/next entries
* point to each other.
*
* This is only for internal llist manipulation where we know
* the prev/next entries already!
*/
static inline void __llist_del(struct llist_head * prev, struct llist_head * next)
{
next->prev = prev;
prev->next = next;
}
/**
* llist_del - deletes entry from llist.
* @entry: the element to delete from the llist.
* Note: llist_empty on entry does not return true after this, the entry is
* in an undefined state.
*/
static inline void llist_del(struct llist_head *entry)
{
__llist_del(entry->prev, entry->next);
entry->next = (struct llist_head *)LLIST_POISON1;
entry->prev = (struct llist_head *)LLIST_POISON2;
}
/**
* llist_del_init - deletes entry from llist and reinitialize it.
* @entry: the element to delete from the llist.
*/
static inline void llist_del_init(struct llist_head *entry)
{
__llist_del(entry->prev, entry->next);
INIT_LLIST_HEAD(entry);
}
/**
* llist_move - delete from one llist and add as another's head
* @llist: the entry to move
* @head: the head that will precede our entry
*/
static inline void llist_move(struct llist_head *llist, struct llist_head *head)
{
__llist_del(llist->prev, llist->next);
llist_add(llist, head);
}
/**
* llist_move_tail - delete from one llist and add as another's tail
* @llist: the entry to move
* @head: the head that will follow our entry
*/
static inline void llist_move_tail(struct llist_head *llist,
struct llist_head *head)
{
__llist_del(llist->prev, llist->next);
llist_add_tail(llist, head);
}
/**
* llist_empty - tests whether a llist is empty
* @head: the llist to test.
*/
static inline int llist_empty(const struct llist_head *head)
{
return head->next == head;
}
static inline void __llist_splice(struct llist_head *llist,
struct llist_head *head)
{
struct llist_head *first = llist->next;
struct llist_head *last = llist->prev;
struct llist_head *at = head->next;
first->prev = head;
head->next = first;
last->next = at;
at->prev = last;
}
/**
* llist_splice - join two llists
* @llist: the new llist to add.
* @head: the place to add it in the first llist.
*/
static inline void llist_splice(struct llist_head *llist, struct llist_head *head)
{
if (!llist_empty(llist))
__llist_splice(llist, head);
}
/**
* llist_splice_init - join two llists and reinitialise the emptied llist.
* @llist: the new llist to add.
* @head: the place to add it in the first llist.
*
* The llist at @llist is reinitialised
*/
static inline void llist_splice_init(struct llist_head *llist,
struct llist_head *head)
{
if (!llist_empty(llist)) {
__llist_splice(llist, head);
INIT_LLIST_HEAD(llist);
}
}
/**
* llist_entry - get the struct for this entry
* @ptr: the &struct llist_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the llist_struct within the struct.
*/
#define llist_entry(ptr, type, member) \
container_of(ptr, type, member)
/**
* llist_for_each - iterate over a llist
* @pos: the &struct llist_head to use as a loop counter.
* @head: the head for your llist.
*/
#define llist_for_each(pos, head) \
for (pos = (head)->next, prefetch(pos->next); pos != (head); \
pos = pos->next, prefetch(pos->next))
/**
* __llist_for_each - iterate over a llist
* @pos: the &struct llist_head to use as a loop counter.
* @head: the head for your llist.
*
* This variant differs from llist_for_each() in that it's the
* simplest possible llist iteration code, no prefetching is done.
* Use this for code that knows the llist to be very short (empty
* or 1 entry) most of the time.
*/
#define __llist_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
/**
* llist_for_each_prev - iterate over a llist backwards
* @pos: the &struct llist_head to use as a loop counter.
* @head: the head for your llist.
*/
#define llist_for_each_prev(pos, head) \
for (pos = (head)->prev, prefetch(pos->prev); pos != (head); \
pos = pos->prev, prefetch(pos->prev))
/**
* llist_for_each_safe - iterate over a llist safe against removal of llist entry
* @pos: the &struct llist_head to use as a loop counter.
* @n: another &struct llist_head to use as temporary storage
* @head: the head for your llist.
*/
#define llist_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
/**
* llist_for_each_entry - iterate over llist of given type
* @pos: the type * to use as a loop counter.
* @head: the head for your llist.
* @member: the name of the llist_struct within the struct.
*/
#define llist_for_each_entry(pos, head, member) \
for (pos = llist_entry((head)->next, typeof(*pos), member), \
prefetch(pos->member.next); \
&pos->member != (head); \
pos = llist_entry(pos->member.next, typeof(*pos), member), \
prefetch(pos->member.next))
/**
* llist_for_each_entry_reverse - iterate backwards over llist of given type.
* @pos: the type * to use as a loop counter.
* @head: the head for your llist.
* @member: the name of the llist_struct within the struct.
*/
#define llist_for_each_entry_reverse(pos, head, member) \
for (pos = llist_entry((head)->prev, typeof(*pos), member), \
prefetch(pos->member.prev); \
&pos->member != (head); \
pos = llist_entry(pos->member.prev, typeof(*pos), member), \
prefetch(pos->member.prev))
/**
* llist_for_each_entry_continue - iterate over llist of given type
* continuing after existing point
* @pos: the type * to use as a loop counter.
* @head: the head for your llist.
* @member: the name of the llist_struct within the struct.
*/
#define llist_for_each_entry_continue(pos, head, member) \
for (pos = llist_entry(pos->member.next, typeof(*pos), member), \
prefetch(pos->member.next); \
&pos->member != (head); \
pos = llist_entry(pos->member.next, typeof(*pos), member), \
prefetch(pos->member.next))
/**
* llist_for_each_entry_safe - iterate over llist of given type safe against removal of llist entry
* @pos: the type * to use as a loop counter.
* @n: another type * to use as temporary storage
* @head: the head for your llist.
* @member: the name of the llist_struct within the struct.
*/
#define llist_for_each_entry_safe(pos, n, head, member) \
for (pos = llist_entry((head)->next, typeof(*pos), member), \
n = llist_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = llist_entry(n->member.next, typeof(*n), member))
/**
* llist_for_each_rcu - iterate over an rcu-protected llist
* @pos: the &struct llist_head to use as a loop counter.
* @head: the head for your llist.
*/
#define llist_for_each_rcu(pos, head) \
for (pos = (head)->next, prefetch(pos->next); pos != (head); \
pos = pos->next, ({ smp_read_barrier_depends(); 0;}), prefetch(pos->next))
#define __llist_for_each_rcu(pos, head) \
for (pos = (head)->next; pos != (head); \
pos = pos->next, ({ smp_read_barrier_depends(); 0;}))
/**
* llist_for_each_safe_rcu - iterate over an rcu-protected llist safe
* against removal of llist entry
* @pos: the &struct llist_head to use as a loop counter.
* @n: another &struct llist_head to use as temporary storage
* @head: the head for your llist.
*/
#define llist_for_each_safe_rcu(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, ({ smp_read_barrier_depends(); 0;}), n = pos->next)
/**
* llist_for_each_entry_rcu - iterate over rcu llist of given type
* @pos: the type * to use as a loop counter.
* @head: the head for your llist.
* @member: the name of the llist_struct within the struct.
*/
#define llist_for_each_entry_rcu(pos, head, member) \
for (pos = llist_entry((head)->next, typeof(*pos), member), \
prefetch(pos->member.next); \
&pos->member != (head); \
pos = llist_entry(pos->member.next, typeof(*pos), member), \
({ smp_read_barrier_depends(); 0;}), \
prefetch(pos->member.next))
/**
* llist_for_each_continue_rcu - iterate over an rcu-protected llist
* continuing after existing point.
* @pos: the &struct llist_head to use as a loop counter.
* @head: the head for your llist.
*/
#define llist_for_each_continue_rcu(pos, head) \
for ((pos) = (pos)->next, prefetch((pos)->next); (pos) != (head); \
(pos) = (pos)->next, ({ smp_read_barrier_depends(); 0;}), prefetch((pos)->next))
#endif

View File

@ -0,0 +1,160 @@
/*
Red Black Trees
(C) 1999 Andrea Arcangeli <andrea@suse.de>
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
linux/include/linux/rbtree.h
To use rbtrees you'll have to implement your own insert and search cores.
This will avoid us to use callbacks and to drop drammatically performances.
I know it's not the cleaner way, but in C (not in C++) to get
performances and genericity...
Some example of insert and search follows here. The search is a plain
normal search over an ordered tree. The insert instead must be implemented
int two steps: as first thing the code must insert the element in
order as a red leaf in the tree, then the support library function
rb_insert_color() must be called. Such function will do the
not trivial work to rebalance the rbtree if necessary.
-----------------------------------------------------------------------
static inline struct page * rb_search_page_cache(struct inode * inode,
unsigned long offset)
{
struct rb_node * n = inode->i_rb_page_cache.rb_node;
struct page * page;
while (n)
{
page = rb_entry(n, struct page, rb_page_cache);
if (offset < page->offset)
n = n->rb_left;
else if (offset > page->offset)
n = n->rb_right;
else
return page;
}
return NULL;
}
static inline struct page * __rb_insert_page_cache(struct inode * inode,
unsigned long offset,
struct rb_node * node)
{
struct rb_node ** p = &inode->i_rb_page_cache.rb_node;
struct rb_node * parent = NULL;
struct page * page;
while (*p)
{
parent = *p;
page = rb_entry(parent, struct page, rb_page_cache);
if (offset < page->offset)
p = &(*p)->rb_left;
else if (offset > page->offset)
p = &(*p)->rb_right;
else
return page;
}
rb_link_node(node, parent, p);
return NULL;
}
static inline struct page * rb_insert_page_cache(struct inode * inode,
unsigned long offset,
struct rb_node * node)
{
struct page * ret;
if ((ret = __rb_insert_page_cache(inode, offset, node)))
goto out;
rb_insert_color(node, &inode->i_rb_page_cache);
out:
return ret;
}
-----------------------------------------------------------------------
*/
#ifndef _LINUX_RBTREE_H
#define _LINUX_RBTREE_H
#include <stdlib.h>
struct rb_node
{
unsigned long rb_parent_color;
#define RB_RED 0
#define RB_BLACK 1
struct rb_node *rb_right;
struct rb_node *rb_left;
} __attribute__((aligned(sizeof(long))));
/* The alignment might seem pointless, but allegedly CRIS needs it */
struct rb_root
{
struct rb_node *rb_node;
};
#define rb_parent(r) ((struct rb_node *)((r)->rb_parent_color & ~3))
#define rb_color(r) ((r)->rb_parent_color & 1)
#define rb_is_red(r) (!rb_color(r))
#define rb_is_black(r) rb_color(r)
#define rb_set_red(r) do { (r)->rb_parent_color &= ~1; } while (0)
#define rb_set_black(r) do { (r)->rb_parent_color |= 1; } while (0)
static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
{
rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p;
}
static inline void rb_set_color(struct rb_node *rb, int color)
{
rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
}
#define RB_ROOT { NULL, }
#define rb_entry(ptr, type, member) container_of(ptr, type, member)
#define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL)
#define RB_EMPTY_NODE(node) (rb_parent(node) == node)
#define RB_CLEAR_NODE(node) (rb_set_parent(node, node))
extern void rb_insert_color(struct rb_node *, struct rb_root *);
extern void rb_erase(struct rb_node *, struct rb_root *);
/* Find logical next and previous nodes in a tree */
extern struct rb_node *rb_next(const struct rb_node *);
extern struct rb_node *rb_prev(const struct rb_node *);
extern struct rb_node *rb_first(const struct rb_root *);
extern struct rb_node *rb_last(const struct rb_root *);
/* Fast replacement of a single node without remove/rebalance/add/rebalance */
extern void rb_replace_node(struct rb_node *victim, struct rb_node *_new,
struct rb_root *root);
static inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
struct rb_node ** rb_link)
{
node->rb_parent_color = (unsigned long )parent;
node->rb_left = node->rb_right = NULL;
*rb_link = node;
}
#endif /* _LINUX_RBTREE_H */

View File

@ -0,0 +1,214 @@
#ifndef _OSMOCORE_LOGGING_H
#define _OSMOCORE_LOGGING_H
/*! \defgroup logging Osmocom logging framework
* @{
*/
/*! \file logging.h */
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
#include <osmocom/core/linuxlist.h>
/*! \brief Maximum number of logging contexts */
#define LOG_MAX_CTX 8
/*! \brief Maximum number of logging filters */
#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
void osmo_vlogp(int subsys, int level, const char *file, int line,
int cont, const char *format, va_list ap);
void logp(int subsys, const char *file, int line, int cont, const char *format, ...) __attribute__ ((format (printf, 5, 6)));
/*! \brief Log a new message through the Osmocom logging framework
* \param[in] ss logging subsystem (e.g. \ref DLGLOBAL)
* \param[in] level logging level (e.g. \ref LOGL_NOTICE)
* \param[in] fmt format string
* \param[in] args variable argument list
*/
#define LOGP(ss, level, fmt, args...) \
logp2(ss, level, __FILE__, __LINE__, 0, fmt, ##args)
/*! \brief Continue a log message through the Osmocom logging framework
* \param[in] ss logging subsystem (e.g. \ref DLGLOBAL)
* \param[in] level logging level (e.g. \ref LOGL_NOTICE)
* \param[in] fmt format string
* \param[in] args variable argument list
*/
#define LOGPC(ss, level, fmt, args...) \
logp2(ss, level, __FILE__, __LINE__, 1, fmt, ##args)
/*! \brief different log levels */
#define LOGL_DEBUG 1 /*!< \brief debugging information */
#define LOGL_INFO 3
#define LOGL_NOTICE 5 /*!< \brief abnormal/unexpected condition */
#define LOGL_ERROR 7 /*!< \brief error condition, requires user action */
#define LOGL_FATAL 8 /*!< \brief fatal, program aborted */
#define LOG_FILTER_ALL 0x0001
/* logging levels defined by the library itself */
#define DLGLOBAL -1
#define DLLAPD -2
#define DLINP -3
#define DLMUX -4
#define DLMI -5
#define DLMIB -6
#define DLSMS -7
#define OSMO_NUM_DLIB 7
struct log_category {
uint8_t loglevel;
uint8_t enabled;
};
/*! \brief Information regarding one logging category */
struct log_info_cat {
const char *name; /*!< name of category */
const char *color; /*!< color string for cateyory */
const char *description; /*!< description text */
uint8_t loglevel; /*!< currently selected log-level */
uint8_t enabled; /*!< is this category enabled or not */
};
/*! \brief Log context information, passed to filter */
struct log_context {
void *ctx[LOG_MAX_CTX+1];
};
struct log_target;
/*! \brief Log filter function */
typedef int log_filter(const struct log_context *ctx,
struct log_target *target);
/*! \brief Logging configuration, passed to \ref log_init */
struct log_info {
/* \brief filter callback function */
log_filter *filter_fn;
/*! \brief per-category information */
const struct log_info_cat *cat;
/*! \brief total number of categories */
unsigned int num_cat;
/*! \brief total number of user categories (not library) */
unsigned int num_cat_user;
};
/*! \brief Type of logging target */
enum log_target_type {
LOG_TGT_TYPE_VTY, /*!< \brief VTY logging */
LOG_TGT_TYPE_SYSLOG, /*!< \brief syslog based logging */
LOG_TGT_TYPE_FILE, /*!< \brief text file logging */
LOG_TGT_TYPE_STDERR, /*!< \brief stderr logging */
};
/*! \brief structure representing a logging target */
struct log_target {
struct llist_head entry; /*!< \brief linked list */
/*! \brief Internal data for filtering */
int filter_map;
/*! \brief Internal data for filtering */
void *filter_data[LOG_MAX_FILTERS+1];
/*! \brief logging categories */
struct log_category *categories;
/*! \brief global log level */
uint8_t loglevel;
/*! \brief should color be used when printing log messages? */
unsigned int use_color:1;
/*! \brief should log messages be prefixed with a timestamp? */
unsigned int print_timestamp:1;
/*! \brief should log messages be prefixed with a filename? */
unsigned int print_filename:1;
/*! \brief the type of this log taget */
enum log_target_type type;
union {
struct {
FILE *out;
const char *fname;
} tgt_file;
struct {
int priority;
int facility;
} tgt_syslog;
struct {
void *vty;
} tgt_vty;
};
/*! \brief call-back function to be called when the logging framework
* wants to log somethnig.
* \param[[in] target logging target
* \param[in] level log level of currnet message
* \param[in] string the string that is to be written to the log
*/
void (*output) (struct log_target *target, unsigned int level,
const char *string);
};
/* use the above macros */
void logp2(int subsys, unsigned int level, const char *file,
int line, int cont, const char *format, ...)
__attribute__ ((format (printf, 6, 7)));
int log_init(const struct log_info *inf, void *talloc_ctx);
/* 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_print_filename(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);
const char *log_level_str(unsigned int 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);
void log_target_destroy(struct log_target *target);
struct log_target *log_target_create_stderr(void);
struct log_target *log_target_create_file(const char *fname);
struct log_target *log_target_create_syslog(const char *ident, int option,
int facility);
int log_target_file_reopen(struct log_target *tgt);
void log_add_target(struct log_target *target);
void log_del_target(struct log_target *target);
/* Generate command string for VTY use */
const char *log_vty_command_string(const struct log_info *info);
const char *log_vty_command_description(const struct log_info *info);
struct log_target *log_target_find(int type, const char *fname);
extern struct llist_head osmo_log_target_list;
/*! @} */
#endif /* _OSMOCORE_LOGGING_H */

View File

@ -0,0 +1,401 @@
#ifndef _MSGB_H
#define _MSGB_H
/* (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>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/utils.h>
/*! \defgroup msgb Message buffers
* @{
*/
/*! \file msgb.h
* \brief Osmocom message buffers
* The Osmocom message buffers are modelled after the 'struct skb'
* inside the Linux kernel network stack. As they exist in userspace,
* they are much simplified. However, terminology such as headroom,
* tailroom, push/pull/put etc. remains the same.
*/
#define MSGB_DEBUG
/*! \brief Osmocom message buffer */
struct msgb {
struct llist_head list; /*!< \brief linked list header */
/* Part of which TRX logical channel we were received / transmitted */
/* FIXME: move them into the control buffer */
union {
void *dst; /*!< \brief reference of origin/destination */
struct gsm_bts_trx *trx;
};
struct gsm_lchan *lchan; /*!< \brief logical channel */
unsigned char *l1h; /*!< \brief pointer to Layer1 header (if any) */
unsigned char *l2h; /*!< \brief pointer to A-bis layer 2 header: OML, RSL(RLL), NS */
unsigned char *l3h; /*!< \brief pointer to Layer 3 header. For OML: FOM; RSL: 04.08; GPRS: BSSGP */
unsigned char *l4h; /*!< \brief pointer to layer 4 header */
unsigned long cb[5]; /*!< \brief control buffer */
uint16_t data_len; /*!< \brief length of underlying data array */
uint16_t len; /*!< \brief length of bytes used in msgb */
unsigned char *head; /*!< \brief start of underlying memory buffer */
unsigned char *tail; /*!< \brief end of message in buffer */
unsigned char *data; /*!< \brief start of message in buffer */
unsigned char _data[0]; /*!< \brief optional immediate data array */
};
extern struct msgb *msgb_alloc(uint16_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);
uint16_t msgb_length(const struct msgb *msg);
#ifdef MSGB_DEBUG
#include <osmocom/core/panic.h>
#define MSGB_ABORT(msg, fmt, args ...) do { \
osmo_panic("msgb(%p): " fmt, msg, ## args); \
} while(0)
#else
#define MSGB_ABORT(msg, fmt, args ...)
#endif
/*! \brief obtain L1 header of msgb */
#define msgb_l1(m) ((void *)(m->l1h))
/*! \brief obtain L2 header of msgb */
#define msgb_l2(m) ((void *)(m->l2h))
/*! \brief obtain L3 header of msgb */
#define msgb_l3(m) ((void *)(m->l3h))
/*! \brief obtain SMS header of msgb */
#define msgb_sms(m) ((void *)(m->l4h))
/*! \brief determine length of L1 message
* \param[in] msgb message buffer
* \returns size of L1 message in bytes
*
* This function computes the number of bytes between the tail of the
* message and the layer 1 header.
*/
static inline unsigned int msgb_l1len(const struct msgb *msgb)
{
return msgb->tail - (uint8_t *)msgb_l1(msgb);
}
/*! \brief determine length of L2 message
* \param[in] msgb message buffer
* \returns size of L2 message in bytes
*
* This function computes the number of bytes between the tail of the
* message and the layer 2 header.
*/
static inline unsigned int msgb_l2len(const struct msgb *msgb)
{
return msgb->tail - (uint8_t *)msgb_l2(msgb);
}
/*! \brief determine length of L3 message
* \param[in] msgb message buffer
* \returns size of L3 message in bytes
*
* This function computes the number of bytes between the tail of the
* message and the layer 3 header.
*/
static inline unsigned int msgb_l3len(const struct msgb *msgb)
{
return msgb->tail - (uint8_t *)msgb_l3(msgb);
}
/*! \brief determine the length of the header
* \param[in] msgb message buffer
* \returns number of bytes between start of buffer and start of msg
*
* This function computes the length difference between the underlying
* data buffer and the used section of the \a msgb.
*/
static inline unsigned int msgb_headlen(const struct msgb *msgb)
{
return msgb->len - msgb->data_len;
}
/*! \brief determine how much tail room is left in msgb
* \param[in] msgb message buffer
* \returns number of bytes remaining at end of msgb
*
* This function computes the amount of octets left in the underlying
* data buffer after the end of the message.
*/
static inline int msgb_tailroom(const struct msgb *msgb)
{
return (msgb->head + msgb->data_len) - msgb->tail;
}
/*! \brief determine the amount of headroom in msgb
* \param[in] msgb message buffer
* \returns number of bytes left ahead of message start in msgb
*
* This function computes the amount of bytes left in the underlying
* data buffer before the start of the actual message.
*/
static inline int msgb_headroom(const struct msgb *msgb)
{
return (msgb->data - msgb->head);
}
/*! \brief append data to end of message buffer
* \param[in] msgb message buffer
* \param[in] len number of bytes to append to message
* \returns pointer to start of newly-appended data
*
* This function will move the \a tail pointer of the message buffer \a
* len bytes further, thus enlarging the message by \a len bytes.
*
* The return value is a pointer to start of the newly added section at
* the end of the message and can be used for actually filling/copying
* data into it.
*/
static inline unsigned char *msgb_put(struct msgb *msgb, unsigned int len)
{
unsigned char *tmp = msgb->tail;
if (msgb_tailroom(msgb) < (int) len)
MSGB_ABORT(msgb, "Not enough tailroom msgb_push (%u < %u)\n",
msgb_tailroom(msgb), len);
msgb->tail += len;
msgb->len += len;
return tmp;
}
/*! \brief append a uint8 value to the end of the message
* \param[in] msgb message buffer
* \param[in] word unsigned 8bit byte to be appended
*/
static inline void msgb_put_u8(struct msgb *msgb, uint8_t word)
{
uint8_t *space = msgb_put(msgb, 1);
space[0] = word & 0xFF;
}
/*! \brief append a uint16 value to the end of the message
* \param[in] msgb message buffer
* \param[in] word unsigned 16bit byte to be appended
*/
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;
}
/*! \brief append a uint32 value to the end of the message
* \param[in] msgb message buffer
* \param[in] word unsigned 32bit byte to be appended
*/
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;
}
/*! \brief remove data from end of message
* \param[in] msgb message buffer
* \param[in] len number of bytes to remove from end
*/
static inline unsigned char *msgb_get(struct msgb *msgb, unsigned int len)
{
unsigned char *tmp = msgb->data - len;
if (msgb_length(msgb) < len)
MSGB_ABORT(msgb, "msgb too small to get %u (len %u)\n",
len, msgb_length(msgb));
msgb->tail -= len;
msgb->len -= len;
return tmp;
}
/*! \brief remove uint8 from end of message
* \param[in] msgb message buffer
* \returns 8bit value taken from end of msgb
*/
static inline uint8_t msgb_get_u8(struct msgb *msgb)
{
uint8_t *space = msgb_get(msgb, 1);
return space[0];
}
/*! \brief remove uint16 from end of message
* \param[in] msgb message buffer
* \returns 16bit value taken from end of msgb
*/
static inline uint16_t msgb_get_u16(struct msgb *msgb)
{
uint8_t *space = msgb_get(msgb, 2);
return space[0] << 8 | space[1];
}
/*! \brief remove uint32 from end of message
* \param[in] msgb message buffer
* \returns 32bit value taken from end of msgb
*/
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];
}
/*! \brief prepend (push) some data to start of message
* \param[in] msgb message buffer
* \param[in] len number of bytes to pre-pend
* \returns pointer to newly added portion at start of \a msgb
*
* This function moves the \a data pointer of the \ref msgb further
* to the front (by \a len bytes), thereby enlarging the message by \a
* len bytes.
*
* The return value is a pointer to the newly added section in the
* beginning of the message. It can be used to fill/copy data into it.
*/
static inline unsigned char *msgb_push(struct msgb *msgb, unsigned int len)
{
if (msgb_headroom(msgb) < (int) len)
MSGB_ABORT(msgb, "Not enough headroom msgb_push (%u < %u)\n",
msgb_headroom(msgb), len);
msgb->data -= len;
msgb->len += len;
return msgb->data;
}
/*! \brief remove (pull) a header from the front of the message buffer
* \param[in] msgb message buffer
* \param[in] len number of octets to be pulled
* \returns pointer to new start of msgb
*
* This function moves the \a data pointer of the \ref msgb further back
* in the message, thereby shrinking the size of the message by \a len
* bytes.
*/
static inline unsigned char *msgb_pull(struct msgb *msgb, unsigned int len)
{
msgb->len -= len;
return msgb->data += len;
}
/*! \brief remove uint8 from front of message
* \param[in] msgb message buffer
* \returns 8bit value taken from end of msgb
*/
static inline uint8_t msgb_pull_u8(struct msgb *msgb)
{
uint8_t *space = msgb_pull(msgb, 1) - 1;
return space[0];
}
/*! \brief remove uint16 from front of message
* \param[in] msgb message buffer
* \returns 16bit value taken from end of msgb
*/
static inline uint16_t msgb_pull_u16(struct msgb *msgb)
{
uint8_t *space = msgb_pull(msgb, 2) - 2;
return space[0] << 8 | space[1];
}
/*! \brief remove uint32 from front of message
* \param[in] msgb message buffer
* \returns 32bit value taken from end of msgb
*/
static inline uint32_t msgb_pull_u32(struct msgb *msgb)
{
uint8_t *space = msgb_pull(msgb, 4) - 4;
return space[0] << 24 | space[1] << 16 | space[2] << 8 | space[3];
}
/*! \brief Increase headroom of empty msgb, reducing the tailroom
* \param[in] msg message buffer
* \param[in] len amount of extra octets to be reserved as headroom
*
* This function reserves some memory at the beginning of the underlying
* data buffer. The idea is to reserve space in case further headers
* have to be pushed to the \ref msgb during further processing.
*
* Calling this function leads to undefined reusults if it is called on
* a non-empty \ref msgb.
*/
static inline void msgb_reserve(struct msgb *msg, int len)
{
msg->data += len;
msg->tail += len;
}
/*! \brief Trim the msgb to a given absolute length
* \param[in] msg message buffer
* \param[in] len new total length of buffer
* \returns 0 in case of success, negative in case of error
*/
static inline int msgb_trim(struct msgb *msg, int len)
{
if (len > msg->data_len)
return -1;
msg->len = len;
msg->tail = msg->data + len;
return 0;
}
/*! \brief Trim the msgb to a given layer3 length
* \pram[in] msg message buffer
* \param[in] l3len new layer3 length
* \returns 0 in case of success, negative in case of error
*/
static inline int msgb_l3trim(struct msgb *msg, int l3len)
{
return msgb_trim(msg, (msg->l3h - msg->data) + l3len);
}
/*! \brief Allocate message buffer with specified headroom
* \param[in] size size in bytes, including headroom
* \param[in] headroom headroom in bytes
* \param[in] name human-readable name
* \returns allocated message buffer with specified headroom
*
* This function is a convenience wrapper around \ref msgb_alloc
* followed by \ref msgb_reserve in order to create a new \ref msgb with
* user-specified amount of headroom.
*/
static inline struct msgb *msgb_alloc_headroom(int size, int headroom,
const char *name)
{
osmo_static_assert(size > headroom, headroom_bigger);
struct msgb *msg = msgb_alloc(size, name);
if (msg)
msgb_reserve(msg, headroom);
return msg;
}
/* non inline functions to ease binding */
uint8_t *msgb_data(const struct msgb *msg);
void msgb_set_talloc_ctx(void *ctx);
/*! @} */
#endif /* _MSGB_H */

View File

@ -0,0 +1,49 @@
/*
* (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 MSG_FILE_H
#define MSG_FILE_H
#include <osmocom/core/linuxlist.h>
/**
* One message in the list.
*/
struct osmo_config_entry {
struct llist_head list;
/* number for everyone to use */
int nr;
/* data from the file */
char *mcc;
char *mnc;
char *option;
char *text;
};
struct osmo_config_list {
struct llist_head entry;
};
struct osmo_config_list* osmo_config_list_parse(void *ctx, const char *filename);
#endif

View File

@ -0,0 +1,20 @@
#ifndef OSMOCORE_PANIC_H
#define OSMOCORE_PANIC_H
/*! \addtogroup utils
* @{
*/
/*! \file panic.h */
#include <stdarg.h>
/*! \brief panic handler callback function type */
typedef void (*osmo_panic_handler_t)(const char *fmt, va_list args);
extern void osmo_panic(const char *fmt, ...);
extern void osmo_set_panic_handler(osmo_panic_handler_t h);
/*! @} */
#endif /* OSMOCORE_PANIC_H */

View File

@ -0,0 +1,6 @@
#ifndef _OSMO_PLUGIN_H
#define _OSMO_PLUGIN_H
int osmo_plugin_load_all(const char *directory);
#endif

View File

@ -0,0 +1,58 @@
#ifndef OSMO_PRIMITIVE_H
#define OSMO_PRIMITIVE_H
/*! \defgroup prim Osmocom primitives
* @{
*/
/*! \file prim.c */
#include <stdint.h>
#include <osmocom/core/msgb.h>
#define OSMO_PRIM(prim, op) ((prim << 8) | (op & 0xFF))
#define OSMO_PRIM_HDR(oph) OSMO_PRIM((oph)->primitive, (oph)->operation)
/*! \brief primitive operation */
enum osmo_prim_operation {
PRIM_OP_REQUEST, /*!< \brief request */
PRIM_OP_RESPONSE, /*!< \brief response */
PRIM_OP_INDICATION, /*!< \brief indication */
PRIM_OP_CONFIRM, /*!< \brief cofirm */
};
#define _SAP_GSM_SHIFT 24
#define _SAP_GSM_BASE (0x01 << _SAP_GSM_SHIFT)
#define _SAP_TETRA_BASE (0x02 << _SAP_GSM_SHIFT)
/*! \brief primitive header */
struct osmo_prim_hdr {
unsigned int sap; /*!< \brief Service Access Point */
unsigned int primitive; /*!< \brief Primitive number */
enum osmo_prim_operation operation; /*! \brief Primitive Operation */
struct msgb *msg; /*!< \brief \ref msgb containing associated data */
};
/*! \brief initialize a primitive header
* \param[in,out] oph primitive header
* \param[in] sap Service Access Point
* \param[in] primtive Primitive Number
* \param[in] operation Primitive Operation (REQ/RESP/IND/CONF)
* \param[in] msg Message
*/
static inline void
osmo_prim_init(struct osmo_prim_hdr *oph, unsigned int sap,
unsigned int primitive, enum osmo_prim_operation operation,
struct msgb *msg)
{
oph->sap = sap;
oph->primitive = primitive;
oph->operation = operation;
oph->msg = msg;
}
/*! \brief primitive handler callback type */
typedef int (*osmo_prim_cb)(struct osmo_prim_hdr *oph, void *ctx);
#endif /* OSMO_PRIMITIVE_H */

View File

@ -0,0 +1,2 @@
#warning "Update from osmocom/core/process.h to osmocom/core/application.h"
#include <osmocom/core/application.h>

View File

@ -0,0 +1,88 @@
#ifndef _RATE_CTR_H
#define _RATE_CTR_H
/*! \defgroup rate_ctr Rate counters
* @{
*/
/*! \file rate_ctr.h */
#include <stdint.h>
#include <osmocom/core/linuxlist.h>
/*! \brief Number of rate counter intervals */
#define RATE_CTR_INTV_NUM 4
/*! \brief Rate counter interval */
enum rate_ctr_intv {
RATE_CTR_INTV_SEC, /*!< \brief last second */
RATE_CTR_INTV_MIN, /*!< \brief last minute */
RATE_CTR_INTV_HOUR, /*!< \brief last hour */
RATE_CTR_INTV_DAY, /*!< \brief last day */
};
/*! \brief data we keep for each of the intervals */
struct rate_ctr_per_intv {
uint64_t last; /*!< \brief counter value in last interval */
uint64_t rate; /*!< \brief counter rate */
};
/*! \brief data we keep for each actual value */
struct rate_ctr {
uint64_t current; /*!< \brief current value */
/*! \brief per-interval data */
struct rate_ctr_per_intv intv[RATE_CTR_INTV_NUM];
};
/*! \brief rate counter description */
struct rate_ctr_desc {
const char *name; /*!< \brief name of the counter */
const char *description;/*!< \brief description of the counter */
};
/*! \brief description of a rate counter group */
struct rate_ctr_group_desc {
/*! \brief The prefix to the name of all counters in this group */
const char *group_name_prefix;
/*! \brief The human-readable description of the group */
const char *group_description;
/*! \brief The number of counters in this group */
const unsigned int num_ctr;
/*! \brief Pointer to array of counter names */
const struct rate_ctr_desc *ctr_desc;
};
/*! \brief One instance of a counter group class */
struct rate_ctr_group {
/*! \brief Linked list of all counter groups in the system */
struct llist_head list;
/*! \brief Pointer to the counter group class */
const struct rate_ctr_group_desc *desc;
/*! \brief The index of this ctr_group within its class */
unsigned int idx;
/*! \brief Actual counter structures below */
struct rate_ctr ctr[0];
};
struct rate_ctr_group *rate_ctr_group_alloc(void *ctx,
const struct rate_ctr_group_desc *desc,
unsigned int idx);
void rate_ctr_group_free(struct rate_ctr_group *grp);
void rate_ctr_add(struct rate_ctr *ctr, int inc);
/*! \brief Increment the counter by 1 */
static inline void rate_ctr_inc(struct rate_ctr *ctr)
{
rate_ctr_add(ctr, 1);
}
int rate_ctr_init(void *tall_ctx);
struct rate_ctr_group *rate_ctr_get_group_by_name_idx(const char *name, const unsigned int idx);
const struct rate_ctr *rate_ctr_get_by_name(const struct rate_ctr_group *ctrg, const char *name);
/*! @} */
#endif /* RATE_CTR_H */

View File

@ -0,0 +1,45 @@
#ifndef _BSC_SELECT_H
#define _BSC_SELECT_H
#include <osmocom/core/linuxlist.h>
/*! \defgroup select Select loop abstraction
* @{
*/
/*! \file select.h
* \brief select loop abstraction
*/
/*! \brief Indicate interest in reading from the file descriptor */
#define BSC_FD_READ 0x0001
/*! \brief Indicate interest in writing to the file descriptor */
#define BSC_FD_WRITE 0x0002
/*! \brief Indicate interest in exceptions from the file descriptor */
#define BSC_FD_EXCEPT 0x0004
/*! \brief Structure representing a file dsecriptor */
struct osmo_fd {
/*! linked list for internal management */
struct llist_head list;
/*! actual operating-system level file decriptor */
int fd;
/*! bit-mask or of \ref BSC_FD_READ, \ref BSC_FD_WRITE and/or
* \ref BSC_FD_EXCEPT */
unsigned int when;
/*! call-back function to be called once file descriptor becomes
* available */
int (*cb)(struct osmo_fd *fd, unsigned int what);
/*! data pointer passed through to call-back function */
void *data;
/*! private number, extending \a data */
unsigned int priv_nr;
};
int osmo_fd_register(struct osmo_fd *fd);
void osmo_fd_unregister(struct osmo_fd *fd);
int osmo_select_main(int polling);
/*! @} */
#endif /* _BSC_SELECT_H */

View File

@ -0,0 +1,43 @@
/*
* serial.h
*
* Copyright (C) 2011 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.
*/
/*! \defgroup serial Utility functions to deal with serial ports
* @{
*/
/*! \file serial.h
* \file Osmocom serial port helpers
*/
#ifndef __OSMO_SERIAL_H__
#define __OSMO_SERIAL_H__
#include <termios.h>
int osmo_serial_init(const char *dev, speed_t baudrate);
int osmo_serial_set_baudrate(int fd, speed_t baudrate);
int osmo_serial_set_custom_baudrate(int fd, int baudrate);
int osmo_serial_clear_custom_baudrate(int fd);
/*! @} */
#endif /* __OSMO_SERIAL_H__ */

View File

@ -0,0 +1,46 @@
#ifndef OSMO_SIGNAL_H
#define OSMO_SIGNAL_H
#include <stdint.h>
/*! \defgroup signal Intra-application signals
* @{
*/
/*! \file signal.h */
/* subsystem signaling numbers: we split the numberspace for applications and
* libraries: from 0 to UINT_MAX/2 for applications, from UINT_MAX/2 to
* UINT_MAX for libraries. */
#define OSMO_SIGNAL_SS_APPS 0
#define OSMO_SIGNAL_SS_RESERVED 2147483648u
/*! \brief signal subsystems */
enum {
SS_L_GLOBAL = OSMO_SIGNAL_SS_RESERVED,
SS_L_INPUT,
SS_L_NS,
};
/* application-defined signal types. */
#define OSMO_SIGNAL_T_APPS 0
#define OSMO_SIGNAL_T_RESERVED 2147483648u
/*! \brief signal types. */
enum {
S_L_GLOBAL_SHUTDOWN = OSMO_SIGNAL_T_RESERVED,
};
/*! signal callback function type */
typedef int osmo_signal_cbfn(unsigned int subsys, unsigned int signal, void *handler_data, void *signal_data);
/* Management */
int osmo_signal_register_handler(unsigned int subsys, osmo_signal_cbfn *cbfn, void *data);
void osmo_signal_unregister_handler(unsigned int subsys, osmo_signal_cbfn *cbfn, void *data);
/* Dispatch */
void osmo_signal_dispatch(unsigned int subsys, unsigned int signal, void *signal_data);
/*! @} */
#endif /* OSMO_SIGNAL_H */

View File

@ -0,0 +1,35 @@
#ifndef _OSMOCORE_SOCKET_H
#define _OSMOCORE_SOCKET_H
/*! \defgroup socket Socket convenience functions
* @{
*/
/*! \file socket.h
* \brief Osmocom socket convenience functions
*/
#include <stdint.h>
struct sockaddr;
struct osmo_fd;
/* flags for osmo_sock_init. */
#define OSMO_SOCK_F_CONNECT (1 << 0)
#define OSMO_SOCK_F_BIND (1 << 1)
#define OSMO_SOCK_F_NONBLOCK (1 << 2)
int osmo_sock_init(uint16_t family, uint16_t type, uint8_t proto,
const char *host, uint16_t port, unsigned int flags);
int osmo_sock_init_ofd(struct osmo_fd *ofd, int family, int type, int proto,
const char *host, uint16_t port, unsigned int flags);
int osmo_sock_init_sa(struct sockaddr *ss, uint16_t type,
uint8_t proto, unsigned int flags);
int osmo_sockaddr_is_local(struct sockaddr *addr, unsigned int addrlen);
/*! @} */
#endif /* _OSMOCORE_SOCKET_H */

View File

@ -0,0 +1,53 @@
#ifndef _STATISTICS_H
#define _STATISTICS_H
/*! \file statistics.h
* \brief Common routines regarding statistics */
/*! structure representing a single counter */
struct osmo_counter {
struct llist_head list; /*!< \brief internal list head */
const char *name; /*!< \brief human-readable name */
const char *description; /*!< \brief humn-readable description */
unsigned long value; /*!< \brief current value */
};
/*! \brief Increment counter */
static inline void osmo_counter_inc(struct osmo_counter *ctr)
{
ctr->value++;
}
/*! \brief Get current value of counter */
static inline unsigned long osmo_counter_get(struct osmo_counter *ctr)
{
return ctr->value;
}
/*! \brief Reset current value of counter to 0 */
static inline void osmo_counter_reset(struct osmo_counter *ctr)
{
ctr->value = 0;
}
/*! \brief Allocate a new counter */
struct osmo_counter *osmo_counter_alloc(const char *name);
/*! \brief Free the specified counter
* \param[ctr] Counter
*/
void osmo_counter_free(struct osmo_counter *ctr);
/*! \brief Iteate over all counters
* \param[in] handle_counter Call-back function
* \param[in] data Private dtata handed through to \a handle_counter
*/
int osmo_counters_for_each(int (*handle_counter)(struct osmo_counter *, void *), void *data);
/*! \brief Resolve counter by human-readable name
* \param[in] name human-readable name of counter
* \returns pointer to counter (\ref osmo_counter) or NULL otherwise
*/
struct osmo_counter *osmo_counter_get_by_name(const char *name);
#endif /* _STATISTICS_H */

View File

@ -0,0 +1,192 @@
#ifndef _TALLOC_H_
#define _TALLOC_H_
/*
Unix SMB/CIFS implementation.
Samba temporary memory allocation functions
Copyright (C) Andrew Tridgell 2004-2005
Copyright (C) Stefan Metzmacher 2006
** NOTE! The following LGPL license applies to the talloc
** library. This does NOT imply that all of Samba is released
** under the LGPL
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#define HAVE_VA_COPY
/* this is only needed for compatibility with the old talloc */
typedef void TALLOC_CTX;
/*
this uses a little trick to allow __LINE__ to be stringified
*/
#ifndef __location__
#define __TALLOC_STRING_LINE1__(s) #s
#define __TALLOC_STRING_LINE2__(s) __TALLOC_STRING_LINE1__(s)
#define __TALLOC_STRING_LINE3__ __TALLOC_STRING_LINE2__(__LINE__)
#define __location__ __FILE__ ":" __TALLOC_STRING_LINE3__
#endif
#ifndef TALLOC_DEPRECATED
#define TALLOC_DEPRECATED 0
#endif
#ifndef PRINTF_ATTRIBUTE
#if (__GNUC__ >= 3)
/** Use gcc attribute to check printf fns. a1 is the 1-based index of
* the parameter containing the format, and a2 the index of the first
* argument. Note that some gcc 2.x versions don't handle this
* properly **/
#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2)))
#else
#define PRINTF_ATTRIBUTE(a1, a2)
#endif
#endif
/* try to make talloc_set_destructor() and talloc_steal() type safe,
if we have a recent gcc */
#if (__GNUC__ >= 3)
#define _TALLOC_TYPEOF(ptr) __typeof__(ptr)
#define talloc_set_destructor(ptr, function) \
do { \
int (*_talloc_destructor_fn)(_TALLOC_TYPEOF(ptr)) = (function); \
_talloc_set_destructor((ptr), (int (*)(void *))_talloc_destructor_fn); \
} while(0)
/* this extremely strange macro is to avoid some braindamaged warning
stupidity in gcc 4.1.x */
#define talloc_steal(ctx, ptr) ({ _TALLOC_TYPEOF(ptr) __talloc_steal_ret = (_TALLOC_TYPEOF(ptr))_talloc_steal((ctx),(ptr)); __talloc_steal_ret; })
#else
#define talloc_set_destructor(ptr, function) \
_talloc_set_destructor((ptr), (int (*)(void *))(function))
#define _TALLOC_TYPEOF(ptr) void *
#define talloc_steal(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_steal((ctx),(ptr))
#endif
#define talloc_reference(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_reference((ctx),(ptr))
#define talloc_move(ctx, ptr) (_TALLOC_TYPEOF(*(ptr)))_talloc_move((ctx),(void *)(ptr))
/* useful macros for creating type checked pointers */
#define talloc(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type)
#define talloc_size(ctx, size) talloc_named_const(ctx, size, __location__)
#define talloc_ptrtype(ctx, ptr) (_TALLOC_TYPEOF(ptr))talloc_size(ctx, sizeof(*(ptr)))
#define talloc_new(ctx) talloc_named_const(ctx, 0, "talloc_new: " __location__)
#define talloc_zero(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type)
#define talloc_zero_size(ctx, size) _talloc_zero(ctx, size, __location__)
#define talloc_zero_array(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type)
#define talloc_array(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type)
#define talloc_array_size(ctx, size, count) _talloc_array(ctx, size, count, __location__)
#define talloc_array_ptrtype(ctx, ptr, count) (_TALLOC_TYPEOF(ptr))talloc_array_size(ctx, sizeof(*(ptr)), count)
#define talloc_array_length(ctx) (talloc_get_size(ctx)/sizeof(*ctx))
#define talloc_realloc(ctx, p, type, count) (type *)_talloc_realloc_array(ctx, p, sizeof(type), count, #type)
#define talloc_realloc_size(ctx, ptr, size) _talloc_realloc(ctx, ptr, size, __location__)
#define talloc_memdup(t, p, size) _talloc_memdup(t, p, size, __location__)
#define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type)
#define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type)
#define talloc_get_type_abort(ptr, type) (type *)_talloc_get_type_abort(ptr, #type, __location__)
#define talloc_find_parent_bytype(ptr, type) (type *)talloc_find_parent_byname(ptr, #type)
#if TALLOC_DEPRECATED
#define talloc_zero_p(ctx, type) talloc_zero(ctx, type)
#define talloc_p(ctx, type) talloc(ctx, type)
#define talloc_array_p(ctx, type, count) talloc_array(ctx, type, count)
#define talloc_realloc_p(ctx, p, type, count) talloc_realloc(ctx, p, type, count)
#define talloc_destroy(ctx) talloc_free(ctx)
#define talloc_append_string(c, s, a) (s?talloc_strdup_append(s,a):talloc_strdup(c, a))
#endif
#define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0)
/* The following definitions come from talloc.c */
void *_talloc(const void *context, size_t size);
void *talloc_pool(const void *context, size_t size);
void _talloc_set_destructor(const void *ptr, int (*_destructor)(void *));
int talloc_increase_ref_count(const void *ptr);
size_t talloc_reference_count(const void *ptr);
void *_talloc_reference(const void *context, const void *ptr);
int talloc_unlink(const void *context, void *ptr);
const char *talloc_set_name(const void *ptr, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
void talloc_set_name_const(const void *ptr, const char *name);
void *talloc_named(const void *context, size_t size,
const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
void *talloc_named_const(const void *context, size_t size, const char *name);
const char *talloc_get_name(const void *ptr);
void *talloc_check_name(const void *ptr, const char *name);
void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location);
void *talloc_parent(const void *ptr);
const char *talloc_parent_name(const void *ptr);
void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
int talloc_free(void *ptr);
void talloc_free_children(void *ptr);
void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name);
void *_talloc_steal(const void *new_ctx, const void *ptr);
void *_talloc_move(const void *new_ctx, const void *pptr);
size_t talloc_total_size(const void *ptr);
size_t talloc_total_blocks(const void *ptr);
void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
void (*callback)(const void *ptr,
int depth, int max_depth,
int is_ref,
void *private_data),
void *private_data);
void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f);
void talloc_report_full(const void *ptr, FILE *f);
void talloc_report(const void *ptr, FILE *f);
void talloc_enable_null_tracking(void);
void talloc_disable_null_tracking(void);
void talloc_enable_leak_report(void);
void talloc_enable_leak_report_full(void);
void *_talloc_zero(const void *ctx, size_t size, const char *name);
void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name);
void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name);
void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name);
void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name);
void *talloc_realloc_fn(const void *context, void *ptr, size_t size);
void *talloc_autofree_context(void);
size_t talloc_get_size(const void *ctx);
void *talloc_find_parent_byname(const void *ctx, const char *name);
void talloc_show_parents(const void *context, FILE *file);
int talloc_is_parent(const void *context, const void *ptr);
char *talloc_strdup(const void *t, const char *p);
char *talloc_strdup_append(char *s, const char *a);
char *talloc_strdup_append_buffer(char *s, const char *a);
char *talloc_strndup(const void *t, const char *p, size_t n);
char *talloc_strndup_append(char *s, const char *a, size_t n);
char *talloc_strndup_append_buffer(char *s, const char *a, size_t n);
char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
char *talloc_asprintf_append(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
void talloc_set_abort_fn(void (*abort_fn)(const char *reason));
#endif

View File

@ -0,0 +1,89 @@
/*
* (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.
*
*/
/*! \defgroup timer Osmocom timers
* @{
*/
/*! \file timer.h
* \brief Osmocom timer handling routines
*/
#ifndef TIMER_H
#define TIMER_H
#include <sys/time.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/linuxrbtree.h>
/**
* Timer management:
* - Create a struct osmo_timer_list
* - Fill out timeout and use add_timer or
* use schedule_timer to schedule a timer in
* x seconds and microseconds from now...
* - Use del_timer to remove the timer
*
* Internally:
* - We hook into select.c to give a timeval of the
* nearest timer. On already passed timers we give
* it a 0 to immediately fire after the select
* - update_timers will call the callbacks and remove
* the timers.
*
*/
/*! \brief A structure representing a single instance of a timer */
struct osmo_timer_list {
struct rb_node node; /*!< \brief rb-tree node header */
struct llist_head list; /*!< \brief internal list header */
struct timeval timeout; /*!< \brief expiration time */
unsigned int active : 1; /*!< \brief is it active? */
void (*cb)(void*); /*!< \brief call-back called at timeout */
void *data; /*!< \brief user data for callback */
};
/**
* timer management
*/
void osmo_timer_add(struct osmo_timer_list *timer);
void osmo_timer_schedule(struct osmo_timer_list *timer, int seconds, int microseconds);
void osmo_timer_del(struct osmo_timer_list *timer);
int osmo_timer_pending(struct osmo_timer_list *timer);
int osmo_timer_remaining(const struct osmo_timer_list *timer,
const struct timeval *now,
struct timeval *remaining);
/*
* internal timer list management
*/
struct timeval *osmo_timers_nearest(void);
void osmo_timers_prepare(void);
int osmo_timers_update(void);
int osmo_timers_check(void);
/*! @} */
#endif

View File

@ -0,0 +1,79 @@
/*
* (C) 2011 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.
*
*/
/*! \defgroup timer Osmocom timers
* @{
*/
/*! \file timer_compat.h
* \brief Compatibility header with some helpers
*/
#ifndef TIMER_COMPAT_H
#define TIMER_COMPAT_H
/* Convenience macros for operations on timevals.
NOTE: `timercmp' does not work for >= or <=. */
#ifndef timerisset
# define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
#endif
#ifndef timerclear
# define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0)
#endif
#ifndef timercmp
# define timercmp(a, b, CMP) \
(((a)->tv_sec == (b)->tv_sec) ? \
((a)->tv_usec CMP (b)->tv_usec) : \
((a)->tv_sec CMP (b)->tv_sec))
#endif
#ifndef timeradd
# define timeradd(a, b, result) \
do { \
(result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \
(result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \
if ((result)->tv_usec >= 1000000) \
{ \
++(result)->tv_sec; \
(result)->tv_usec -= 1000000; \
} \
} while (0)
#endif
#ifndef timersub
# define timersub(a, b, result) \
do { \
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
(result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
if ((result)->tv_usec < 0) { \
--(result)->tv_sec; \
(result)->tv_usec += 1000000; \
} \
} while (0)
#endif
/*! @} */
#endif /* TIMER_COMPAT_H */

View File

@ -0,0 +1,56 @@
#ifndef OSMOCORE_UTIL_H
#define OSMOCORE_UTIL_H
/*! \defgroup utils General-purpose utility functions
* @{
*/
/*! \file utils.h */
/*! \brief Determine number of elements in an array of static size */
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
/*! \brief Return the maximum of two specified values */
#define OSMO_MAX(a, b) ((a) >= (b) ? (a) : (b))
/*! \brief Return the minimum of two specified values */
#define OSMO_MIN(a, b) ((a) >= (b) ? (b) : (a))
#include <stdint.h>
/*! \brief A mapping between human-readable string and numeric value */
struct value_string {
unsigned int value; /*!< \brief numeric value */
const char *str; /*!< \brief human-readable string */
};
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 osmo_bcd2char(uint8_t bcd);
/* only works for numbers in ascci */
uint8_t osmo_char2bcd(char c);
int osmo_hexparse(const char *str, uint8_t *b, int max_len);
char *osmo_ubit_dump(const uint8_t *bits, unsigned int len);
char *osmo_hexdump(const unsigned char *buf, int len);
char *osmo_hexdump_nospc(const unsigned char *buf, int len);
char *osmo_osmo_hexdump_nospc(const unsigned char *buf, int len) __attribute__((__deprecated__));
#define osmo_static_assert(exp, name) typedef int dummy##name [(exp) ? 1 : -1];
void osmo_str2lower(char *out, const char *in);
void osmo_str2upper(char *out, const char *in);
#define OSMO_SNPRINTF_RET(ret, rem, offset, len) \
do { \
len += ret; \
if (ret > rem) \
ret = rem; \
offset += ret; \
rem -= ret; \
} while (0)
/*! @} */
#endif

View File

@ -0,0 +1,63 @@
/* 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 OSMO_WQUEUE_H
#define OSMO_WQUEUE_H
/*! \defgroup write_queue Osmocom msgb write queues
* @{
*/
/*! \file write_queue.h
*/
#include <osmocom/core/select.h>
#include <osmocom/core/msgb.h>
/*! write queue instance */
struct osmo_wqueue {
/*! \brief osmocom file descriptor */
struct osmo_fd bfd;
/*! \brief maximum length of write queue */
unsigned int max_length;
/*! \brief current length of write queue */
unsigned int current_length;
/*! \brief actual linked list implementing the queue */
struct llist_head msg_queue;
/*! \brief call-back in case qeueue is readable */
int (*read_cb)(struct osmo_fd *fd);
/*! \brief call-back in case qeueue is writable */
int (*write_cb)(struct osmo_fd *fd, struct msgb *msg);
/*! \brief call-back in case qeueue has exceptions */
int (*except_cb)(struct osmo_fd *fd);
};
void osmo_wqueue_init(struct osmo_wqueue *queue, int max_length);
void osmo_wqueue_clear(struct osmo_wqueue *queue);
int osmo_wqueue_enqueue(struct osmo_wqueue *queue, struct msgb *data);
int osmo_wqueue_bfd_cb(struct osmo_fd *fd, unsigned int what);
/*! @} */
#endif

View File

@ -0,0 +1,101 @@
#ifndef _OSMOCRYPTO_AUTH_H
#define _OSMOCRYPTO_AUTH_H
/*! \addtogroup auth
* @{
*/
/*! \file auth.h */
#include <stdint.h>
#include <osmocom/core/linuxlist.h>
/*! \brief Authentication Type (GSM/UMTS) */
enum osmo_sub_auth_type {
OSMO_AUTH_TYPE_NONE = 0x00,
OSMO_AUTH_TYPE_GSM = 0x01,
OSMO_AUTH_TYPE_UMTS = 0x02,
};
/*! \brief Authentication Algorithm */
enum osmo_auth_algo {
OSMO_AUTH_ALG_NONE,
OSMO_AUTH_ALG_COMP128v1,
OSMO_AUTH_ALG_COMP128v2,
OSMO_AUTH_ALG_COMP128v3,
OSMO_AUTH_ALG_XOR,
OSMO_AUTH_ALG_MILENAGE,
_OSMO_AUTH_ALG_NUM,
};
/*! \brief permanent (secret) subscriber auth data */
struct osmo_sub_auth_data {
enum osmo_sub_auth_type type;
enum osmo_auth_algo algo;
union {
struct {
uint8_t opc[16]; /*!< operator invariant value */
uint8_t k[16]; /*!< secret key of the subscriber */
uint8_t amf[2];
uint64_t sqn; /*!< sequence number */
int opc_is_op; /*!< is the OPC field OPC (0) or OP (1) ? */
} umts;
struct {
uint8_t ki[16]; /*!< secret key */
} gsm;
} u;
};
/* data structure describing a computed auth vector, generated by AuC */
struct osmo_auth_vector {
uint8_t rand[16]; /*!< random challenge */
uint8_t autn[16]; /*!< authentication nonce */
uint8_t ck[16]; /*!< ciphering key */
uint8_t ik[16]; /*!< integrity key */
uint8_t res[16]; /*!< authentication result */
uint8_t res_len; /*!< length (in bytes) of res */
uint8_t kc[8]; /*!< Kc for GSM encryption (A5) */
uint8_t sres[4]; /*!< authentication result for GSM */
uint32_t auth_types; /*!< bitmask of OSMO_AUTH_TYPE_* */
};
/* \brief An implementation of an authentication algorithm */
struct osmo_auth_impl {
struct llist_head list;
enum osmo_auth_algo algo; /*!< algorithm we implement */
const char *name; /*!< name of the implementation */
unsigned int priority; /*!< priority value (resp. othe implementations */
/*! \brief callback for generate authentication vectors */
int (*gen_vec)(struct osmo_auth_vector *vec,
struct osmo_sub_auth_data *aud,
const uint8_t *_rand);
/* \brief callback for generationg auth vectors + re-sync */
int (*gen_vec_auts)(struct osmo_auth_vector *vec,
struct osmo_sub_auth_data *aud,
const uint8_t *rand_auts, const uint8_t *auts,
const uint8_t *_rand);
};
int osmo_auth_gen_vec(struct osmo_auth_vector *vec,
struct osmo_sub_auth_data *aud, const uint8_t *_rand);
int osmo_auth_gen_vec_auts(struct osmo_auth_vector *vec,
struct osmo_sub_auth_data *aud,
const uint8_t *rand_auts, const uint8_t *auts,
const uint8_t *_rand);
int osmo_auth_register(struct osmo_auth_impl *impl);
int osmo_auth_load(const char *path);
int osmo_auth_supported(enum osmo_auth_algo algo);
const char *osmo_auth_alg_name(enum osmo_auth_algo alg);
enum osmo_auth_algo osmo_auth_alg_parse(const char *name);
#endif /* _OSMOCRYPTO_AUTH_H */
/* @} */

View File

@ -0,0 +1,54 @@
#ifndef _GPRS_CIPHER_H
#define _GPRS_CIPHER_H
#include <osmocom/core/linuxlist.h>
#define GSM0464_CIPH_MAX_BLOCK 1523
enum gprs_ciph_algo {
GPRS_ALGO_GEA0,
GPRS_ALGO_GEA1,
GPRS_ALGO_GEA2,
GPRS_ALGO_GEA3,
_GPRS_ALGO_NUM
};
enum gprs_cipher_direction {
GPRS_CIPH_MS2SGSN,
GPRS_CIPH_SGSN2MS,
};
/* An implementation of a GPRS cipher */
struct gprs_cipher_impl {
struct llist_head list;
enum gprs_ciph_algo algo;
const char *name;
unsigned int priority;
/* As specified in 04.64 Annex A. Uses Kc, IV and direction
* to generate the 1523 bytes cipher stream that need to be
* XORed wit the plaintext for encrypt / ciphertext for decrypt */
int (*run)(uint8_t *out, uint16_t len, uint64_t kc, uint32_t iv,
enum gprs_cipher_direction direction);
};
/* register a cipher with the core (from a plugin) */
int gprs_cipher_register(struct gprs_cipher_impl *ciph);
/* load all available GPRS cipher plugins */
int gprs_cipher_load(const char *path);
/* function to be called by core code */
int gprs_cipher_run(uint8_t *out, uint16_t len, enum gprs_ciph_algo algo,
uint64_t kc, uint32_t iv, enum gprs_cipher_direction dir);
/* Do we have an implementation for this cipher? */
int gprs_cipher_supported(enum gprs_ciph_algo algo);
/* GSM TS 04.64 / Section A.2.1 : Generation of 'input' */
uint32_t gprs_cipher_gen_input_ui(uint32_t iov_ui, uint8_t sapi, uint32_t lfn, uint32_t oc);
/* GSM TS 04.64 / Section A.2.1 : Generation of 'input' */
uint32_t gprs_cipher_gen_input_i(uint32_t iov_i, uint32_t lfn, uint32_t oc);
#endif /* _GPRS_CIPHER_H */

View File

@ -0,0 +1,211 @@
#ifndef _GPRS_BSSGP_H
#define _GPRS_BSSGP_H
#include <stdint.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/gsm/gsm48.h>
#include <osmocom/gsm/prim.h>
#include <osmocom/gprs/protocol/gsm_08_18.h>
/* gprs_bssgp_util.c */
extern struct gprs_ns_inst *bssgp_nsi;
struct msgb *bssgp_msgb_alloc(void);
const char *bssgp_cause_str(enum gprs_bssgp_cause cause);
/* Transmit a simple response such as BLOCK/UNBLOCK/RESET ACK/NACK */
int bssgp_tx_simple_bvci(uint8_t pdu_type, uint16_t nsei,
uint16_t bvci, uint16_t ns_bvci);
/* Chapter 10.4.14: Status */
int bssgp_tx_status(uint8_t cause, uint16_t *bvci, struct msgb *orig_msg);
enum bssgp_prim {
PRIM_BSSGP_DL_UD,
PRIM_BSSGP_UL_UD,
PRIM_BSSGP_PTM_UD,
PRIM_BSSGP_GMM_SUSPEND,
PRIM_BSSGP_GMM_RESUME,
PRIM_BSSGP_GMM_PAGING,
PRIM_NM_FLUSH_LL,
PRIM_NM_LLC_DISCARDED,
PRIM_NM_BVC_RESET,
PRIM_NM_BVC_BLOCK,
PRIM_NM_BVC_UNBLOCK,
};
struct osmo_bssgp_prim {
struct osmo_prim_hdr oph;
/* common fields */
uint16_t nsei;
uint16_t bvci;
uint32_t tlli;
struct tlv_parsed *tp;
struct gprs_ra_id *ra_id;
/* specific fields */
union {
struct {
uint8_t suspend_ref;
} resume;
} u;
};
/* gprs_bssgp.c */
/*! \brief BSSGP flow control (SGSN side) According to Section 8.2 */
struct bssgp_flow_control {
uint32_t bucket_size_max; /*!< maximum size of the bucket (octets) */
uint32_t bucket_leak_rate; /*!< leak rate of the bucket (octets/sec) */
uint32_t bucket_counter; /*!< number of tokens in the bucket */
struct timeval time_last_pdu; /*!< timestamp of last PDU sent */
/* the built-in queue */
uint32_t max_queue_depth; /*!< how many packets to queue (mgs) */
uint32_t queue_depth; /*!< current length of queue (msgs) */
struct llist_head queue; /*!< linked list of msgb's */
struct osmo_timer_list timer; /*!< timer-based dequeueing */
/*! callback to be called at output of flow control */
int (*out_cb)(struct bssgp_flow_control *fc, struct msgb *msg,
uint32_t llc_pdu_len, void *priv);
};
#define BVC_S_BLOCKED 0x0001
/* The per-BTS context that we keep on the SGSN side of the BSSGP link */
struct bssgp_bvc_ctx {
struct llist_head list;
struct gprs_ra_id ra_id; /*!< parsed RA ID of the remote BTS */
uint16_t cell_id; /*!< Cell ID of the remote BTS */
/* NSEI and BVCI of underlying Gb link. Together they
* uniquely identify a link to a BTS (5.4.4) */
uint16_t bvci;
uint16_t nsei;
uint32_t state;
struct rate_ctr_group *ctrg;
struct bssgp_flow_control *fc;
/*! default maximum size of per-MS bucket in octets */
uint32_t bmax_default_ms;
/*! default bucket leak rate of per-MS bucket in octests/s */
uint32_t r_default_ms;
/* we might want to add this as a shortcut later, avoiding the NSVC
* lookup for every packet, similar to a routing cache */
//struct gprs_nsvc *nsvc;
};
extern struct llist_head bssgp_bvc_ctxts;
/* Find a BTS Context based on parsed RA ID and Cell ID */
struct bssgp_bvc_ctx *btsctx_by_raid_cid(const struct gprs_ra_id *raid, uint16_t cid);
/* Find a BTS context based on BVCI+NSEI tuple */
struct bssgp_bvc_ctx *btsctx_by_bvci_nsei(uint16_t bvci, uint16_t nsei);
#define BVC_F_BLOCKED 0x0001
enum bssgp_ctr {
BSSGP_CTR_PKTS_IN,
BSSGP_CTR_PKTS_OUT,
BSSGP_CTR_BYTES_IN,
BSSGP_CTR_BYTES_OUT,
BSSGP_CTR_BLOCKED,
BSSGP_CTR_DISCARDED,
};
#include <osmocom/gsm/tlv.h>
#include <osmocom/gprs/gprs_msgb.h>
/* BSSGP-UL-UNITDATA.ind */
int bssgp_rcvmsg(struct msgb *msg);
/* BSSGP-DL-UNITDATA.req */
struct bssgp_lv {
uint16_t len;
uint8_t *v;
};
/* parameters for BSSGP downlink userdata transmission */
struct bssgp_dl_ud_par {
uint32_t *tlli;
char *imsi;
struct bssgp_flow_control *fc;
uint16_t drx_parms;
/* FIXME: priority */
struct bssgp_lv ms_ra_cap;
uint8_t qos_profile[3];
};
int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
struct bssgp_dl_ud_par *dup);
uint16_t bssgp_parse_cell_id(struct gprs_ra_id *raid, const uint8_t *buf);
int bssgp_create_cell_id(uint8_t *buf, const struct gprs_ra_id *raid,
uint16_t cid);
/* Wrapper around TLV parser to parse BSSGP IEs */
static inline int bssgp_tlv_parse(struct tlv_parsed *tp, uint8_t *buf, int len)
{
return tlv_parse(tp, &tvlv_att_def, buf, len, 0, 0);
}
/*! \brief BSSGP Paging mode */
enum bssgp_paging_mode {
BSSGP_PAGING_PS,
BSSGP_PAGING_CS,
};
/*! \brief BSSGP Paging scope */
enum bssgp_paging_scope {
BSSGP_PAGING_BSS_AREA, /*!< all cells in BSS */
BSSGP_PAGING_LOCATION_AREA, /*!< all cells in LA */
BSSGP_PAGING_ROUTEING_AREA, /*!< all cells in RA */
BSSGP_PAGING_BVCI, /*!< one cell */
};
/*! \brief BSSGP paging information */
struct bssgp_paging_info {
enum bssgp_paging_mode mode; /*!< CS or PS paging */
enum bssgp_paging_scope scope; /*!< bssgp_paging_scope */
struct gprs_ra_id raid; /*!< RA Identifier */
uint16_t bvci; /*!< BVCI */
char *imsi; /*!< IMSI, if any */
uint32_t *ptmsi; /*!< P-TMSI, if any */
uint16_t drx_params; /*!< DRX parameters */
uint8_t qos[3]; /*!< QoS parameters */
};
/* Send a single GMM-PAGING.req to a given NSEI/NS-BVCI */
int bssgp_tx_paging(uint16_t nsei, uint16_t ns_bvci,
struct bssgp_paging_info *pinfo);
void bssgp_fc_init(struct bssgp_flow_control *fc,
uint32_t bucket_size_max, uint32_t bucket_leak_rate,
uint32_t max_queue_depth,
int (*out_cb)(struct bssgp_flow_control *fc, struct msgb *msg,
uint32_t llc_pdu_len, void *priv));
/* input function of the flow control implementation, called first
* for the MM flow control, and then as the MM flow control output
* callback in order to perform BVC flow control */
int bssgp_fc_in(struct bssgp_flow_control *fc, struct msgb *msg,
uint32_t llc_pdu_len, void *priv);
/* Initialize the Flow Control parameters for a new MS according to
* default values for the BVC specified by BVCI and NSEI */
int bssgp_fc_ms_init(struct bssgp_flow_control *fc_ms, uint16_t bvci,
uint16_t nsei, uint32_t max_queue_depth);
/* gprs_bssgp_vty.c */
int bssgp_vty_init(void);
void bssgp_set_log_ss(int ss);
int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx);
#endif /* _GPRS_BSSGP_H */

View File

@ -0,0 +1,75 @@
#ifndef _BSSGP_BSS_H
#define _BSSGP_BSS_H
#include <osmocom/core/msgb.h>
#include <osmocom/gprs/gprs_bssgp.h>
/* GPRS BSSGP protocol implementation as per 3GPP TS 08.18 */
/* (C) 2009-2012 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 Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
uint8_t *bssgp_msgb_tlli_put(struct msgb *msg, uint32_t tlli);
int bssgp_tx_suspend(uint16_t nsei, uint32_t tlli,
const struct gprs_ra_id *ra_id);
int bssgp_tx_resume(uint16_t nsei, uint32_t tlli,
const struct gprs_ra_id *ra_id, uint8_t suspend_ref);
int bssgp_tx_ra_capa_upd(struct bssgp_bvc_ctx *bctx, uint32_t tlli, uint8_t tag);
int bssgp_tx_radio_status_tlli(struct bssgp_bvc_ctx *bctx, uint8_t cause,
uint32_t tlli);
int bssgp_tx_radio_status_tmsi(struct bssgp_bvc_ctx *bctx, uint8_t cause,
uint32_t tmsi);
int bssgp_tx_radio_status_imsi(struct bssgp_bvc_ctx *bctx, uint8_t cause,
const char *imsi);
int bssgp_tx_flush_ll_ack(struct bssgp_bvc_ctx *bctx, uint32_t tlli,
uint8_t action, uint16_t bvci_new,
uint32_t num_octets);
int bssgp_tx_llc_discarded(struct bssgp_bvc_ctx *bctx, uint32_t tlli,
uint8_t num_frames, uint32_t num_octets);
int bssgp_tx_bvc_block(struct bssgp_bvc_ctx *bctx, uint8_t cause);
int bssgp_tx_bvc_unblock(struct bssgp_bvc_ctx *bctx);
int bssgp_tx_bvc_reset(struct bssgp_bvc_ctx *bctx, uint16_t bvci, uint8_t cause);
int bssgp_tx_ul_ud(struct bssgp_bvc_ctx *bctx, uint32_t tlli,
const uint8_t *qos_profile, struct msgb *llc_pdu);
int bssgp_rx_paging(struct bssgp_paging_info *pinfo,
struct msgb *msg);
int bssgp_tx_fc_bvc(struct bssgp_bvc_ctx *bctx, uint8_t tag,
uint32_t bucket_size, uint32_t bucket_leak_rate,
uint16_t bmax_default_ms, uint32_t r_default_ms,
uint8_t *bucket_full_ratio, uint32_t *queue_delay_ms);
int bssgp_tx_fc_ms(struct bssgp_bvc_ctx *bctx, uint32_t tlli, uint8_t tag,
uint32_t ms_bucket_size, uint32_t bucket_leak_rate,
uint8_t *bucket_full_ratio);
#endif

View File

@ -0,0 +1,37 @@
#ifndef _LIBGB_MSGB_H
#define _LIBGB_MSGB_H
#include <stdint.h>
/* the data structure stored in msgb->cb for libgb apps */
struct libgb_msgb_cb {
unsigned char *bssgph;
unsigned char *llch;
/* Cell Identifier */
unsigned char *bssgp_cell_id;
/* Identifiers of a BTS, equal to 'struct bssgp_bts_ctx' */
uint16_t nsei;
uint16_t bvci;
/* Identifier of a MS (inside BTS), equal to 'struct sgsn_mm_ctx' */
uint32_t tlli;
} __attribute__((packed));
#define LIBGB_MSGB_CB(__msgb) ((struct libgb_msgb_cb *)&((__msgb)->cb[0]))
#define msgb_tlli(__x) LIBGB_MSGB_CB(__x)->tlli
#define msgb_nsei(__x) LIBGB_MSGB_CB(__x)->nsei
#define msgb_bvci(__x) LIBGB_MSGB_CB(__x)->bvci
#define msgb_gmmh(__x) (__x)->l3h
#define msgb_bssgph(__x) LIBGB_MSGB_CB(__x)->bssgph
#define msgb_bssgp_len(__x) ((__x)->tail - (uint8_t *)msgb_bssgph(__x))
#define msgb_bcid(__x) LIBGB_MSGB_CB(__x)->bssgp_cell_id
#define msgb_llch(__x) LIBGB_MSGB_CB(__x)->llch
/* logging contexts */
#define GPRS_CTX_NSVC 0
#define GPRS_CTX_BVC 1
#include <osmocom/core/logging.h>
int gprs_log_filter_fn(const struct log_context *ctx,
struct log_target *tar);
#endif

View File

@ -0,0 +1,189 @@
#ifndef _GPRS_NS_H
#define _GPRS_NS_H
#include <stdint.h>
/* Our Implementation */
#include <netinet/in.h>
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/select.h>
#include <osmocom/gprs/gprs_msgb.h>
#include <osmocom/gprs/protocol/gsm_08_16.h>
#define NS_TIMERS_COUNT 7
#define NS_TIMERS "(tns-block|tns-block-retries|tns-reset|tns-reset-retries|tns-test|tns-alive|tns-alive-retries)"
#define NS_TIMERS_HELP \
"(un)blocking Timer (Tns-block) timeout\n" \
"(un)blocking Timer (Tns-block) number of retries\n" \
"Reset Timer (Tns-reset) timeout\n" \
"Reset Timer (Tns-reset) number of retries\n" \
"Test Timer (Tns-test) timeout\n" \
"Alive Timer (Tns-alive) timeout\n" \
"Alive Timer (Tns-alive) number of retries\n"
enum ns_timeout {
NS_TOUT_TNS_BLOCK,
NS_TOUT_TNS_BLOCK_RETRIES,
NS_TOUT_TNS_RESET,
NS_TOUT_TNS_RESET_RETRIES,
NS_TOUT_TNS_TEST,
NS_TOUT_TNS_ALIVE,
NS_TOUT_TNS_ALIVE_RETRIES,
};
#define NSE_S_BLOCKED 0x0001
#define NSE_S_ALIVE 0x0002
/*! \brief Osmocom NS link layer types */
enum gprs_ns_ll {
GPRS_NS_LL_UDP, /*!< NS/UDP/IP */
GPRS_NS_LL_E1, /*!< NS/E1 */
GPRS_NS_LL_FR_GRE, /*!< NS/FR/GRE/IP */
};
/*! \brief Osmoco NS events */
enum gprs_ns_evt {
GPRS_NS_EVT_UNIT_DATA,
};
struct gprs_nsvc;
/*! \brief Osmocom GPRS callback function type */
typedef int gprs_ns_cb_t(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
struct msgb *msg, uint16_t bvci);
/*! \brief An instance of the NS protocol stack */
struct gprs_ns_inst {
/*! \brief callback to the user for incoming UNIT DATA IND */
gprs_ns_cb_t *cb;
/*! \brief linked lists of all NSVC in this instance */
struct llist_head gprs_nsvcs;
/*! \brief a NSVC object that's needed to deal with packets for
* unknown NSVC */
struct gprs_nsvc *unknown_nsvc;
uint16_t timeout[NS_TIMERS_COUNT];
/*! \brief NS-over-IP specific bits */
struct {
struct osmo_fd fd;
uint32_t local_ip;
uint16_t local_port;
} nsip;
/*! \brief NS-over-FR-over-GRE-over-IP specific bits */
struct {
struct osmo_fd fd;
uint32_t local_ip;
unsigned int enabled:1;
} frgre;
};
enum nsvc_timer_mode {
/* standard timers */
NSVC_TIMER_TNS_TEST,
NSVC_TIMER_TNS_ALIVE,
NSVC_TIMER_TNS_RESET,
_NSVC_TIMER_NR,
};
/*! \brief Structure representing a single NS-VC */
struct gprs_nsvc {
/*! \brief list of NS-VCs within NS Instance */
struct llist_head list;
/*! \brief pointer to NS Instance */
struct gprs_ns_inst *nsi;
uint16_t nsei; /*! \brief end-to-end significance */
uint16_t nsvci; /*! \brief uniquely identifies NS-VC at SGSN */
uint32_t state;
uint32_t remote_state;
struct osmo_timer_list timer;
enum nsvc_timer_mode timer_mode;
int alive_retries;
unsigned int remote_end_is_sgsn:1;
unsigned int persistent:1;
struct rate_ctr_group *ctrg;
/*! \brief which link-layer are we based on? */
enum gprs_ns_ll ll;
union {
struct {
struct sockaddr_in bts_addr;
} ip;
struct {
struct sockaddr_in bts_addr;
} frgre;
};
};
/* Create a new NS protocol instance */
struct gprs_ns_inst *gprs_ns_instantiate(gprs_ns_cb_t *cb, void *ctx);
/* Destroy a NS protocol instance */
void gprs_ns_destroy(struct gprs_ns_inst *nsi);
/* Listen for incoming GPRS packets via NS/UDP */
int gprs_ns_nsip_listen(struct gprs_ns_inst *nsi);
/* Establish a connection (from the BSS) to the SGSN */
struct gprs_nsvc *gprs_ns_nsip_connect(struct gprs_ns_inst *nsi,
struct sockaddr_in *dest,
uint16_t nsei, uint16_t nsvci);
struct sockaddr_in;
/* main function for higher layers (BSSGP) to send NS messages */
int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg);
int gprs_ns_tx_reset(struct gprs_nsvc *nsvc, uint8_t cause);
int gprs_ns_tx_block(struct gprs_nsvc *nsvc, uint8_t cause);
int gprs_ns_tx_unblock(struct gprs_nsvc *nsvc);
/* Listen for incoming GPRS packets via NS/FR/GRE */
int gprs_ns_frgre_listen(struct gprs_ns_inst *nsi);
struct gprs_nsvc *gprs_nsvc_create(struct gprs_ns_inst *nsi, uint16_t nsvci);
void gprs_nsvc_delete(struct gprs_nsvc *nsvc);
struct gprs_nsvc *gprs_nsvc_by_nsei(struct gprs_ns_inst *nsi, uint16_t nsei);
struct gprs_nsvc *gprs_nsvc_by_nsvci(struct gprs_ns_inst *nsi, uint16_t nsvci);
/* Initiate a RESET procedure (including timer start, ...)*/
void gprs_nsvc_reset(struct gprs_nsvc *nsvc, uint8_t cause);
/* Add NS-specific VTY stuff */
int gprs_ns_vty_init(struct gprs_ns_inst *nsi);
#define NS_ALLOC_SIZE 2048
#define NS_ALLOC_HEADROOM 20
static inline struct msgb *gprs_ns_msgb_alloc(void)
{
return msgb_alloc_headroom(NS_ALLOC_SIZE, NS_ALLOC_HEADROOM, "GPRS/NS");
}
enum signal_ns {
S_NS_RESET,
S_NS_BLOCK,
S_NS_UNBLOCK,
S_NS_ALIVE_EXP, /* Tns-alive expired more than N times */
};
struct ns_signal_data {
struct gprs_nsvc *nsvc;
uint8_t cause;
};
void gprs_ns_set_log_ss(int ss);
/*! }@ */
#endif

View File

@ -0,0 +1,6 @@
#ifndef _GPRS_NS_FRGRE_H
#define _GPRS_NS_FRGRE_H
int gprs_ns_frgre_sendmsg(struct gprs_nsvc *nsvc, struct msgb *msg);
#endif

View File

@ -0,0 +1,85 @@
#ifndef _OSMO_08_16_H
#define _OSMO_08_16_H
/* GPRS Networks Service (NS) messages on the Gb interface
* 3GPP TS 08.16 version 8.0.1 Release 1999 / ETSI TS 101 299 V8.0.1 (2002-05)
* 3GPP TS 48.016 version 6.5.0 Release 6 / ETSI TS 148 016 V6.5.0 (2005-11) */
#include <stdint.h>
/*! \addtogroup libgb
* @{
*/
/*! \file gprs_ns.h */
/*! \brief Common header of GPRS NS */
struct gprs_ns_hdr {
uint8_t pdu_type; /*!< NS PDU type */
uint8_t data[0]; /*!< variable-length payload */
} __attribute__((packed));
/*! \brief NS PDU Type (TS 08.16, Section 10.3.7, Table 14) */
enum ns_pdu_type {
NS_PDUT_UNITDATA = 0x00,
NS_PDUT_RESET = 0x02,
NS_PDUT_RESET_ACK = 0x03,
NS_PDUT_BLOCK = 0x04,
NS_PDUT_BLOCK_ACK = 0x05,
NS_PDUT_UNBLOCK = 0x06,
NS_PDUT_UNBLOCK_ACK = 0x07,
NS_PDUT_STATUS = 0x08,
NS_PDUT_ALIVE = 0x0a,
NS_PDUT_ALIVE_ACK = 0x0b,
/* TS 48.016 Section 10.3.7, Table 10.3.7.1 */
SNS_PDUT_ACK = 0x0c,
SNS_PDUT_ADD = 0x0d,
SNS_PDUT_CHANGE_WEIGHT = 0x0e,
SNS_PDUT_CONFIG = 0x0f,
SNS_PDUT_CONFIG_ACK = 0x10,
SNS_PDUT_DELETE = 0x11,
SNS_PDUT_SIZE = 0x12,
SNS_PDUT_SIZE_ACK = 0x13,
};
/*! \brief NS Control IE (TS 08.16, Section 10.3, Table 12) */
enum ns_ctrl_ie {
NS_IE_CAUSE = 0x00,
NS_IE_VCI = 0x01,
NS_IE_PDU = 0x02,
NS_IE_BVCI = 0x03,
NS_IE_NSEI = 0x04,
/* TS 48.016 Section 10.3, Table 10.3.1 */
NS_IE_IPv4_LIST = 0x05,
NS_IE_IPv6_LIST = 0x06,
NS_IE_MAX_NR_NSVC = 0x07,
NS_IE_IPv4_EP_NR = 0x08,
NS_IE_IPv6_EP_NR = 0x09,
NS_IE_RESET_FLAG = 0x0a,
NS_IE_IP_ADDR = 0x0b,
};
/*! \brief NS Cause (TS 08.16, Section 10.3.2, Table 13) */
enum ns_cause {
NS_CAUSE_TRANSIT_FAIL = 0x00,
NS_CAUSE_OM_INTERVENTION = 0x01,
NS_CAUSE_EQUIP_FAIL = 0x02,
NS_CAUSE_NSVC_BLOCKED = 0x03,
NS_CAUSE_NSVC_UNKNOWN = 0x04,
NS_CAUSE_BVCI_UNKNOWN = 0x05,
NS_CAUSE_SEM_INCORR_PDU = 0x08,
NS_CAUSE_PDU_INCOMP_PSTATE = 0x0a,
NS_CAUSE_PROTO_ERR_UNSPEC = 0x0b,
NS_CAUSE_INVAL_ESSENT_IE = 0x0c,
NS_CAUSE_MISSING_ESSENT_IE = 0x0d,
/* TS 48.016 Section 10.3.2, Table 10.3.2.1 */
NS_CAUSE_INVAL_NR_IPv4_EP = 0x0e,
NS_CAUSE_INVAL_NR_IPv6_EP = 0x0f,
NS_CAUSE_INVAL_NR_NS_VC = 0x10,
NS_CAUSE_INVAL_WEIGH = 0x11,
NS_CAUSE_UNKN_IP_EP = 0x12,
NS_CAUSE_UNKN_IP_ADDR = 0x13,
NS_CAUSE_UNKN_IP_TEST_FAILED = 0x14,
};
#endif

View File

@ -0,0 +1,144 @@
#ifndef _OSMO_08_18_H
#define _OSMO_08_18_H
#include <stdint.h>
/*! \brief Fixed BVCI definitions (Section 5.4.1) */
#define BVCI_SIGNALLING 0x0000
#define BVCI_PTM 0x0001
/*! \brief BSSGP PDU types (Section 11.3.26 / Table 11.27) */
enum bssgp_pdu_type {
/* PDUs between RL and BSSGP SAPs */
BSSGP_PDUT_DL_UNITDATA = 0x00,
BSSGP_PDUT_UL_UNITDATA = 0x01,
BSSGP_PDUT_RA_CAPABILITY = 0x02,
BSSGP_PDUT_PTM_UNITDATA = 0x03,
/* PDUs between GMM SAPs */
BSSGP_PDUT_PAGING_PS = 0x06,
BSSGP_PDUT_PAGING_CS = 0x07,
BSSGP_PDUT_RA_CAPA_UDPATE = 0x08,
BSSGP_PDUT_RA_CAPA_UPDATE_ACK = 0x09,
BSSGP_PDUT_RADIO_STATUS = 0x0a,
BSSGP_PDUT_SUSPEND = 0x0b,
BSSGP_PDUT_SUSPEND_ACK = 0x0c,
BSSGP_PDUT_SUSPEND_NACK = 0x0d,
BSSGP_PDUT_RESUME = 0x0e,
BSSGP_PDUT_RESUME_ACK = 0x0f,
BSSGP_PDUT_RESUME_NACK = 0x10,
/* PDus between NM SAPs */
BSSGP_PDUT_BVC_BLOCK = 0x20,
BSSGP_PDUT_BVC_BLOCK_ACK = 0x21,
BSSGP_PDUT_BVC_RESET = 0x22,
BSSGP_PDUT_BVC_RESET_ACK = 0x23,
BSSGP_PDUT_BVC_UNBLOCK = 0x24,
BSSGP_PDUT_BVC_UNBLOCK_ACK = 0x25,
BSSGP_PDUT_FLOW_CONTROL_BVC = 0x26,
BSSGP_PDUT_FLOW_CONTROL_BVC_ACK = 0x27,
BSSGP_PDUT_FLOW_CONTROL_MS = 0x28,
BSSGP_PDUT_FLOW_CONTROL_MS_ACK = 0x29,
BSSGP_PDUT_FLUSH_LL = 0x2a,
BSSGP_PDUT_FLUSH_LL_ACK = 0x2b,
BSSGP_PDUT_LLC_DISCARD = 0x2c,
BSSGP_PDUT_SGSN_INVOKE_TRACE = 0x40,
BSSGP_PDUT_STATUS = 0x41,
/* PDUs between PFM SAP's */
BSSGP_PDUT_DOWNLOAD_BSS_PFC = 0x50,
BSSGP_PDUT_CREATE_BSS_PFC = 0x51,
BSSGP_PDUT_CREATE_BSS_PFC_ACK = 0x52,
BSSGP_PDUT_CREATE_BSS_PFC_NACK = 0x53,
BSSGP_PDUT_MODIFY_BSS_PFC = 0x54,
BSSGP_PDUT_MODIFY_BSS_PFC_ACK = 0x55,
BSSGP_PDUT_DELETE_BSS_PFC = 0x56,
BSSGP_PDUT_DELETE_BSS_PFC_ACK = 0x57,
};
/*! \brief BSSGP User-Data header (Section 10.2.1 and 10.2.2) */
struct bssgp_ud_hdr {
uint8_t pdu_type; /*!< BSSGP PDU type */
uint32_t tlli; /*!< Temporary Link-Local Identifier */
uint8_t qos_profile[3]; /*!< QoS profile */
uint8_t data[0]; /* optional/conditional IEs as TLVs */
} __attribute__((packed));
/*! \brief BSSGP normal header */
struct bssgp_normal_hdr {
uint8_t pdu_type; /*!< BSSGP PDU type */
uint8_t data[0]; /*!< optional/conditional IEs as TLVs */
};
/*! \brief BSSGP Information Element Identifiers */
enum bssgp_iei_type {
BSSGP_IE_ALIGNMENT = 0x00,
BSSGP_IE_BMAX_DEFAULT_MS = 0x01,
BSSGP_IE_BSS_AREA_ID = 0x02,
BSSGP_IE_BUCKET_LEAK_RATE = 0x03,
BSSGP_IE_BVCI = 0x04,
BSSGP_IE_BVC_BUCKET_SIZE = 0x05,
BSSGP_IE_BVC_MEASUREMENT = 0x06,
BSSGP_IE_CAUSE = 0x07,
BSSGP_IE_CELL_ID = 0x08,
BSSGP_IE_CHAN_NEEDED = 0x09,
BSSGP_IE_DRX_PARAMS = 0x0a,
BSSGP_IE_EMLPP_PRIO = 0x0b,
BSSGP_IE_FLUSH_ACTION = 0x0c,
BSSGP_IE_IMSI = 0x0d,
BSSGP_IE_LLC_PDU = 0x0e,
BSSGP_IE_LLC_FRAMES_DISCARDED = 0x0f,
BSSGP_IE_LOCATION_AREA = 0x10,
BSSGP_IE_MOBILE_ID = 0x11,
BSSGP_IE_MS_BUCKET_SIZE = 0x12,
BSSGP_IE_MS_RADIO_ACCESS_CAP = 0x13,
BSSGP_IE_OMC_ID = 0x14,
BSSGP_IE_PDU_IN_ERROR = 0x15,
BSSGP_IE_PDU_LIFETIME = 0x16,
BSSGP_IE_PRIORITY = 0x17,
BSSGP_IE_QOS_PROFILE = 0x18,
BSSGP_IE_RADIO_CAUSE = 0x19,
BSSGP_IE_RA_CAP_UPD_CAUSE = 0x1a,
BSSGP_IE_ROUTEING_AREA = 0x1b,
BSSGP_IE_R_DEFAULT_MS = 0x1c,
BSSGP_IE_SUSPEND_REF_NR = 0x1d,
BSSGP_IE_TAG = 0x1e,
BSSGP_IE_TLLI = 0x1f,
BSSGP_IE_TMSI = 0x20,
BSSGP_IE_TRACE_REFERENC = 0x21,
BSSGP_IE_TRACE_TYPE = 0x22,
BSSGP_IE_TRANSACTION_ID = 0x23,
BSSGP_IE_TRIGGER_ID = 0x24,
BSSGP_IE_NUM_OCT_AFF = 0x25,
BSSGP_IE_LSA_ID_LIST = 0x26,
BSSGP_IE_LSA_INFORMATION = 0x27,
BSSGP_IE_PACKET_FLOW_ID = 0x28,
BSSGP_IE_PACKET_FLOW_TIMER = 0x29,
BSSGP_IE_AGG_BSS_QOS_PROFILE = 0x3a,
BSSGP_IE_FEATURE_BITMAP = 0x3b,
BSSGP_IE_BUCKET_FULL_RATIO = 0x3c,
BSSGP_IE_SERVICE_UTRAN_CCO = 0x3d,
};
/*! \brief Cause coding (Section 11.3.8 / Table 11.10) */
enum gprs_bssgp_cause {
BSSGP_CAUSE_PROC_OVERLOAD = 0x00,
BSSGP_CAUSE_EQUIP_FAIL = 0x01,
BSSGP_CAUSE_TRASIT_NET_FAIL = 0x02,
BSSGP_CAUSE_CAPA_GREATER_0KPBS = 0x03,
BSSGP_CAUSE_UNKNOWN_MS = 0x04,
BSSGP_CAUSE_UNKNOWN_BVCI = 0x05,
BSSGP_CAUSE_CELL_TRAF_CONG = 0x06,
BSSGP_CAUSE_SGSN_CONG = 0x07,
BSSGP_CAUSE_OML_INTERV = 0x08,
BSSGP_CAUSE_BVCI_BLOCKED = 0x09,
BSSGP_CAUSE_PFC_CREATE_FAIL = 0x0a,
BSSGP_CAUSE_SEM_INCORR_PDU = 0x20,
BSSGP_CAUSE_INV_MAND_INF = 0x21,
BSSGP_CAUSE_MISSING_MAND_IE = 0x22,
BSSGP_CAUSE_MISSING_COND_IE = 0x23,
BSSGP_CAUSE_UNEXP_COND_IE = 0x24,
BSSGP_CAUSE_COND_IE_ERR = 0x25,
BSSGP_CAUSE_PDU_INCOMP_STATE = 0x26,
BSSGP_CAUSE_PROTO_ERR_UNSPEC = 0x27,
BSSGP_CAUSE_PDU_INCOMP_FEAT = 0x28,
};
#endif

View File

@ -0,0 +1,63 @@
/*
* a5.h
*
* Copyright (C) 2011 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.
*/
#ifndef __OSMO_A5_H__
#define __OSMO_A5_H__
#include <stdint.h>
#include <osmocom/core/bits.h>
/*! \defgroup a5 GSM A5 ciphering algorithm
* @{
*/
/*! \file gsm/a5.h
* \brief Osmocom GSM A5 ciphering algorithm header
*/
/*! \brief Converts a frame number into the 22 bit number used in A5/x
* \param[in] fn The true framenumber
* \return 22 bit word
*/
static inline uint32_t
osmo_a5_fn_count(uint32_t fn)
{
int t1 = fn / (26 * 51);
int t2 = fn % 26;
int t3 = fn % 51;
return (t1 << 11) | (t3 << 5) | t2;
}
/* Notes:
* - key must be 8 bytes long (or NULL for A5/0)
* - the dl and ul pointer must be either NULL or 114 bits long
* - fn is the _real_ GSM frame number.
* (converted internally to fn_count)
*/
void osmo_a5(int n, const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul);
void osmo_a5_1(const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul);
void osmo_a5_2(const uint8_t *key, uint32_t fn, ubit_t *dl, ubit_t *ul);
/*! @} */
#endif /* __OSMO_A5_H__ */

View File

@ -0,0 +1,40 @@
#ifndef _OSMO_GSM_ABIS_NM_H
#define _OSMO_GSM_ABIS_NM_H
/*! \defgroup oml A-bis OML
* @{
*/
#include <osmocom/gsm/tlv.h>
#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/gsm/protocol/gsm_12_21.h>
/*! \file abis_nm.h */
enum abis_nm_msgtype;
enum gsm_phys_chan_config;
extern const enum abis_nm_msgtype abis_nm_reports[4];
extern const enum abis_nm_msgtype abis_nm_no_ack_nack[3];
extern const enum abis_nm_msgtype abis_nm_sw_load_msgs[9];
extern const enum abis_nm_msgtype abis_nm_nacks[33];
extern const struct value_string abis_nm_obj_class_names[];
extern const struct value_string abis_nm_adm_state_names[];
const char *abis_nm_nack_cause_name(uint8_t cause);
const char *abis_nm_nack_name(uint8_t nack);
const char *abis_nm_event_type_name(uint8_t cause);
const char *abis_nm_severity_name(uint8_t cause);
extern const struct tlv_definition abis_nm_att_tlvdef;
const char *abis_nm_opstate_name(uint8_t os);
const char *abis_nm_avail_name(uint8_t avail);
const char *abis_nm_test_name(uint8_t test);
void abis_nm_debugp_foh(int ss, struct abis_om_fom_hdr *foh);
int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan);
enum abis_nm_chan_comb abis_nm_pchan4chcomb(uint8_t chcomb);
/*! @} */
#endif /* _OSMO_GSM_ABIS_NM_H */

View File

@ -0,0 +1,22 @@
/*
* 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(const uint8_t *ki, const uint8_t *srand, uint8_t *sres, uint8_t *kc);
#endif /* __COMP128_H__ */

View File

@ -0,0 +1,9 @@
#ifndef _OSMO_GSM_GAN_H
#define _OSMO_GSM_GAN_H
#include <osmocom/core/utils.h>
extern const struct value_string gan_msgt_vals[];
static const struct value_string gan_pdisc_vals[];
#endif

View File

@ -0,0 +1,63 @@
#ifndef _GSM0411_SMC_H
#define _GSM0411_SMC_H
#include <osmocom/core/timer.h>
#include <osmocom/gsm/protocol/gsm_04_11.h>
#define GSM411_MMSMS_EST_REQ 0x310
#define GSM411_MMSMS_EST_IND 0x312
#define GSM411_MMSMS_EST_CNF 0x311
#define GSM411_MMSMS_REL_REQ 0x320
#define GSM411_MMSMS_REL_IND 0x322
#define GSM411_MMSMS_DATA_REQ 0x330
#define GSM411_MMSMS_DATA_IND 0x332
#define GSM411_MMSMS_UNIT_DATA_REQ 0x340
#define GSM411_MMSMS_UNIT_DATA_IND 0x342
#define GSM411_MMSMS_ERR_IND 0x372
#define GSM411_MNSMS_ABORT_REQ 0x101
#define GSM411_MNSMS_DATA_REQ 0x102
#define GSM411_MNSMS_DATA_IND 0x103
#define GSM411_MNSMS_EST_REQ 0x104
#define GSM411_MNSMS_EST_IND 0x105
#define GSM411_MNSMS_ERROR_IND 0x106
#define GSM411_MNSMS_REL_REQ 0x107
struct gsm411_smc_inst {
int network; /* is this a MO (0) or MT (1) transfer */
int (*mn_recv) (struct gsm411_smc_inst *inst, int msg_type,
struct msgb *msg);
int (*mm_send) (struct gsm411_smc_inst *inst, int msg_type,
struct msgb *msg, int cp_msg_type);
enum gsm411_cp_state cp_state;
struct osmo_timer_list cp_timer;
struct msgb *cp_msg; /* store pending message */
int cp_rel; /* store pending release */
int cp_retx; /* retry counter */
int cp_max_retr; /* maximum retry */
int cp_tc1; /* timer value TC1* */
};
extern const struct value_string gsm411_cp_cause_strs[];
/* init a new instance */
void gsm411_smc_init(struct gsm411_smc_inst *inst, int network,
int (*mn_recv) (struct gsm411_smc_inst *inst, int msg_type,
struct msgb *msg),
int (*mm_send) (struct gsm411_smc_inst *inst, int msg_type,
struct msgb *msg, int cp_msg_type));
/* clear instance */
void gsm411_smc_clear(struct gsm411_smc_inst *inst);
/* message from upper layer */
int gsm411_smc_send(struct gsm411_smc_inst *inst, int msg_type,
struct msgb *msg);
/* message from lower layer */
int gsm411_smc_recv(struct gsm411_smc_inst *inst, int msg_type,
struct msgb *msg, int cp_msg_type);
#endif /* _GSM0411_SMC_H */

View File

@ -0,0 +1,45 @@
#ifndef _GSM0411_SMR_H
#define _GSM0411_SMR_H
#include <osmocom/gsm/protocol/gsm_04_11.h>
#define GSM411_SM_RL_DATA_REQ 0x401
#define GSM411_SM_RL_DATA_IND 0x402
#define GSM411_SM_RL_MEM_AVAIL_REQ 0x403
#define GSM411_SM_RL_MEM_AVAIL_IND 0x404
#define GSM411_SM_RL_REPORT_REQ 0x405
#define GSM411_SM_RL_REPORT_IND 0x406
struct gsm411_smr_inst {
int network; /* is this a MO (0) or MT (1) transfer */
int (*rl_recv) (struct gsm411_smr_inst *inst, int msg_type,
struct msgb *msg);
int (*mn_send) (struct gsm411_smr_inst *inst, int msg_type,
struct msgb *msg);
enum gsm411_rp_state rp_state;
struct osmo_timer_list rp_timer;
};
extern const struct value_string gsm411_rp_cause_strs[];
/* init a new instance */
void gsm411_smr_init(struct gsm411_smr_inst *inst, int network,
int (*rl_recv) (struct gsm411_smr_inst *inst, int msg_type,
struct msgb *msg),
int (*mn_send) (struct gsm411_smr_inst *inst, int msg_type,
struct msgb *msg));
/* clear instance */
void gsm411_smr_clear(struct gsm411_smr_inst *inst);
/* message from upper layer */
int gsm411_smr_send(struct gsm411_smr_inst *inst, int msg_type,
struct msgb *msg);
/* message from lower layer */
int gsm411_smr_recv(struct gsm411_smr_inst *inst, int msg_type,
struct msgb *msg);
#endif /* _GSM0411_SMR_H */

View File

@ -0,0 +1,36 @@
#ifndef _GSM0411_UTILS_H
#define _GSM0411_UTILS_H
/* Turn int into semi-octet representation: 98 => 0x89 */
uint8_t gsm411_bcdify(uint8_t value);
/* Turn semi-octet representation into int: 0x89 => 98 */
uint8_t gsm411_unbcdify(uint8_t value);
struct msgb *gsm411_msgb_alloc(void);
/* Generate 03.40 TP-SCTS */
void gsm340_gen_scts(uint8_t *scts, time_t time);
/* Decode 03.40 TP-SCTS (into utc/gmt timestamp) */
time_t gsm340_scts(uint8_t *scts);
/* decode validity period. return minutes */
unsigned long gsm340_validity_period(uint8_t sms_vpf, uint8_t *sms_vp);
/* determine coding alphabet dependent on GSM 03.38 Section 4 DCS */
enum sms_alphabet gsm338_get_sms_alphabet(uint8_t dcs);
/* generate a TPDU address field compliant with 03.40 sec. 9.1.2.5 */
int gsm340_gen_oa(uint8_t *oa, unsigned int oa_len, uint8_t type,
uint8_t plan, const char *number);
/* Prefix msg with a RP header */
int gsm411_push_rp_header(struct msgb *msg, uint8_t rp_msg_type,
uint8_t rp_msg_ref);
/* Prefix msg with a 04.08/04.11 CP header */
int gsm411_push_cp_header(struct msgb *msg, uint8_t proto, uint8_t trans,
uint8_t msg_type);
#endif /* _GSM0411_UTILS_H */

View File

@ -0,0 +1,26 @@
#ifndef gsm0480_h
#define gsm0480_h
#include <osmocom/core/msgb.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <osmocom/gsm/protocol/gsm_04_80.h>
#define MAX_LEN_USSD_STRING 31
struct ussd_request {
char text[MAX_LEN_USSD_STRING + 1];
uint8_t transaction_id;
uint8_t invoke_id;
};
int gsm0480_decode_ussd_request(const struct gsm48_hdr *hdr, uint16_t len,
struct ussd_request *request);
struct msgb *gsm0480_create_ussd_resp(uint8_t invoke_id, uint8_t trans_id, const char *text);
struct msgb *gsm0480_create_unstructuredSS_Notify(int alertPattern, const char *text);
struct msgb *gsm0480_create_notifySS(const char *text);
int gsm0480_wrap_invoke(struct msgb *msg, int op, int link_id);
int gsm0480_wrap_facility(struct msgb *msg);
#endif

View File

@ -0,0 +1,38 @@
#ifndef OSMOCOM_GSM_0502_H
#define OSMOCOM_GSM_0502_H
#include <stdint.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <osmocom/gsm/protocol/gsm_08_58.h>
/* Table 5 Clause 7 TS 05.02 */
static inline unsigned int
gsm0502_get_n_pag_blocks(struct gsm48_control_channel_descr *chan_desc)
{
if (chan_desc->ccch_conf == RSL_BCCH_CCCH_CONF_1_C)
return 3 - chan_desc->bs_ag_blks_res;
else
return 9 - chan_desc->bs_ag_blks_res;
}
/* Chapter 6.5.2 of TS 05.02 */
static inline unsigned int
gsm0502_get_ccch_group(uint64_t imsi, unsigned int bs_cc_chans,
unsigned int n_pag_blocks)
{
return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) / n_pag_blocks;
}
/* Chapter 6.5.2 of TS 05.02 */
static inline unsigned int
gsm0502_get_paging_group(uint64_t imsi, unsigned int bs_cc_chans,
int n_pag_blocks)
{
return (imsi % 1000) % (bs_cc_chans * n_pag_blocks) % n_pag_blocks;
}
unsigned int
gsm0502_calc_paging_group(struct gsm48_control_channel_descr *chan_desc, uint64_t imsi);
#endif

View File

@ -0,0 +1,50 @@
/* (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 OSMOCORE_GSM0808_H
#define OSMOCORE_GSM0808_H
#include "tlv.h"
struct msgb;
struct msgb *gsm0808_create_layer3(struct msgb *msg, uint16_t netcode, uint16_t countrycode, int lac, uint16_t ci);
struct msgb *gsm0808_create_reset(void);
struct msgb *gsm0808_create_clear_command(uint8_t reason);
struct msgb *gsm0808_create_clear_complete(void);
struct msgb *gsm0808_create_cipher_complete(struct msgb *layer3, uint8_t alg_id);
struct msgb *gsm0808_create_cipher_reject(uint8_t cause);
struct msgb *gsm0808_create_classmark_update(const uint8_t *cm2, uint8_t cm2_len,
const uint8_t *cm3, uint8_t cm3_len);
struct msgb *gsm0808_create_sapi_reject(uint8_t link_id);
struct msgb *gsm0808_create_assignment_completed(uint8_t rr_cause,
uint8_t chosen_channel, uint8_t encr_alg_id,
uint8_t speech_mode);
struct msgb *gsm0808_create_assignment_failure(uint8_t cause, uint8_t *rr_cause);
struct msgb *gsm0808_create_clear_rqst(uint8_t cause);
struct msgb *gsm0808_create_dtap(struct msgb *msg, uint8_t link_id);
void gsm0808_prepend_dtap_header(struct msgb *msg, uint8_t link_id);
const struct tlv_definition *gsm0808_att_tlvdef(void);
const char *gsm0808_bssmap_name(uint8_t msg_type);
const char *gsm0808_bssap_name(uint8_t msg_type);
#endif

View File

@ -0,0 +1,40 @@
#ifndef _OSMOCORE_GSM48_H
#define _OSMOCORE_GSM48_H
#include <osmocom/gsm/tlv.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <osmocom/gsm/gsm48_ie.h>
/* A parsed GPRS routing area */
struct gprs_ra_id {
uint16_t mnc;
uint16_t mcc;
uint16_t lac;
uint8_t rac;
};
extern const struct tlv_definition gsm48_att_tlvdef;
extern const struct tlv_definition gsm48_rr_att_tlvdef;
extern const struct tlv_definition gsm48_mm_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);
int gsm48_decode_lai(struct gsm48_loc_area_id *lai, uint16_t *mcc,
uint16_t *mnc, uint16_t *lac);
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);
/* Convert Mobile Identity (10.5.1.4) to string */
int gsm48_mi_to_string(char *string, const int str_len,
const uint8_t *mi, const int mi_len);
/* Parse Routeing Area Identifier */
void gsm48_parse_ra(struct gprs_ra_id *raid, const uint8_t *buf);
int gsm48_construct_ra(uint8_t *buf, const struct gprs_ra_id *raid);
int gsm48_number_of_paging_subchannels(struct gsm48_control_channel_descr *chan_desc);
#endif

View File

@ -0,0 +1,117 @@
#ifndef _OSMOCORE_GSM48_IE_H
#define _OSMOCORE_GSM48_IE_H
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <osmocom/core/msgb.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/gsm/mncc.h>
#include <osmocom/gsm/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);
/* structure of one frequency */
struct gsm_sysinfo_freq {
/* if the frequency included in the sysinfo */
uint8_t mask;
} __attribute__ ((packed));
/* decode "Cell Channel Description" (10.5.2.1b) and other frequency lists */
int gsm48_decode_freq_list(struct gsm_sysinfo_freq *f, uint8_t *cd,
uint8_t len, uint8_t mask, uint8_t frqt);
#endif

View File

@ -0,0 +1,151 @@
/* 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>
#define ADD_MODULO(sum, delta, modulo) do { \
if ((sum += delta) >= modulo) \
sum -= modulo; \
} while (0)
#define GSM_MAX_FN (26*51*2048)
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_decode_hdr(char *decoded, const uint8_t *user_data, uint8_t length, uint8_t ud_hdr_ind);
int gsm_7bit_encode(uint8_t *result, const char *data);
int gsm_septets2octets(uint8_t *result, uint8_t *rdata, uint8_t septet_len, uint8_t padding);
int gsm_septet_encode(uint8_t *result, const char *data);
uint8_t gsm_get_octet_len(const uint8_t sept_len);
unsigned int ms_class_gmsk_dbm(enum gsm_band band, int ms_class);
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.1.6 */
static inline int ms_cm2_a5n_support(uint8_t *cm2, int n) {
switch (n) {
case 0: return 1;
case 1: return (cm2[0] & (1<<3)) ? 0 : 1;
case 2: return (cm2[2] & (1<<0)) ? 1 : 0;
case 3: return (cm2[2] & (1<<1)) ? 1 : 0;
default:
return 0;
}
}
/* 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
#define ARFCN_FLAG_MASK 0xf000 /* Reserve the upper 5 bits for flags */
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);
/* GSM TS 03.03 Chapter 2.6 */
enum gprs_tlli_type {
TLLI_LOCAL,
TLLI_FOREIGN,
TLLI_RANDOM,
TLLI_AUXILIARY,
TLLI_RESERVED,
};
/* TS 03.03 Chapter 2.6 */
int gprs_tlli_type(uint32_t tlli);
uint32_t gprs_tmsi2tlli(uint32_t p_tmsi, enum gprs_tlli_type type);
/* Osmocom internal, not part of any gsm spec */
enum gsm_phys_chan_config {
GSM_PCHAN_NONE,
GSM_PCHAN_CCCH,
GSM_PCHAN_CCCH_SDCCH4,
GSM_PCHAN_TCH_F,
GSM_PCHAN_TCH_H,
GSM_PCHAN_SDCCH8_SACCH8C,
GSM_PCHAN_PDCH, /* GPRS PDCH */
GSM_PCHAN_TCH_F_PDCH, /* TCH/F if used, PDCH otherwise */
GSM_PCHAN_UNKNOWN,
_GSM_PCHAN_MAX
};
/* Osmocom internal, not part of any gsm spec */
enum gsm_chan_t {
GSM_LCHAN_NONE,
GSM_LCHAN_SDCCH,
GSM_LCHAN_TCH_F,
GSM_LCHAN_TCH_H,
GSM_LCHAN_UNKNOWN,
GSM_LCHAN_CCCH,
GSM_LCHAN_PDTCH,
_GSM_LCHAN_MAX
};
#endif

View File

@ -0,0 +1,171 @@
#ifndef _OSMOCOM_LAPD_H
#define _OSMOCOM_LAPD_H
#include <stdint.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/msgb.h>
#include <osmocom/gsm/prim.h>
/*! \defgroup lapd LAPD implementation common part
* @{
*/
/*! \file lapd.h */
/* primitive related sutff */
/*! \brief LAPD related primitives (L2<->L3 SAP)*/
enum osmo_dl_prim {
PRIM_DL_UNIT_DATA, /*!< \brief DL-UNIT-DATA */
PRIM_DL_DATA, /*!< \brief DL-DATA */
PRIM_DL_EST, /*!< \brief DL-ESTABLISH */
PRIM_DL_REL, /*!< \brief DL-RLEEASE */
PRIM_DL_SUSP, /*!< \brief DL-SUSPEND */
PRIM_DL_RES, /*!< \brief DL-RESUME */
PRIM_DL_RECON, /*!< \brief DL-RECONNECT */
PRIM_MDL_ERROR, /*!< \brief MDL-ERROR */
};
/* Uses the same values as RLL, so no conversion for GSM is required. */
#define MDL_CAUSE_T200_EXPIRED 0x01
#define MDL_CAUSE_REEST_REQ 0x02
#define MDL_CAUSE_UNSOL_UA_RESP 0x03
#define MDL_CAUSE_UNSOL_DM_RESP 0x04
#define MDL_CAUSE_UNSOL_DM_RESP_MF 0x05
#define MDL_CAUSE_UNSOL_SPRV_RESP 0x06
#define MDL_CAUSE_SEQ_ERR 0x07
#define MDL_CAUSE_UFRM_INC_PARAM 0x08
#define MDL_CAUSE_SFRM_INC_PARAM 0x09
#define MDL_CAUSE_IFRM_INC_MBITS 0x0a
#define MDL_CAUSE_IFRM_INC_LEN 0x0b
#define MDL_CAUSE_FRM_UNIMPL 0x0c
#define MDL_CAUSE_SABM_MF 0x0d
#define MDL_CAUSE_SABM_INFO_NOTALL 0x0e
#define MDL_CAUSE_FRMR 0x0f
/*! \brief for MDL-ERROR.ind */
struct mdl_error_ind_param {
uint8_t cause; /*!< \brief generic cause value */
};
/*! \brief for DL-REL.req */
struct dl_rel_req_param {
uint8_t mode; /*!< \brief release mode */
};
/*! \brief primitive header for LAPD DL-SAP primitives */
struct osmo_dlsap_prim {
struct osmo_prim_hdr oph; /*!< \brief generic primitive header */
union {
struct mdl_error_ind_param error_ind;
struct dl_rel_req_param rel_req;
} u; /*!< \brief request-specific data */
};
/*! \brief LAPD mode/role */
enum lapd_mode {
LAPD_MODE_USER, /*!< \brief behave like user */
LAPD_MODE_NETWORK, /*!< \brief behave like network */
};
/*! \brief LAPD state (Figure B.2/Q.921)*/
enum lapd_state {
LAPD_STATE_NULL = 0,
LAPD_STATE_TEI_UNASS,
LAPD_STATE_ASS_TEI_WAIT,
LAPD_STATE_EST_TEI_WAIT,
LAPD_STATE_IDLE,
LAPD_STATE_SABM_SENT,
LAPD_STATE_DISC_SENT,
LAPD_STATE_MF_EST,
LAPD_STATE_TIMER_RECOV,
};
/*! \brief LAPD message format (I / S / U) */
enum lapd_format {
LAPD_FORM_UKN = 0,
LAPD_FORM_I,
LAPD_FORM_S,
LAPD_FORM_U,
};
/*! \brief LAPD message context */
struct lapd_msg_ctx {
struct lapd_datalink *dl;
int n201;
/* address */
uint8_t cr;
uint8_t sapi;
uint8_t tei;
uint8_t lpd;
/* control */
uint8_t format;
uint8_t p_f; /* poll / final bit */
uint8_t n_send;
uint8_t n_recv;
uint8_t s_u; /* S or repectivly U function bits */
/* length */
int length;
uint8_t more;
};
struct lapd_cr_ent {
uint8_t cmd;
uint8_t resp;
};
struct lapd_history {
struct msgb *msg; /* message to be sent / NULL, if histoy is empty */
int more; /* if message is fragmented */
};
/*! \brief LAPD datalink */
struct lapd_datalink {
int (*send_dlsap)(struct osmo_dlsap_prim *dp,
struct lapd_msg_ctx *lctx);
int (*send_ph_data_req)(struct lapd_msg_ctx *lctx, struct msgb *msg);
struct {
/*! \brief filled-in once we set the lapd_mode above */
struct lapd_cr_ent loc2rem;
struct lapd_cr_ent rem2loc;
} cr;
enum lapd_mode mode; /*!< \brief current mode of link */
int use_sabme; /*!< \brief use SABME instead of SABM */
int reestablish; /*!< \brief enable reestablish support */
int n200, n200_est_rel; /*!< \brief number of retranmissions */
struct lapd_msg_ctx lctx; /*!< \brief LAPD context */
int maxf; /*!< \brief maximum frame size (after defragmentation) */
uint8_t k; /*!< \brief maximum number of unacknowledged frames */
uint8_t v_range; /*!< \brief range of sequence numbers */
uint8_t v_send; /*!< \brief seq nr of next I frame to be transmitted */
uint8_t v_ack; /*!< \brief last frame ACKed by peer */
uint8_t v_recv; /*!< \brief seq nr of next I frame expected to be received */
uint32_t state; /*!< \brief LAPD state (\ref lapd_state) */
int seq_err_cond; /*!< \brief condition of sequence error */
uint8_t own_busy; /*!< \brief receiver busy on our side */
uint8_t peer_busy; /*!< \brief receiver busy on remote side */
int t200_sec, t200_usec; /*!< \brief retry timer (default 1 sec) */
int t203_sec, t203_usec; /*!< \brief retry timer (default 10 secs) */
struct osmo_timer_list t200; /*!< \brief T200 timer */
struct osmo_timer_list t203; /*!< \brief T203 timer */
uint8_t retrans_ctr; /*!< \brief re-transmission counter */
struct llist_head tx_queue; /*!< \brief frames to L1 */
struct llist_head send_queue; /*!< \brief frames from L3 */
struct msgb *send_buffer; /*!< \brief current frame transmitting */
int send_out; /*!< \brief how much was sent from send_buffer */
struct lapd_history *tx_hist; /*!< \brief tx history structure array */
uint8_t range_hist; /*!< \brief range of history buffer 2..2^n */
struct msgb *rcv_buffer; /*!< \brief buffer to assemble the received message */
struct msgb *cont_res; /*!< \brief buffer to store content resolution data on network side, to detect multiple phones on same channel */
};
void lapd_dl_init(struct lapd_datalink *dl, uint8_t k, uint8_t v_range,
int maxf);
void lapd_dl_exit(struct lapd_datalink *dl);
void lapd_dl_reset(struct lapd_datalink *dl);
int lapd_set_mode(struct lapd_datalink *dl, enum lapd_mode mode);
int lapd_ph_data_ind(struct msgb *msg, struct lapd_msg_ctx *lctx);
int lapd_recv_dlsap(struct osmo_dlsap_prim *dp, struct lapd_msg_ctx *lctx);
#endif /* _OSMOCOM_LAPD_H */

View File

@ -0,0 +1,162 @@
#ifndef _OSMOCOM_LAPDM_H
#define _OSMOCOM_LAPDM_H
#include <osmocom/gsm/lapd_core.h>
/*! \defgroup lapdm LAPDm implementation according to GSM TS 04.06
* @{
*/
/*! \file lapdm.h */
/* primitive related sutff */
/*! \brief LAPDm related primitives (L1<->L2 SAP) */
enum osmo_ph_prim {
PRIM_PH_DATA, /*!< \brief PH-DATA */
PRIM_PH_RACH, /*!< \brief PH-RANDOM_ACCESS */
PRIM_PH_CONN, /*!< \brief PH-CONNECT */
PRIM_PH_EMPTY_FRAME, /*!< \brief PH-EMPTY_FRAME */
PRIM_PH_RTS, /*!< \brief PH-RTS */
};
/*! \brief for PH-RANDOM_ACCESS.req */
struct ph_rach_req_param {
uint8_t ra; /*!< \brief Random Access */
uint8_t ta; /*!< \brief Timing Advance */
uint8_t tx_power; /*!< \brief Transmit Power */
uint8_t is_combined_ccch;/*!< \brief Are we using a combined CCCH? */
uint16_t offset; /*!< \brief Timing Offset */
};
/*! \brief for PH-RANDOM_ACCESS.ind */
struct ph_rach_ind_param {
uint8_t ra; /*!< \brief Random Access */
uint8_t acc_delay; /*!< \brief Delay in bit periods */
uint32_t fn; /*!< \brief GSM Frame Number at time of RA */
};
/*! \brief for PH-[UNIT]DATA.{req,ind} */
struct ph_data_param {
uint8_t link_id; /*!< \brief Link Identifier (Like RSL) */
uint8_t chan_nr; /*!< \brief Channel Number (Like RSL) */
};
/*! \brief for PH-CONN.ind */
struct ph_conn_ind_param {
uint32_t fn; /*!< \brief GSM Frame Number */
};
/*! \brief primitive header for LAPDm PH-SAP primitives */
struct osmo_phsap_prim {
struct osmo_prim_hdr oph; /*!< \brief generic primitive header */
union {
struct ph_data_param data;
struct ph_rach_req_param rach_req;
struct ph_rach_ind_param rach_ind;
struct ph_conn_ind_param conn_ind;
} u; /*!< \brief request-specific data */
};
/*! \brief LAPDm mode/role */
enum lapdm_mode {
LAPDM_MODE_MS, /*!< \brief behave like a MS (mobile phone) */
LAPDM_MODE_BTS, /*!< \brief behave like a BTS (network) */
};
struct lapdm_entity;
/*! \brief LAPDm message context */
struct lapdm_msg_ctx {
struct lapdm_datalink *dl;
int lapdm_fmt;
uint8_t chan_nr;
uint8_t link_id;
uint8_t ta_ind; /* TA indicated by network */
uint8_t tx_power_ind; /* MS power indicated by network */
};
/*! \brief LAPDm datalink like TS 04.06 / Section 3.5.2 */
struct lapdm_datalink {
struct lapd_datalink dl; /* \brief common LAPD */
struct lapdm_msg_ctx mctx; /*!< \brief context of established connection */
struct lapdm_entity *entity; /*!< \brief LAPDm entity we are part of */
};
/*! \brief LAPDm datalink SAPIs */
enum lapdm_dl_sapi {
DL_SAPI0 = 0, /*!< \brief SAPI 0 */
DL_SAPI3 = 1, /*!< \brief SAPI 1 */
_NR_DL_SAPI
};
typedef int (*lapdm_cb_t)(struct msgb *msg, struct lapdm_entity *le, void *ctx);
#define LAPDM_ENT_F_EMPTY_FRAME 0x0001
#define LAPDM_ENT_F_POLLING_ONLY 0x0002
/*! \brief a LAPDm Entity */
struct lapdm_entity {
/*! \brief the SAPIs of the LAPDm entity */
struct lapdm_datalink datalink[_NR_DL_SAPI];
int last_tx_dequeue; /*!< \brief last entity that was dequeued */
int tx_pending; /*!< \brief currently a pending frame not confirmed by L1 */
enum lapdm_mode mode; /*!< \brief are we in BTS mode or MS mode */
unsigned int flags;
void *l1_ctx; /*!< \brief context for layer1 instance */
void *l3_ctx; /*!< \brief context for layer3 instance */
osmo_prim_cb l1_prim_cb;/*!< \brief callback for sending prims to L1 */
lapdm_cb_t l3_cb; /*!< \brief callback for sending stuff to L3 */
/*! \brief pointer to \ref lapdm_channel of which we're part */
struct lapdm_channel *lapdm_ch;
uint8_t ta; /* TA used and indicated to network */
uint8_t tx_power; /* MS power used and indicated to network */
};
/*! \brief the two lapdm_entities that form a GSM logical channel (ACCH + DCCH) */
struct lapdm_channel {
struct llist_head list; /*!< \brief internal linked list */
char *name; /*!< \brief human-readable name */
struct lapdm_entity lapdm_acch; /*!< \brief Associated Control Channel */
struct lapdm_entity lapdm_dcch; /*!< \brief Dedicated Control Channel */
};
const char *get_rsl_name(int value);
extern const char *lapdm_state_names[];
/* initialize a LAPDm entity */
void lapdm_entity_init(struct lapdm_entity *le, enum lapdm_mode mode, int t200);
void lapdm_channel_init(struct lapdm_channel *lc, enum lapdm_mode mode);
/* deinitialize a LAPDm entity */
void lapdm_entity_exit(struct lapdm_entity *le);
void lapdm_channel_exit(struct lapdm_channel *lc);
/* input into layer2 (from layer 1) */
int lapdm_phsap_up(struct osmo_prim_hdr *oph, struct lapdm_entity *le);
/* input into layer2 (from layer 3) */
int lapdm_rslms_recvmsg(struct msgb *msg, struct lapdm_channel *lc);
void lapdm_channel_set_l3(struct lapdm_channel *lc, lapdm_cb_t cb, void *ctx);
void lapdm_channel_set_l1(struct lapdm_channel *lc, osmo_prim_cb cb, void *ctx);
int lapdm_entity_set_mode(struct lapdm_entity *le, enum lapdm_mode mode);
int lapdm_channel_set_mode(struct lapdm_channel *lc, enum lapdm_mode mode);
void lapdm_entity_reset(struct lapdm_entity *le);
void lapdm_channel_reset(struct lapdm_channel *lc);
void lapdm_entity_set_flags(struct lapdm_entity *le, unsigned int flags);
void lapdm_channel_set_flags(struct lapdm_channel *lc, unsigned int flags);
int lapdm_phsap_dequeue_prim(struct lapdm_entity *le, struct osmo_phsap_prim *pp);
/*! @} */
#endif /* _OSMOCOM_LAPDM_H */

View File

@ -0,0 +1,85 @@
#ifndef _OSMOCORE_MNCC_H
#define _OSMOCORE_MNCC_H
#include <osmocom/gsm/protocol/gsm_04_08.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 {
enum gsm48_bcap_ra rate_adaption;
enum gsm48_bcap_sig_access sig_access;
int async;
int nr_stop_bits;
int nr_data_bits;
enum gsm48_bcap_user_rate user_rate;
enum gsm48_bcap_parity parity;
enum gsm48_bcap_interm_rate interm_rate;
enum gsm48_bcap_transp transp;
enum gsm48_bcap_modem_type modem_type;
} data;
};
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

View File

@ -0,0 +1,18 @@
#ifndef OSMO_GSM_PRIM_H
#define OSMO_GSM_PRIM_H
#include <osmocom/core/prim.h>
/* enumeration of GSM related SAPs */
enum osmo_gsm_sap {
SAP_GSM_PH = _SAP_GSM_BASE,
SAP_GSM_DL,
SAP_GSM_MDL,
SAP_BSSGP_GMM,
SAP_BSSGP_LL,
SAP_BSSGP_NM,
SAP_BSSGP_PFM,
};
#endif

View File

@ -0,0 +1,51 @@
#ifndef PROTO_GSM_03_41_H
#define PROTO_GSM_03_41_H
#include <stdint.h>
/* GSM TS 03.41 definitions also TS 23.041*/
/* Chapter 9.3.2 */
struct gsm341_ms_message {
struct {
uint8_t code_hi:6;
uint8_t gs:2;
uint8_t update:4;
uint8_t code_lo:4;
} serial;
uint16_t msg_id;
struct {
uint8_t language:4;
uint8_t group:4;
} dcs;
struct {
uint8_t total:4;
uint8_t current:4;
} page;
uint8_t data[0];
} __attribute__((packed));
/* Chapter 9.4.1.3 */
struct gsm341_etws_message {
struct {
uint8_t code_hi:4;
uint8_t popup:1;
uint8_t alert:1;
uint8_t gs:2;
uint8_t update:4;
uint8_t code_lo:4;
} serial;
uint16_t msg_id;
uint16_t warning_type;
uint8_t data[0];
} __attribute__((packed));
#define GSM341_MSG_CODE(ms) ((ms)->serial.code_lo | ((ms)->serial.code_hi << 4))
/* Section 9.3.2.1 - Geographical Scope */
#define GSM341_GS_CELL_WIDE_IMMED 0
#define GSM341_GS_PLMN_WIDE 1
#define GSM341_GS_LA_WIDE 2
#define GSM341_GS_CELL_WIDE 3
#endif /* PROTO_GSM_03_41_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,190 @@
#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 user/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 user/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,
GSM411_RPS_WAIT_FOR_RETRANS_T = 4,
};
/* 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 /* TR1M - 10 */
#define GSM411_TMR_TC1A_SEC 30 /* TR1M - 10 */
/* 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 */

View File

@ -0,0 +1,31 @@
#ifndef PROTO_GSM_04_12_H
#define PROTO_GSM_04_12_H
#include <stdint.h>
/* GSM TS 04.12 definitions for Short Message Service Cell Broadcast */
#define GSM412_SEQ_FST_BLOCK 0x0
#define GSM412_SEQ_SND_BLOCK 0x1
#define GSM412_SEQ_TRD_BLOCK 0x2
#define GSM412_SEQ_FTH_BLOCK 0x3
#define GSM412_SEQ_FST_SCHED_BLOCK 0x8
#define GSM412_SEQ_NULL_MSG 0xf
struct gsm412_block_type {
uint8_t seq_nr : 4,
lb : 1,
lpd : 2,
spare : 1;
} __attribute__((packed));
struct gsm412_sched_msg {
uint8_t beg_slot_nr : 6,
type : 2;
uint8_t end_slot_nr : 6,
spare1 : 1, spare2: 1;
uint8_t cbsms_msg_map[6];
uint8_t data[0];
} __attribute__((packed));
#endif

View File

@ -0,0 +1,126 @@
#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 */

View File

@ -0,0 +1,303 @@
/* From GSM08.08 */
#ifndef GSM_0808_H
#define GSM_0808_H
#include <stdlib.h>
/*
* this is from GSM 03.03 CGI but is copied in GSM 08.08
* in § 3.2.2.27 for Cell Identifier List
*/
enum CELL_IDENT {
CELL_IDENT_WHOLE_GLOBAL = 0,
CELL_IDENT_LAC_AND_CI = 1,
CELL_IDENT_CI = 2,
CELL_IDENT_NO_CELL = 3,
CELL_IDENT_LAI_AND_LAC = 4,
CELL_IDENT_LAC = 5,
CELL_IDENT_BSS = 6,
CELL_IDENT_UTRAN_PLMN_LAC_RNC = 8,
CELL_IDENT_UTRAN_RNC = 9,
CELL_IDENT_UTRAN_LAC_RNC = 10,
};
/* GSM 08.06 § 6.3 */
enum BSSAP_MSG_TYPE {
BSSAP_MSG_BSS_MANAGEMENT = 0x0,
BSSAP_MSG_DTAP = 0x1,
};
struct bssmap_header {
uint8_t type;
uint8_t length;
} __attribute__((packed));
struct dtap_header {
uint8_t type;
uint8_t link_id;
uint8_t length;
} __attribute__((packed));
enum BSS_MAP_MSG_TYPE {
BSS_MAP_MSG_RESERVED_0 = 0,
/* ASSIGNMENT MESSAGES */
BSS_MAP_MSG_ASSIGMENT_RQST = 1,
BSS_MAP_MSG_ASSIGMENT_COMPLETE = 2,
BSS_MAP_MSG_ASSIGMENT_FAILURE = 3,
/* HANDOVER MESSAGES */
BSS_MAP_MSG_HANDOVER_RQST = 16,
BSS_MAP_MSG_HANDOVER_REQUIRED = 17,
BSS_MAP_MSG_HANDOVER_RQST_ACKNOWLEDGE= 18,
BSS_MAP_MSG_HANDOVER_CMD = 19,
BSS_MAP_MSG_HANDOVER_COMPLETE = 20,
BSS_MAP_MSG_HANDOVER_SUCCEEDED = 21,
BSS_MAP_MSG_HANDOVER_FAILURE = 22,
BSS_MAP_MSG_HANDOVER_PERFORMED = 23,
BSS_MAP_MSG_HANDOVER_CANDIDATE_ENQUIRE = 24,
BSS_MAP_MSG_HANDOVER_CANDIDATE_RESPONSE = 25,
BSS_MAP_MSG_HANDOVER_REQUIRED_REJECT = 26,
BSS_MAP_MSG_HANDOVER_DETECT = 27,
/* RELEASE MESSAGES */
BSS_MAP_MSG_CLEAR_CMD = 32,
BSS_MAP_MSG_CLEAR_COMPLETE = 33,
BSS_MAP_MSG_CLEAR_RQST = 34,
BSS_MAP_MSG_RESERVED_1 = 35,
BSS_MAP_MSG_RESERVED_2 = 36,
BSS_MAP_MSG_SAPI_N_REJECT = 37,
BSS_MAP_MSG_CONFUSION = 38,
/* OTHER CONNECTION RELATED MESSAGES */
BSS_MAP_MSG_SUSPEND = 40,
BSS_MAP_MSG_RESUME = 41,
BSS_MAP_MSG_CONNECTION_ORIENTED_INFORMATION = 42,
BSS_MAP_MSG_PERFORM_LOCATION_RQST = 43,
BSS_MAP_MSG_LSA_INFORMATION = 44,
BSS_MAP_MSG_PERFORM_LOCATION_RESPONSE = 45,
BSS_MAP_MSG_PERFORM_LOCATION_ABORT = 46,
BSS_MAP_MSG_COMMON_ID = 47,
/* GENERAL MESSAGES */
BSS_MAP_MSG_RESET = 48,
BSS_MAP_MSG_RESET_ACKNOWLEDGE = 49,
BSS_MAP_MSG_OVERLOAD = 50,
BSS_MAP_MSG_RESERVED_3 = 51,
BSS_MAP_MSG_RESET_CIRCUIT = 52,
BSS_MAP_MSG_RESET_CIRCUIT_ACKNOWLEDGE = 53,
BSS_MAP_MSG_MSC_INVOKE_TRACE = 54,
BSS_MAP_MSG_BSS_INVOKE_TRACE = 55,
BSS_MAP_MSG_CONNECTIONLESS_INFORMATION = 58,
/* TERRESTRIAL RESOURCE MESSAGES */
BSS_MAP_MSG_BLOCK = 64,
BSS_MAP_MSG_BLOCKING_ACKNOWLEDGE = 65,
BSS_MAP_MSG_UNBLOCK = 66,
BSS_MAP_MSG_UNBLOCKING_ACKNOWLEDGE = 67,
BSS_MAP_MSG_CIRCUIT_GROUP_BLOCK = 68,
BSS_MAP_MSG_CIRCUIT_GROUP_BLOCKING_ACKNOWLEDGE = 69,
BSS_MAP_MSG_CIRCUIT_GROUP_UNBLOCK = 70,
BSS_MAP_MSG_CIRCUIT_GROUP_UNBLOCKING_ACKNOWLEDGE = 71,
BSS_MAP_MSG_UNEQUIPPED_CIRCUIT = 72,
BSS_MAP_MSG_CHANGE_CIRCUIT = 78,
BSS_MAP_MSG_CHANGE_CIRCUIT_ACKNOWLEDGE = 79,
/* RADIO RESOURCE MESSAGES */
BSS_MAP_MSG_RESOURCE_RQST = 80,
BSS_MAP_MSG_RESOURCE_INDICATION = 81,
BSS_MAP_MSG_PAGING = 82,
BSS_MAP_MSG_CIPHER_MODE_CMD = 83,
BSS_MAP_MSG_CLASSMARK_UPDATE = 84,
BSS_MAP_MSG_CIPHER_MODE_COMPLETE = 85,
BSS_MAP_MSG_QUEUING_INDICATION = 86,
BSS_MAP_MSG_COMPLETE_LAYER_3 = 87,
BSS_MAP_MSG_CLASSMARK_RQST = 88,
BSS_MAP_MSG_CIPHER_MODE_REJECT = 89,
BSS_MAP_MSG_LOAD_INDICATION = 90,
/* VGCS/VBS */
BSS_MAP_MSG_VGCS_VBS_SETUP = 4,
BSS_MAP_MSG_VGCS_VBS_SETUP_ACK = 5,
BSS_MAP_MSG_VGCS_VBS_SETUP_REFUSE = 6,
BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RQST = 7,
BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RESULT = 28,
BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_FAILURE = 29,
BSS_MAP_MSG_VGCS_VBS_QUEUING_INDICATION = 30,
BSS_MAP_MSG_UPLINK_RQST = 31,
BSS_MAP_MSG_UPLINK_RQST_ACKNOWLEDGE = 39,
BSS_MAP_MSG_UPLINK_RQST_CONFIRMATION = 73,
BSS_MAP_MSG_UPLINK_RELEASE_INDICATION = 74,
BSS_MAP_MSG_UPLINK_REJECT_CMD = 75,
BSS_MAP_MSG_UPLINK_RELEASE_CMD = 76,
BSS_MAP_MSG_UPLINK_SEIZED_CMD = 77,
};
enum GSM0808_IE_CODING {
GSM0808_IE_CIRCUIT_IDENTITY_CODE = 1,
GSM0808_IE_RESERVED_0 = 2,
GSM0808_IE_RESOURCE_AVAILABLE = 3,
GSM0808_IE_CAUSE = 4,
GSM0808_IE_CELL_IDENTIFIER = 5,
GSM0808_IE_PRIORITY = 6,
GSM0808_IE_LAYER_3_HEADER_INFORMATION = 7,
GSM0808_IE_IMSI = 8,
GSM0808_IE_TMSI = 9,
GSM0808_IE_ENCRYPTION_INFORMATION = 10,
GSM0808_IE_CHANNEL_TYPE = 11,
GSM0808_IE_PERIODICITY = 12,
GSM0808_IE_EXTENDED_RESOURCE_INDICATOR = 13,
GSM0808_IE_NUMBER_OF_MSS = 14,
GSM0808_IE_RESERVED_1 = 15,
GSM0808_IE_RESERVED_2 = 16,
GSM0808_IE_RESERVED_3 = 17,
GSM0808_IE_CLASSMARK_INFORMATION_T2 = 18,
GSM0808_IE_CLASSMARK_INFORMATION_T3 = 19,
GSM0808_IE_INTERFERENCE_BAND_TO_USE = 20,
GSM0808_IE_RR_CAUSE = 21,
GSM0808_IE_RESERVED_4 = 22,
GSM0808_IE_LAYER_3_INFORMATION = 23,
GSM0808_IE_DLCI = 24,
GSM0808_IE_DOWNLINK_DTX_FLAG = 25,
GSM0808_IE_CELL_IDENTIFIER_LIST = 26,
GSM0808_IE_RESPONSE_RQST = 27,
GSM0808_IE_RESOURCE_INDICATION_METHOD = 28,
GSM0808_IE_CLASSMARK_INFORMATION_TYPE_1 = 29,
GSM0808_IE_CIRCUIT_IDENTITY_CODE_LIST = 30,
GSM0808_IE_DIAGNOSTIC = 31,
GSM0808_IE_LAYER_3_MESSAGE_CONTENTS = 32,
GSM0808_IE_CHOSEN_CHANNEL = 33,
GSM0808_IE_TOTAL_RESOURCE_ACCESSIBLE = 34,
GSM0808_IE_CIPHER_RESPONSE_MODE = 35,
GSM0808_IE_CHANNEL_NEEDED = 36,
GSM0808_IE_TRACE_TYPE = 37,
GSM0808_IE_TRIGGERID = 38,
GSM0808_IE_TRACE_REFERENCE = 39,
GSM0808_IE_TRANSACTIONID = 40,
GSM0808_IE_MOBILE_IDENTITY = 41,
GSM0808_IE_OMCID = 42,
GSM0808_IE_FORWARD_INDICATOR = 43,
GSM0808_IE_CHOSEN_ENCR_ALG = 44,
GSM0808_IE_CIRCUIT_POOL = 45,
GSM0808_IE_CIRCUIT_POOL_LIST = 46,
GSM0808_IE_TIME_INDICATION = 47,
GSM0808_IE_RESOURCE_SITUATION = 48,
GSM0808_IE_CURRENT_CHANNEL_TYPE_1 = 49,
GSM0808_IE_QUEUEING_INDICATOR = 50,
GSM0808_IE_SPEECH_VERSION = 64,
GSM0808_IE_ASSIGNMENT_REQUIREMENT = 51,
GSM0808_IE_TALKER_FLAG = 53,
GSM0808_IE_CONNECTION_RELEASE_RQSTED = 54,
GSM0808_IE_GROUP_CALL_REFERENCE = 55,
GSM0808_IE_EMLPP_PRIORITY = 56,
GSM0808_IE_CONFIG_EVO_INDI = 57,
GSM0808_IE_OLD_BSS_TO_NEW_BSS_INFORMATION = 58,
GSM0808_IE_LSA_IDENTIFIER = 59,
GSM0808_IE_LSA_IDENTIFIER_LIST = 60,
GSM0808_IE_LSA_INFORMATION = 61,
GSM0808_IE_LCS_QOS = 62,
GSM0808_IE_LSA_ACCESS_CTRL_SUPPR = 63,
GSM0808_IE_LCS_PRIORITY = 67,
GSM0808_IE_LOCATION_TYPE = 68,
GSM0808_IE_LOCATION_ESTIMATE = 69,
GSM0808_IE_POSITIONING_DATA = 70,
GSM0808_IE_LCS_CAUSE = 71,
GSM0808_IE_LCS_CLIENT_TYPE = 72,
GSM0808_IE_APDU = 73,
GSM0808_IE_NETWORK_ELEMENT_IDENTITY = 74,
GSM0808_IE_GPS_ASSISTANCE_DATA = 75,
GSM0808_IE_DECIPHERING_KEYS = 76,
GSM0808_IE_RETURN_ERROR_RQST = 77,
GSM0808_IE_RETURN_ERROR_CAUSE = 78,
GSM0808_IE_SEGMENTATION = 79,
GSM0808_IE_SERVICE_HANDOVER = 80,
GSM0808_IE_SOURCE_RNC_TO_TARGET_RNC_TRANSPARENT_UMTS = 81,
GSM0808_IE_SOURCE_RNC_TO_TARGET_RNC_TRANSPARENT_CDMA2000= 82,
GSM0808_IE_RESERVED_5 = 65,
GSM0808_IE_RESERVED_6 = 66,
};
enum gsm0808_cause {
GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE = 0,
GSM0808_CAUSE_RADIO_INTERFACE_FAILURE = 1,
GSM0808_CAUSE_UPLINK_QUALITY = 2,
GSM0808_CAUSE_UPLINK_STRENGTH = 3,
GSM0808_CAUSE_DOWNLINK_QUALITY = 4,
GSM0808_CAUSE_DOWNLINK_STRENGTH = 5,
GSM0808_CAUSE_DISTANCE = 6,
GSM0808_CAUSE_O_AND_M_INTERVENTION = 7,
GSM0808_CAUSE_RESPONSE_TO_MSC_INVOCATION = 8,
GSM0808_CAUSE_CALL_CONTROL = 9,
GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION = 10,
GSM0808_CAUSE_HANDOVER_SUCCESSFUL = 11,
GSM0808_CAUSE_BETTER_CELL = 12,
GSM0808_CAUSE_DIRECTED_RETRY = 13,
GSM0808_CAUSE_JOINED_GROUP_CALL_CHANNEL = 14,
GSM0808_CAUSE_TRAFFIC = 15,
GSM0808_CAUSE_EQUIPMENT_FAILURE = 32,
GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE = 33,
GSM0808_CAUSE_RQSTED_TERRESTRIAL_RESOURCE_UNAVAILABLE = 34,
GSM0808_CAUSE_CCCH_OVERLOAD = 35,
GSM0808_CAUSE_PROCESSOR_OVERLOAD = 36,
GSM0808_CAUSE_BSS_NOT_EQUIPPED = 37,
GSM0808_CAUSE_MS_NOT_EQUIPPED = 38,
GSM0808_CAUSE_INVALID_CELL = 39,
GSM0808_CAUSE_TRAFFIC_LOAD = 40,
GSM0808_CAUSE_PREEMPTION = 41,
GSM0808_CAUSE_RQSTED_TRANSCODING_RATE_ADAPTION_UNAVAILABLE = 48,
GSM0808_CAUSE_CIRCUIT_POOL_MISMATCH = 49,
GSM0808_CAUSE_SWITCH_CIRCUIT_POOL = 50,
GSM0808_CAUSE_RQSTED_SPEECH_VERSION_UNAVAILABLE = 51,
GSM0808_CAUSE_LSA_NOT_ALLOWED = 52,
GSM0808_CAUSE_CIPHERING_ALGORITHM_NOT_SUPPORTED = 64,
GSM0808_CAUSE_TERRESTRIAL_CIRCUIT_ALREADY_ALLOCATED = 80,
GSM0808_CAUSE_INVALID_MESSAGE_CONTENTS = 81,
GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING = 82,
GSM0808_CAUSE_INCORRECT_VALUE = 83,
GSM0808_CAUSE_UNKNOWN_MESSAGE_TYPE = 84,
GSM0808_CAUSE_UNKNOWN_INFORMATION_ELEMENT = 85,
GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC = 96,
};
/* GSM 08.08 3.2.2.11 Channel Type */
enum gsm0808_chan_indicator {
GSM0808_CHAN_SPEECH = 1,
GSM0808_CHAN_DATA = 2,
GSM0808_CHAN_SIGN = 3,
};
enum gsm0808_chan_rate_type_data {
GSM0808_DATA_FULL_BM = 0x8,
GSM0808_DATA_HALF_LM = 0x9,
GSM0808_DATA_FULL_RPREF = 0xa,
GSM0808_DATA_HALF_PREF = 0xb,
GSM0808_DATA_FULL_PREF_NO_CHANGE = 0x1a,
GSM0808_DATA_HALF_PREF_NO_CHANGE = 0x1b,
GSM0808_DATA_MULTI_MASK = 0x20,
GSM0808_DATA_MULTI_MASK_NO_CHANGE = 0x30,
};
enum gsm0808_chan_rate_type_speech {
GSM0808_SPEECH_FULL_BM = 0x8,
GSM0808_SPEECH_HALF_LM = 0x9,
GSM0808_SPEECH_FULL_PREF= 0xa,
GSM0808_SPEECH_HALF_PREF= 0xb,
GSM0808_SPEECH_FULL_PREF_NO_CHANGE = 0x1a,
GSM0808_SPEECH_HALF_PREF_NO_CHANGE = 0x1b,
GSM0808_SPEECH_PERM = 0xf,
GSM0808_SPEECH_PERM_NO_CHANGE = 0x1f,
};
enum gsm0808_permitted_speech {
GSM0808_PERM_FR1 = 0x01,
GSM0808_PERM_FR2 = 0x11,
GSM0808_PERM_FR3 = 0x21,
GSM0808_PERM_HR1 = GSM0808_PERM_FR1 | 0x4,
GSM0808_PERM_HR2 = GSM0808_PERM_FR2 | 0x4,
GSM0808_PERM_HR3 = GSM0808_PERM_FR3 | 0x4,
};
#endif

View File

@ -0,0 +1,577 @@
#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>
/*! \addtogroup rsl
* @{
*/
/*! \file gsm_08_58.h */
/*! \brief RSL common header */
struct abis_rsl_common_hdr {
uint8_t msg_discr; /*!< \brief message discriminator (ABIS_RSL_MDISC_*) */
uint8_t msg_type; /*!< \brief message type (\ref abis_rsl_msgtype) */
uint8_t data[0]; /*!< \brief actual payload data */
} __attribute__ ((packed));
/* \brief RSL RLL header (Chapter 8.3) */
struct abis_rsl_rll_hdr {
struct abis_rsl_common_hdr c;
uint8_t ie_chan; /*!< \brief \ref RSL_IE_CHAN_NR (tag) */
uint8_t chan_nr; /*!< \brief RSL channel number (value) */
uint8_t ie_link_id; /*!< \brief \ref RSL_IE_LINK_IDENT (tag) */
uint8_t link_id; /*!< \brief RSL link identifier (value) */
uint8_t data[0]; /*!< \brief message payload data */
} __attribute__ ((packed));
/* \brief RSL Dedicated Channel header (Chapter 8.3 and 8.4) */
struct abis_rsl_dchan_hdr {
struct abis_rsl_common_hdr c;
uint8_t ie_chan; /*!< \brief \ref RSL_IE_CHAN_NR (tag) */
uint8_t chan_nr; /*!< \brief RSL channel number (value) */
uint8_t data[0]; /*!< \brief message payload data */
} __attribute__ ((packed));
/* \brief RSL Common Channel header (Chapter 8.5) */
struct abis_rsl_cchan_hdr {
struct abis_rsl_common_hdr c;
uint8_t ie_chan; /*!< \brief \ref RSL_IE_CHAN_NR (tag) */
uint8_t chan_nr; /*!< \brief RSL channel number (value) */
uint8_t data[0]; /*!< \brief message payload data */
} __attribute__ ((packed));
/* Chapter 9.1 */
/* \brief RSL Message Discriminator: RLL */
#define ABIS_RSL_MDISC_RLL 0x02
/* \brief RSL Message Discriminator: Dedicated Channel */
#define ABIS_RSL_MDISC_DED_CHAN 0x08
/* \brief RSL Message Discriminator: Common Channel */
#define ABIS_RSL_MDISC_COM_CHAN 0x0c
/* \brief RSL Message Discriminator: TRX Management */
#define ABIS_RSL_MDISC_TRX 0x10
/* \brief RSL Message Discriminator: Location Service */
#define ABIS_RSL_MDISC_LOC 0x20
/* \brief RSL Message Discriminator: ip.access */
#define ABIS_RSL_MDISC_IPACCESS 0x7e
#define ABIS_RSL_MDISC_TRANSP 0x01
/* \brief Check if given RSL message discriminator is transparent */
#define ABIS_RSL_MDISC_IS_TRANSP(x) (x & 0x01)
/* \brief RSL Message Tyoe (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 */
RSL_MT_SUSP_REQ, /* non-standard elements */
RSL_MT_SUSP_CONF,
RSL_MT_RES_REQ,
RSL_MT_RECON_REQ, /* 0x0f */
/* 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,
RSL_MT_CHAN_CONF, /* non-standard element */
/* 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,
};
/*! \brief Siemens vendor-specific RSL message types */
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,
};
/*! \brief RSL Information Element Identifiers (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
/*! \brief RSL Channel Mode IF (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
/* non-transparent data */
#define RSL_CMOD_CSD_NT_43k5 0x74
#define RSL_CMOD_CSD_NT_28k8 0x71
#define RSL_CMOD_CSD_NT_14k5 0x58
#define RSL_CMOD_CSD_NT_12k0 0x50
#define RSL_CMOD_CSD_NT_6k0 0x51
/* legacy #defines with wrong name */
#define RSL_CMOD_SP_NT_14k5 RSL_CMOD_CSD_NT_14k5
#define RSL_CMOD_SP_NT_12k0 RSL_CMOD_CSD_NT_12k0
#define RSL_CMOD_SP_NT_6k0 RSL_CMOD_CSD_NT_6k0
/* transparent data */
#define RSL_CMOD_CSD_T_32000 0x38
#define RSL_CMOD_CSD_T_29000 0x39
#define RSL_CMOD_CSD_T_14400 0x18
#define RSL_CMOD_CSD_T_9600 0x10
#define RSL_CMOD_CSD_T_4800 0x11
#define RSL_CMOD_CSD_T_2400 0x12
#define RSL_CMOD_CSD_T_1200 0x13
#define RSL_CMOD_CSD_T_600 0x14
#define RSL_CMOD_CSD_T_1200_75 0x15
/*! \brief RSL Channel Identification IE (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 RSL_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
/*! \brief RSL Cell Broadcast Command (Chapter 9.3.45) */
struct rsl_ie_cb_cmd_type {
uint8_t last_block:2;
uint8_t spare:1;
uint8_t def_bcast:1;
uint8_t command:4;
} __attribute__ ((packed));
/* ->command */
#define RSL_CB_CMD_TYPE_NORMAL 0x00
#define RSL_CB_CMD_TYPE_SCHEDULE 0x08
#define RSL_CB_CMD_TYPE_DEFAULT 0x0e
#define RSL_CB_CMD_TYPE_NULL 0x0f
/* ->def_bcast */
#define RSL_CB_CMD_DEFBCAST_NORMAL 0
#define RSL_CB_CMD_DEFBCAST_NULL 1
/* ->last_block */
#define RSL_CB_CMD_LASTBLOCK_4 0
#define RSL_CB_CMD_LASTBLOCK_1 1
#define RSL_CB_CMD_LASTBLOCK_2 2
#define RSL_CB_CMD_LASTBLOCK_3 3
/* 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 */

View File

@ -0,0 +1,748 @@
#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.
*
*/
/*! \addtogroup oml
* @{
*/
/*! \file gsm_12_21.h */
#include <stdint.h>
#include <osmocom/gsm/tlv.h>
/*! \brief generic header in front of every OML message according to TS 08.59 */
struct abis_om_hdr {
/*! \brief Message Discriminator \ref abis_oml_mdisc */
uint8_t mdisc;
/*! \brief Placement (like \ref ABIS_OM_PLACEMENT_ONLY) */
uint8_t placement;
/*! \brief Sequence Number (if \ref ABIS_OM_PLACEMENT_MIDDLE) */
uint8_t sequence;
/*! \brief Length in octets */
uint8_t length;
/*! \brief actual payload data */
uint8_t data[0];
} __attribute__ ((packed));
/*! \brief Message Discriminator for Formatted Object Messages */
#define ABIS_OM_MDISC_FOM 0x80
/*! \brief Message Discriminator for Man Machine Interface */
#define ABIS_OM_MDISC_MMI 0x40
/*! \brief Message Discriminator for TRAU management */
#define ABIS_OM_MDISC_TRAU 0x20
/*! \brief Message Discriminator for Manufacturer Specific Messages */
#define ABIS_OM_MDISC_MANUF 0x10
/*! \brief Entire OML message is in the L2 frame */
#define ABIS_OM_PLACEMENT_ONLY 0x80
/*! \brief First fragment of OML message is in this L2 frame */
#define ABIS_OM_PLACEMENT_FIRST 0x40
/*! \brief Middle fragment of OML message is in this L2 frame */
#define ABIS_OM_PLACEMENT_MIDDLE 0x20
/*! \brief Last fragment of OML message is in this L2 frame */
#define ABIS_OM_PLACEMENT_LAST 0x10
/*! \brief OML Object Instance */
struct abis_om_obj_inst {
uint8_t bts_nr; /*!< \brief BTS Number */
uint8_t trx_nr; /*!< \brief TRX Number */
uint8_t ts_nr; /*!< \brief Timeslot Number */
} __attribute__ ((packed));
/*! \brief OML Object Instance */
struct abis_om_fom_hdr {
uint8_t msg_type; /*!< \brief Message Type (\ref abis_nm_msgtype) */
uint8_t obj_class; /*!< \brief Object Class (\ref abis_nm_obj_class) */
struct abis_om_obj_inst obj_inst; /*!< \brief Object Instance */
uint8_t data[0]; /*!< \brief Data */
} __attribute__ ((packed));
/*! \brief Size of the OML FOM header in octets */
#define ABIS_OM_FOM_HDR_SIZE (sizeof(struct abis_om_hdr) + sizeof(struct abis_om_fom_hdr))
/*! \brief OML Message Type (Section 9.1) */
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,
};
/*! \brief Siemens specific OML Message Types */
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,
};
/*! \brief ip.access specific OML Message Types */
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,
};
/*! \brief OML Object Class (Section 9.2) */
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,
};
/*! \brief OML Attributes / IEs (Section 9.4) */
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
/*! \brief OML Administrative State (Section 9.4.4) */
enum abis_nm_adm_state {
NM_STATE_LOCKED = 0x01,
NM_STATE_UNLOCKED = 0x02,
NM_STATE_SHUTDOWN = 0x03,
NM_STATE_NULL = 0xff,
};
/*! \brief OML Availability State (Section 9.4.7) */
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,
};
/*! \brief OML Operational State */
enum abis_nm_op_state {
NM_OPSTATE_DISABLED = 1,
NM_OPSTATE_ENABLED = 2,
NM_OPSTATE_NULL = 0xff,
};
/* \brief Channel Combination (Section 9.4.13) */
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,
};
/*! \brief Event Type (Section 9.4.16) */
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,
};
/*! \brief Perceived Severity (Section: 9.4.63) */
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,
};
/*! \brief Probable Cause Type (Section 9.4.43) */
enum abis_nm_pcause_type {
NM_PCAUSE_T_X721 = 0x01,
NM_PCAUSE_T_GSM = 0x02,
NM_PCAUSE_T_MANUF = 0x03,
};
/*! \brief NACK causes (Section 9.4.36) */
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,
};
/*! \brief Abis OML Channel (Section 9.4.1) */
struct abis_nm_channel {
uint8_t attrib;
uint8_t bts_port; /*!< \brief BTS port number */
uint8_t timeslot; /*!< \brief E1 timeslot */
uint8_t subslot; /*!< \brief E1 sub-slot */
} __attribute__ ((packed));
/*! \brief 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*/
};
/*! \brief Siemens BS11 TRX power */
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,
};
/*! \brief Siemens BS11 PLL mode */
enum abis_bs11_li_pll_mode {
BS11_LI_PLL_LOCKED = 2,
BS11_LI_PLL_STANDALONE = 3,
};
/*! \brief Siemens BS11 E1 line configuration */
enum abis_bs11_line_cfg {
BS11_LINE_CFG_STAR = 0x00,
BS11_LINE_CFG_MULTIDROP = 0x01,
BS11_LINE_CFG_LOOP = 0x02,
};
/*! \brief Siemens BS11 boot phase */
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,
};
/*! \brief ip.access test number */
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,
};
/*! \brief 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,
};
/*! \brief 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,
};
/*! \brief ip.access IEI */
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,
};
/*! \brief ip.access NWL BCCH information type */
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 */

View File

@ -0,0 +1,200 @@
#ifndef PROTO_GSM_44_318_H
#define PROTO_GSM_44_318_H
#include <stdint.h>
/* Definitions according to 3GPP TS 44.318 6.8.0 Release 6 */
/* Table 11.1.1.2.1: Protocol Discriminator */
enum gan_pdisc {
GA_PDISC_RC = 0,
GA_PDISC_CSR = 1,
GA_PDISC_PSR = 2,
};
/* Table 11.1.1.4.1: Message types for URR */
enum gan_msg_type {
GA_MT_RC_DISCOVERY_REQUEST = 0x01,
GA_MT_RC_DISCOVERY_ACCEPT = 0x02,
GA_MT_RC_DISCOVERY_REJECT = 0x03,
GA_MT_RC_REGISTER_REQUEST = 0x10,
GA_MT_RC_REGISTER_ACCEPT = 0x11,
GA_MT_RC_REGISTER_REDIRECT = 0x12,
GA_MT_RC_REGISTER_REJECT = 0x13,
GA_MT_RC_DEREGISTER = 0x14,
GA_MT_RC_REGISTER_UPDATE_UL = 0x15,
GA_MT_RC_REGISTER_UPDATE_DL = 0x16,
GA_MT_RC_CELL_BCAST_INFO = 0x17,
GA_MT_CSR_CIPH_MODE_CMD = 0x20,
GA_MT_CSR_CIPH_MODE_COMPL = 0x21,
GA_MT_CSR_ACT_CHAN = 0x30,
GA_MT_CSR_ACT_CHAN_ACK = 0x31,
GA_MT_CSR_ACT_CHAN_COMPL = 0x32,
GA_MT_CSR_ACT_CHAN_FAIL = 0x33,
GA_MT_CSR_CHAN_MODE_MOD = 0x34,
GA_MT_CSR_CHAN_MODE_MOD_ACK = 0x35,
GA_MT_CSR_RELEASE = 0x40,
GA_MT_CSR_RELEASE_COMPL = 0x41,
GA_MT_CSR_CLEAR_REQ = 0x42,
GA_MT_CSR_HO_ACCESS = 0x50,
GA_MT_CSR_HO_COMPL = 0x51,
GA_MT_CSR_UL_QUAL_IND = 0x52,
GA_MT_CSR_HO_INFO = 0x53,
GA_MT_CSR_HO_CMD = 0x54,
GA_MT_CSR_HO_FAIL = 0x55,
GA_MT_CSR_PAGING_REQ = 0x60,
GA_MT_CSR_PAGING_RESP = 0x61,
GA_MT_CSR_UL_DIRECT_XFER = 0x70,
GA_MT_CSR_DL_DIRECT_XFER = 0x72,
GA_MT_CSR_STATUS = 0x73,
GA_MT_RC_KEEPALIVE = 0x74,
GA_MT_CSR_CM_ENQ = 0x75,
GA_MT_CSR_CM_CHANGE = 0x76,
GA_MT_PSR_GPRS_SUSPEND_REQ = 0x77,
GA_RC_SYNC_INFO = 0x78,
GA_CSR_UTRAN_CM_CHG = 0x79,
GA_MT_CSR_REQUEST = 0x80,
GA_MT_CSR_REQUEST_ACCEPT = 0x81,
GA_MT_CSR_REQUEST_REJECT = 0x82,
};
/* All tables in 10.1.x and 10.2.x / Table 11.2.1 */
enum gan_iei {
GA_IE_MI = 1,
GA_IE_GAN_RELEASE_IND = 2,
GA_IE_RADIO_IE = 3,
GA_IE_GERAN_CELL_ID = 4,
GA_IE_LAC = 5,
GA_IE_GERAN_COV_IND = 6,
GA_IE_GAN_CM = 7,
GA_IE_GEO_LOC = 8,
GA_IE_DEF_SEGW_IP = 9,
GA_IE_DEF_SEGW_FQDN = 10,
GA_IE_REDIR_CTR = 11,
GA_IE_DISCOV_REJ_CAUSE = 12,
GA_IE_GANC_CELL_DESC = 13,
GA_IE_GANC_CTRL_CH_DESC = 14,
GA_IE_GERAN_CELL_ID_LIST= 15,
GA_IE_TU3907_TIMER = 16,
GA_IE_RR_STATE = 17,
GA_IE_RAI = 18,
GA_IE_GAN_BAND = 19,
GA_IE_GARC_GACSR_STATE = 20,
GA_IE_REG_REJ_CAUSE = 21,
GA_IE_TU3906_TIMER = 22,
GA_IE_TU3910_TIMER = 23,
GA_IE_TU3902_TIMER = 24,
GA_IE_L3_MSG = 26,
GA_IE_CHAN_MODE = 27,
GA_IE_MS_CLASSMARK2 = 28,
GA_IE_RR_CAUSE = 29,
GA_EI_CIPH_MODE_SET = 30,
GA_IE_GPRS_RESUMPTION = 31,
GA_IE_HO_FROM_GAN_CMD = 32,
GA_IE_UL_QUAL_IND = 33,
GA_IE_TLLI = 34,
GA_IE_PFI = 35,
GA_IE_SUSP_CAUSE = 36,
GA_IE_TU3920_TIMER = 37,
GA_IE_REQD_QOS = 38,
GA_IE_P_DEACT_CAUSE = 39,
GA_IE_REQD_UL_RATE = 40,
GA_IE_RAC = 41,
GA_IE_AP_LOCATION = 42,
GA_IE_TU4001_TIMER = 43,
GA_IE_LOC_STATUS = 44,
GA_IE_CIPH_RESP = 45,
GA_IE_CIPH_RAND = 46,
GA_IE_CIPH_MAC = 47,
GA_IE_CKSN = 48,
GA_IE_SAPI_ID = 49,
GA_IE_EST_CAUSE = 50,
GA_IE_CHAN_NEEDED = 51,
GA_IE_PDU_IN_ERROR = 52,
GA_IE_SAMPLE_SIZE = 53,
GA_IE_PAYLOAD_TYPE = 54,
GA_IE_MULTIRATE_CONF = 55,
GA_IE_MS_CLASSMARK3 = 56,
GA_IE_LLC_PDU = 57,
GA_IE_LOC_BLACKL_IND = 58,
GA_IE_RESET_IND = 59,
GA_IE_TU4003_TIMER = 60,
GA_IE_AP_SERV_NAME = 61,
GA_IE_SERV_ZONE_INFO = 62,
GA_IE_RTP_RED_CONF = 63,
GA_IE_UTRAN_CLASSMARK = 64,
GA_IE_CM_ENQ_MASK = 65,
GA_IE_UTRAN_CELLID_LIST = 66,
GA_IE_SERV_GANC_TBL_IND = 67,
GA_IE_AP_REG_IND = 68,
GA_IE_GAN_PLMN_LIST = 69,
GA_IE_REQD_GAN_SERV = 71,
GA_IE_BCAST_CONTAINER = 72,
GA_IE_3G_CELL_ID = 73,
GA_IE_MS_RADIO_ID = 96,
GA_IE_DEF_GANC_IP = 97,
GA_IE_DEF_GANC_FQDN = 98,
GA_IE_GPRS_IP_ADDR = 99,
GA_IE_GPRS_UDP_PORT = 100,
GA_IE_GANC_TCP_PORT = 103,
GA_IE_RTP_UDP_PORT = 104,
GA_IE_RTCP_UDP_PORT = 105,
GA_IE_GERAN_RCV_SIGL_LIST = 106,
GA_IE_UTRAN_RCV_SIGL_LIST = 107,
};
/* 11.1.1 GA-RC and GA-CSR Message header IE */
struct gan_rc_csr_hdr {
uint16_t len;
uint8_t pdisc:4,
skip_ind:4;
uint8_t msg_type;
uint8_t data[0];
} __attribute__((packed));
/* 11.2.14.1: GAN Control Channel Description IE */
struct gan_cch_desc_ie {
uint8_t spare:1,
ecmc:1,
nmo:2,
gprs:1,
dtm:1,
att:1,
mscr:1;
#if 0
uint8_t mscr:1,
att:1,
dtm:1,
gprs:1,
nmo:2,
ecmc:1,
spare:1;
#endif
uint8_t t3212;
uint8_t rac;
uint8_t sgsnr:1,
ecmp:1,
re:1,
pfcfm:1,
tgecs:2,
spare2:2;
#if 0
uint8_t spare2:2,
tgecs:2,
pfcfm:1,
re:1,
ecmp:1,
sgsnr:1;
#endif
uint8_t access_class[2];
} __attribute__((packed));
#endif /* PROTO_GSM_44_318_H */

View File

@ -0,0 +1,94 @@
#ifndef _OSMO_PROTO_IPACCESS_H
#define _OSMO_PROTO_IPACCESS_H
#include <stdint.h>
#define IPA_TCP_PORT_OML 3002
#define IPA_TCP_PORT_RSL 3003
struct ipaccess_head {
uint16_t len; /* network byte order */
uint8_t proto;
uint8_t data[0];
} __attribute__ ((packed));
struct ipaccess_head_ext {
uint8_t proto;
uint8_t data[0];
} __attribute__ ((packed));
enum ipaccess_proto {
IPAC_PROTO_RSL = 0x00,
IPAC_PROTO_IPACCESS = 0xfe,
IPAC_PROTO_SCCP = 0xfd,
IPAC_PROTO_OML = 0xff,
/* OpenBSC extensions */
IPAC_PROTO_OSMO = 0xee,
IPAC_PROTO_MGCP_OLD = 0xfc,
};
enum ipaccess_proto_ext {
IPAC_PROTO_EXT_CTRL = 0x00,
IPAC_PROTO_EXT_MGCP = 0x01,
IPAC_PROTO_EXT_LAC = 0x02,
IPAC_PROTO_EXT_SMSC = 0x03,
};
enum ipaccess_msgtype {
IPAC_MSGT_PING = 0x00,
IPAC_MSGT_PONG = 0x01,
IPAC_MSGT_ID_GET = 0x04,
IPAC_MSGT_ID_RESP = 0x05,
IPAC_MSGT_ID_ACK = 0x06,
/* OpenBSC extension */
IPAC_MSGT_SCCP_OLD = 0xff,
};
enum ipaccess_id_tags {
IPAC_IDTAG_SERNR = 0x00,
IPAC_IDTAG_UNITNAME = 0x01,
IPAC_IDTAG_LOCATION1 = 0x02,
IPAC_IDTAG_LOCATION2 = 0x03,
IPAC_IDTAG_EQUIPVERS = 0x04,
IPAC_IDTAG_SWVERSION = 0x05,
IPAC_IDTAG_IPADDR = 0x06,
IPAC_IDTAG_MACADDR = 0x07,
IPAC_IDTAG_UNIT = 0x08,
};
/*
* Firmware specific header
*/
struct sdp_firmware {
char magic[4];
char more_magic[2];
uint16_t more_more_magic;
uint32_t header_length;
uint32_t file_length;
char sw_part[20];
char text1[64];
char time[12];
char date[14];
char text2[10];
char version[20];
uint16_t table_offset;
/* stuff i don't know */
} __attribute__((packed));
struct sdp_header_entry {
uint16_t something1;
char text1[64];
char time[12];
char date[14];
char text2[10];
char version[20];
uint32_t length;
uint32_t addr1;
uint32_t addr2;
uint32_t start;
} __attribute__((packed));
#endif /* _OSMO_PROTO_IPACCESS_H */

View File

@ -0,0 +1,55 @@
#ifndef _OSMOCORE_RSL_H
#define _OSMOCORE_RSL_H
#include <stdint.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/msgb.h>
#include <osmocom/gsm/protocol/gsm_08_58.h>
/*! \defgroup rsl RSL
* @{
*/
/*! \file rsl.h */
void rsl_init_rll_hdr(struct abis_rsl_rll_hdr *dh, uint8_t msg_type);
void rsl_init_cchan_hdr(struct abis_rsl_cchan_hdr *ch, uint8_t msg_type);
extern const struct tlv_definition rsl_att_tlvdef;
/*! \brief Parse RSL TLV structure using \ref tlv_parse */
#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);
/* Turns channel number into a string */
const char *rsl_chan_nr_str(uint8_t chan_nr);
const char *rsl_err_name(uint8_t err);
const char *rsl_rlm_cause_name(uint8_t err);
const char *rsl_msg_name(uint8_t err);
const char *rsl_ipac_msg_name(uint8_t msg_type);
/* 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 */
void rsl_rll_push_hdr(struct msgb *msg, uint8_t msg_type, uint8_t chan_nr,
uint8_t link_id, int transparent);
/* 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 */

View File

@ -0,0 +1,22 @@
#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 */

View File

@ -0,0 +1,43 @@
#ifndef _OSMO_GSM_SYSINFO_H
#define _OSMO_GSM_SYSINFO_H
#include <osmocom/core/utils.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
enum osmo_sysinfo_type {
SYSINFO_TYPE_NONE,
SYSINFO_TYPE_1,
SYSINFO_TYPE_2,
SYSINFO_TYPE_3,
SYSINFO_TYPE_4,
SYSINFO_TYPE_5,
SYSINFO_TYPE_6,
SYSINFO_TYPE_7,
SYSINFO_TYPE_8,
SYSINFO_TYPE_9,
SYSINFO_TYPE_10,
SYSINFO_TYPE_13,
SYSINFO_TYPE_16,
SYSINFO_TYPE_17,
SYSINFO_TYPE_18,
SYSINFO_TYPE_19,
SYSINFO_TYPE_20,
SYSINFO_TYPE_2bis,
SYSINFO_TYPE_2ter,
SYSINFO_TYPE_2quater,
SYSINFO_TYPE_5bis,
SYSINFO_TYPE_5ter,
SYSINFO_TYPE_EMO,
SYSINFO_TYPE_MEAS_INFO,
/* FIXME all the various bis and ter */
_MAX_SYSINFO_TYPE
};
typedef uint8_t sysinfo_buf_t[GSM_MACBLOCK_LEN];
extern const struct value_string osmo_sitype_strs[_MAX_SYSINFO_TYPE];
uint8_t osmo_sitype2rsl(enum osmo_sysinfo_type si_type);
enum osmo_sysinfo_type osmo_rsl2sitype(uint8_t rsl_si);
#endif /* _OSMO_GSM_SYSINFO_H */

View File

@ -0,0 +1,415 @@
#ifndef _TLV_H
#define _TLV_H
#include <stdint.h>
#include <string.h>
#include <osmocom/core/msgb.h>
/*! \defgroup tlv GSM L3 compatible TLV parser
* @{
*/
/*! \file tlv.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
vTvLV 8/16 8/16 N * 8
*/
/*! \brief gross length of a LV type field */
#define LV_GROSS_LEN(x) (x+1)
/*! \brief gross length of a TLV type field */
#define TLV_GROSS_LEN(x) (x+2)
/*! \brief gross length of a TLV16 type field */
#define TLV16_GROSS_LEN(x) ((2*x)+2)
/*! \brief gross length of a TL16V type field */
#define TL16V_GROSS_LEN(x) (x+3)
/*! \brief gross length of a L16TV type field */
#define L16TV_GROSS_LEN(x) (x+3)
/*! \brief maximum length of TLV of one byte length */
#define TVLV_MAX_ONEBYTE 0x7f
/*! \brief gross length of a TVLV type field */
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);
}
/*! \brief gross length of vTvL header (tag+len) */
static inline uint16_t VTVL_GAN_GROSS_LEN(uint16_t tag, uint16_t len)
{
uint16_t ret = 2;
if (tag > TVLV_MAX_ONEBYTE)
ret++;
if (len > TVLV_MAX_ONEBYTE)
ret++;
return ret;
}
/*! \brief gross length of vTvLV (tag+len+val) */
static inline uint16_t VTVLV_GAN_GROSS_LEN(uint16_t tag, uint16_t len)
{
uint16_t ret;
if (len <= TVLV_MAX_ONEBYTE)
return TLV_GROSS_LEN(len);
else
return TL16V_GROSS_LEN(len);
if (tag > TVLV_MAX_ONEBYTE)
ret += 1;
return ret;
}
/* TLV generation */
/*! \brief put (append) a LV field */
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;
}
/*! \brief put (append) a TLV field */
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;
}
/*! \brief put (append) a TLV16 field */
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;
}
/*! \brief put (append) a TL16V field */
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;
}
/*! \brief put (append) a TvLV field */
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;
}
/*! \brief put (append) a variable-length tag or variable-length length * */
static inline uint8_t *vt_gan_put(uint8_t *buf, uint16_t tag)
{
if (tag > TVLV_MAX_ONEBYTE) {
/* two-byte TAG */
*buf++ = 0x80 | (tag >> 8);
*buf++ = (tag & 0xff);
} else
*buf++ = tag;
return buf;
}
/* \brief put (append) vTvL (GAN) field (tag + length)*/
static inline uint8_t *vtvl_gan_put(uint8_t *buf, uint16_t tag, uint16_t len)
{
uint8_t *ret;
ret = vt_gan_put(buf, tag);
return vt_gan_put(ret, len);
}
/* \brief put (append) vTvLV (GAN) field (tag + length + val) */
static inline uint8_t *vtvlv_gan_put(uint8_t *buf, uint16_t tag, uint16_t len,
const uint8_t *val)
{
uint8_t *ret;
ret = vtvl_gan_put(buf, tag, len );
memcpy(ret, val, len);
ret = buf + len;
return ret;
}
/*! \brief put (append) a TLV16 field to \ref msgb */
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);
}
/*! \brief put (append) a TL16V field to \ref msgb */
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);
}
/*! \brief put (append) a TvLV field to \ref msgb */
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);
}
/*! \brief put (append) a vTvLV field to \ref msgb */
static inline uint8_t *msgb_vtvlv_gan_put(struct msgb *msg, uint16_t tag,
uint16_t len, const uint8_t *val)
{
uint8_t *buf = msgb_put(msg, VTVLV_GAN_GROSS_LEN(tag, len));
return vtvlv_gan_put(buf, tag, len, val);
}
/*! \brief put (append) a L16TV field to \ref msgb */
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;
}
/*! \brief put (append) a V field */
static inline uint8_t *v_put(uint8_t *buf, uint8_t val)
{
*buf++ = val;
return buf;
}
/*! \brief put (append) a TV field */
static inline uint8_t *tv_put(uint8_t *buf, uint8_t tag,
uint8_t val)
{
*buf++ = tag;
*buf++ = val;
return buf;
}
/*! \brief put (append) a TVfixed field */
static inline uint8_t *tv_fixed_put(uint8_t *buf, uint8_t tag,
unsigned int len, const uint8_t *val)
{
*buf++ = tag;
memcpy(buf, val, len);
return buf + len;
}
/*! \brief put (append) a TV16 field
* \param[in,out] buf data buffer
* \param[in] tag Tag value
* \param[in] val Value (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;
}
/*! \brief put (append) a LV field to a \ref msgb
* \returns pointer to first byte after newly-put information */
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);
}
/*! \brief put (append) a TLV field to a \ref msgb
* \returns pointer to first byte after newly-put information */
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);
}
/*! \brief put (append) a TV field to a \ref msgb
* \returns pointer to first byte after newly-put information */
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);
}
/*! \brief put (append) a TVfixed field to a \ref msgb
* \returns pointer to first byte after newly-put information */
static inline uint8_t *msgb_tv_fixed_put(struct msgb *msg, uint8_t tag,
unsigned int len, const uint8_t *val)
{
uint8_t *buf = msgb_put(msg, 1+len);
return tv_fixed_put(buf, tag, len, val);
}
/*! \brief put (append) a V field to a \ref msgb
* \returns pointer to first byte after newly-put information */
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);
}
/*! \brief put (append) a TV16 field to a \ref msgb
* \returns pointer to first byte after newly-put information */
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);
}
/*! \brief push (prepend) a TLV field to a \ref msgb
* \returns pointer to first byte of newly-pushed information */
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));
tlv_put(buf, tag, len, val);
return buf;
}
/*! \brief push (prepend) a TV field to a \ref msgb
* \returns pointer to first byte of newly-pushed information */
static inline uint8_t *msgb_tv_push(struct msgb *msg, uint8_t tag, uint8_t val)
{
uint8_t *buf = msgb_push(msg, 2);
tv_put(buf, tag, val);
return buf;
}
/*! \brief push (prepend) a TV16 field to a \ref msgb
* \returns pointer to first byte of newly-pushed information */
static inline uint8_t *msgb_tv16_push(struct msgb *msg, uint8_t tag, uint16_t val)
{
uint8_t *buf = msgb_push(msg, 3);
tv16_put(buf, tag, val);
return buf;
}
/*! \brief push (prepend) a TvLV field to a \ref msgb
* \returns pointer to first byte of newly-pushed information */
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));
tvlv_put(buf, tag, len, val);
return buf;
}
/* \brief push (prepend) a vTvL header to a \ref msgb
*/
static inline uint8_t *msgb_vtvl_gan_push(struct msgb *msg, uint16_t tag,
uint16_t len)
{
uint8_t *buf = msgb_push(msg, VTVL_GAN_GROSS_LEN(tag, len));
vtvl_gan_put(buf, tag, len);
return buf;
}
static inline uint8_t *msgb_vtvlv_gan_push(struct msgb *msg, uint16_t tag,
uint16_t len, const uint8_t *val)
{
uint8_t *buf = msgb_push(msg, VTVLV_GAN_GROSS_LEN(tag, len));
vtvlv_gan_put(buf, tag, len, val);
return buf;
}
/* TLV parsing */
/*! \brief Entry in a TLV parser array */
struct tlv_p_entry {
uint16_t len; /*!< \brief length */
const uint8_t *val; /*!< \brief pointer to value */
};
/*! \brief TLV type */
enum tlv_type {
TLV_TYPE_NONE, /*!< \brief no type */
TLV_TYPE_FIXED, /*!< \brief fixed-length value-only */
TLV_TYPE_T, /*!< \brief tag-only */
TLV_TYPE_TV, /*!< \brief tag-value (8bit) */
TLV_TYPE_TLV, /*!< \brief tag-length-value */
TLV_TYPE_TL16V, /*!< \brief tag, 16 bit length, value */
TLV_TYPE_TvLV, /*!< \brief tag, variable length, value */
TLV_TYPE_SINGLE_TV, /*!< \brief tag and value (both 4 bit) in 1 byte */
TLV_TYPE_vTvLV_GAN, /*!< \brief variable-length tag, variable-length length */
};
/*! \brief Definition of a single IE (Information Element) */
struct tlv_def {
enum tlv_type type; /*!< \brief TLV type */
uint8_t fixed_len; /*!< \brief length in case of \ref TLV_TYPE_FIXED */
};
/*! \brief Definition of All 256 IE / TLV */
struct tlv_definition {
struct tlv_def def[256];
};
/*! \brief result of the TLV parser */
struct tlv_parsed {
struct tlv_p_entry lv[256];
};
extern struct tlv_definition tvlv_att_def;
extern struct tlv_definition vtvlv_gan_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 */

View File

@ -0,0 +1,102 @@
/*
* Buffering to output and input.
* Copyright (C) 1998 Kunihiro Ishiguro
*
* This file is part of GNU Zebra.
*
* GNU Zebra 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, or (at your
* option) any later version.
*
* GNU Zebra 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 GNU Zebra; see the file COPYING. If not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef _ZEBRA_BUFFER_H
#define _ZEBRA_BUFFER_H
#include <sys/types.h>
/* 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);
/* Free all data in the buffer. */
void buffer_reset(struct buffer *);
/* This function first calls buffer_reset to release all buffered data.
Then it frees the struct buffer itself. */
void buffer_free(struct buffer *);
/* Add the given data to the end of the buffer. */
extern void buffer_put(struct buffer *, const void *, size_t);
/* Add a single character to the end of the buffer. */
extern void buffer_putc(struct buffer *, u_char);
/* Add a NUL-terminated string to the end of the buffer. */
extern void buffer_putstr(struct buffer *, const char *);
/* Combine all accumulated (and unflushed) data inside the buffer into a
single NUL-terminated string allocated using XMALLOC(MTYPE_TMP). Note
that this function does not alter the state of the buffer, so the data
is still inside waiting to be flushed. */
char *buffer_getstr(struct buffer *);
/* Returns 1 if there is no pending data in the buffer. Otherwise returns 0. */
int buffer_empty(struct buffer *);
typedef enum {
/* An I/O error occurred. The buffer should be destroyed and the
file descriptor should be closed. */
BUFFER_ERROR = -1,
/* The data was written successfully, and the buffer is now empty
(there is no pending data waiting to be flushed). */
BUFFER_EMPTY = 0,
/* There is pending data in the buffer waiting to be flushed. Please
try flushing the buffer when select indicates that the file descriptor
is writeable. */
BUFFER_PENDING = 1
} buffer_status_t;
/* Try to write this data to the file descriptor. Any data that cannot
be written immediately is added to the buffer queue. */
extern buffer_status_t buffer_write(struct buffer *, int fd,
const void *, size_t);
/* This function attempts to flush some (but perhaps not all) of
the queued data to the given file descriptor. */
extern buffer_status_t buffer_flush_available(struct buffer *, int fd);
/* The following 2 functions (buffer_flush_all and buffer_flush_window)
are for use in lib/vty.c only. They should not be used elsewhere. */
/* Call buffer_flush_available repeatedly until either all data has been
flushed, or an I/O error has been encountered, or the operation would
block. */
extern buffer_status_t buffer_flush_all(struct buffer *, int fd);
/* Attempt to write enough data to the given fd to fill a window of the
given width and height (and remove the data written from the buffer).
If !no_more, then a message saying " --More-- " is appended.
If erase is true, then first overwrite the previous " --More-- " message
with spaces.
Any write error (including EAGAIN or EINTR) will cause this function
to return -1 (because the logic for handling the erase and more features
is too complicated to retry the write later).
*/
extern buffer_status_t buffer_flush_window(struct buffer *, int fd, int width,
int height, int erase, int no_more);
#endif /* _ZEBRA_BUFFER_H */

View File

@ -0,0 +1,374 @@
/*
* Zebra configuration command interface routine
* Copyright (C) 1997, 98 Kunihiro Ishiguro
*
* This file is part of GNU Zebra.
*
* GNU Zebra 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, or (at your
* option) any later version.
*
* GNU Zebra 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 GNU Zebra; see the file COPYING. If not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef _ZEBRA_COMMAND_H
#define _ZEBRA_COMMAND_H
#include <stdio.h>
#include <sys/types.h>
#include "vector.h"
/*! \defgroup command VTY Command
* @{
*/
/*! \file command.h */
/*! \brief Host configuration variable */
struct host {
/*! \brief Host name of this router. */
char *name;
/*! \brief Password for vty interface. */
char *password;
char *password_encrypt;
/*! \brief Enable password */
char *enable;
char *enable_encrypt;
/*! \brief System wide terminal lines. */
int lines;
/*! \brief Log filename. */
char *logfile;
/*! \brief config file name of this host */
char *config;
/*! \brief Flags for services */
int advanced;
int encrypt;
/*! \brief Banner configuration. */
const char *motd;
char *motdfile;
/*! \brief VTY application information */
const struct vty_app_info *app_info;
};
/*! \brief There are some command levels which called from command node. */
enum node_type {
AUTH_NODE, /*!< \brief Authentication mode of vty interface. */
VIEW_NODE, /*!< \brief View node. Default mode of vty interface. */
AUTH_ENABLE_NODE, /*!< \brief Authentication mode for change enable. */
ENABLE_NODE, /*!< \brief Enable node. */
CONFIG_NODE, /*!< \brief Config node. Default mode of config file. */
SERVICE_NODE, /*!< \brief Service node. */
DEBUG_NODE, /*!< \brief Debug node. */
CFG_LOG_NODE, /*!< \brief Configure the logging */
VTY_NODE, /*!< \brief Vty node. */
L_E1INP_NODE, /*!< \brief E1 line in libosmo-abis. */
L_IPA_NODE, /*!< \brief IPA proxying commands in libosmo-abis. */
L_NS_NODE, /*!< \brief NS node in libosmo-gb. */
L_BSSGP_NODE, /*!< \brief BSSGP node in libosmo-gb. */
_LAST_OSMOVTY_NODE
};
#include "vty.h"
/*! \brief Node which has some commands and prompt string and
* configuration function pointer . */
struct cmd_node {
/*! \brief Node index */
enum node_type node;
/*! \brief Prompt character at vty interface. */
const char *prompt;
/*! \brief Is this node's configuration goes to vtysh ? */
int vtysh;
/*! \brief Node's configuration write function */
int (*func) (struct vty *);
/*! \brief Vector of this node's command list. */
vector cmd_vector;
};
enum {
CMD_ATTR_DEPRECATED = 1,
CMD_ATTR_HIDDEN,
};
/*! \brief Structure of a command element */
struct cmd_element {
const char *string; /*!< \brief Command specification by string. */
int (*func) (struct cmd_element *, struct vty *, int, const char *[]);
const char *doc; /*!< \brief Documentation of this command. */
int daemon; /*!< \brief Daemon to which this command belong. */
vector strvec; /*!< \brief Pointing out each description vector. */
unsigned int cmdsize; /*!< \brief Command index count. */
char *config; /*!< \brief Configuration string */
vector subconfig; /*!< \brief Sub configuration string */
u_char attr; /*!< \brief Command attributes */
};
/*! \brief Command description structure. */
struct desc {
const char *cmd; /*!< \brief Command string. */
const char *str; /*!< \brief Command's description. */
};
/*! \brief Return value of the commands. */
#define CMD_SUCCESS 0
#define CMD_WARNING 1
#define CMD_ERR_NO_MATCH 2
#define CMD_ERR_AMBIGUOUS 3
#define CMD_ERR_INCOMPLETE 4
#define CMD_ERR_EXEED_ARGC_MAX 5
#define CMD_ERR_NOTHING_TODO 6
#define CMD_COMPLETE_FULL_MATCH 7
#define CMD_COMPLETE_MATCH 8
#define CMD_COMPLETE_LIST_MATCH 9
#define CMD_SUCCESS_DAEMON 10
/* Argc max counts. */
#define CMD_ARGC_MAX 256
/* Turn off these macros when uisng cpp with extract.pl */
#ifndef VTYSH_EXTRACT_PL
/* helper defines for end-user DEFUN* macros */
#define DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attrs, dnum) \
static struct cmd_element cmdname = \
{ \
.string = cmdstr, \
.func = funcname, \
.doc = helpstr, \
.attr = attrs, \
.daemon = dnum, \
};
/* global (non static) cmd_element */
#define gDEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attrs, dnum) \
struct cmd_element cmdname = \
{ \
.string = cmdstr, \
.func = funcname, \
.doc = helpstr, \
.attr = attrs, \
.daemon = dnum, \
};
#define DEFUN_CMD_FUNC_DECL(funcname) \
static int funcname (struct cmd_element *, struct vty *, int, const char *[]); \
#define DEFUN_CMD_FUNC_TEXT(funcname) \
static int funcname \
(struct cmd_element *self, struct vty *vty, int argc, const char *argv[])
/*! \brief Macro for defining a VTY node and function
* \param[in] funcname Name of the function implementing the node
* \param[in] cmdname Name of the command node
* \param[in] cmdstr String with syntax of node
* \param[in] helpstr String with help message of node
*/
#define DEFUN(funcname, cmdname, cmdstr, helpstr) \
DEFUN_CMD_FUNC_DECL(funcname) \
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) \
DEFUN_CMD_FUNC_TEXT(funcname)
/*! \brief Macro for defining a non-static (global) VTY node and function
* \param[in] funcname Name of the function implementing the node
* \param[in] cmdname Name of the command node
* \param[in] cmdstr String with syntax of node
* \param[in] helpstr String with help message of node
*/
#define gDEFUN(funcname, cmdname, cmdstr, helpstr) \
DEFUN_CMD_FUNC_DECL(funcname) \
gDEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) \
DEFUN_CMD_FUNC_TEXT(funcname)
#define DEFUN_ATTR(funcname, cmdname, cmdstr, helpstr, attr) \
DEFUN_CMD_FUNC_DECL(funcname) \
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, 0) \
DEFUN_CMD_FUNC_TEXT(funcname)
#define DEFUN_HIDDEN(funcname, cmdname, cmdstr, helpstr) \
DEFUN_ATTR (funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN)
#define DEFUN_DEPRECATED(funcname, cmdname, cmdstr, helpstr) \
DEFUN_ATTR (funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED) \
/* DEFUN_NOSH for commands that vtysh should ignore */
#define DEFUN_NOSH(funcname, cmdname, cmdstr, helpstr) \
DEFUN(funcname, cmdname, cmdstr, helpstr)
/* DEFSH for vtysh. */
#define DEFSH(daemon, cmdname, cmdstr, helpstr) \
DEFUN_CMD_ELEMENT(NULL, cmdname, cmdstr, helpstr, 0, daemon) \
/* DEFUN + DEFSH */
#define DEFUNSH(daemon, funcname, cmdname, cmdstr, helpstr) \
DEFUN_CMD_FUNC_DECL(funcname) \
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, daemon) \
DEFUN_CMD_FUNC_TEXT(funcname)
/* DEFUN + DEFSH with attributes */
#define DEFUNSH_ATTR(daemon, funcname, cmdname, cmdstr, helpstr, attr) \
DEFUN_CMD_FUNC_DECL(funcname) \
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, daemon) \
DEFUN_CMD_FUNC_TEXT(funcname)
#define DEFUNSH_HIDDEN(daemon, funcname, cmdname, cmdstr, helpstr) \
DEFUNSH_ATTR (daemon, funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN)
#define DEFUNSH_DEPRECATED(daemon, funcname, cmdname, cmdstr, helpstr) \
DEFUNSH_ATTR (daemon, funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED)
/* ALIAS macro which define existing command's alias. */
#define ALIAS(funcname, cmdname, cmdstr, helpstr) \
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0)
/* global (non static) cmd_element */
#define gALIAS(funcname, cmdname, cmdstr, helpstr) \
gDEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0)
#define ALIAS_ATTR(funcname, cmdname, cmdstr, helpstr, attr) \
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, 0)
#define ALIAS_HIDDEN(funcname, cmdname, cmdstr, helpstr) \
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN, 0)
#define ALIAS_DEPRECATED(funcname, cmdname, cmdstr, helpstr) \
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED, 0)
#define ALIAS_SH(daemon, funcname, cmdname, cmdstr, helpstr) \
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, daemon)
#define ALIAS_SH_HIDDEN(daemon, funcname, cmdname, cmdstr, helpstr) \
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN, daemon)
#define ALIAS_SH_DEPRECATED(daemon, funcname, cmdname, cmdstr, helpstr) \
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED, daemon)
#endif /* VTYSH_EXTRACT_PL */
/* Some macroes */
#define CMD_OPTION(S) ((S[0]) == '[')
#define CMD_VARIABLE(S) (((S[0]) >= 'A' && (S[0]) <= 'Z') || ((S[0]) == '<'))
#define CMD_VARARG(S) ((S[0]) == '.')
#define CMD_RANGE(S) ((S[0] == '<'))
#define CMD_IPV4(S) ((strcmp ((S), "A.B.C.D") == 0))
#define CMD_IPV4_PREFIX(S) ((strcmp ((S), "A.B.C.D/M") == 0))
#define CMD_IPV6(S) ((strcmp ((S), "X:X::X:X") == 0))
#define CMD_IPV6_PREFIX(S) ((strcmp ((S), "X:X::X:X/M") == 0))
/* Common descriptions. */
#define SHOW_STR "Show running system information\n"
#define IP_STR "IP information\n"
#define IPV6_STR "IPv6 information\n"
#define NO_STR "Negate a command or set its defaults\n"
#define CLEAR_STR "Reset functions\n"
#define RIP_STR "RIP information\n"
#define BGP_STR "BGP information\n"
#define OSPF_STR "OSPF information\n"
#define NEIGHBOR_STR "Specify neighbor router\n"
#define DEBUG_STR "Debugging functions (see also 'undebug')\n"
#define UNDEBUG_STR "Disable debugging functions (see also 'debug')\n"
#define ROUTER_STR "Enable a routing process\n"
#define AS_STR "AS number\n"
#define MBGP_STR "MBGP information\n"
#define MATCH_STR "Match values from routing table\n"
#define SET_STR "Set values in destination routing protocol\n"
#define OUT_STR "Filter outgoing routing updates\n"
#define IN_STR "Filter incoming routing updates\n"
#define V4NOTATION_STR "specify by IPv4 address notation(e.g. 0.0.0.0)\n"
#define OSPF6_NUMBER_STR "Specify by number\n"
#define INTERFACE_STR "Interface infomation\n"
#define IFNAME_STR "Interface name(e.g. ep0)\n"
#define IP6_STR "IPv6 Information\n"
#define OSPF6_STR "Open Shortest Path First (OSPF) for IPv6\n"
#define OSPF6_ROUTER_STR "Enable a routing process\n"
#define OSPF6_INSTANCE_STR "<1-65535> Instance ID\n"
#define SECONDS_STR "<1-65535> Seconds\n"
#define ROUTE_STR "Routing Table\n"
#define PREFIX_LIST_STR "Build a prefix list\n"
#define OSPF6_DUMP_TYPE_LIST \
"(neighbor|interface|area|lsa|zebra|config|dbex|spf|route|lsdb|redistribute|hook|asbr|prefix|abr)"
#define ISIS_STR "IS-IS information\n"
#define AREA_TAG_STR "[area tag]\n"
#define CONF_BACKUP_EXT ".sav"
/* IPv4 only machine should not accept IPv6 address for peer's IP
address. So we replace VTY command string like below. */
#ifdef HAVE_IPV6
#define NEIGHBOR_CMD "neighbor (A.B.C.D|X:X::X:X) "
#define NO_NEIGHBOR_CMD "no neighbor (A.B.C.D|X:X::X:X) "
#define NEIGHBOR_ADDR_STR "Neighbor address\nIPv6 address\n"
#define NEIGHBOR_CMD2 "neighbor (A.B.C.D|X:X::X:X|WORD) "
#define NO_NEIGHBOR_CMD2 "no neighbor (A.B.C.D|X:X::X:X|WORD) "
#define NEIGHBOR_ADDR_STR2 "Neighbor address\nNeighbor IPv6 address\nNeighbor tag\n"
#else
#define NEIGHBOR_CMD "neighbor A.B.C.D "
#define NO_NEIGHBOR_CMD "no neighbor A.B.C.D "
#define NEIGHBOR_ADDR_STR "Neighbor address\n"
#define NEIGHBOR_CMD2 "neighbor (A.B.C.D|WORD) "
#define NO_NEIGHBOR_CMD2 "no neighbor (A.B.C.D|WORD) "
#define NEIGHBOR_ADDR_STR2 "Neighbor address\nNeighbor tag\n"
#endif /* HAVE_IPV6 */
/* Prototypes. */
void install_node(struct cmd_node *, int (*)(struct vty *));
void install_default(enum node_type);
void install_element(enum node_type, struct cmd_element *);
void install_element_ve(struct cmd_element *cmd);
void sort_node(void);
/* Concatenates argv[shift] through argv[argc-1] into a single NUL-terminated
string with a space between each element (allocated using
XMALLOC(MTYPE_TMP)). Returns NULL if shift >= argc. */
char *argv_concat(const char **argv, int argc, int shift);
vector cmd_make_strvec(const char *);
void cmd_free_strvec(vector);
vector cmd_describe_command();
char **cmd_complete_command();
const char *cmd_prompt(enum node_type);
int config_from_file(struct vty *, FILE *);
enum node_type node_parent(enum node_type);
int cmd_execute_command(vector, struct vty *, struct cmd_element **, int);
int cmd_execute_command_strict(vector, struct vty *, struct cmd_element **);
void config_replace_string(struct cmd_element *, char *, ...);
void cmd_init(int);
/* Export typical functions. */
extern struct cmd_element config_exit_cmd;
extern struct cmd_element config_help_cmd;
extern struct cmd_element config_list_cmd;
extern struct cmd_element config_end_cmd;
char *host_config_file();
void host_config_set(const char *);
/* This is called from main when a daemon is invoked with -v or --version. */
void print_version(int print_copyright);
extern void *tall_vty_cmd_ctx;
/*! @} */
#endif /* _ZEBRA_COMMAND_H */

View File

@ -0,0 +1,12 @@
#ifndef _VTY_LOGGING_H
#define _VTY_LOGGING_H
#define LOGGING_STR "Configure log message to this terminal\n"
#define FILTER_STR "Filter log messages\n"
struct log_info;
void logging_vty_add_cmds(const struct log_info *cat);
struct vty;
struct log_target *osmo_log_vty2tgt(struct vty *vty);
#endif /* _VTY_LOGGING_H */

View File

@ -0,0 +1,19 @@
#ifndef OSMO_VTY_MISC_H
#define OSMO_VTY_MISC_H
#include <osmocom/vty/vty.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/utils.h>
#define VTY_DO_LOWER 1
char *vty_cmd_string_from_valstr(void *ctx, const struct value_string *vals,
const char *prefix, const char *sep,
const char *end, int do_lower);
void vty_out_rate_ctr_group(struct vty *vty, const char *prefix,
struct rate_ctr_group *ctrg);
int osmo_vty_write_config_file(const char *filename);
int osmo_vty_save_config_file(void);
#endif

View File

@ -0,0 +1,56 @@
/* minimalistic telnet/network interface it might turn into a wire interface */
/* (C) 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.
*
*/
#ifndef TELNET_INTERFACE_H
#define TELNET_INTERFACE_H
#include <osmocom/core/logging.h>
#include <osmocom/core/select.h>
#include <osmocom/vty/vty.h>
/*! \defgroup telnet_interface Telnet Interface
* @{
*/
/*! \file telnet_interface.h */
/*! \brief A telnet connection */
struct telnet_connection {
/*! \brief linked list header for internal management */
struct llist_head entry;
/*! \brief private data pointer passed through */
void *priv;
/*! \brief filedsecriptor (socket ) */
struct osmo_fd fd;
/*! \brief VTY instance associated with telnet connection */
struct vty *vty;
/*! \brief logging target associated with this telnet connection */
struct log_target *dbg;
};
int telnet_init(void *tall_ctx, void *priv, int port);
int telnet_init_dynif(void *tall_ctx, void *priv, const char *ip, int port);
void telnet_exit(void);
/*! @} */
#endif /* TELNET_INTERFACE_H */

View File

@ -0,0 +1,64 @@
/*
* Generic vector interface header.
* Copyright (C) 1997, 98 Kunihiro Ishiguro
*
* This file is part of GNU Zebra.
*
* GNU Zebra 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, or (at your option) any
* later version.
*
* GNU Zebra 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 GNU Zebra; see the file COPYING. If not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef _ZEBRA_VECTOR_H
#define _ZEBRA_VECTOR_H
/* struct for vector */
struct _vector {
unsigned int active; /* number of active slots */
unsigned int alloced; /* number of allocated slot */
void **index; /* index to data */
};
typedef struct _vector *vector;
#define VECTOR_MIN_SIZE 1
/* (Sometimes) usefull macros. This macro convert index expression to
array expression. */
/* Reference slot at given index, caller must ensure slot is active */
#define vector_slot(V,I) ((V)->index[(I)])
/* Number of active slots.
* Note that this differs from vector_count() as it the count returned
* will include any empty slots
*/
#define vector_active(V) ((V)->active)
/* Prototypes. */
vector vector_init(unsigned int size);
void vector_ensure(vector v, unsigned int num);
int vector_empty_slot(vector v);
int vector_set(vector v, void *val);
int vector_set_index(vector v, unsigned int i, void *val);
void vector_unset(vector v, unsigned int i);
unsigned int vector_count(vector v);
void vector_only_wrapper_free(vector v);
void vector_only_index_free(void *index);
void vector_free(vector v);
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 */

Some files were not shown because too many files have changed in this diff Show More