mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
synced 2025-10-23 08:12:01 +00:00
Compare commits
35 Commits
1.14.0
...
on-waves/0
Author | SHA1 | Date | |
---|---|---|---|
|
851ace9f33 | ||
|
d1dd069b48 | ||
|
401db32ca2 | ||
|
17e03d21d2 | ||
|
26a9bff201 | ||
|
80fb260a60 | ||
|
55a0716da7 | ||
|
c88fb75616 | ||
|
d55a4dc326 | ||
|
a4e6f2e6e1 | ||
|
7f71d99cc3 | ||
|
b92167cf80 | ||
|
4b6a6dbe7e | ||
|
763e8c7766 | ||
|
823ff16088 | ||
|
6f93c6a1e0 | ||
|
f97e48b0de | ||
|
761600b0fd | ||
|
8549462bc6 | ||
|
436e5c6308 | ||
|
f8b9d844c1 | ||
|
58ec07d580 | ||
|
71465c21f4 | ||
|
16d0a833f8 | ||
|
ea72b62cac | ||
|
49a84ec6e9 | ||
|
42c636b6c8 | ||
|
a0a55f555e | ||
|
23ed00e410 | ||
|
3fe910b9f1 | ||
|
097bdeb77d | ||
|
1b85de02e0 | ||
|
2281d1835f | ||
|
fb4433a129 | ||
|
d954dcf9e1 |
118
.clang-format
118
.clang-format
@@ -1,118 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# clang-format configuration file. Intended for clang-format >= 4.
|
||||
#
|
||||
# For more information, see:
|
||||
#
|
||||
# Documentation/process/clang-format.rst
|
||||
# https://clang.llvm.org/docs/ClangFormat.html
|
||||
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
|
||||
#
|
||||
---
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
#AlignEscapedNewlines: Left # Unknown to clang-format-4.0
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: false
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BraceWrapping:
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: true
|
||||
AfterNamespace: true
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
#AfterExternBlock: false # Unknown to clang-format-5.0
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
#SplitEmptyFunction: true # Unknown to clang-format-4.0
|
||||
#SplitEmptyRecord: true # Unknown to clang-format-4.0
|
||||
#SplitEmptyNamespace: true # Unknown to clang-format-4.0
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Custom
|
||||
#BreakBeforeInheritanceComma: false # Unknown to clang-format-4.0
|
||||
BreakBeforeTernaryOperators: false
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
#BreakConstructorInitializers: BeforeComma # Unknown to clang-format-4.0
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: false
|
||||
ColumnLimit: 120
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
#CompactNamespaces: false # Unknown to clang-format-4.0
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 8
|
||||
ContinuationIndentWidth: 8
|
||||
Cpp11BracedListStyle: false
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
#FixNamespaceComments: false # Unknown to clang-format-4.0
|
||||
|
||||
#IncludeBlocks: Preserve # Unknown to clang-format-5.0
|
||||
IncludeCategories:
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IndentCaseLabels: false
|
||||
#IndentPPDirectives: None # Unknown to clang-format-5.0
|
||||
IndentWidth: 8
|
||||
IndentWrappedFunctionNames: false
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
#ObjCBinPackProtocolList: Auto # Unknown to clang-format-5.0
|
||||
ObjCBlockIndentWidth: 8
|
||||
ObjCSpaceAfterProperty: true
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
|
||||
# Taken from git's rules
|
||||
#PenaltyBreakAssignment: 10 # Unknown to clang-format-4.0
|
||||
PenaltyBreakBeforeFirstCallParameter: 30
|
||||
PenaltyBreakComment: 10
|
||||
PenaltyBreakFirstLessLess: 0
|
||||
PenaltyBreakString: 10
|
||||
PenaltyExcessCharacter: 100
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
|
||||
PointerAlignment: Right
|
||||
ReflowComments: false
|
||||
SortIncludes: false
|
||||
#SortUsingDeclarations: false # Unknown to clang-format-4.0
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
#SpaceBeforeCtorInitializerColon: true # Unknown to clang-format-5.0
|
||||
#SpaceBeforeInheritanceColon: true # Unknown to clang-format-5.0
|
||||
SpaceBeforeParens: ControlStatements
|
||||
#SpaceBeforeRangeBasedForLoopColon: true # Unknown to clang-format-5.0
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp03
|
||||
TabWidth: 8
|
||||
UseTab: Always
|
||||
...
|
71
.gitignore
vendored
71
.gitignore
vendored
@@ -1,71 +0,0 @@
|
||||
debian/*.log
|
||||
*.o
|
||||
*.lo
|
||||
*.a
|
||||
*.la
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
bscconfig.h
|
||||
bscconfig.h.in
|
||||
src/osmo-mgw/osmo-mgw
|
||||
*.*~
|
||||
*.sw?
|
||||
.libs
|
||||
*.pyc
|
||||
*.gcda
|
||||
*.gcno
|
||||
*.pc
|
||||
*~
|
||||
|
||||
#configure
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
config.log
|
||||
config.status
|
||||
config.guess
|
||||
config.sub
|
||||
configure
|
||||
compile
|
||||
depcomp
|
||||
install-sh
|
||||
missing
|
||||
stamp-h1
|
||||
libtool
|
||||
ltmain.sh
|
||||
m4/*.m4
|
||||
|
||||
# git-version-gen magic
|
||||
.tarball-version
|
||||
.version
|
||||
|
||||
|
||||
#tests
|
||||
tests/testsuite.dir
|
||||
tests/*/*_test
|
||||
|
||||
tests/atconfig
|
||||
tests/atlocal
|
||||
tests/package.m4
|
||||
tests/testsuite
|
||||
tests/testsuite.log
|
||||
|
||||
writtenconfig/
|
||||
|
||||
# manuals
|
||||
doc/manuals/*.html
|
||||
doc/manuals/*.svg
|
||||
doc/manuals/*.pdf
|
||||
doc/manuals/*__*.png
|
||||
doc/manuals/*.check
|
||||
doc/manuals/generated/
|
||||
doc/manuals/osmomsc-usermanual.xml
|
||||
doc/manuals/common
|
||||
doc/manuals/build
|
||||
|
||||
contrib/osmo-mgw.spec
|
||||
|
||||
#vs code
|
||||
.cache
|
||||
.vscode
|
||||
|
@@ -1,3 +0,0 @@
|
||||
[gerrit]
|
||||
host=gerrit.osmocom.org
|
||||
project=osmo-mgw
|
12
.mailmap
12
.mailmap
@@ -1,12 +0,0 @@
|
||||
Harald Welte <laforge@gnumonks.org>
|
||||
Harald Welte <laforge@gnumonks.org> <laflocal@hanuman.gnumonks.org>
|
||||
Harald Welte <laforge@gnumonks.org> <laflocal@goeller.de.gnumonks.org>
|
||||
Holger Hans Peter Freyther <holger@moiji-mobile.com> <zecke@selfish.org>
|
||||
Holger Hans Peter Freyther <holger@moiji-mobile.com> <ich@tamarin.(none)>
|
||||
Holger Hans Peter Freyther <holgre@moiji-mobile.com> <holger@freyther.de>
|
||||
Andreas Eversberg <jolly@eversberg.eu>
|
||||
Andreas Eversberg <jolly@eversberg.eu> <Andreas.Eversberg@versatel.de>
|
||||
Andreas Eversberg <jolly@eversberg.eu> <root@nuedel.(none)>
|
||||
Pablo Neira Ayuso <pablo@soleta.eu> <pablo@gnumonks.org>
|
||||
Max Suraev <msuraev@sysmocom.de>
|
||||
Tom Tsou <tom.tsou@ettus.com> <tom@tsou.cc>
|
661
COPYING
661
COPYING
@@ -1,661 +0,0 @@
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users.
|
||||
|
||||
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
|
||||
them 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.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey 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;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If 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 convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero 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 that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
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.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
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.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
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
|
||||
state 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 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/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
41
Makefile.am
41
Makefile.am
@@ -1,41 +0,0 @@
|
||||
AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6
|
||||
|
||||
## FIXME: automake >= 1.13 or autoconf >= 2.70 provide better suited AC_CONFIG_MACRO_DIRS for configure.ac
|
||||
## remove line below when OE toolchain is updated to version which include those
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
AM_CPPFLAGS = \
|
||||
$(all_includes) \
|
||||
-I$(top_srcdir)/include \
|
||||
$(NULL)
|
||||
|
||||
SUBDIRS = \
|
||||
include \
|
||||
src \
|
||||
tests \
|
||||
doc \
|
||||
contrib \
|
||||
$(NULL)
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = \
|
||||
libosmo-mgcp-client.pc \
|
||||
$(NULL)
|
||||
|
||||
BUILT_SOURCES = $(top_srcdir)/.version
|
||||
EXTRA_DIST = \
|
||||
.version \
|
||||
README.md \
|
||||
debian \
|
||||
git-version-gen \
|
||||
osmoappdesc.py \
|
||||
$(NULL)
|
||||
|
||||
AM_DISTCHECK_CONFIGURE_FLAGS = \
|
||||
--with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)
|
||||
|
||||
@RELMAKE@
|
||||
|
||||
$(top_srcdir)/.version:
|
||||
echo $(VERSION) > $@-t && mv $@-t $@
|
||||
dist-hook:
|
||||
echo $(VERSION) > $(distdir)/.tarball-version
|
102
README.md
102
README.md
@@ -1,102 +0,0 @@
|
||||
osmo-mgw - Osmocom MGW (Media GateWay) Implementation
|
||||
=====================================================
|
||||
|
||||
This repository contains a C-language implementation of an MGW (Media
|
||||
GateWay) for use [not only] within the 2G (GSM) and/or 3G (UMTS)
|
||||
Cellular Network built using Osmocom CNI (Cellular Network
|
||||
Infrastructure) software.
|
||||
|
||||
The OsmoMGW program provides an MGCP interface towards an MGCP call agent
|
||||
(client) like OsmoMSC and OsmoBSC, and receives and sends RTP streams as
|
||||
configured via the MGCP control plane.
|
||||
|
||||
This Media Gateway implementation is capable of
|
||||
|
||||
* streaming RTP for 2G (3GPP AoIP and Abis-over-IP)
|
||||
* streaming RTP for 3G (IuCS including the IuFP protocol)
|
||||
* TDM (E1/T1) based Abis interface with TRAU frames on 16k sub-slots
|
||||
* basic support for LCLS (Local Call, Local Switch) related features
|
||||
* various built-in translation capabilities
|
||||
* between Abis TRAU frames and RTP formats
|
||||
* between 2G AMR/RTP and 3G AMR/IuFP/RTP
|
||||
* between bandwidth-efficient and octet-aligned AMR
|
||||
* between different standards for encapsulating GSM HR codec frames in RTP
|
||||
|
||||
osmo-mgw is typically co-located with
|
||||
|
||||
* osmo-bsc (GSM BSC)
|
||||
* osmo-msc (GSM/UMTS MSC)
|
||||
* osmo-hnbgw (UMTS HNBGW); osmo-mgw implements RTP relay between Iuh
|
||||
and IuCS interfaces
|
||||
|
||||
The libosmo-mgcp-client library exposes utilities used by e.g. OsmoMSC
|
||||
(found in osmo-msc.git) to instruct OsmoMGW via its MGCP service.
|
||||
|
||||
Homepage
|
||||
--------
|
||||
|
||||
You can find the OsmoMGW issue tracker and wiki online at
|
||||
<https://osmocom.org/projects/osmo-mgw> and <https://osmocom.org/projects/osmo-mgw/wiki>.
|
||||
|
||||
|
||||
GIT Repository
|
||||
--------------
|
||||
|
||||
You can clone from the official osmo-mgw.git repository using
|
||||
|
||||
git clone https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw
|
||||
|
||||
There is a web interface at <https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw>
|
||||
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
User Manuals and VTY reference manuals are [optionally] built in PDF form
|
||||
as part of the build process.
|
||||
|
||||
Pre-rendered PDF version of the current "master" can be found at
|
||||
[User Manual](https://ftp.osmocom.org/docs/latest/osmomgw-usermanual.pdf)
|
||||
as well as the [VTY Reference Manual](https://ftp.osmocom.org/docs/latest/osmomgw-vty-reference.pdf)
|
||||
|
||||
|
||||
Mailing List
|
||||
------------
|
||||
|
||||
Discussions related to osmo-mgw are happening on the
|
||||
openbsc@lists.osmocom.org mailing list, please see
|
||||
<https://lists.osmocom.org/mailman/listinfo/openbsc> for subscription
|
||||
options and the list archive.
|
||||
|
||||
Please observe the [Osmocom Mailing List
|
||||
Rules](https://osmocom.org/projects/cellular-infrastructure/wiki/Mailing_List_Rules)
|
||||
when posting.
|
||||
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
Our coding standards are described at
|
||||
<https://osmocom.org/projects/cellular-infrastructure/wiki/Coding_standards>
|
||||
|
||||
We use a gerrit based patch submission/review process for managing
|
||||
contributions. Please see
|
||||
<https://osmocom.org/projects/cellular-infrastructure/wiki/Gerrit> for
|
||||
more details
|
||||
|
||||
The current patch queue for osmo-mgw can be seen at
|
||||
<https://gerrit.osmocom.org/#/q/project:osmo-mgw+status:open>
|
||||
|
||||
|
||||
History
|
||||
-------
|
||||
|
||||
OsmoMGW originated from the OpenBSC project, which started as a minimalistic
|
||||
all-in-one implementation of the GSM Network. In 2017, OpenBSC had reached
|
||||
maturity and diversity (including M3UA SIGTRAN and 3G support in the form of
|
||||
IuCS and IuPS interfaces) that naturally lead to a separation of the all-in-one
|
||||
approach to fully independent separate programs as in typical GSM networks.
|
||||
|
||||
OsmoMGW was one of the parts split off from the old openbsc.git. It originated
|
||||
as a solution to merely navigate RTP streams through a NAT, but has since
|
||||
matured.
|
@@ -1,11 +0,0 @@
|
||||
To run the configuration parsing and output (VTY) test suite, first install
|
||||
|
||||
https://gitea.osmocom.org/cellular-infrastructure/osmo-python-tests
|
||||
|
||||
and pass the following configure options here:
|
||||
|
||||
./configure --enable-vty-tests --enable-external-tests
|
||||
|
||||
The VTY tests are then included in the standard check target:
|
||||
|
||||
make check
|
11
TODO-RELEASE
11
TODO-RELEASE
@@ -1,11 +0,0 @@
|
||||
# When cleaning up this file: bump API version in corresponding Makefile.am and rename corresponding debian/lib*.install
|
||||
# according to https://osmocom.org/projects/cellular-infrastructure/wiki/Make_a_new_release
|
||||
# In short: https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info
|
||||
# LIBVERSION=c:r:a
|
||||
# If the library source code has changed at all since the last update, then increment revision: c:r + 1:a.
|
||||
# If any interfaces have been added, removed, or changed since the last update: c + 1:0:a.
|
||||
# If any interfaces have been added since the last public release: c:r:a + 1.
|
||||
# If any interfaces have been removed or changed since the last public release: c:r:0.
|
||||
#library what description / commit summary line
|
||||
libosmocore bump_dep; workaround Bump libosmocore version dependency after I68328adb952ca8833ba047cb3b49ccc6f8a1f1b5
|
||||
has been merged to libosmocore.git; then remove my_msgb_copy_c wrapper function.
|
207
configure.ac
207
configure.ac
@@ -1,207 +0,0 @@
|
||||
dnl Process this file with autoconf to produce a configure script
|
||||
AC_INIT([osmo-mgw],
|
||||
m4_esyscmd([./git-version-gen .tarball-version]),
|
||||
[openbsc@lists.osmocom.org])
|
||||
|
||||
dnl *This* is the root dir, even if an install-sh exists in ../ or ../../
|
||||
AC_CONFIG_AUX_DIR([.])
|
||||
|
||||
AM_INIT_AUTOMAKE([dist-bzip2])
|
||||
AC_CONFIG_TESTDIR(tests)
|
||||
|
||||
CFLAGS="$CFLAGS -std=gnu11"
|
||||
|
||||
dnl kernel style compile messages
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
dnl include release helper
|
||||
RELMAKE='-include osmo-release.mk'
|
||||
AC_SUBST([RELMAKE])
|
||||
|
||||
dnl checks for programs
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
LT_INIT
|
||||
|
||||
dnl patching ${archive_cmds} to affect generation of file "libtool" to fix linking with clang
|
||||
AS_CASE(["$LD"],[*clang*],
|
||||
[AS_CASE(["${host_os}"],
|
||||
[*linux*],[archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'])])
|
||||
|
||||
dnl check for pkg-config (explained in detail in libosmocore/configure.ac)
|
||||
AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no)
|
||||
if test "x$PKG_CONFIG_INSTALLED" = "xno"; then
|
||||
AC_MSG_WARN([You need to install pkg-config])
|
||||
fi
|
||||
PKG_PROG_PKG_CONFIG([0.20])
|
||||
|
||||
dnl checks for libraries
|
||||
AC_SEARCH_LIBS([dlopen], [dl dld], [LIBRARY_DL="$LIBS";LIBS=""])
|
||||
AC_SUBST(LIBRARY_DL)
|
||||
|
||||
AC_SEARCH_LIBS([dlsym], [dl dld], [LIBRARY_DLSYM="$LIBS";LIBS=""])
|
||||
AC_SUBST(LIBRARY_DLSYM)
|
||||
|
||||
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.11.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.11.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.11.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.11.0)
|
||||
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.6.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 2.0.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 2.0.0)
|
||||
|
||||
CFLAGS="$CFLAGS -DBUILDING_LIBOSMOMGCPCLIENT -pthread"
|
||||
CPPFLAGS="$CPPFLAGS -DBUILDING_LIBOSMOMGCPCLIENT -pthread"
|
||||
LDFLAGS="$LDFLAGS -pthread"
|
||||
|
||||
AC_ARG_ENABLE(sanitize,
|
||||
[AS_HELP_STRING(
|
||||
[--enable-sanitize],
|
||||
[Compile with address sanitizer enabled],
|
||||
)],
|
||||
[sanitize=$enableval], [sanitize="no"])
|
||||
if test x"$sanitize" = x"yes"
|
||||
then
|
||||
CFLAGS="$CFLAGS -fsanitize=address -fsanitize=undefined"
|
||||
CPPFLAGS="$CPPFLAGS -fsanitize=address -fsanitize=undefined"
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(werror,
|
||||
[AS_HELP_STRING(
|
||||
[--enable-werror],
|
||||
[Turn all compiler warnings into errors, with exceptions:
|
||||
a) deprecation (allow upstream to mark deprecation without breaking builds);
|
||||
b) "#warning" pragmas (allow to remind ourselves of errors without breaking builds)
|
||||
]
|
||||
)],
|
||||
[werror=$enableval], [werror="no"])
|
||||
if test x"$werror" = x"yes"
|
||||
then
|
||||
WERROR_FLAGS="-Werror"
|
||||
WERROR_FLAGS+=" -Werror=implicit-int -Werror=int-conversion -Werror=old-style-definition"
|
||||
WERROR_FLAGS+=" -Wno-error=deprecated -Wno-error=deprecated-declarations"
|
||||
WERROR_FLAGS+=" -Wno-error=cpp" # "#warning"
|
||||
CFLAGS="$CFLAGS $WERROR_FLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $WERROR_FLAGS"
|
||||
fi
|
||||
|
||||
# Coverage build taken from WebKit's configure.in
|
||||
AC_MSG_CHECKING([whether to enable code coverage support])
|
||||
AC_ARG_ENABLE(coverage,
|
||||
AC_HELP_STRING([--enable-coverage],
|
||||
[enable code coverage support [default=no]]),
|
||||
[],[enable_coverage="no"])
|
||||
AC_MSG_RESULT([$enable_coverage])
|
||||
if test "$enable_coverage" = "yes"; then
|
||||
COVERAGE_CFLAGS="-ftest-coverage -fprofile-arcs"
|
||||
COVERAGE_LDFLAGS="-ftest-coverage -fprofile-arcs"
|
||||
AC_SUBST([COVERAGE_CFLAGS])
|
||||
AC_SUBST([COVERAGE_LDFLAGS])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE([vty_tests],
|
||||
AC_HELP_STRING([--enable-vty-tests],
|
||||
[Include the VTY/CTRL tests in make check (deprecated)
|
||||
[default=no]]),
|
||||
[enable_ext_tests="$enableval"],[enable_ext_tests="no"])
|
||||
AC_ARG_ENABLE([external_tests],
|
||||
AC_HELP_STRING([--enable-external-tests],
|
||||
[Include the VTY/CTRL tests in make check [default=no]]),
|
||||
[enable_ext_tests="$enableval"],[enable_ext_tests="no"])
|
||||
if test "x$enable_ext_tests" = "xyes" ; then
|
||||
AM_PATH_PYTHON
|
||||
AC_CHECK_PROG(OSMOTESTEXT_CHECK,osmotestvty.py,yes)
|
||||
if test "x$OSMOTESTEXT_CHECK" != "xyes" ; then
|
||||
AC_MSG_ERROR([Please install https://gitea.osmocom.org/cellular-infrastructure/osmo-python-tests to run the VTY/CTRL tests.])
|
||||
fi
|
||||
fi
|
||||
AC_MSG_CHECKING([whether to enable VTY/CTRL tests])
|
||||
AC_MSG_RESULT([$enable_ext_tests])
|
||||
AM_CONDITIONAL(ENABLE_EXT_TESTS, test "x$enable_ext_tests" = "xyes")
|
||||
|
||||
# Generate manuals
|
||||
AC_ARG_ENABLE(manuals,
|
||||
[AS_HELP_STRING(
|
||||
[--enable-manuals],
|
||||
[Generate manual PDFs [default=no]],
|
||||
)],
|
||||
[osmo_ac_build_manuals=$enableval], [osmo_ac_build_manuals="no"])
|
||||
AM_CONDITIONAL([BUILD_MANUALS], [test x"$osmo_ac_build_manuals" = x"yes"])
|
||||
AC_ARG_VAR(OSMO_GSM_MANUALS_DIR, [path to common osmo-gsm-manuals files, overriding pkg-config and "../osmo-gsm-manuals"
|
||||
fallback])
|
||||
if test x"$osmo_ac_build_manuals" = x"yes"
|
||||
then
|
||||
# Find OSMO_GSM_MANUALS_DIR (env, pkg-conf, fallback)
|
||||
if test -n "$OSMO_GSM_MANUALS_DIR"; then
|
||||
echo "checking for OSMO_GSM_MANUALS_DIR... $OSMO_GSM_MANUALS_DIR (from env)"
|
||||
else
|
||||
OSMO_GSM_MANUALS_DIR="$($PKG_CONFIG osmo-gsm-manuals --variable=osmogsmmanualsdir 2>/dev/null)"
|
||||
if test -n "$OSMO_GSM_MANUALS_DIR"; then
|
||||
echo "checking for OSMO_GSM_MANUALS_DIR... $OSMO_GSM_MANUALS_DIR (from pkg-conf)"
|
||||
else
|
||||
OSMO_GSM_MANUALS_DIR="../osmo-gsm-manuals"
|
||||
echo "checking for OSMO_GSM_MANUALS_DIR... $OSMO_GSM_MANUALS_DIR (fallback)"
|
||||
fi
|
||||
fi
|
||||
if ! test -d "$OSMO_GSM_MANUALS_DIR"; then
|
||||
AC_MSG_ERROR("OSMO_GSM_MANUALS_DIR does not exist! Install osmo-gsm-manuals or set OSMO_GSM_MANUALS_DIR.")
|
||||
fi
|
||||
|
||||
# Find and run check-depends
|
||||
CHECK_DEPENDS="$OSMO_GSM_MANUALS_DIR/check-depends.sh"
|
||||
if ! test -x "$CHECK_DEPENDS"; then
|
||||
CHECK_DEPENDS="osmo-gsm-manuals-check-depends"
|
||||
fi
|
||||
if ! $CHECK_DEPENDS; then
|
||||
AC_MSG_ERROR("missing dependencies for --enable-manuals")
|
||||
fi
|
||||
|
||||
# Put in Makefile with absolute path
|
||||
OSMO_GSM_MANUALS_DIR="$(realpath "$OSMO_GSM_MANUALS_DIR")"
|
||||
AC_SUBST([OSMO_GSM_MANUALS_DIR])
|
||||
fi
|
||||
|
||||
# https://www.freedesktop.org/software/systemd/man/daemon.html
|
||||
AC_ARG_WITH([systemdsystemunitdir],
|
||||
[AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files])],,
|
||||
[with_systemdsystemunitdir=auto])
|
||||
AS_IF([test "x$with_systemdsystemunitdir" = "xyes" -o "x$with_systemdsystemunitdir" = "xauto"], [
|
||||
def_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)
|
||||
|
||||
AS_IF([test "x$def_systemdsystemunitdir" = "x"],
|
||||
[AS_IF([test "x$with_systemdsystemunitdir" = "xyes"],
|
||||
[AC_MSG_ERROR([systemd support requested but pkg-config unable to query systemd package])])
|
||||
with_systemdsystemunitdir=no],
|
||||
[with_systemdsystemunitdir="$def_systemdsystemunitdir"])])
|
||||
AS_IF([test "x$with_systemdsystemunitdir" != "xno"],
|
||||
[AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])])
|
||||
AM_CONDITIONAL([HAVE_SYSTEMD], [test "x$with_systemdsystemunitdir" != "xno"])
|
||||
|
||||
AC_MSG_RESULT([CFLAGS="$CFLAGS"])
|
||||
AC_MSG_RESULT([CPPFLAGS="$CPPFLAGS"])
|
||||
|
||||
dnl Generate the output
|
||||
AM_CONFIG_HEADER(bscconfig.h)
|
||||
|
||||
AC_OUTPUT(
|
||||
libosmo-mgcp-client.pc
|
||||
include/Makefile
|
||||
include/osmocom/Makefile
|
||||
include/osmocom/mgcp_client/Makefile
|
||||
include/osmocom/mgcp/Makefile
|
||||
src/Makefile
|
||||
src/libosmo-mgcp-client/Makefile
|
||||
src/libosmo-mgcp/Makefile
|
||||
src/osmo-mgw/Makefile
|
||||
tests/Makefile
|
||||
tests/atlocal
|
||||
tests/mgcp_client/Makefile
|
||||
tests/mgcp/Makefile
|
||||
doc/Makefile
|
||||
doc/examples/Makefile
|
||||
doc/manuals/Makefile
|
||||
contrib/Makefile
|
||||
contrib/systemd/Makefile
|
||||
Makefile)
|
@@ -1,3 +0,0 @@
|
||||
SUBDIRS = systemd
|
||||
|
||||
EXTRA_DIST = ipa.py
|
274
contrib/ipa.py
274
contrib/ipa.py
@@ -1,274 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
# -*- mode: python-mode; py-indent-tabs-mode: nil -*-
|
||||
"""
|
||||
/*
|
||||
* Copyright (C) 2016 sysmocom s.f.m.c. GmbH
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
"""
|
||||
|
||||
import struct, random, sys
|
||||
|
||||
class IPA(object):
|
||||
"""
|
||||
Stateless IPA protocol multiplexer: add/remove/parse (extended) header
|
||||
"""
|
||||
version = "0.0.5"
|
||||
TCP_PORT_OML = 3002
|
||||
TCP_PORT_RSL = 3003
|
||||
# OpenBSC extensions: OSMO, MGCP_OLD
|
||||
PROTO = dict(RSL=0x00, CCM=0xFE, SCCP=0xFD, OML=0xFF, OSMO=0xEE, MGCP_OLD=0xFC)
|
||||
# ...OML Router Control, GSUP GPRS extension, Osmocom Authn Protocol
|
||||
EXT = dict(CTRL=0, MGCP=1, LAC=2, SMSC=3, ORC=4, GSUP=5, OAP=6)
|
||||
# OpenBSC extension: SCCP_OLD
|
||||
MSGT = dict(PING=0x00, PONG=0x01, ID_GET=0x04, ID_RESP=0x05, ID_ACK=0x06, SCCP_OLD=0xFF)
|
||||
_IDTAG = dict(SERNR=0, UNITNAME=1, LOCATION=2, TYPE=3, EQUIPVERS=4, SWVERSION=5, IPADDR=6, MACADDR=7, UNIT=8)
|
||||
CTRL_GET = 'GET'
|
||||
CTRL_SET = 'SET'
|
||||
CTRL_REP = 'REPLY'
|
||||
CTRL_ERR = 'ERR'
|
||||
CTRL_TRAP = 'TRAP'
|
||||
|
||||
def _l(self, d, p):
|
||||
"""
|
||||
Reverse dictionary lookup: return key for a given value
|
||||
"""
|
||||
if p is None:
|
||||
return 'UNKNOWN'
|
||||
return list(d.keys())[list(d.values()).index(p)]
|
||||
|
||||
def _tag(self, t, v):
|
||||
"""
|
||||
Create TAG as TLV data
|
||||
"""
|
||||
return struct.pack(">HB", len(v) + 1, t) + v
|
||||
|
||||
def proto(self, p):
|
||||
"""
|
||||
Lookup protocol name
|
||||
"""
|
||||
return self._l(self.PROTO, p)
|
||||
|
||||
def ext(self, p):
|
||||
"""
|
||||
Lookup protocol extension name
|
||||
"""
|
||||
return self._l(self.EXT, p)
|
||||
|
||||
def msgt(self, p):
|
||||
"""
|
||||
Lookup message type name
|
||||
"""
|
||||
return self._l(self.MSGT, p)
|
||||
|
||||
def idtag(self, p):
|
||||
"""
|
||||
Lookup ID tag name
|
||||
"""
|
||||
return self._l(self._IDTAG, p)
|
||||
|
||||
def ext_name(self, proto, exten):
|
||||
"""
|
||||
Return proper extension byte name depending on the protocol used
|
||||
"""
|
||||
if self.PROTO['CCM'] == proto:
|
||||
return self.msgt(exten)
|
||||
if self.PROTO['OSMO'] == proto:
|
||||
return self.ext(exten)
|
||||
return None
|
||||
|
||||
def add_header(self, data, proto, ext=None):
|
||||
"""
|
||||
Add IPA header (with extension if necessary), data must be represented as bytes
|
||||
"""
|
||||
if ext is None:
|
||||
return struct.pack(">HB", len(data) + 1, proto) + data
|
||||
return struct.pack(">HBB", len(data) + 1, proto, ext) + data
|
||||
|
||||
def del_header(self, data):
|
||||
"""
|
||||
Strip IPA protocol header correctly removing extension if present
|
||||
Returns data length, IPA protocol, extension (or None if not defined for a give protocol) and the data without header
|
||||
"""
|
||||
if not len(data):
|
||||
return None, None, None, None
|
||||
(dlen, proto) = struct.unpack('>HB', data[:3])
|
||||
if self.PROTO['OSMO'] == proto or self.PROTO['CCM'] == proto: # there's extension which we have to unpack
|
||||
return struct.unpack('>HBB', data[:4]) + (data[4:], ) # length, protocol, extension, data
|
||||
return dlen, proto, None, data[3:] # length, protocol, _, data
|
||||
|
||||
def split_combined(self, data):
|
||||
"""
|
||||
Split the data which contains multiple concatenated IPA messages into tuple (first, rest) where rest contains remaining messages, first is the single IPA message
|
||||
"""
|
||||
(length, _, _, _) = self.del_header(data)
|
||||
return data[:(length + 3)], data[(length + 3):]
|
||||
|
||||
def tag_serial(self, data):
|
||||
"""
|
||||
Make TAG for serial number
|
||||
"""
|
||||
return self._tag(self._IDTAG['SERNR'], data)
|
||||
|
||||
def tag_name(self, data):
|
||||
"""
|
||||
Make TAG for unit name
|
||||
"""
|
||||
return self._tag(self._IDTAG['UNITNAME'], data)
|
||||
|
||||
def tag_loc(self, data):
|
||||
"""
|
||||
Make TAG for location
|
||||
"""
|
||||
return self._tag(self._IDTAG['LOCATION'], data)
|
||||
|
||||
def tag_type(self, data):
|
||||
"""
|
||||
Make TAG for unit type
|
||||
"""
|
||||
return self._tag(self._IDTAG['TYPE'], data)
|
||||
|
||||
def tag_equip(self, data):
|
||||
"""
|
||||
Make TAG for equipment version
|
||||
"""
|
||||
return self._tag(self._IDTAG['EQUIPVERS'], data)
|
||||
|
||||
def tag_sw(self, data):
|
||||
"""
|
||||
Make TAG for software version
|
||||
"""
|
||||
return self._tag(self._IDTAG['SWVERSION'], data)
|
||||
|
||||
def tag_ip(self, data):
|
||||
"""
|
||||
Make TAG for IP address
|
||||
"""
|
||||
return self._tag(self._IDTAG['IPADDR'], data)
|
||||
|
||||
def tag_mac(self, data):
|
||||
"""
|
||||
Make TAG for MAC address
|
||||
"""
|
||||
return self._tag(self._IDTAG['MACADDR'], data)
|
||||
|
||||
def tag_unit(self, data):
|
||||
"""
|
||||
Make TAG for unit ID
|
||||
"""
|
||||
return self._tag(self._IDTAG['UNIT'], data)
|
||||
|
||||
def identity(self, unit=b'', mac=b'', location=b'', utype=b'', equip=b'', sw=b'', name=b'', serial=b''):
|
||||
"""
|
||||
Make IPA IDENTITY tag list, by default returns empty concatenated bytes of tag list
|
||||
"""
|
||||
return self.tag_unit(unit) + self.tag_mac(mac) + self.tag_loc(location) + self.tag_type(utype) + self.tag_equip(equip) + self.tag_sw(sw) + self.tag_name(name) + self.tag_serial(serial)
|
||||
|
||||
def ping(self):
|
||||
"""
|
||||
Make PING message
|
||||
"""
|
||||
return self.add_header(b'', self.PROTO['CCM'], self.MSGT['PING'])
|
||||
|
||||
def pong(self):
|
||||
"""
|
||||
Make PONG message
|
||||
"""
|
||||
return self.add_header(b'', self.PROTO['CCM'], self.MSGT['PONG'])
|
||||
|
||||
def id_ack(self):
|
||||
"""
|
||||
Make ID_ACK CCM message
|
||||
"""
|
||||
return self.add_header(b'', self.PROTO['CCM'], self.MSGT['ID_ACK'])
|
||||
|
||||
def id_get(self):
|
||||
"""
|
||||
Make ID_GET CCM message
|
||||
"""
|
||||
return self.add_header(self.identity(), self.PROTO['CCM'], self.MSGT['ID_GET'])
|
||||
|
||||
def id_resp(self, data):
|
||||
"""
|
||||
Make ID_RESP CCM message
|
||||
"""
|
||||
return self.add_header(data, self.PROTO['CCM'], self.MSGT['ID_RESP'])
|
||||
|
||||
class Ctrl(IPA):
|
||||
"""
|
||||
Osmocom CTRL protocol implemented on top of IPA multiplexer
|
||||
"""
|
||||
def __init__(self):
|
||||
random.seed()
|
||||
|
||||
def add_header(self, data):
|
||||
"""
|
||||
Add CTRL header
|
||||
"""
|
||||
return super(Ctrl, self).add_header(data.encode('utf-8'), IPA.PROTO['OSMO'], IPA.EXT['CTRL'])
|
||||
|
||||
def rem_header(self, data):
|
||||
"""
|
||||
Remove CTRL header, check for appropriate protocol and extension
|
||||
"""
|
||||
(_, proto, ext, d) = super(Ctrl, self).del_header(data)
|
||||
if self.PROTO['OSMO'] != proto or self.EXT['CTRL'] != ext:
|
||||
return None
|
||||
return d
|
||||
|
||||
def parse(self, data, op=None):
|
||||
"""
|
||||
Parse Ctrl string returning (var, value) pair
|
||||
var could be None in case of ERROR message
|
||||
value could be None in case of GET message
|
||||
"""
|
||||
(s, i, v) = data.split(' ', 2)
|
||||
if s == self.CTRL_ERR:
|
||||
return None, v
|
||||
if s == self.CTRL_GET:
|
||||
return v, None
|
||||
(s, i, var, val) = data.split(' ', 3)
|
||||
if s == self.CTRL_TRAP and i != '0':
|
||||
return None, '%s with non-zero id %s' % (s, i)
|
||||
if op is not None and i != op:
|
||||
if s == self.CTRL_GET + '_' + self.CTRL_REP or s == self.CTRL_SET + '_' + self.CTRL_REP:
|
||||
return None, '%s with unexpected id %s' % (s, i)
|
||||
return var, val
|
||||
|
||||
def trap(self, var, val):
|
||||
"""
|
||||
Make TRAP message with given (vak, val) pair
|
||||
"""
|
||||
return self.add_header("%s 0 %s %s" % (self.CTRL_TRAP, var, val))
|
||||
|
||||
def cmd(self, var, val=None):
|
||||
"""
|
||||
Make SET/GET command message: returns (r, m) tuple where r is random operation id and m is assembled message
|
||||
"""
|
||||
r = random.randint(1, sys.maxsize)
|
||||
if val is not None:
|
||||
return r, self.add_header("%s %s %s %s" % (self.CTRL_SET, r, var, val))
|
||||
return r, self.add_header("%s %s %s" % (self.CTRL_GET, r, var))
|
||||
|
||||
def verify(self, reply, r, var, val=None):
|
||||
"""
|
||||
Verify reply to SET/GET command: returns (b, v) tuple where v is True/False verification result and v is the variable value
|
||||
"""
|
||||
(k, v) = self.parse(reply)
|
||||
if k != var or (val is not None and v != val):
|
||||
return False, v
|
||||
return True, v
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("IPA multiplexer v%s loaded." % IPA.version)
|
@@ -1,66 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# jenkins build helper script for openbsc. This is how we build on jenkins.osmocom.org
|
||||
#
|
||||
# environment variables:
|
||||
# * WITH_MANUALS: build manual PDFs if set to "1"
|
||||
# * PUBLISH: upload manuals after building if set to "1" (ignored without WITH_MANUALS = "1")
|
||||
#
|
||||
|
||||
if ! [ -x "$(command -v osmo-build-dep.sh)" ]; then
|
||||
echo "Error: We need to have scripts/osmo-deps.sh from http://git.osmocom.org/osmo-ci/ in PATH !"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
|
||||
set -ex
|
||||
|
||||
base="$PWD"
|
||||
deps="$base/deps"
|
||||
inst="$deps/install"
|
||||
export deps inst
|
||||
|
||||
osmo-clean-workspace.sh
|
||||
|
||||
mkdir "$deps" || true
|
||||
osmo-build-dep.sh libosmocore "" --disable-doxygen
|
||||
|
||||
verify_value_string_arrays_are_terminated.py $(find . -name "*.[hc]")
|
||||
|
||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
export LD_LIBRARY_PATH="$inst/lib"
|
||||
export PATH="$inst/bin:$PATH"
|
||||
|
||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||
osmo-build-dep.sh libosmo-abis
|
||||
|
||||
# Additional configure options and depends
|
||||
CONFIG=""
|
||||
if [ "$WITH_MANUALS" = "1" ]; then
|
||||
CONFIG="--enable-manuals"
|
||||
fi
|
||||
|
||||
set +x
|
||||
echo
|
||||
echo
|
||||
echo
|
||||
echo " =============================== osmo-mgw ==============================="
|
||||
echo
|
||||
set -x
|
||||
|
||||
cd "$base"
|
||||
autoreconf --install --force
|
||||
./configure --enable-sanitize --enable-vty-tests --enable-external-tests --enable-werror $CONFIG
|
||||
$MAKE $PARALLEL_MAKE
|
||||
LD_LIBRARY_PATH="$inst/lib" $MAKE check \
|
||||
|| cat-testlogs.sh
|
||||
LD_LIBRARY_PATH="$inst/lib" \
|
||||
DISTCHECK_CONFIGURE_FLAGS="--enable-vty-tests --enable-external-tests $CONFIG" \
|
||||
$MAKE $PARALLEL_MAKE distcheck \
|
||||
|| cat-testlogs.sh
|
||||
|
||||
if [ "$WITH_MANUALS" = "1" ] && [ "$PUBLISH" = "1" ]; then
|
||||
make -C "$base/doc/manuals" publish
|
||||
fi
|
||||
|
||||
$MAKE $PARALLEL_MAKE maintainer-clean
|
||||
osmo-clean-workspace.sh
|
@@ -1,6 +0,0 @@
|
||||
EXTRA_DIST = osmo-mgw.service
|
||||
|
||||
if HAVE_SYSTEMD
|
||||
systemdsystemunit_DATA = \
|
||||
osmo-mgw.service
|
||||
endif
|
@@ -1,24 +0,0 @@
|
||||
[Unit]
|
||||
Description=Osmocom Media Gateway (MGW)
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
LimitNOFILE=65536
|
||||
StateDirectory=osmocom
|
||||
WorkingDirectory=%S/osmocom
|
||||
Restart=always
|
||||
User=osmocom
|
||||
Group=osmocom
|
||||
ExecStart=/usr/bin/osmo-mgw -s -c /etc/osmocom/osmo-mgw.cfg
|
||||
RestartSec=2
|
||||
AmbientCapabilities=CAP_SYS_NICE
|
||||
# CPU scheduling policy:
|
||||
CPUSchedulingPolicy=rr
|
||||
# For real-time scheduling policies an integer between 1 (lowest priority) and 99 (highest priority):
|
||||
CPUSchedulingPriority=1
|
||||
# See sched(7) for further details on real-time policies and priorities
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
1155
debian/changelog
vendored
1155
debian/changelog
vendored
File diff suppressed because it is too large
Load Diff
1
debian/compat
vendored
1
debian/compat
vendored
@@ -1 +0,0 @@
|
||||
10
|
46
debian/control
vendored
46
debian/control
vendored
@@ -1,46 +0,0 @@
|
||||
Source: osmo-mgw
|
||||
Section: net
|
||||
Priority: extra
|
||||
Maintainer: Osmocom team <openbsc@lists.osmocom.org>
|
||||
Build-Depends: debhelper (>= 10),
|
||||
dh-autoreconf,
|
||||
pkg-config,
|
||||
autotools-dev,
|
||||
libosmocore-dev (>= 1.11.0),
|
||||
libosmo-netif-dev (>= 1.6.0),
|
||||
libosmo-abis-dev (>= 2.0.0),
|
||||
osmo-gsm-manuals-dev (>= 1.6.0)
|
||||
Standards-Version: 3.9.8
|
||||
Vcs-Git: https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw
|
||||
Vcs-Browser: https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw
|
||||
Homepage: https://osmocom.org/projects/osmo-mgw
|
||||
|
||||
Package: osmo-mgw
|
||||
Architecture: any
|
||||
Multi-Arch: foreign
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends}
|
||||
Description: OsmoMGW: Osmocom's Media Gateway for 2G and 3G circuit-switched mobile networks
|
||||
|
||||
Package: libosmo-mgcp-client14
|
||||
Section: libs
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
Pre-Depends: ${misc:Pre-Depends}
|
||||
Depends: ${misc:Depends}, ${shlibs:Depends}
|
||||
Description: libosmo-mgcp-client: Osmocom's Media Gateway Control Protocol client utilities
|
||||
|
||||
Package: libosmo-mgcp-client-dev
|
||||
Section: libdevel
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
Depends: libosmo-mgcp-client14 (= ${binary:Version}), ${misc:Depends}
|
||||
Description: libosmo-mgcp-client: Osmocom's Media Gateway Control Protocol client utilities
|
||||
|
||||
Package: osmo-mgw-doc
|
||||
Architecture: all
|
||||
Section: doc
|
||||
Priority: optional
|
||||
Depends: ${misc:Depends}
|
||||
Description: ${misc:Package} PDF documentation
|
||||
Various manuals: user manual, VTY reference manual and/or
|
||||
protocol/interface manuals.
|
65
debian/copyright
vendored
65
debian/copyright
vendored
@@ -1,65 +0,0 @@
|
||||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: osmo-mgw
|
||||
Source: https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw
|
||||
|
||||
Files: *
|
||||
Copyright: 2009-2014 On-Waves
|
||||
2009-2015 Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
2013 Jacob Erlbeck <jerlbeck@sysmocom.de>
|
||||
2016-2017 sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||
License: AGPL-3.0+
|
||||
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/>.
|
||||
|
||||
Files: src/libosmo-mgcp-client/* include/osmocom/mgcp_client/*
|
||||
Copyright: 2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||
Based on OpenBSC interface to quagga VTY (libmsc/vty_interface_layer3.c)
|
||||
2009 by Harald Welte <laforge@gnumonks.org>
|
||||
2009-2011 by Holger Hans Peter Freyther
|
||||
License: GPL-2.0+
|
||||
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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Files: tests/vty_test_runner.py
|
||||
Copyright: 2013 Holger Hans Peter Freyther
|
||||
2013 Katerina Barone-Adesi <kat.obsc@gmail.com>
|
||||
License: GPL-3.0+
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General Public License
|
||||
Version 3 can be found in `/usr/share/common-licenses/GPL-3'.
|
||||
|
||||
Files: osmoappdesc.py
|
||||
Copyright: 2013 Katerina Barone-Adesi <kat.obsc@gmail.com>
|
||||
License: GPL-3.0+
|
4
debian/libosmo-mgcp-client-dev.install
vendored
4
debian/libosmo-mgcp-client-dev.install
vendored
@@ -1,4 +0,0 @@
|
||||
usr/include/osmocom/mgcp_client
|
||||
usr/lib/*/libosmo-mgcp-client.so
|
||||
usr/lib/*/libosmo-mgcp-client.a
|
||||
usr/lib/*/pkgconfig/libosmo-mgcp-client.pc
|
1
debian/libosmo-mgcp-client14.install
vendored
1
debian/libosmo-mgcp-client14.install
vendored
@@ -1 +0,0 @@
|
||||
usr/lib/*/libosmo-mgcp-client.so.*
|
1
debian/osmo-mgw-doc.install
vendored
1
debian/osmo-mgw-doc.install
vendored
@@ -1 +0,0 @@
|
||||
usr/share/doc/osmo-mgw-doc/*.pdf
|
5
debian/osmo-mgw.install
vendored
5
debian/osmo-mgw.install
vendored
@@ -1,5 +0,0 @@
|
||||
etc/osmocom/osmo-mgw.cfg
|
||||
lib/systemd/system/osmo-mgw.service
|
||||
usr/bin/osmo-mgw
|
||||
usr/share/doc/osmo-mgw/examples/osmo-mgw/osmo-mgw.cfg
|
||||
usr/share/doc/osmo-mgw/examples/osmo-mgw/osmo-mgw-abis_e1.cfg
|
38
debian/postinst
vendored
38
debian/postinst
vendored
@@ -1,38 +0,0 @@
|
||||
#!/bin/sh -e
|
||||
case "$1" in
|
||||
configure)
|
||||
# Create the osmocom group and user (if it doesn't exist yet)
|
||||
if ! getent group osmocom >/dev/null; then
|
||||
groupadd --system osmocom
|
||||
fi
|
||||
if ! getent passwd osmocom >/dev/null; then
|
||||
useradd \
|
||||
--system \
|
||||
--gid osmocom \
|
||||
--home-dir /var/lib/osmocom \
|
||||
--shell /sbin/nologin \
|
||||
--comment "Open Source Mobile Communications" \
|
||||
osmocom
|
||||
fi
|
||||
|
||||
# Fix permissions of previous (root-owned) install (OS#4107)
|
||||
if dpkg --compare-versions "$2" le "1.13.0"; then
|
||||
if [ -e /etc/osmocom/osmo-mgw.cfg ]; then
|
||||
chown -v osmocom:osmocom /etc/osmocom/osmo-mgw.cfg
|
||||
chmod -v 0660 /etc/osmocom/osmo-mgw.cfg
|
||||
fi
|
||||
|
||||
if [ -d /etc/osmocom ]; then
|
||||
chown -v root:osmocom /etc/osmocom
|
||||
chmod -v 2775 /etc/osmocom
|
||||
fi
|
||||
|
||||
mkdir -p /var/lib/osmocom
|
||||
chown -R -v osmocom:osmocom /var/lib/osmocom
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# dh_installdeb(1) will replace this with shell code automatically
|
||||
# generated by other debhelper scripts.
|
||||
#DEBHELPER#
|
39
debian/rules
vendored
39
debian/rules
vendored
@@ -1,39 +0,0 @@
|
||||
#!/usr/bin/make -f
|
||||
# You must remove unused comment lines for the released package.
|
||||
# See debhelper(7) (uncomment to enable)
|
||||
# This is an autogenerated template for debian/rules.
|
||||
#
|
||||
# Output every command that modifies files on the build system.
|
||||
#export DH_VERBOSE = 1
|
||||
|
||||
DEBIAN := $(shell dpkg-parsechangelog | grep '^Version:' | cut -d' ' -f2)
|
||||
DEBVERS := $(shell echo '$(DEBIAN)' | cut -d- -f1)
|
||||
VERSION := $(shell echo '$(DEBVERS)' | sed -e 's/[+-].*//' -e 's/~//g')
|
||||
|
||||
CFLAGS += -g
|
||||
|
||||
# main packaging script based on dh7 syntax
|
||||
%:
|
||||
dh $@ --with autoreconf
|
||||
|
||||
# debmake generated override targets
|
||||
# Set options for ./configure
|
||||
#CONFIGURE_FLAGS = <options for ./configure>
|
||||
#overrride_dh_configure:
|
||||
# dh_configure -- $(CONFIGURE_FLAGS)
|
||||
#
|
||||
# Do not install libtool archive, python .pyc .pyo
|
||||
#override_dh_install:
|
||||
# dh_install --list-missing -X.la -X.pyc -X.pyo
|
||||
|
||||
override_dh_auto_test:
|
||||
dh_auto_test || (find . -name testsuite.log -exec cat {} \; ; false)
|
||||
|
||||
override_dh_auto_configure:
|
||||
dh_auto_configure -- --with-systemdsystemunitdir=/lib/systemd/system --enable-manuals
|
||||
|
||||
# Don't create .pdf.gz files (barely saves space and they can't be opened directly by most pdf readers)
|
||||
override_dh_compress:
|
||||
dh_compress -X.pdf
|
||||
|
||||
# See https://www.debian.org/doc/manuals/developers-reference/best-pkging-practices.html#bpp-dbg
|
1
debian/source/format
vendored
1
debian/source/format
vendored
@@ -1 +0,0 @@
|
||||
3.0 (native)
|
@@ -1,4 +0,0 @@
|
||||
SUBDIRS = \
|
||||
examples \
|
||||
manuals \
|
||||
$(NULL)
|
@@ -1,30 +0,0 @@
|
||||
OSMOCONF_FILES = \
|
||||
osmo-mgw/osmo-mgw.cfg
|
||||
|
||||
osmoconfdir = $(sysconfdir)/osmocom
|
||||
osmoconf_DATA = $(OSMOCONF_FILES)
|
||||
|
||||
EXTRA_DIST = $(OSMOCONF_FILES)
|
||||
|
||||
CFG_FILES = find $(srcdir) -name '*.cfg*' | sed -e 's,^$(srcdir),,'
|
||||
|
||||
dist-hook:
|
||||
for f in $$($(CFG_FILES)); do \
|
||||
j="$(distdir)/$$f" && \
|
||||
mkdir -p "$$(dirname $$j)" && \
|
||||
$(INSTALL_DATA) $(srcdir)/$$f $$j; \
|
||||
done
|
||||
|
||||
install-data-hook:
|
||||
for f in $$($(CFG_FILES)); do \
|
||||
j="$(DESTDIR)$(docdir)/examples/$$f" && \
|
||||
mkdir -p "$$(dirname $$j)" && \
|
||||
$(INSTALL_DATA) $(srcdir)/$$f $$j; \
|
||||
done
|
||||
|
||||
uninstall-hook:
|
||||
@$(PRE_UNINSTALL)
|
||||
for f in $$($(CFG_FILES)); do \
|
||||
j="$(DESTDIR)$(docdir)/examples/$$f" && \
|
||||
$(RM) $$j; \
|
||||
done
|
@@ -1,30 +0,0 @@
|
||||
!
|
||||
! MGCP configuration example
|
||||
!
|
||||
log stderr
|
||||
logging color 1
|
||||
logging print category-hex 0
|
||||
logging print category 1
|
||||
logging timestamp 0
|
||||
logging print file basename last
|
||||
logging print level 1
|
||||
|
||||
e1_input
|
||||
e1_line 0 driver dahdi
|
||||
e1_line 0 port 0
|
||||
mgcp
|
||||
bind ip 127.0.0.1
|
||||
rtp port-range 4002 16001
|
||||
rtp bind-ip 127.0.0.1
|
||||
rtp ip-probing
|
||||
rtp ip-dscp 46
|
||||
bind port 2427
|
||||
number endpoints 512
|
||||
force-realloc 1
|
||||
rtcp-omit
|
||||
rtp-patch ssrc
|
||||
rtp-patch timestamp
|
||||
trunk 1
|
||||
rtp keep-alive once
|
||||
no rtp keep-alive
|
||||
line 0
|
@@ -1,23 +0,0 @@
|
||||
!
|
||||
! MGCP configuration example
|
||||
!
|
||||
log stderr
|
||||
logging color 1
|
||||
logging print category-hex 0
|
||||
logging print category 1
|
||||
logging timestamp 0
|
||||
logging print file basename last
|
||||
logging print level 1
|
||||
|
||||
mgcp
|
||||
bind ip 127.0.0.1
|
||||
rtp port-range 4002 16001
|
||||
rtp bind-ip 127.0.0.1
|
||||
rtp ip-probing
|
||||
rtp ip-dscp 46
|
||||
bind port 2427
|
||||
number endpoints 512
|
||||
force-realloc 1
|
||||
rtcp-omit
|
||||
rtp-patch ssrc
|
||||
rtp-patch timestamp
|
@@ -1,23 +0,0 @@
|
||||
EXTRA_DIST = osmomgw-usermanual.adoc \
|
||||
osmomgw-usermanual-docinfo.xml \
|
||||
osmomgw-vty-reference.xml \
|
||||
regen_doc.sh \
|
||||
chapters \
|
||||
vty
|
||||
|
||||
if BUILD_MANUALS
|
||||
ASCIIDOC = osmomgw-usermanual.adoc
|
||||
ASCIIDOC_DEPS = $(srcdir)/chapters/*.adoc
|
||||
include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.asciidoc.inc
|
||||
|
||||
VTY_REFERENCE = osmomgw-vty-reference.xml
|
||||
include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.vty-reference.inc
|
||||
|
||||
BUILT_REFERENCE_XML = $(builddir)/vty/mgw_vty_reference.xml
|
||||
$(builddir)/vty/mgw_vty_reference.xml: $(top_builddir)/src/osmo-mgw/osmo-mgw
|
||||
mkdir -p $(builddir)/vty
|
||||
$(top_builddir)/src/osmo-mgw/osmo-mgw --vty-ref-xml > $@
|
||||
|
||||
OSMO_REPOSITORY = osmo-mgw
|
||||
include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.common.inc
|
||||
endif
|
@@ -1,129 +0,0 @@
|
||||
== Configuring OsmoMGW
|
||||
|
||||
A basic configation of OsmoMGW mainly consists of specifying the IP address
|
||||
and port on which to listen to MGCP commands, but changing the port range at
|
||||
which the RTP streams terminate as well as limiting operation to a single call
|
||||
agent can be done as well as changing the number of endpoints.
|
||||
|
||||
=== Configuring MGCP
|
||||
|
||||
By default OsmoMGW listens for MGCP on port 2427 on any IP address. If a call
|
||||
agent address is configured then OsmoMGW will only answer MGCP commands from
|
||||
that IP port 2727, otherwise all sources are handled. A domain can be
|
||||
specified
|
||||
|
||||
.Example: MGCP configuration
|
||||
----
|
||||
OsmoMGW(config-mgcp)# bind ip 127.0.0.1
|
||||
OsmoMGW(config-mgcp)# bind port 2427
|
||||
OsmoMGW(config-mgcp)# call-agent ip 127.0.0.1
|
||||
OsmoMGW(config-mgcp)# domain mgw-bsc
|
||||
OsmoMGW(config-mgcp)# local ip 127.0.0.1
|
||||
----
|
||||
|
||||
=== Configuring the trunk
|
||||
|
||||
The first trunk is considered a virtual trunk in OsmoMGW. All
|
||||
endpoints of type "rtpbridge" are routed here. The virtual trunk is configured
|
||||
in the config-mgcp context.
|
||||
|
||||
All other trunks are configured in the config-mgcp-trunk context, but the
|
||||
commands used are identical. Right now trunks are considered only for "ds/e1"
|
||||
type endpoints.
|
||||
|
||||
.Example: MGCP trunk configuration
|
||||
----
|
||||
OsmoMGW(config-mgcp)# number endpoints 63 <1>
|
||||
OsmoMGW(config-mgcp)# rtp bind-ip 10.0.0.1 <2>
|
||||
OsmoMGW(config-mgcp)# rtp port-range 12000-14000 <3>
|
||||
----
|
||||
<1> Maximum number of endpoints that can be allocated at once
|
||||
<2> Use this IP when binding RTP endpoints
|
||||
<3> Use ports in this range when binding RTP endpoints
|
||||
|
||||
There are some options to tweak how RTP forwarding behaves in OsmoMGW:
|
||||
|
||||
.Example: MGCP trunk rtp options
|
||||
----
|
||||
OsmoMGW(config-mgcp)# rtp keep-alive 30 <1>
|
||||
OsmoMGW(config-mgcp)# rtp-patch ssrc <2>
|
||||
OsmoMGW(config-mgcp)# rtp-patch timestamp <3>
|
||||
----
|
||||
<1> Send dummy UDP packets periodically to RTP destination
|
||||
<2> Hide SSRC changes
|
||||
<3> Ensure RTP timestamp is aligned with frame duration
|
||||
|
||||
NOTE: Changes to trunks that affect resource allocation, such as newly created
|
||||
trunks or a change of the number of available endpoints, require a full restart
|
||||
of osmo-mgw!
|
||||
|
||||
=== E1 trunk considerations
|
||||
|
||||
While the RTP bridge trunks are natively based on IP no special considerations
|
||||
are required during setup. E1 trunks are mapped on a physical E1 line, which has
|
||||
to be configured as shown below.
|
||||
|
||||
.Example: E1 line setup
|
||||
----
|
||||
OsmoMGW(config-e1_input)# e1_line 0 driver dahdi <1>
|
||||
OsmoMGW(config-e1_input)# e1_line 0 port 2 <2>
|
||||
----
|
||||
<1> Name of the libosmo-abis driver implementation ("dahdi")
|
||||
<2> Port number of the physical E1 port to use (2)
|
||||
|
||||
In osmo-mgw the e1_input node is used to configure the physical E1 line. The
|
||||
line number will be used internally to identify the configured E1 line. The
|
||||
port number is the physical E1 connector (sometimes called 'span') at the E1
|
||||
hardware. Per trunk an individual E1 line will be needed. Beware that the E1
|
||||
driver may also need configuration settings that are not discussed here.
|
||||
|
||||
.Example: E1 trunk setup
|
||||
----
|
||||
OsmoMGW(config-mgcp)# trunk 0 <1>
|
||||
OsmoMGW(config-mgcp-trunk)# line 0 <2>
|
||||
----
|
||||
<1> Creation of a trunk (0)
|
||||
<2> Reference to the E1 line to use (0)
|
||||
|
||||
The E1 trunk is created along with a number, typically starting at 0, but if
|
||||
required any number from 0-64 is allowed. The E1 trunk configuration concerning
|
||||
the IP related aspects is nearly identical to the configuration of the virtual
|
||||
trunk. However, it is important that the user assigns one of the E1 line numbers
|
||||
that were configured under the e1_input node.
|
||||
|
||||
NOTE: The endpoint name that is used on MGCP level will include the trunk number,
|
||||
not the E1 line number. For simplicity (and compatibility with OsmoBSC) it is
|
||||
recommended to use equal numbers for trunk and E1 line. However, if required any
|
||||
E1 line can be mapped flexible on any trunk as long as the mapping is bijective.
|
||||
|
||||
.Example: A typical configuration with one E1 trunk
|
||||
----
|
||||
e1_input
|
||||
e1_line 0 driver dahdi
|
||||
e1_line 0 port 2
|
||||
mgcp
|
||||
bind ip 127.0.0.1
|
||||
rtp net-range 6000 6011
|
||||
rtp net-bind-ip 192.168.100.130
|
||||
rtp ip-probing
|
||||
rtp ip-dscp 46
|
||||
no rtp keep-alive
|
||||
bind port 2428
|
||||
number endpoints 30
|
||||
loop 0
|
||||
force-realloc 1
|
||||
osmux off
|
||||
rtp-patch rfc5993hr
|
||||
trunk 0
|
||||
rtp keep-alive once
|
||||
no rtp keep-alive
|
||||
line 0
|
||||
----
|
||||
|
||||
NOTE: One E1 trunk always covers a whole E1 line. All subslots (I.640) will be mapped
|
||||
to individual MGCP endpoints. As long as the endpoints remain unused the
|
||||
underlying E1 timeslot is not used.
|
||||
|
||||
NOTE: The E1 trunk implementation also works with T1 lines, however since T1 has
|
||||
24 instead of 31 usable timeslots only the endpoints that fall into that 1-24 timeslot
|
||||
range will be useable.
|
@@ -1,4 +0,0 @@
|
||||
[[counters]]
|
||||
== Counters
|
||||
|
||||
include::./counters_generated.adoc[]
|
@@ -1,83 +0,0 @@
|
||||
|
||||
// autogenerated by show asciidoc counters
|
||||
These counters and their description based on OsmoMGW 1.5.0.64-189f (OsmoMGW).
|
||||
|
||||
=== Rate Counters
|
||||
|
||||
// generating tables for rate_ctr_group
|
||||
// rate_ctr_group table aggregated statistics for all rtp connections
|
||||
.all_rtp_conn - aggregated statistics for all rtp connections
|
||||
[options="header"]
|
||||
|===
|
||||
| Name | Reference | Description
|
||||
| all_rtp:err_tstmp_in | <<all_rtp_conn_all_rtp:err_tstmp_in>> | Total inbound rtp-stream timestamp errors.
|
||||
| all_rtp:err_tstmp_out | <<all_rtp_conn_all_rtp:err_tstmp_out>> | Total outbound rtp-stream timestamp errors.
|
||||
| all_rtp:packets_rx | <<all_rtp_conn_all_rtp:packets_rx>> | Total inbound rtp packets.
|
||||
| all_rtp:octets_rx | <<all_rtp_conn_all_rtp:octets_rx>> | Total inbound rtp octets.
|
||||
| all_rtp:packets_tx | <<all_rtp_conn_all_rtp:packets_tx>> | Total outbound rtp packets.
|
||||
| all_rtp:octets_tx | <<all_rtp_conn_all_rtp:octets_tx>> | Total outbound rtp octets.
|
||||
| all_rtp:dropped | <<all_rtp_conn_all_rtp:dropped>> | Total dropped rtp packets.
|
||||
| all_rtp:num_closed_conns | <<all_rtp_conn_all_rtp:num_closed_conns>> | Total number of rtp connections closed.
|
||||
|===
|
||||
// rate_ctr_group table dlcx statistics
|
||||
.dlcx - dlcx statistics
|
||||
[options="header"]
|
||||
|===
|
||||
| Name | Reference | Description
|
||||
| dlcx:success | <<dlcx_dlcx:success>> | DLCX command processed successfully.
|
||||
| dlcx:wildcard | <<dlcx_dlcx:wildcard>> | wildcard names in DLCX commands are unsupported.
|
||||
| dlcx:no_conn | <<dlcx_dlcx:no_conn>> | endpoint specified in DLCX command has no active connections.
|
||||
| dlcx:callid | <<dlcx_dlcx:callid>> | CallId specified in DLCX command mismatches endpoint's CallId .
|
||||
| dlcx:connid | <<dlcx_dlcx:connid>> | connection ID specified in DLCX command does not exist on endpoint.
|
||||
| dlcx:unhandled_param | <<dlcx_dlcx:unhandled_param>> | unhandled parameter in DLCX command.
|
||||
| dlcx:rejected | <<dlcx_dlcx:rejected>> | connection deletion rejected by policy.
|
||||
| dlcx:deferred | <<dlcx_dlcx:deferred>> | connection deletion deferred by policy.
|
||||
|===
|
||||
// rate_ctr_group table mdcx statistics
|
||||
.mdcx - mdcx statistics
|
||||
[options="header"]
|
||||
|===
|
||||
| Name | Reference | Description
|
||||
| mdcx:success | <<mdcx_mdcx:success>> | MDCX command processed successfully.
|
||||
| mdcx:wildcard | <<mdcx_mdcx:wildcard>> | wildcard endpoint names in MDCX commands are unsupported.
|
||||
| mdcx:no_conn | <<mdcx_mdcx:no_conn>> | endpoint specified in MDCX command has no active connections.
|
||||
| mdcx:callid | <<mdcx_mdcx:callid>> | invalid CallId specified in MDCX command.
|
||||
| mdcx:connid | <<mdcx_mdcx:connid>> | invalid connection ID specified in MDCX command.
|
||||
| crcx:unhandled_param | <<mdcx_crcx:unhandled_param>> | unhandled parameter in MDCX command.
|
||||
| mdcx:no_connid | <<mdcx_mdcx:no_connid>> | no connection ID specified in MDCX command.
|
||||
| mdcx:conn_not_found | <<mdcx_mdcx:conn_not_found>> | connection specified in MDCX command does not exist.
|
||||
| mdcx:invalid_mode | <<mdcx_mdcx:invalid_mode>> | invalid connection mode in MDCX command.
|
||||
| mdcx:conn_opt | <<mdcx_mdcx:conn_opt>> | connection options invalid.
|
||||
| mdcx:no_remote_conn_desc | <<mdcx_mdcx:no_remote_conn_desc>> | no opposite end specified for connection.
|
||||
| mdcx:start_rtp_failure | <<mdcx_mdcx:start_rtp_failure>> | failure to start RTP processing.
|
||||
| mdcx:conn_rejected | <<mdcx_mdcx:conn_rejected>> | connection rejected by policy.
|
||||
| mdcx:conn_deferred | <<mdcx_mdcx:conn_deferred>> | connection deferred by policy.
|
||||
|===
|
||||
// rate_ctr_group table crxc statistics
|
||||
.crcx - crxc statistics
|
||||
[options="header"]
|
||||
|===
|
||||
| Name | Reference | Description
|
||||
| crcx:success | <<crcx_crcx:success>> | CRCX command processed successfully.
|
||||
| crcx:bad_action | <<crcx_crcx:bad_action>> | bad action in CRCX command.
|
||||
| crcx:unhandled_param | <<crcx_crcx:unhandled_param>> | unhandled parameter in CRCX command.
|
||||
| crcx:missing_callid | <<crcx_crcx:missing_callid>> | missing CallId in CRCX command.
|
||||
| crcx:invalid_mode | <<crcx_crcx:invalid_mode>> | invalid connection mode in CRCX command.
|
||||
| crcx:limit_exceeded | <<crcx_crcx:limit_exceeded>> | limit of concurrent connections was reached.
|
||||
| crcx:unkown_callid | <<crcx_crcx:unkown_callid>> | unknown CallId in CRCX command.
|
||||
| crcx:alloc_conn_fail | <<crcx_crcx:alloc_conn_fail>> | connection allocation failure.
|
||||
| crcx:no_remote_conn_desc | <<crcx_crcx:no_remote_conn_desc>> | no opposite end specified for connection.
|
||||
| crcx:start_rtp_failure | <<crcx_crcx:start_rtp_failure>> | failure to start RTP processing.
|
||||
| crcx:conn_rejected | <<crcx_crcx:conn_rejected>> | connection rejected by policy.
|
||||
| crcx:no_osmux | <<crcx_crcx:no_osmux>> | no osmux offered by peer.
|
||||
| crcx:conn_opt | <<crcx_crcx:conn_opt>> | connection options invalid.
|
||||
| crcx:codec_nego | <<crcx_crcx:codec_nego>> | codec negotiation failure.
|
||||
| crcx:bind_port | <<crcx_crcx:bind_port>> | port bind failure.
|
||||
|===
|
||||
== Osmo Stat Items
|
||||
|
||||
// generating tables for osmo_stat_items
|
||||
== Osmo Counters
|
||||
|
||||
// generating tables for osmo_counters
|
||||
// there are no ungrouped osmo_counters
|
@@ -1,100 +0,0 @@
|
||||
== MGCP Endpoints
|
||||
|
||||
MGCP organizes the switching resources in so called endpoints. Each endpoint is
|
||||
referenced by its unique identifier. While RFC 3435 specifies a naming scheme, the
|
||||
actual identifier naming is subject to the implementation and configuration.
|
||||
|
||||
=== RTP proxy / RTP bridge endpoints
|
||||
|
||||
OsmoMGW implements a freely configurable number of `rtpbridge` endpoints. Those
|
||||
endpoints are able to host two connections at a time to model the functionality
|
||||
of a tandem switch.
|
||||
|
||||
RTP bridge endpoint identifiers are referenced by the string `rtpbridge/`, a
|
||||
hexadecimal number without leading zeros and a domain name (configurable).
|
||||
|
||||
----
|
||||
rtpbridge/<number>@<domain>
|
||||
----
|
||||
|
||||
.Example: List of virtual endpoints
|
||||
----
|
||||
rtpbridge/1@mgw
|
||||
rtpbridge/2@mgw
|
||||
rtpbridge/3@mgw
|
||||
rtpbridge/4@mgw
|
||||
rtpbridge/5@mgw
|
||||
rtpbridge/6@mgw
|
||||
rtpbridge/7@mgw
|
||||
rtpbridge/8@mgw
|
||||
rtpbridge/9@mgw
|
||||
rtpbridge/a@mgw
|
||||
rtpbridge/b@mgw
|
||||
rtpbridge/c@mgw
|
||||
rtpbridge/d@mgw
|
||||
rtpbridge/e@mgw
|
||||
rtpbridge/f@mgw
|
||||
rtpbridge/10@mgw
|
||||
----
|
||||
|
||||
=== E1/T1 endpoints
|
||||
|
||||
OsmoMGW supports E1 subslot multiplexing as specified by I.460. All possible
|
||||
subslot combinations are mapped on individual endpoints. The endpoint names
|
||||
are prefixed with `ds/e1-` followed by the trunk number and the E1 timeslot.
|
||||
The subslot is defined by a bit rate and a bit offset.
|
||||
|
||||
----
|
||||
ds/e1-<trunk>/s-<timeslot>/su<bitrate>-<bitoffset>@<domain>
|
||||
----
|
||||
|
||||
.Example: List of endpoints on E1 trunk 0 at E1 timeslot 2
|
||||
----
|
||||
ds/e1-0/s-2/su64-0@mgw
|
||||
ds/e1-0/s-2/su32-0@mgw
|
||||
ds/e1-0/s-2/su32-4@mgw
|
||||
ds/e1-0/s-2/su16-0@mgw
|
||||
ds/e1-0/s-2/su16-2@mgw
|
||||
ds/e1-0/s-2/su16-4@mgw
|
||||
ds/e1-0/s-2/su16-6@mgw
|
||||
ds/e1-0/s-2/su8-0@mgw
|
||||
ds/e1-0/s-2/su8-1@mgw
|
||||
ds/e1-0/s-2/su8-2@mgw
|
||||
ds/e1-0/s-2/su8-3@mgw
|
||||
ds/e1-0/s-2/su8-4@mgw
|
||||
ds/e1-0/s-2/su8-5@mgw
|
||||
ds/e1-0/s-2/su8-6@mgw
|
||||
ds/e1-0/s-2/su8-7@mgw
|
||||
----
|
||||
|
||||
When creating connections on endpoints that reside in one E1 timeslot the call
|
||||
agent must make sure that no overlapping endpoints are used. It is for example
|
||||
not possible to use `ds/e1-0/s-2/su16-2@mgw` and `ds/e1-0/s-2/su8-3@mgw` at the
|
||||
same time because they overlap.
|
||||
|
||||
.Subslot overlapping
|
||||
[options="header"]
|
||||
|===
|
||||
| Bit offset 4+| Subslots
|
||||
| 0 | 8k .2+| 16k .4+| 32k .8+| 64k
|
||||
| 1 | 8k
|
||||
| 2 | 8k .2+| 16k
|
||||
| 3 | 8k
|
||||
| 4 | 8k .2+| 16k .4+| 32k
|
||||
| 5 | 8k
|
||||
| 6 | 8k .2+| 16k
|
||||
| 7 | 8k
|
||||
|===
|
||||
|
||||
NOTE: The current implementation (December 2020) only implements TRAU frame
|
||||
encoding/decoding for 16K and 8K subslots. Endpoints with other bitrates are
|
||||
not yet useable.
|
||||
|
||||
NOTE: the VTY command "show mgcp" can be used to get a list of all available
|
||||
endpoints (including identifiers)
|
||||
|
||||
=== The `null` endpoint
|
||||
|
||||
OsmoMGW offers a special `null@<domain>` endpoint which can be audited at all times.
|
||||
This is useful for MGCP clients who wish to submit requests to OsmoMGW
|
||||
periodically to find out whether it is still reachable and in a working state.
|
@@ -1,72 +0,0 @@
|
||||
== MGCP Extensions
|
||||
|
||||
The MGCP protocol is extendable. The following non-standard extensions are
|
||||
understood by OsmoMGW.
|
||||
|
||||
=== `X-Osmo-IGN`
|
||||
|
||||
`X-Osmo-IGN` indicates to OsmoMGW that specific items of an endpoint should be
|
||||
ignored, so that it is lenient on mismatching values that would normally
|
||||
indicate collisions or configuration errors.
|
||||
|
||||
==== `X-Osmo-IGN` Format
|
||||
|
||||
The value part of `X-Osmo-IGN` must be one or more items separated by one or more
|
||||
spaces. Each item consists of one or more non-whitespace characters.
|
||||
|
||||
.Example: `X-Osmo-IGN` format with three ficticious items "X", "abc" and "123".
|
||||
----
|
||||
X-Osmo-IGN: X abc 123
|
||||
----
|
||||
|
||||
`X-Osmo-IGN` must be issued in the MGCP header section (typically as its last item),
|
||||
before the SDP section starts.
|
||||
|
||||
==== Supported `X-Osmo-IGN` Items
|
||||
|
||||
Currently, the following `X-Osmo-IGN` items are supported:
|
||||
|
||||
* `C`: ignore CallID mismatches, i.e. differing "C" values between connections
|
||||
on the same endpoint.
|
||||
|
||||
.Note:
|
||||
`X-Osmo-IGN` does not support ignoring mismatches on the domain part of
|
||||
an endpoint name, e.g. ignoring a mismatch on "example.com" in
|
||||
`rtpbridge/123abc@example.com`. Instead, you may globally configure OsmoMGW
|
||||
with `mgcp` / `domain *` to permit all domain parts.
|
||||
|
||||
===== `X-Osmo-IGN: C`
|
||||
|
||||
By default, OsmoMGW verifies that all CallIDs ("C" values) match for all
|
||||
connections on any one given endpoint. To ignore CallID mismatches, pass a `C`
|
||||
in the `X-Osmo-IGN` header, for the first or the second `CRCX` on an endpoint.
|
||||
When the `X-Osmo-IGN: C` is sent for any one `CRCX` on an endpoint, CallID
|
||||
mismatches will be ignored for that and all subsequent messages for that
|
||||
endpoint. Hence this header only needs to be included once per endpoint, in any
|
||||
`CRCX` message that precedes or coincides with a CallID mismatch.
|
||||
|
||||
This is particularly useful for a BSC that is connected to an A/SCCPlite MSC,
|
||||
where the BSC and MSC each are expected to configure their respective own
|
||||
connection on a shared endpoint. For A/SCCPlite, it is impossible for the BSC
|
||||
to know the CallID that the MSC will use, so CallID mismatches are inevitable.
|
||||
See also OsmoBSC, which will by default pass the `X-Osmo-IGN: C` header for
|
||||
endpoints associated with an A/SCCPlite MSC.
|
||||
|
||||
.Example: `CRCX` message that instructs OsmoMGW to ignore CallID mismatches
|
||||
----
|
||||
CRCX 2 rtpbridge/123abc@mgw MGCP 1.0
|
||||
M: recvonly
|
||||
C: 2
|
||||
L: p:20
|
||||
X-Osmo-IGN: C
|
||||
|
||||
v=0
|
||||
c=IN IP4 123.12.12.123
|
||||
m=audio 5904 RTP/AVP 97
|
||||
a=rtpmap:97 GSM-EFR/8000
|
||||
a=ptime:40
|
||||
----
|
||||
|
||||
=== `X-Osmux`
|
||||
|
||||
See <<mgcp-extension-osmux>>
|
@@ -1,115 +0,0 @@
|
||||
[[overview]]
|
||||
== Overview
|
||||
|
||||
This manual should help you getting started with OsmoMGW. It will cover
|
||||
aspects of configuring and running the media gateway.
|
||||
|
||||
[[intro_overview]]
|
||||
=== About OsmoMGW
|
||||
|
||||
OsmoMGW is the Osmocom implementation of a media gateway to handle user
|
||||
plane (voice) traffic in cellular networks. It can connect and optionally
|
||||
transcode RTP voice streams between different network elements such as BTSs
|
||||
and external entities like SIP. It is typically co-located with both OsmoBSC
|
||||
and OsmoMSC and controlled by them via MGCP, the Media Gateway Control
|
||||
Protocol.
|
||||
|
||||
[[fig-bsc]]
|
||||
.OsmoMGW used with OsmoBSC
|
||||
[graphviz]
|
||||
----
|
||||
digraph G {
|
||||
rankdir = LR;
|
||||
OsmoBTS -> OsmoBSC [label="Abis/IP"];
|
||||
OsmoBSC -> "core-network" [label="3GPP AoIP"];
|
||||
OsmoBSC -> OsmoMGW [label="MGCP"];
|
||||
OsmoBTS -> OsmoMGW [label="RTP",dir=both];
|
||||
OsmoMGW -> "core-network" [label="RTP",dir=both];
|
||||
{rank=same OsmoBSC OsmoMGW}
|
||||
OsmoMGW [color=red];
|
||||
}
|
||||
----
|
||||
|
||||
[[fig-msc]]
|
||||
.OsmoMGW used with OsmoMSC
|
||||
[graphviz]
|
||||
----
|
||||
digraph G {
|
||||
rankdir = LR;
|
||||
"2G BSS" -> OsmoMSC [label="3GPP AoIP"];
|
||||
OsmoMSC -> OsmoMGW [label="MGCP"];
|
||||
"2G BSS" -> OsmoMGW [label="RTP",dir=both];
|
||||
OsmoMSC -> OsmoSIP [label="MNCC"];
|
||||
OsmoSIP -> PBX [label="SIP Trunk"];
|
||||
OsmoMGW -> PBX [label="RTP",dir=both];
|
||||
{rank=same OsmoMSC OsmoMGW}
|
||||
OsmoSIP [label="osmo-sip-connector"];
|
||||
OsmoMGW [color=red];
|
||||
|
||||
hNodeB -> OsmoHNBGW [label="Iuh"];
|
||||
OsmoHNBGW -> OsmoMSC [label="IuCS"];
|
||||
hNodeB -> OsmoMGW [label="RTP",dir=both];
|
||||
}
|
||||
----
|
||||
|
||||
[[fig-bsc-e1]]
|
||||
.Integration of legacy E1 BTS in AoIP network
|
||||
[graphviz]
|
||||
----
|
||||
digraph G {
|
||||
rankdir = LR;
|
||||
BTS -> OsmoBSC [label="Abis/E1"];
|
||||
OsmoBSC -> "core-network" [label="3GPP AoIP"];
|
||||
OsmoBSC -> OsmoMGW [label="MGCP"];
|
||||
BTS -> OsmoMGW [label="TRAU/E1",dir=both];
|
||||
OsmoMGW -> "core-network" [label="RTP",dir=both];
|
||||
{rank=same OsmoBSC OsmoMGW}
|
||||
OsmoMGW [color=red];
|
||||
}
|
||||
----
|
||||
|
||||
=== Software Components
|
||||
|
||||
OsmoMGW contains a variety of different software components, which we’ll
|
||||
quickly describe in this section.
|
||||
|
||||
==== MGCP Implementation
|
||||
|
||||
OsmoMGW brings its own MGCP implementation through which OsmoMGW is
|
||||
controlled.
|
||||
|
||||
The commands implemented are CRCX, MDCX, DLCX and RSIP. The command AUEP is
|
||||
implemented as a stub and will simply respond with OK.
|
||||
|
||||
==== RTP implementation
|
||||
|
||||
Support for IuUP which is used in 3G cells is quite lacking at the moment.
|
||||
3G<->3G and 2G<->2G calls should work, but 3G<->2G does not.
|
||||
|
||||
==== Audio transcoder
|
||||
|
||||
Transcoding is currently not supported in OsmoMGW.
|
||||
|
||||
=== Limitations
|
||||
|
||||
At the moment (November 2020), OsmoMGW implements RTP proxy / RTP bridge
|
||||
type endpoints and E1/T1 16k/8k sub-slots with TRAU frames for classic BTS
|
||||
support. To the RTP proxy / RTP bridge endpoints two RTP connections can
|
||||
be established, which then work as a tandem. E1/T1 endpoints support one
|
||||
RTP connection at a time that is associated with a sub-slot on an E1 line.
|
||||
We are planning to add further endpoint types for:
|
||||
|
||||
- classic E1/T1 timeslots (64kBps alaw/ulaw)
|
||||
- announcement/playout end-points
|
||||
- conference endpoints
|
||||
|
||||
=== Additional resources
|
||||
|
||||
You can find the OsmoMGW issue tracker and wiki online at
|
||||
|
||||
- https://osmocom.org/projects/osmo-mgw
|
||||
- https://osmocom.org/projects/osmo-mgw/wiki
|
||||
|
||||
RFC 3435 for MGCP is located at
|
||||
|
||||
- https://tools.ietf.org/html/rfc3435
|
@@ -1,42 +0,0 @@
|
||||
==== Full example of QoS for osmo-mgw
|
||||
|
||||
In the below example we will show the full set of configuration required
|
||||
for both DSCP and PCP differentiation of RTP traffic by osmo-mgw.
|
||||
|
||||
What we want to achieve in this example is the following configuration:
|
||||
|
||||
.DSCP and PCP assignments for osmo-mgw Abis downlink traffic in this example
|
||||
[options="header",width="30%",cols="2,1,1"]
|
||||
|===
|
||||
|Traffic |DSCP|PCP
|
||||
|RTP | 46| 6
|
||||
|===
|
||||
|
||||
. configure the osmo-mgw program to set the DSCP value
|
||||
. configure an egrees QoS map to map from priority to PCP
|
||||
|
||||
.Example Step 1: add related VTY configuration to `osmo-mgw.cfg`
|
||||
----
|
||||
...
|
||||
mgcp
|
||||
rtp ip-dscp 46
|
||||
rtp socket-priority 6
|
||||
...
|
||||
----
|
||||
|
||||
.Example Step 2: egress QoS map to map from socket priority to PCP values
|
||||
----
|
||||
$ sudo ip link set dev eth0.9<1> type vlan egress-qos-map 0:0 5:5 6:6 7:7 <2>
|
||||
----
|
||||
<1> make sure to specify your specific VLAN interface name here instead of `eth0.9`.
|
||||
<2> create a egress QoS map that maps the priority value 1:1 to the PCP. We also include the
|
||||
mapping 5:5 and 7:7 from the osmo-bsc example (see <<userman-osmobsc>>) here.
|
||||
|
||||
NOTE:: The settings of the `ip` command are volatile and only active until
|
||||
the next reboot (or the network device or VLAN is removed). Please refer to
|
||||
the documentation of your specific Linux distribution in order to find out how
|
||||
to make such settings persistent by means of an `ifup` hook whenever the interface
|
||||
comes up. For CentOS/RHEL 8 this can e.g. be achieved by means of an `/sbin/ifup-local
|
||||
script` (when using `network-scripts` and not NetworkManager). For Debian or Ubuntu,
|
||||
this typically involves adding `up` lines to `/etc/network/interfaces` or a `/etc/network/if-up.d`
|
||||
script.
|
@@ -1,42 +0,0 @@
|
||||
== Running OsmoMGW
|
||||
|
||||
The OsmoMGW executable (`osmo-mgw`) offers the following command-line
|
||||
arguments:
|
||||
|
||||
=== SYNOPSIS
|
||||
|
||||
*osmo-mgw* [-h|-V] [-D] [-c 'CONFIGFILE'] [-s]
|
||||
|
||||
=== OPTIONS
|
||||
|
||||
*-h, --help*::
|
||||
Print a short help message about the supported options
|
||||
*-V, --version*::
|
||||
Print the compile-time version number of the program
|
||||
*-D, --daemonize*::
|
||||
Fork the process as a daemon into background.
|
||||
*-c, --config-file 'CONFIGFILE'*::
|
||||
Specify the file and path name of the configuration file to be
|
||||
used. If none is specified, use `osmo-mgw.cfg` in the current
|
||||
working directory.
|
||||
*-s, --disable-color*::
|
||||
Disable colors for logging to stderr. This has mostly been
|
||||
deprecated by VTY based logging configuration, see <<logging>>
|
||||
for more information.
|
||||
|
||||
|
||||
=== Configure limits
|
||||
|
||||
When servicing hundreds of media endpoints, it may be necessary to adjust the
|
||||
operating system's limit on open file descriptors for the osmo-mgw process. A
|
||||
typical default limit imposed by operating systems is 1024; this would be
|
||||
exceeded by, for example, about 256 active voice calls with 4 RTP/RTPC ports
|
||||
each, sockets for other interfaces not considered yet.
|
||||
|
||||
It should be ok to set an OS limit on open file descriptors as high as 65536
|
||||
for osmo-mgw, which practically rules out failure from running out of file
|
||||
descriptors anywhere (<16,000 active calls).
|
||||
|
||||
When using systemd, the file descriptor limit may be adjusted in the service
|
||||
file by the `LimitNOFILE` setting ("Number of Open FILE descriptors"). OsmoMGW
|
||||
ships a systemd service file with a high LimitNOFILE setting.
|
@@ -1,47 +0,0 @@
|
||||
<revhistory>
|
||||
<revision>
|
||||
<revnumber>1</revnumber>
|
||||
<date>July 24th, 2018</date>
|
||||
<authorinitials>DW</authorinitials>
|
||||
<revremark>
|
||||
Initial version
|
||||
</revremark>
|
||||
</revision>
|
||||
</revhistory>
|
||||
|
||||
<authorgroup>
|
||||
<author>
|
||||
<firstname>Daniel</firstname>
|
||||
<surname>Willmann</surname>
|
||||
<email>dwillmann@sysmocom.de</email>
|
||||
<authorinitials>DW</authorinitials>
|
||||
<affiliation>
|
||||
<shortaffil>sysmocom</shortaffil>
|
||||
<orgname>sysmocom - s.f.m.c. GmbH</orgname>
|
||||
</affiliation>
|
||||
</author>
|
||||
</authorgroup>
|
||||
|
||||
<copyright>
|
||||
<year>2018</year>
|
||||
<holder>sysmocom - s.f.m.c. GmbH</holder>
|
||||
</copyright>
|
||||
|
||||
<legalnotice>
|
||||
<para>
|
||||
Permission is granted to copy, distribute and/or modify this
|
||||
document under the terms of the GNU Free Documentation License,
|
||||
Version 1.3 or any later version published by the Free Software
|
||||
Foundation; with the Invariant Sections being just 'Foreword',
|
||||
'Acknowledgements' and 'Preface', with no Front-Cover Texts,
|
||||
and no Back-Cover Texts. A copy of the license is included in
|
||||
the section entitled "GNU Free Documentation License".
|
||||
</para>
|
||||
<para>
|
||||
The Asciidoc source code of this manual can be found at
|
||||
<ulink url="http://git.osmocom.org/osmo-gsm-manuals/">
|
||||
http://git.osmocom.org/osmo-gsm-manuals/
|
||||
</ulink>
|
||||
</para>
|
||||
</legalnotice>
|
||||
|
@@ -1,39 +0,0 @@
|
||||
:gfdl-enabled:
|
||||
:program-name: OsmoMGW
|
||||
|
||||
OsmoMGW User Manual
|
||||
====================
|
||||
Daniel Willmann <dwillmann@sysmocom.de>
|
||||
|
||||
|
||||
include::./common/chapters/preface.adoc[]
|
||||
|
||||
include::{srcdir}/chapters/overview.adoc[]
|
||||
|
||||
include::{srcdir}/chapters/running.adoc[]
|
||||
|
||||
include::./common/chapters/vty.adoc[]
|
||||
|
||||
include::./common/chapters/logging.adoc[]
|
||||
|
||||
include::{srcdir}/chapters/configuration.adoc[]
|
||||
|
||||
include::{srcdir}/chapters/mgcp_endpoints.adoc[]
|
||||
|
||||
include::{srcdir}/chapters/mgcp_extensions.adoc[]
|
||||
|
||||
include::./common/chapters/osmux/osmux.adoc[]
|
||||
|
||||
include::./common/chapters/qos-dscp-pcp.adoc[]
|
||||
|
||||
//include::{srcdir}/chapters/counters.adoc[]
|
||||
|
||||
include::./common/chapters/vty_cpu_sched.adoc[]
|
||||
|
||||
include::./common/chapters/port_numbers.adoc[]
|
||||
|
||||
include::./common/chapters/bibliography.adoc[]
|
||||
|
||||
include::./common/chapters/glossary.adoc[]
|
||||
|
||||
include::./common/chapters/gfdl.adoc[]
|
@@ -1,38 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
ex:ts=2:sw=42sts=2:et
|
||||
-*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
|
||||
-->
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML 5.0//EN"
|
||||
"http://docbook.org/xml/5.0/dtd/docbook.dtd" [
|
||||
<!ENTITY chapter-vty SYSTEM "./common/chapters/vty.xml" >
|
||||
<!ENTITY sections-vty SYSTEM "generated/docbook_vty.xml" >
|
||||
]>
|
||||
|
||||
<book>
|
||||
<info>
|
||||
<revhistory>
|
||||
<revision>
|
||||
<revnumber>v1</revnumber>
|
||||
<date>12th December 2017</date>
|
||||
<authorinitials>pm</authorinitials>
|
||||
<revremark>Initial</revremark>
|
||||
</revision>
|
||||
</revhistory>
|
||||
|
||||
<title>OsmoMGW VTY Reference</title>
|
||||
|
||||
<copyright>
|
||||
<year>2017</year>
|
||||
</copyright>
|
||||
|
||||
<legalnotice>
|
||||
<para>This work is copyright by <orgname>sysmocom - s.f.m.c. GmbH</orgname>. All rights reserved.
|
||||
</para>
|
||||
</legalnotice>
|
||||
</info>
|
||||
|
||||
<!-- Main chapters-->
|
||||
&chapter-vty;
|
||||
</book>
|
||||
|
@@ -1,17 +0,0 @@
|
||||
#!/bin/sh -x
|
||||
|
||||
if [ -z "$DOCKER_PLAYGROUND" ]; then
|
||||
echo "You need to set DOCKER_PLAYGROUND"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SCRIPT=$(realpath "$0")
|
||||
MANUAL_DIR=$(dirname "$SCRIPT")
|
||||
|
||||
COMMIT=${COMMIT:-$(git log -1 --format=format:%H)}
|
||||
|
||||
cd "$DOCKER_PLAYGROUND/scripts" || exit 1
|
||||
|
||||
OSMO_MGW_BRANCH=$COMMIT ./regen_doc.sh osmo-mgw 4243 \
|
||||
"$MANUAL_DIR/chapters/counters_generated.adoc" \
|
||||
"$MANUAL_DIR/vty/mgw_vty_reference.xml"
|
@@ -1,2 +0,0 @@
|
||||
<vtydoc xmlns='urn:osmocom:xml:libosmocore:vty:doc:1.0'>
|
||||
</vtydoc>
|
151
git-version-gen
151
git-version-gen
@@ -1,151 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Print a version string.
|
||||
scriptversion=2010-01-28.01
|
||||
|
||||
# Copyright (C) 2007-2010 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# This script is derived from GIT-VERSION-GEN from GIT: http://git.or.cz/.
|
||||
# It may be run two ways:
|
||||
# - from a git repository in which the "git describe" command below
|
||||
# produces useful output (thus requiring at least one signed tag)
|
||||
# - from a non-git-repo directory containing a .tarball-version file, which
|
||||
# presumes this script is invoked like "./git-version-gen .tarball-version".
|
||||
|
||||
# In order to use intra-version strings in your project, you will need two
|
||||
# separate generated version string files:
|
||||
#
|
||||
# .tarball-version - present only in a distribution tarball, and not in
|
||||
# a checked-out repository. Created with contents that were learned at
|
||||
# the last time autoconf was run, and used by git-version-gen. Must not
|
||||
# be present in either $(srcdir) or $(builddir) for git-version-gen to
|
||||
# give accurate answers during normal development with a checked out tree,
|
||||
# but must be present in a tarball when there is no version control system.
|
||||
# Therefore, it cannot be used in any dependencies. GNUmakefile has
|
||||
# hooks to force a reconfigure at distribution time to get the value
|
||||
# correct, without penalizing normal development with extra reconfigures.
|
||||
#
|
||||
# .version - present in a checked-out repository and in a distribution
|
||||
# tarball. Usable in dependencies, particularly for files that don't
|
||||
# want to depend on config.h but do want to track version changes.
|
||||
# Delete this file prior to any autoconf run where you want to rebuild
|
||||
# files to pick up a version string change; and leave it stale to
|
||||
# minimize rebuild time after unrelated changes to configure sources.
|
||||
#
|
||||
# It is probably wise to add these two files to .gitignore, so that you
|
||||
# don't accidentally commit either generated file.
|
||||
#
|
||||
# Use the following line in your configure.ac, so that $(VERSION) will
|
||||
# automatically be up-to-date each time configure is run (and note that
|
||||
# since configure.ac no longer includes a version string, Makefile rules
|
||||
# should not depend on configure.ac for version updates).
|
||||
#
|
||||
# AC_INIT([GNU project],
|
||||
# m4_esyscmd([build-aux/git-version-gen .tarball-version]),
|
||||
# [bug-project@example])
|
||||
#
|
||||
# Then use the following lines in your Makefile.am, so that .version
|
||||
# will be present for dependencies, and so that .tarball-version will
|
||||
# exist in distribution tarballs.
|
||||
#
|
||||
# BUILT_SOURCES = $(top_srcdir)/.version
|
||||
# $(top_srcdir)/.version:
|
||||
# echo $(VERSION) > $@-t && mv $@-t $@
|
||||
# dist-hook:
|
||||
# echo $(VERSION) > $(distdir)/.tarball-version
|
||||
|
||||
case $# in
|
||||
1) ;;
|
||||
*) echo 1>&2 "Usage: $0 \$srcdir/.tarball-version"; exit 1;;
|
||||
esac
|
||||
|
||||
tarball_version_file=$1
|
||||
nl='
|
||||
'
|
||||
|
||||
# First see if there is a tarball-only version file.
|
||||
# then try "git describe", then default.
|
||||
if test -f $tarball_version_file
|
||||
then
|
||||
v=`cat $tarball_version_file` || exit 1
|
||||
case $v in
|
||||
*$nl*) v= ;; # reject multi-line output
|
||||
[0-9]*) ;;
|
||||
*) v= ;;
|
||||
esac
|
||||
test -z "$v" \
|
||||
&& echo "$0: WARNING: $tarball_version_file seems to be damaged" 1>&2
|
||||
fi
|
||||
|
||||
if test -n "$v"
|
||||
then
|
||||
: # use $v
|
||||
elif
|
||||
v=`git describe --abbrev=4 --match='v*' HEAD 2>/dev/null \
|
||||
|| git describe --abbrev=4 HEAD 2>/dev/null` \
|
||||
&& case $v in
|
||||
[0-9]*) ;;
|
||||
v[0-9]*) ;;
|
||||
*) (exit 1) ;;
|
||||
esac
|
||||
then
|
||||
# Is this a new git that lists number of commits since the last
|
||||
# tag or the previous older version that did not?
|
||||
# Newer: v6.10-77-g0f8faeb
|
||||
# Older: v6.10-g0f8faeb
|
||||
case $v in
|
||||
*-*-*) : git describe is okay three part flavor ;;
|
||||
*-*)
|
||||
: git describe is older two part flavor
|
||||
# Recreate the number of commits and rewrite such that the
|
||||
# result is the same as if we were using the newer version
|
||||
# of git describe.
|
||||
vtag=`echo "$v" | sed 's/-.*//'`
|
||||
numcommits=`git rev-list "$vtag"..HEAD | wc -l`
|
||||
v=`echo "$v" | sed "s/\(.*\)-\(.*\)/\1-$numcommits-\2/"`;
|
||||
;;
|
||||
esac
|
||||
|
||||
# Change the first '-' to a '.', so version-comparing tools work properly.
|
||||
# Remove the "g" in git describe's output string, to save a byte.
|
||||
v=`echo "$v" | sed 's/-/./;s/\(.*\)-g/\1-/'`;
|
||||
else
|
||||
v=UNKNOWN
|
||||
fi
|
||||
|
||||
v=`echo "$v" |sed 's/^v//'`
|
||||
|
||||
# Don't declare a version "dirty" merely because a time stamp has changed.
|
||||
git status > /dev/null 2>&1
|
||||
|
||||
dirty=`sh -c 'git diff-index --name-only HEAD' 2>/dev/null` || dirty=
|
||||
case "$dirty" in
|
||||
'') ;;
|
||||
*) # Append the suffix only if there isn't one already.
|
||||
case $v in
|
||||
*-dirty) ;;
|
||||
*) v="$v-dirty" ;;
|
||||
esac ;;
|
||||
esac
|
||||
|
||||
# Omit the trailing newline, so that m4_esyscmd can use the result directly.
|
||||
echo "$v" | tr -d '\012'
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-end: "$"
|
||||
# End:
|
125
hlrsync/hlrsync.py
Executable file
125
hlrsync/hlrsync.py
Executable file
@@ -0,0 +1,125 @@
|
||||
#!/usr/bin/python2.5
|
||||
|
||||
from __future__ import with_statement
|
||||
|
||||
from pysqlite2 import dbapi2 as sqlite3
|
||||
import sys
|
||||
|
||||
hlr = sqlite3.connect(sys.argv[1])
|
||||
web = sqlite3.connect(sys.argv[2])
|
||||
|
||||
# switch to autocommit
|
||||
hlr.isolation_level = None
|
||||
web.isolation_level = None
|
||||
|
||||
hlr.row_factory = sqlite3.Row
|
||||
web.row_factory = sqlite3.Row
|
||||
|
||||
with hlr:
|
||||
hlr_subscrs = hlr.execute("""
|
||||
SELECT * FROM Subscriber
|
||||
""").fetchall()
|
||||
hlr_tokens = hlr.execute("""
|
||||
SELECT * FROM AuthToken
|
||||
""").fetchall()
|
||||
|
||||
with web:
|
||||
web_tokens = web.execute("""
|
||||
SELECT * FROM reg_tokens
|
||||
""").fetchall()
|
||||
web_sms = web.execute("""
|
||||
SELECT * FROM sms_queue
|
||||
""").fetchall()
|
||||
|
||||
# index by subscr id
|
||||
hlr_subscrs_by_id = {}
|
||||
hlr_subscrs_by_ext = {}
|
||||
hlr_tokens_by_subscr_id = {}
|
||||
for x in hlr_subscrs:
|
||||
hlr_subscrs_by_id[x['id']] = x
|
||||
hlr_subscrs_by_ext[x['extension']] = x
|
||||
del hlr_subscrs
|
||||
for x in hlr_tokens:
|
||||
hlr_tokens_by_subscr_id[x['subscriber_id']] = x
|
||||
del hlr_tokens
|
||||
|
||||
web_tokens_by_subscr_id = {}
|
||||
for x in web_tokens:
|
||||
web_tokens_by_subscr_id[x['subscriber_id']] = x
|
||||
del web_tokens
|
||||
|
||||
# remove leftover web_tokens and correct inconsistent fields
|
||||
with web:
|
||||
for x in web_tokens_by_subscr_id.values():
|
||||
subscr = hlr_subscrs_by_id.get(x['subscriber_id'], None)
|
||||
if subscr is None:
|
||||
web.execute("""
|
||||
DELETE FROM reg_tokens WHERE subscriber_id = ?
|
||||
""", (x['subscriber_id'],))
|
||||
del web_tokens_by_subscr_id[x['subscriber_id']]
|
||||
continue
|
||||
if str(x['imsi']) != str(subscr['imsi']) or \
|
||||
x['extension'] != subscr['extension'] or \
|
||||
x['tmsi'] != subscr['tmsi'] or \
|
||||
x['lac'] != subscr['lac']:
|
||||
web.execute("""
|
||||
UPDATE reg_tokens
|
||||
SET imsi = ?, extension = ?, tmsi = ?, lac = ?
|
||||
WHERE subscriber_id = ?
|
||||
""", (str(subscr['imsi']), subscr['extension'],
|
||||
subscr['tmsi'], subscr['lac'], x['subscriber_id']))
|
||||
|
||||
# add missing web_tokens
|
||||
with web:
|
||||
for x in hlr_tokens_by_subscr_id.values():
|
||||
subscr = hlr_subscrs_by_id.get(x['subscriber_id'], None)
|
||||
if subscr is None:
|
||||
hlr.execute("""
|
||||
DELETE FROM AuthToken WHERE subscriber_id = ?
|
||||
""", (x['subscriber_id'],))
|
||||
del hlr_tokens_by_subscr_id[x['subscriber_id']]
|
||||
continue
|
||||
webtoken = web_tokens_by_subscr_id.get(x['subscriber_id'], None)
|
||||
if webtoken is None:
|
||||
web.execute("""
|
||||
INSERT INTO reg_tokens
|
||||
(subscriber_id, extension, reg_completed, name, email, lac, imsi, token, tmsi)
|
||||
VALUES
|
||||
(?, ?, 0, ?, '', ?, ?, ?, ?)
|
||||
""", (x['subscriber_id'], subscr['extension'], subscr['name'],
|
||||
subscr['lac'], str(subscr['imsi']), x['token'], subscr['tmsi']))
|
||||
|
||||
# authorize subscribers
|
||||
with hlr:
|
||||
for x in web_tokens_by_subscr_id.values():
|
||||
subscr = hlr_subscrs_by_id.get(x['subscriber_id'], None)
|
||||
if x['reg_completed'] and not subscr['authorized']:
|
||||
hlr.execute("""
|
||||
UPDATE Subscriber
|
||||
SET authorized = 1
|
||||
WHERE id = ?
|
||||
""", (x['subscriber_id'],))
|
||||
|
||||
# Sync SMS from web to hlr
|
||||
with hlr:
|
||||
for sms in web_sms:
|
||||
subscr = hlr_subscrs_by_ext.get(sms['receiver_ext'])
|
||||
if subscr is None:
|
||||
print '%s not found' % sms['receiver_ext']
|
||||
continue
|
||||
hlr.execute("""
|
||||
INSERT INTO SMS
|
||||
(created, sender_id, receiver_id, reply_path_req, status_rep_req, protocol_id, data_coding_scheme, ud_hdr_ind, text)
|
||||
VALUES
|
||||
(?, 1, ?, 0, 0, 0, 0, 0, ?)
|
||||
""", (sms['created'], subscr['id'], sms['text']))
|
||||
with web:
|
||||
for sms in web_sms:
|
||||
web.execute("""
|
||||
DELETE FROM sms_queue WHERE id = ?
|
||||
""", (sms['id'],))
|
||||
|
||||
|
||||
hlr.close()
|
||||
web.close()
|
||||
|
@@ -1,23 +0,0 @@
|
||||
SUBDIRS = \
|
||||
osmocom \
|
||||
$(NULL)
|
||||
|
||||
nobase_include_HEADERS = \
|
||||
osmocom/mgcp_client/defs.h \
|
||||
osmocom/mgcp_client/mgcp_client.h \
|
||||
osmocom/mgcp_client/mgcp_client_endpoint_fsm.h \
|
||||
osmocom/mgcp_client/mgcp_client_fsm.h \
|
||||
osmocom/mgcp_client/mgcp_client_pool.h \
|
||||
$(NULL)
|
||||
|
||||
noinst_HEADERS = \
|
||||
osmocom/mgcp/mgcp.h \
|
||||
osmocom/mgcp/mgcp_common.h \
|
||||
osmocom/mgcp/osmux.h \
|
||||
$(NULL)
|
||||
|
||||
# This gets copied during make from osmocom/mgcp/mgcp_common.h. Therefore it is not included in the source tree and we
|
||||
# don't need to distribute it (OS#4084).
|
||||
nobase_nodist_include_HEADERS = \
|
||||
osmocom/mgcp_client/mgcp_common.h \
|
||||
$(NULL)
|
@@ -1,4 +0,0 @@
|
||||
SUBDIRS = \
|
||||
mgcp_client \
|
||||
mgcp \
|
||||
$(NULL)
|
@@ -1,18 +0,0 @@
|
||||
noinst_HEADERS = \
|
||||
vty.h \
|
||||
mgcp_msg.h \
|
||||
mgcp_codec.h \
|
||||
mgcp_conn.h \
|
||||
mgcp_stat.h \
|
||||
mgcp_endp.h \
|
||||
mgcp_sdp.h \
|
||||
mgcp_codec.h \
|
||||
mgcp_trunk.h \
|
||||
debug.h \
|
||||
mgcp_ratectr.h \
|
||||
mgcp_e1.h \
|
||||
mgcp_network.h \
|
||||
mgcp_protocol.h \
|
||||
mgcp_iuup.h \
|
||||
mgcp_rtp_end.h \
|
||||
$(NULL)
|
@@ -1,37 +0,0 @@
|
||||
/* (C) 2017 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Author: Philipp Maier
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
|
||||
#define DEBUG
|
||||
#include <osmocom/core/logging.h>
|
||||
|
||||
/* Debug Areas of the code */
|
||||
enum {
|
||||
DRTP,
|
||||
DE1,
|
||||
DOSMUX,
|
||||
Debug_LastEntry,
|
||||
};
|
||||
|
||||
extern const struct log_info log_info;
|
@@ -1,209 +0,0 @@
|
||||
/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
|
||||
|
||||
/*
|
||||
* (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009-2012 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 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/socket.h>
|
||||
#include <osmocom/core/osmo_io.h>
|
||||
#include <osmocom/core/write_queue.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
#include <osmocom/core/logging.h>
|
||||
|
||||
#include <osmocom/mgcp/mgcp_common.h>
|
||||
#include <osmocom/mgcp/osmux.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "mgcp_ratectr.h"
|
||||
|
||||
#define RTP_PORT_DEFAULT_RANGE_START 16002
|
||||
#define RTP_PORT_DEFAULT_RANGE_END RTP_PORT_DEFAULT_RANGE_START + 64
|
||||
|
||||
/*
|
||||
* Handling of MGCP Endpoints and the MGCP Config
|
||||
*/
|
||||
struct mgcp_endpoint;
|
||||
struct mgcp_config;
|
||||
struct mgcp_trunk;
|
||||
struct mgcp_rtp_end;
|
||||
|
||||
#define MGCP_ENDP_CRCX 1
|
||||
#define MGCP_ENDP_DLCX 2
|
||||
#define MGCP_ENDP_MDCX 3
|
||||
|
||||
/*
|
||||
* what to do with the msg?
|
||||
* - continue as usual?
|
||||
* - reject and send a failure code?
|
||||
* - defer? do not send anything
|
||||
*/
|
||||
#define MGCP_POLICY_CONT 4
|
||||
#define MGCP_POLICY_REJECT 5
|
||||
#define MGCP_POLICY_DEFER 6
|
||||
|
||||
typedef int (*mgcp_reset)(struct mgcp_trunk *cfg);
|
||||
typedef int (*mgcp_rqnt)(struct mgcp_endpoint *endp, char tone);
|
||||
|
||||
/**
|
||||
* Return:
|
||||
* < 0 in case no audio was processed
|
||||
* >= 0 in case audio was processed.
|
||||
*/
|
||||
typedef int (*mgcp_processing)(struct mgcp_endpoint *endp,
|
||||
struct mgcp_rtp_end *dst_end, struct msgb *msg);
|
||||
|
||||
struct mgcp_conn_rtp;
|
||||
|
||||
typedef int (*mgcp_processing_setup)(struct mgcp_endpoint *endp,
|
||||
struct mgcp_conn_rtp *conn_dst,
|
||||
struct mgcp_conn_rtp *conn_src);
|
||||
|
||||
struct mgcp_rtp_codec;
|
||||
|
||||
typedef void (*mgcp_get_format)(struct mgcp_endpoint *endp,
|
||||
const struct mgcp_rtp_codec **codec,
|
||||
const char **fmtp_extra,
|
||||
struct mgcp_conn_rtp *conn);
|
||||
|
||||
/**
|
||||
* This holds information on how to allocate ports
|
||||
*/
|
||||
struct mgcp_port_range {
|
||||
pthread_mutex_t lock;
|
||||
/* addr or NULL to fall-back to default */
|
||||
char bind_addr_v4[INET6_ADDRSTRLEN];
|
||||
char bind_addr_v6[INET6_ADDRSTRLEN];
|
||||
|
||||
/* dynamically allocated */
|
||||
int range_start;
|
||||
int range_end;
|
||||
int last_port;
|
||||
|
||||
/* set to true to enable automatic probing
|
||||
* of the local bind IP-Address, bind_addr
|
||||
* (or its fall back) is used when automatic
|
||||
* probing fails */
|
||||
bool bind_addr_probe;
|
||||
};
|
||||
|
||||
/* There are up to three modes in which the keep-alive dummy packet can be
|
||||
* sent. The behaviour is controlled via the keepalive_interval member of the
|
||||
* trunk config. If that member is set to 0 (MGCP_KEEPALIVE_NEVER) no dummy-
|
||||
* packet is sent at all and the timer that sends regular dummy packets
|
||||
* is no longer scheduled. If the keepalive_interval is set to -1, only
|
||||
* one dummy packet is sent when an CRCX or an MDCX is performed. No timer
|
||||
* is scheduled. For all vales greater 0, the timer is scheduled and the
|
||||
* value is used as interval. See also mgcp_keepalive_timer_cb(),
|
||||
* handle_modify_con(), and handle_create_con() */
|
||||
#define MGCP_KEEPALIVE_ONCE (-1)
|
||||
#define MGCP_KEEPALIVE_NEVER 0
|
||||
|
||||
enum mgcp_role {
|
||||
MGCP_BSC = 0,
|
||||
MGCP_BSC_NAT,
|
||||
};
|
||||
|
||||
struct mgcp_config {
|
||||
int source_port;
|
||||
char local_ip[INET6_ADDRSTRLEN];
|
||||
char source_addr[INET6_ADDRSTRLEN];
|
||||
char call_agent_addr[INET6_ADDRSTRLEN];
|
||||
|
||||
/* RTP processing */
|
||||
mgcp_processing rtp_processing_cb;
|
||||
mgcp_processing_setup setup_rtp_processing_cb;
|
||||
|
||||
struct osmo_wqueue gw_fd;
|
||||
|
||||
struct mgcp_port_range net_ports;
|
||||
int endp_dscp;
|
||||
int endp_priority;
|
||||
|
||||
int force_ptime;
|
||||
|
||||
mgcp_reset reset_cb;
|
||||
mgcp_rqnt rqnt_cb;
|
||||
void *data;
|
||||
|
||||
/* list holding the trunks */
|
||||
struct llist_head trunks;
|
||||
|
||||
enum mgcp_role role;
|
||||
|
||||
struct {
|
||||
/* Osmux usage policy: */
|
||||
enum osmux_usage usage;
|
||||
/* addr to bind the server to */
|
||||
char *local_addr_v4;
|
||||
char *local_addr_v6;
|
||||
/* osmux port */
|
||||
uint16_t local_port;
|
||||
/* The osmux socket is allocated on demand (1st time used).
|
||||
* This tells us if the osmux socket is already initialized. */
|
||||
bool initialized;
|
||||
/* osmux batch factor: from 1 to 4 maximum */
|
||||
int batch_factor;
|
||||
/* osmux batch size (in bytes) */
|
||||
int batch_size;
|
||||
/* Pad circuit with dummy AMR frames if no payload to transmit is available */
|
||||
bool dummy_padding;
|
||||
/* Whether peer is behind NAT (Retrieve remote addr from 1st received Osmux packet) */
|
||||
bool peer_behind_nat;
|
||||
} osmux;
|
||||
/* domain name of the media gateway */
|
||||
char domain[255+1];
|
||||
|
||||
/* time after which inactive connections (CIs) get closed */
|
||||
int conn_timeout;
|
||||
|
||||
/* osmocom CTRL interface */
|
||||
struct ctrl_handle *ctrl;
|
||||
|
||||
/* global rate counters to measure the MGWs overall performance and
|
||||
* health */
|
||||
struct mgcp_ratectr_global ratectr;
|
||||
};
|
||||
|
||||
/* config management */
|
||||
struct mgcp_config *mgcp_config_alloc(void);
|
||||
int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg,
|
||||
enum mgcp_role role);
|
||||
int mgcp_vty_init(void);
|
||||
void mgcp_trunk_set_keepalive(struct mgcp_trunk *trunk, int interval);
|
||||
|
||||
/*
|
||||
* format helper functions
|
||||
*/
|
||||
struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg);
|
||||
|
||||
|
||||
int mgcp_send_reset_ep(struct mgcp_endpoint *endp);
|
||||
int mgcp_send_reset_all(struct mgcp_config *cfg);
|
||||
|
||||
|
||||
int mgcp_create_bind(const char *source_addr, int port, uint8_t dscp, uint8_t prio);
|
||||
int mgcp_udp_send(struct osmo_io_fd *iofd, const struct osmo_sockaddr *addr, const char *buf, int len);
|
@@ -1,48 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <osmocom/mgcp/mgcp_common.h>
|
||||
|
||||
#define DEFAULT_RTP_AUDIO_FRAME_DUR_NUM 20
|
||||
#define DEFAULT_RTP_AUDIO_FRAME_DUR_DEN 1000
|
||||
#define DEFAULT_RTP_AUDIO_PACKET_DURATION_MS 20
|
||||
#define DEFAULT_RTP_AUDIO_DEFAULT_RATE 8000
|
||||
#define DEFAULT_RTP_AUDIO_DEFAULT_CHANNELS 1
|
||||
|
||||
#define PTYPE_UNDEFINED (-1)
|
||||
|
||||
struct mgcp_rtp_codec {
|
||||
uint32_t rate;
|
||||
int channels;
|
||||
uint32_t frame_duration_num;
|
||||
uint32_t frame_duration_den;
|
||||
|
||||
int payload_type;
|
||||
char audio_name[64];
|
||||
char subtype_name[64];
|
||||
|
||||
bool param_present;
|
||||
struct mgcp_codec_param param;
|
||||
};
|
||||
|
||||
bool mgcp_codec_amr_align_mode_is_indicated(const struct mgcp_rtp_codec *codec);
|
||||
bool mgcp_codec_amr_is_octet_aligned(const struct mgcp_rtp_codec *codec);
|
||||
|
||||
struct mgcp_rtp_codecset {
|
||||
/* currently selected audio codec */
|
||||
struct mgcp_rtp_codec *codec;
|
||||
/* array with assigned audio codecs to choose from (SDP) */
|
||||
struct mgcp_rtp_codec codecs[MGCP_MAX_CODECS];
|
||||
/* number of assigned audio codecs (SDP) */
|
||||
unsigned int codecs_assigned;
|
||||
};
|
||||
|
||||
void mgcp_codecset_reset(struct mgcp_rtp_codecset *cset);
|
||||
void mgcp_codecset_summary(struct mgcp_rtp_codecset *cset, const char *prefix_str);
|
||||
int mgcp_codecset_add_codec(struct mgcp_rtp_codecset *cset, int payload_type,
|
||||
const char *audio_name, const struct mgcp_codec_param *param);
|
||||
int mgcp_codecset_decide(struct mgcp_rtp_codecset *cset_src, struct mgcp_rtp_codecset *cset_dst);
|
||||
const struct mgcp_rtp_codec *mgcp_codecset_pt_find_by_subtype_name(const struct mgcp_rtp_codecset *cset,
|
||||
const char *subtype_name, unsigned int match_nr);
|
||||
struct mgcp_rtp_codec *mgcp_codecset_find_codec_from_pt(struct mgcp_rtp_codecset *cset, int payload_type);
|
@@ -1,112 +0,0 @@
|
||||
/* MGCP common implementations.
|
||||
* These are used in libosmo-mgcp as well as libosmo-mgcp-client.
|
||||
* To avoid interdependency, these are implemented in .h file only. */
|
||||
|
||||
/*
|
||||
* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009-2012 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 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Two copies of this file are kept in osmocom/mgcp/ and osmocom/mgcp_client/.
|
||||
* Since both are by definition identical, use the old header exclusion ifdefs
|
||||
* instead of '#pragma once' to avoid including both of these files.
|
||||
* Though at the time of writing there are no such users, this allows including
|
||||
* both libosmo-mgcp and libosmo-mgcp-client headers in the same file. */
|
||||
#ifndef OSMO_MGCP_COMMON_H
|
||||
#define OSMO_MGCP_COMMON_H
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/logging.h>
|
||||
|
||||
#define for_each_non_empty_line(line, save) \
|
||||
for (line = strtok_r(NULL, "\r\n", &save); line; \
|
||||
line = strtok_r(NULL, "\r\n", &save))
|
||||
|
||||
enum mgcp_connection_mode {
|
||||
MGCP_CONN_NONE = 0,
|
||||
MGCP_CONN_RECV_ONLY = 1,
|
||||
MGCP_CONN_SEND_ONLY = 2,
|
||||
MGCP_CONN_RECV_SEND = MGCP_CONN_RECV_ONLY | MGCP_CONN_SEND_ONLY,
|
||||
MGCP_CONN_LOOPBACK = 4 | MGCP_CONN_RECV_SEND,
|
||||
MGCP_CONN_CONFECHO = 8 | MGCP_CONN_RECV_SEND,
|
||||
};
|
||||
|
||||
#define MGCP_X_OSMO_IGN_HEADER "X-Osmo-IGN:"
|
||||
#define MGCP_X_OSMO_OSMUX_HEADER "X-Osmux:"
|
||||
|
||||
/* Values should be bitwise-OR-able */
|
||||
enum mgcp_x_osmo_ign {
|
||||
MGCP_X_OSMO_IGN_NONE = 0,
|
||||
MGCP_X_OSMO_IGN_CALLID = 1,
|
||||
};
|
||||
|
||||
/* Codec parameters (communicated via SDP/fmtp) */
|
||||
struct mgcp_codec_param {
|
||||
bool amr_octet_aligned_present;
|
||||
bool amr_octet_aligned;
|
||||
};
|
||||
|
||||
/* Ensure that the msg->l2h is NUL terminated. */
|
||||
static inline int mgcp_msg_terminate_nul(struct msgb *msg)
|
||||
{
|
||||
unsigned char *tail = msg->tail; /* char after l2 data */
|
||||
if (tail[-1] == '\0')
|
||||
/* nothing to do */;
|
||||
else if (msgb_tailroom(msg) > 0)
|
||||
msgb_put_u8(msg, (uint8_t)'\0');
|
||||
else if (tail[-1] == '\r' || tail[-1] == '\n')
|
||||
tail[-1] = '\0';
|
||||
else {
|
||||
LOGP(DLMGCP, LOGL_ERROR, "Cannot NUL terminate MGCP message: "
|
||||
"Length: %d, Buffer size: %d\n",
|
||||
msgb_l2len(msg), msg->data_len);
|
||||
return -ENOTSUP;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Maximum length of the comment field */
|
||||
#define MGCP_COMMENT_MAXLEN 256
|
||||
|
||||
/* Maximum allowed String length of Connection Identifiers as per spec
|
||||
* (see also RFC3435 2.1.3.2 Names of Connections), plus one for '\0'. */
|
||||
#define MGCP_CONN_ID_MAXLEN 32+1
|
||||
|
||||
/* Deprecated: old name of MGCP_CONN_ID_MAXLEN. */
|
||||
#define MGCP_CONN_ID_LENGTH MGCP_CONN_ID_MAXLEN
|
||||
|
||||
/* String length of Endpoint Identifiers.
|
||||
/ (see also RFC3435 section 3.2.1.3) */
|
||||
#define MGCP_ENDPOINT_MAXLEN (255*2+1+1)
|
||||
|
||||
/* A prefix to denote the virtual trunk (RTP on both ends) */
|
||||
#define MGCP_ENDPOINT_PREFIX_VIRTUAL_TRUNK "rtpbridge/"
|
||||
|
||||
/* A prefix to denote the e1 trunk
|
||||
* (see also RFC3435 section E.2) */
|
||||
#define MGCP_ENDPOINT_PREFIX_E1_TRUNK "ds/e1-"
|
||||
|
||||
/* Maximal number of payload types / codecs that can be negotiated via SDP at
|
||||
* at once. */
|
||||
#define MGCP_MAX_CODECS 10
|
||||
|
||||
#endif
|
@@ -1,255 +0,0 @@
|
||||
/* Message connection list handling */
|
||||
|
||||
/*
|
||||
* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Author: Philipp Maier
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <osmocom/mgcp/mgcp.h>
|
||||
#include <osmocom/mgcp/mgcp_common.h>
|
||||
#include <osmocom/mgcp/mgcp_network.h>
|
||||
#include <osmocom/mgcp/osmux.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/core/rate_ctr.h>
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/gsm/iuup.h>
|
||||
#include <osmocom/mgcp/mgcp_rtp_end.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#define LOGPCONN(conn, cat, level, fmt, args...) \
|
||||
LOGPENDP((conn)->endp, cat, level, "CI:%s " fmt, \
|
||||
(conn)->id, \
|
||||
## args)
|
||||
|
||||
#define LOG_CONN(conn, level, fmt, args...) \
|
||||
LOGP(DRTP, level, "(%s I:%s) " fmt, \
|
||||
(conn)->endp ? (conn)->endp->name : "none", (conn)->id, ## args)
|
||||
|
||||
#define LOG_CONN_RTP(conn_rtp, level, fmt, args...) \
|
||||
LOG_CONN((conn_rtp)->conn, level, fmt, ## args)
|
||||
|
||||
/* Specific rtp connection type (see struct mgcp_conn_rtp) */
|
||||
enum mgcp_conn_rtp_type {
|
||||
MGCP_RTP_DEFAULT = 0,
|
||||
MGCP_RTP_OSMUX,
|
||||
MGCP_RTP_IUUP,
|
||||
};
|
||||
extern const struct value_string mgcp_conn_rtp_type_names[];
|
||||
static inline const char *mgcp_conn_rtp_type_name(enum mgcp_conn_rtp_type val)
|
||||
{
|
||||
return get_value_string(mgcp_conn_rtp_type_names, val);
|
||||
}
|
||||
|
||||
/*! Connection type, specifies which member of the union "u" in mgcp_conn
|
||||
* contains a useful connection description (currently only RTP) */
|
||||
enum mgcp_conn_type {
|
||||
MGCP_CONN_TYPE_RTP,
|
||||
};
|
||||
|
||||
/* MGCP connection (RTP) */
|
||||
struct mgcp_conn_rtp {
|
||||
|
||||
/* Backpointer to conn struct */
|
||||
struct mgcp_conn *conn;
|
||||
|
||||
/* Specific connection type */
|
||||
enum mgcp_conn_rtp_type type;
|
||||
|
||||
/* Port status */
|
||||
struct mgcp_rtp_end end;
|
||||
|
||||
/* Sequence bits */
|
||||
struct mgcp_rtp_state state;
|
||||
|
||||
/* taps for the rtp connection; one per direction */
|
||||
struct mgcp_rtp_tap tap_in;
|
||||
struct mgcp_rtp_tap tap_out;
|
||||
|
||||
/* Osmux states (optional) */
|
||||
struct {
|
||||
/* Osmux state: disabled, activating, active */
|
||||
enum osmux_state state;
|
||||
/* Is local_cid holding valid data? is it allocated from pool? */
|
||||
bool local_cid_allocated;
|
||||
/* Allocated local Osmux circuit ID for this conn */
|
||||
uint8_t local_cid;
|
||||
/* Is remote_cid holding valid data? was it already received from client? */
|
||||
bool remote_cid_present;
|
||||
/* Received remote Osmux circuit ID for this conn */
|
||||
uint8_t remote_cid;
|
||||
/* handle to batch messages, shared (refcounted) among several conns */
|
||||
struct osmux_in_handle *in;
|
||||
/* handle to unbatch messages, one allocated and owned per conn */
|
||||
struct osmux_out_handle *out;
|
||||
/* statistics: */
|
||||
struct rate_ctr_group *ctrg;
|
||||
} osmux;
|
||||
|
||||
struct {
|
||||
struct osmo_iuup_instance *iui;
|
||||
bool active_init; /* true: Send IuUP Init */
|
||||
int rfci_id_no_data; /* RFCI Id for RFCI NO_DATA (-1 if not available) */
|
||||
bool configured;
|
||||
struct osmo_iuup_rnl_prim *init_ind;
|
||||
} iuup;
|
||||
|
||||
struct rate_ctr_group *ctrg;
|
||||
};
|
||||
|
||||
/*! MGCP connection (untyped) */
|
||||
struct mgcp_conn {
|
||||
/*! list head */
|
||||
struct llist_head entry;
|
||||
|
||||
/*! Backpointer to the endpoint where the conn belongs to */
|
||||
struct mgcp_endpoint *endp;
|
||||
|
||||
/*! type of the connection (union) */
|
||||
enum mgcp_conn_type type;
|
||||
|
||||
/*! mode of the connection */
|
||||
enum mgcp_connection_mode mode;
|
||||
|
||||
/*! copy of the mode to restore the original setting (VTY) */
|
||||
enum mgcp_connection_mode mode_orig;
|
||||
|
||||
/*! connection id to identify the connection */
|
||||
char id[MGCP_CONN_ID_MAXLEN];
|
||||
|
||||
/*! human readable name (vty, logging) */
|
||||
char name[256];
|
||||
|
||||
/*! activity tracker (for cleaning up inactive connections) */
|
||||
struct osmo_timer_list watchdog;
|
||||
|
||||
/*! union with connection description */
|
||||
union {
|
||||
struct mgcp_conn_rtp rtp;
|
||||
} u;
|
||||
|
||||
/*! pointer to optional private data */
|
||||
void *priv;
|
||||
};
|
||||
|
||||
/* RTP connection related counters */
|
||||
enum {
|
||||
IN_STREAM_ERR_TSTMP_CTR,
|
||||
OUT_STREAM_ERR_TSTMP_CTR,
|
||||
RTP_PACKETS_RX_CTR,
|
||||
RTP_OCTETS_RX_CTR,
|
||||
RTP_PACKETS_TX_CTR,
|
||||
RTP_OCTETS_TX_CTR,
|
||||
RTP_DROPPED_PACKETS_CTR,
|
||||
RTP_NUM_CONNECTIONS,
|
||||
};
|
||||
|
||||
/* RTP per-connection statistics. Instances of the corresponding rate counter group
|
||||
* exist for the lifetime of an RTP connection.
|
||||
* Must be kept in sync with all_rtp_conn_rate_ctr_desc below */
|
||||
static const struct rate_ctr_desc mgcp_conn_rate_ctr_desc[] = {
|
||||
[IN_STREAM_ERR_TSTMP_CTR] = {"stream_err_tstmp:in", "Inbound rtp-stream timestamp errors."},
|
||||
[OUT_STREAM_ERR_TSTMP_CTR] = {"stream_err_tstmp:out", "Outbound rtp-stream timestamp errors."},
|
||||
[RTP_PACKETS_RX_CTR] = {"rtp:packets_rx", "Inbound rtp packets."},
|
||||
[RTP_OCTETS_RX_CTR] = {"rtp:octets_rx", "Inbound rtp octets."},
|
||||
[RTP_PACKETS_TX_CTR] = {"rtp:packets_tx", "Outbound rtp packets."},
|
||||
[RTP_OCTETS_TX_CTR] = {"rtp:octets_tx", "Outbound rtp octets."},
|
||||
[RTP_DROPPED_PACKETS_CTR] = {"rtp:dropped", "Dropped rtp packets."}
|
||||
};
|
||||
|
||||
/* Aggregated RTP connection stats. These are updated when an RTP connection is freed.
|
||||
* Must be kept in sync with mgcp_conn_rate_ctr_desc above */
|
||||
static const struct rate_ctr_desc all_rtp_conn_rate_ctr_desc[] = {
|
||||
[IN_STREAM_ERR_TSTMP_CTR] = {"all_rtp:err_tstmp_in", "Total inbound rtp-stream timestamp errors."},
|
||||
[OUT_STREAM_ERR_TSTMP_CTR] = {"all_rtp:err_tstmp_out", "Total outbound rtp-stream timestamp errors."},
|
||||
[RTP_PACKETS_RX_CTR] = {"all_rtp:packets_rx", "Total inbound rtp packets."},
|
||||
[RTP_OCTETS_RX_CTR] = {"all_rtp:octets_rx", "Total inbound rtp octets."},
|
||||
[RTP_PACKETS_TX_CTR] = {"all_rtp:packets_tx", "Total outbound rtp packets."},
|
||||
[RTP_OCTETS_TX_CTR] = {"all_rtp:octets_tx", "Total outbound rtp octets."},
|
||||
[RTP_DROPPED_PACKETS_CTR] = {"all_rtp:dropped", "Total dropped rtp packets."},
|
||||
|
||||
/* This last counter does not exist in per-connection stats, only here. */
|
||||
[RTP_NUM_CONNECTIONS] = {"all_rtp:num_closed_conns", "Total number of rtp connections closed."}
|
||||
};
|
||||
|
||||
/* Osmux connection related counters */
|
||||
enum {
|
||||
OSMUX_CHUNKS_RX_CTR,
|
||||
OSMUX_OCTETS_RX_CTR,
|
||||
OSMUX_RTP_PACKETS_TX_CTR,
|
||||
OSMUX_RTP_PACKETS_TX_DROPPED_CTR,
|
||||
OSMUX_AMR_OCTETS_TX_CTR,
|
||||
/* Only available in global stats: */
|
||||
OSMUX_NUM_CONNECTIONS,
|
||||
OSMUX_PACKETS_RX_CTR,
|
||||
OSMUX_PACKETS_TX_CTR,
|
||||
OSMUX_DROPPED_PACKETS_CTR,
|
||||
};
|
||||
|
||||
/* RTP per-connection statistics. Instances of the corresponding rate counter group
|
||||
* exist for the lifetime of an RTP connection.
|
||||
* Must be kept in sync with all_rtp_conn_rate_ctr_desc below */
|
||||
static const struct rate_ctr_desc mgcp_conn_osmux_rate_ctr_desc[] = {
|
||||
[OSMUX_CHUNKS_RX_CTR] = {"osmux:chunks_rx", "Inbound Osmux chunks."},
|
||||
[OSMUX_OCTETS_RX_CTR] = {"osmux:octets_rx", "Inbound Osmux octets."},
|
||||
[OSMUX_RTP_PACKETS_TX_CTR] = {"osmux:rtp_packets_tx", "Tx outbound RTP packets to encode as Osmux."},
|
||||
[OSMUX_RTP_PACKETS_TX_DROPPED_CTR] = {"osmux:rtp_packets_tx_dropped", "Dropped Tx outbound RTP packets to encode as Osmux."},
|
||||
[OSMUX_AMR_OCTETS_TX_CTR] = {"osmux:amr_octets_tx", "Tx outbound AMD payload octets."},
|
||||
};
|
||||
|
||||
/* Aggregated Osmux connection stats. These are updated when an Osmux connection is freed.
|
||||
* Must be kept in sync with mgcp_conn_osmux_rate_ctr_desc above */
|
||||
static const struct rate_ctr_desc all_osmux_conn_rate_ctr_desc[] = {
|
||||
[OSMUX_CHUNKS_RX_CTR] = {"all_osmux:chunks_rx", "Inbound Osmux chunks."},
|
||||
[OSMUX_OCTETS_RX_CTR] = {"all_osmux:octets_rx", "Inbound Osmux octets."},
|
||||
[OSMUX_RTP_PACKETS_TX_CTR] = {"all_osmux:rtp_packets_tx", "Tx outbound RTP packets to encode as Osmux."},
|
||||
[OSMUX_RTP_PACKETS_TX_DROPPED_CTR] = {"all_osmux:rtp_packets_tx_dropped", "Dropped Tx outbound RTP packets to encode as Osmux."},
|
||||
[OSMUX_AMR_OCTETS_TX_CTR] = {"all_osmux:amr_octets_tx", "Tx outbound AMD payload octets."},
|
||||
/* These last counters below do not exist in per-connection stats, only here: */
|
||||
[OSMUX_NUM_CONNECTIONS] = {"all_osmux:num_closed_conns", "Total number of osmux connections closed."},
|
||||
[OSMUX_PACKETS_RX_CTR] = {"all_osmux:packets_rx", "Total inbound UDP/Osmux packets."},
|
||||
[OSMUX_PACKETS_TX_CTR] = {"all_osmux:packets_tx", "Total outbound UDP/Osmux packets."},
|
||||
[OSMUX_DROPPED_PACKETS_CTR] = {"all_osmux:dropped_packets", "Dropped outbound UDP/Osmux packets."}
|
||||
};
|
||||
|
||||
/* Was conn configured to handle Osmux? */
|
||||
static inline bool mgcp_conn_rtp_is_osmux(const struct mgcp_conn_rtp *conn) {
|
||||
return conn->type == MGCP_RTP_OSMUX;
|
||||
}
|
||||
|
||||
/* Was conn configured to handle Osmux? */
|
||||
static inline bool mgcp_conn_rtp_is_iuup(const struct mgcp_conn_rtp *conn)
|
||||
{
|
||||
return conn->type == MGCP_RTP_IUUP;
|
||||
}
|
||||
|
||||
static inline struct mgcp_conn_rtp *mgcp_conn_get_conn_rtp(struct mgcp_conn *conn)
|
||||
{
|
||||
OSMO_ASSERT(conn->type == MGCP_CONN_TYPE_RTP);
|
||||
return &conn->u.rtp;
|
||||
}
|
||||
|
||||
struct mgcp_conn *mgcp_conn_alloc(void *ctx, struct mgcp_endpoint *endp,
|
||||
enum mgcp_conn_type type, char *name);
|
||||
void mgcp_conn_free(struct mgcp_conn *conn);
|
||||
int mgcp_conn_set_mode(struct mgcp_conn *conn, enum mgcp_connection_mode mode);
|
||||
char *mgcp_conn_dump(struct mgcp_conn *conn);
|
||||
struct mgcp_conn *mgcp_find_dst_conn(struct mgcp_conn *conn);
|
||||
void mgcp_conn_watchdog_kick(struct mgcp_conn *conn);
|
@@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
/* A 64k timeslot on an E1 line can be subdevied into the following
|
||||
* subslot combinations:
|
||||
*
|
||||
* subslot: offset:
|
||||
* [ ][ ][ 16k ][8k_subslot] 0
|
||||
* [ ][ 32k ][_subslot__][8k_subslot] 1
|
||||
* [ ][ subslot ][ 16k ][8k_subslot] 2
|
||||
* [ 64k ][__________][_subslot__][8k_subslot] 3
|
||||
* [ timeslot ][ ][ 16k ][8k_subslot] 4
|
||||
* [ ][ 32K ][_subslot__][8k_subslot] 5
|
||||
* [ ][ subslot ][ 16k ][8k_subslot] 6
|
||||
* [ ][ ][ subslot ][8k_subslot] 7
|
||||
*
|
||||
* Since overlapping assignment of subslots is not possible there is a limited
|
||||
* set of subslot assignments possible. The e1_rates array lists the possible
|
||||
* assignments as depicted above. Also each subslot assignment comes along with
|
||||
* a bit offset in the E1 bitstream. The e1_offsets arrays lists the bit
|
||||
* offsets. */
|
||||
static const uint8_t e1_rates[] = { 64, 32, 32, 16, 16, 16, 16, 8, 8, 8, 8, 8, 8, 8, 8 };
|
||||
static const uint8_t e1_offsets[] = { 0, 0, 4, 0, 2, 4, 6, 0, 1, 2, 3, 4, 5, 6, 7 };
|
||||
|
||||
int mgcp_e1_endp_equip(struct mgcp_endpoint *endp, uint8_t ts, uint8_t ss, uint8_t offs);
|
||||
void mgcp_e1_endp_update(struct mgcp_endpoint *endp);
|
||||
void mgcp_e1_endp_release(struct mgcp_endpoint *endp, uint8_t ts);
|
||||
int mgcp_e1_send_rtp(struct mgcp_endpoint *endp, struct mgcp_rtp_codec *codec, struct msgb *msg);
|
@@ -1,157 +0,0 @@
|
||||
/* Endpoint types */
|
||||
|
||||
/*
|
||||
* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Author: Philipp Maier
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/gsm/i460_mux.h>
|
||||
#include <osmocom/mgcp/mgcp_protocol.h>
|
||||
|
||||
struct sockaddr;
|
||||
struct mgcp_conn;
|
||||
struct mgcp_conn_rtp;
|
||||
struct mgcp_endpoint;
|
||||
|
||||
/* Number of E1 subslots (different variants, not all useable at the same time) */
|
||||
#define MGCP_ENDP_E1_SUBSLOTS 15
|
||||
|
||||
#define LOGPENDP(endp, cat, level, fmt, args...) \
|
||||
LOGP(cat, level, "endpoint:%s " fmt, \
|
||||
endp ? endp->name : "none", \
|
||||
## args)
|
||||
|
||||
enum rtp_proto {
|
||||
MGCP_PROTO_RTP,
|
||||
MGCP_PROTO_RTCP,
|
||||
};
|
||||
|
||||
struct osmo_rtp_msg_ctx {
|
||||
enum rtp_proto proto;
|
||||
struct mgcp_conn_rtp *conn_src;
|
||||
struct osmo_sockaddr *from_addr;
|
||||
};
|
||||
|
||||
#define OSMO_RTP_MSG_CTX(MSGB) ((struct osmo_rtp_msg_ctx*)(MSGB)->cb)
|
||||
|
||||
osmo_static_assert(sizeof(((struct msgb*)0)->cb) >= sizeof(struct osmo_rtp_msg_ctx), osmo_rtp_msg_ctx_fits_in_msgb_cb);
|
||||
|
||||
/* Callback type for RTP dispatcher functions (e.g mgcp_dispatch_rtp_bridge_cb, see below).
|
||||
* The OSMO_RTP_MSG_CTX() should be set appropriately on the msg. */
|
||||
typedef int (*mgcp_dispatch_rtp_cb) (struct msgb *msg);
|
||||
|
||||
/* Callback type for endpoint specific cleanup actions. This function
|
||||
* is automatically executed when a connection is freed (see mgcp_conn_free()
|
||||
* in mgcp_conn.c). Depending on the type of the endpoint there may be endpoint
|
||||
* specific things to take care of once a connection has been removed. */
|
||||
typedef void (*mgcp_cleanup_cp) (struct mgcp_endpoint *endp,
|
||||
struct mgcp_conn *conn);
|
||||
|
||||
/*! MGCP endpoint properties */
|
||||
struct mgcp_endpoint_type {
|
||||
/*! maximum number of connections */
|
||||
int max_conns;
|
||||
|
||||
/*! callback that defines how to dispatch incoming RTP data */
|
||||
mgcp_dispatch_rtp_cb dispatch_rtp_cb;
|
||||
|
||||
/*! callback that implements endpoint specific cleanup actions */
|
||||
mgcp_cleanup_cp cleanup_cb;
|
||||
};
|
||||
|
||||
/*! MGCP endpoint typeset */
|
||||
struct mgcp_endpoint_typeset {
|
||||
struct mgcp_endpoint_type rtp;
|
||||
struct mgcp_endpoint_type e1;
|
||||
};
|
||||
|
||||
/*! static MGCP endpoint typeset (pre-initalized, read-only) */
|
||||
extern const struct mgcp_endpoint_typeset ep_typeset;
|
||||
|
||||
/*! MGCP endpoint model */
|
||||
struct mgcp_endpoint {
|
||||
|
||||
/*! Unique endpoint name, used for addressing via MGCP */
|
||||
char *name;
|
||||
|
||||
/*! Call identifier string (as supplied by the call agant) */
|
||||
char *callid;
|
||||
|
||||
/*! Local connection options (see mgcp_internal.h) */
|
||||
struct mgcp_lco local_options;
|
||||
|
||||
/*! List of struct mgcp_conn, of the connections active on this endpoint */
|
||||
struct llist_head conns;
|
||||
|
||||
/*! Backpointer to the trunk this endpoint belongs to */
|
||||
struct mgcp_trunk *trunk;
|
||||
|
||||
/*! Endpoint properties (see above) */
|
||||
const struct mgcp_endpoint_type *type;
|
||||
|
||||
/*! Last MGCP transmission (in case re-transmission is required) */
|
||||
char *last_trans;
|
||||
|
||||
/*! Last MGCP response (in case re-transmission is required) */
|
||||
char *last_response;
|
||||
|
||||
/*! MGCP_X_OSMO_IGN_* flags from 'X-Osmo-IGN:' header */
|
||||
uint32_t x_osmo_ign;
|
||||
|
||||
/* E1 specific */
|
||||
struct {
|
||||
struct osmo_i460_schan_desc scd;
|
||||
struct osmo_i460_subchan *schan;
|
||||
struct osmo_fsm_inst *trau_sync_fi;
|
||||
struct osmo_trau2rtp_state *trau_rtp_st;
|
||||
uint8_t last_amr_ft;
|
||||
struct mgcp_rtp_codec *last_codec;
|
||||
} e1;
|
||||
|
||||
};
|
||||
|
||||
struct mgcp_endpoint *mgcp_endp_alloc(struct mgcp_trunk *trunk, unsigned int index);
|
||||
int mgcp_endp_claim(struct mgcp_endpoint *endp, const char *callid);
|
||||
void mgcp_endp_update(struct mgcp_endpoint *endp);
|
||||
bool mgcp_endp_is_wildcarded(const char *epname);
|
||||
bool mgcp_endp_is_null(const char *epname);
|
||||
struct mgcp_endpoint *mgcp_endp_by_name_trunk(int *cause, const char *epname,
|
||||
const struct mgcp_trunk *trunk);
|
||||
struct mgcp_endpoint *mgcp_endp_by_name(int *cause, const char *epname,
|
||||
struct mgcp_config *cfg);
|
||||
bool mgcp_endp_avail(const struct mgcp_endpoint *endp);
|
||||
unsigned int mgcp_endp_num_conns(const struct mgcp_endpoint *endp);
|
||||
bool mgcp_endp_is_full(const struct mgcp_endpoint *endp);
|
||||
void mgcp_endp_add_conn(struct mgcp_endpoint *endp, struct mgcp_conn *conn);
|
||||
void mgcp_endp_remove_conn(struct mgcp_endpoint *endp, struct mgcp_conn *conn);
|
||||
void mgcp_endp_free_conn_oldest(struct mgcp_endpoint *endp);
|
||||
void mgcp_endp_free_conn_all(struct mgcp_endpoint *endp);
|
||||
void mgcp_endp_strip_name(char *epname_stripped, const char *epname,
|
||||
const struct mgcp_trunk *trunk);
|
||||
struct mgcp_endpoint *mgcp_endp_find_specific(const char *epname,
|
||||
const struct mgcp_trunk *trunk);
|
||||
void mgcp_endp_release(struct mgcp_endpoint *endp);
|
||||
|
||||
struct mgcp_conn *mgcp_endp_get_conn(struct mgcp_endpoint *endp, const char *id);
|
||||
struct mgcp_conn *mgcp_endp_get_conn_oldest(struct mgcp_endpoint *endp);
|
||||
struct mgcp_conn_rtp *mgcp_endp_get_conn_rtp(struct mgcp_endpoint *endp,
|
||||
const char *id);
|
@@ -1,33 +0,0 @@
|
||||
/* IuUP connection functionalitites */
|
||||
|
||||
/*
|
||||
* (C) 2021 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Author: Pau Espin Pedrol
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <osmocom/core/msgb.h>
|
||||
|
||||
struct mgcp_conn_rtp;
|
||||
|
||||
int mgcp_conn_iuup_init(struct mgcp_conn_rtp *conn_rtp);
|
||||
void mgcp_conn_iuup_cleanup(struct mgcp_conn_rtp *conn_rtp);
|
||||
int mgcp_conn_iuup_dispatch_rtp(struct msgb *msg);
|
||||
int mgcp_conn_iuup_send_rtp(struct mgcp_conn_rtp *conn_src_rtp, struct mgcp_conn_rtp *conn_dest_rtp, struct msgb *msg);
|
||||
int mgcp_conn_iuup_send_dummy(struct mgcp_conn_rtp *conn_rtp);
|
@@ -1,60 +0,0 @@
|
||||
/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
|
||||
/* Message parser/generator utilities */
|
||||
|
||||
/*
|
||||
* (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009-2012 by On-Waves
|
||||
* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <osmocom/mgcp/mgcp_common.h>
|
||||
|
||||
struct mgcp_conn;
|
||||
struct mgcp_parse_data;
|
||||
struct mgcp_endpoint;
|
||||
struct mgcp_trunk;
|
||||
|
||||
void mgcp_disp_msg(unsigned char *message, unsigned int len, char *preamble);
|
||||
|
||||
enum mgcp_connection_mode mgcp_parse_conn_mode(const char *msg);
|
||||
|
||||
int mgcp_parse_header(struct mgcp_parse_data *pdata, char *data);
|
||||
int mgcp_parse_hdr_pars(struct mgcp_parse_data *pdata);
|
||||
|
||||
int mgcp_parse_osmux_cid(const char *line);
|
||||
|
||||
bool mgcp_check_param(const char *line);
|
||||
|
||||
int mgcp_verify_call_id(struct mgcp_endpoint *endp, const char *callid);
|
||||
|
||||
int mgcp_verify_ci(struct mgcp_endpoint *endp, const char *conn_id);
|
||||
|
||||
char *mgcp_strline(char *str, char **saveptr);
|
||||
|
||||
#define for_each_line(line, save)\
|
||||
for (line = mgcp_strline(NULL, &save); line;\
|
||||
line = mgcp_strline(NULL, &save))
|
||||
|
||||
#define for_each_non_empty_line(line, save)\
|
||||
for (line = strtok_r(NULL, "\r\n", &save); line;\
|
||||
line = strtok_r(NULL, "\r\n", &save))
|
@@ -1,125 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <osmocom/core/socket.h>
|
||||
#include <osmocom/core/osmo_io.h>
|
||||
|
||||
#include <osmocom/mgcp/mgcp.h>
|
||||
|
||||
/* The following constant defines an RTP dummy payload that is used for
|
||||
* "UDP Hole Punching" (NAT) */
|
||||
#define MGCP_DUMMY_LOAD 0x23
|
||||
static const char rtp_dummy_payload[] = { MGCP_DUMMY_LOAD };
|
||||
|
||||
/* Check if the data in a given message buffer matches the rtp dummy payload
|
||||
* defined above */
|
||||
#define mgcp_is_rtp_dummy_payload(msg) \
|
||||
(msgb_length(msg) == sizeof(rtp_dummy_payload) && \
|
||||
memcmp(msgb_data(msg), rtp_dummy_payload, sizeof(rtp_dummy_payload)) == 0)
|
||||
|
||||
#define RTP_BUF_SIZE 4096
|
||||
|
||||
struct mgcp_rtp_stream_state {
|
||||
uint32_t ssrc;
|
||||
uint16_t last_seq;
|
||||
uint32_t last_timestamp;
|
||||
struct rate_ctr *err_ts_ctr;
|
||||
int32_t last_tsdelta;
|
||||
uint32_t last_arrival_time;
|
||||
};
|
||||
|
||||
struct mgcp_rtp_state {
|
||||
/* has this state structure been initialized? */
|
||||
int initialized;
|
||||
|
||||
struct {
|
||||
/* are we patching the SSRC value? */
|
||||
bool patch_ssrc;
|
||||
/* original SSRC (to which we shall patch any different SSRC) */
|
||||
uint32_t orig_ssrc;
|
||||
/* offset to apply on the sequence number */
|
||||
int seq_offset;
|
||||
/* offset to apply on the timestamp number */
|
||||
int32_t timestamp_offset;
|
||||
} patch;
|
||||
|
||||
/* duration of a packet (FIXME: in which unit?) */
|
||||
uint32_t packet_duration;
|
||||
|
||||
/* Note: These states are not continuously updated, they serve as an
|
||||
* information source to patch certain values in the RTP header. Do
|
||||
* not use this state if constantly updated data about the RTP stream
|
||||
* is needed. (see also mgcp_patch_and_count() */
|
||||
struct mgcp_rtp_stream_state in_stream;
|
||||
struct mgcp_rtp_stream_state out_stream;
|
||||
|
||||
/* jitter and packet loss calculation */
|
||||
struct {
|
||||
int initialized;
|
||||
uint16_t base_seq;
|
||||
uint16_t max_seq;
|
||||
uint32_t ssrc;
|
||||
uint32_t jitter;
|
||||
int32_t transit;
|
||||
int cycles;
|
||||
} stats;
|
||||
|
||||
/* Alternative values for RTP tx, in case no sufficient header
|
||||
* information is available so the header needs to be generated
|
||||
* locally (when just forwarding packets, the header of incoming
|
||||
* data is just re-used) */
|
||||
uint16_t alt_rtp_tx_sequence;
|
||||
uint32_t alt_rtp_tx_ssrc;
|
||||
};
|
||||
|
||||
struct mgcp_rtp_tap {
|
||||
/* is this tap active (1) or not (0) */
|
||||
int enabled;
|
||||
/* IP/port to which we're forwarding the tapped data */
|
||||
struct osmo_sockaddr forward;
|
||||
};
|
||||
|
||||
struct mgcp_conn;
|
||||
|
||||
int mgcp_send(struct mgcp_endpoint *endp, int is_rtp, struct osmo_sockaddr *addr,
|
||||
struct msgb *msg, struct mgcp_conn_rtp *conn_src,
|
||||
struct mgcp_conn_rtp *conn_dst);
|
||||
int mgcp_send_dummy(struct mgcp_endpoint *endp, struct mgcp_conn_rtp *conn);
|
||||
int mgcp_dispatch_rtp_bridge_cb(struct msgb *msg);
|
||||
void mgcp_cleanup_rtp_bridge_cb(struct mgcp_endpoint *endp, struct mgcp_conn *conn);
|
||||
int mgcp_dispatch_e1_bridge_cb(struct msgb *msg);
|
||||
void mgcp_cleanup_e1_bridge_cb(struct mgcp_endpoint *endp, struct mgcp_conn *conn);
|
||||
int mgcp_conn_rtp_bind_rtp_ports(struct mgcp_conn_rtp *conn, int rtp_port);
|
||||
void mgcp_patch_and_count(const struct mgcp_endpoint *endp,
|
||||
struct mgcp_rtp_state *state,
|
||||
struct mgcp_rtp_end *rtp_end,
|
||||
struct osmo_sockaddr *addr, struct msgb *msg);
|
||||
int mgcp_get_local_addr(char *addr, struct mgcp_conn_rtp *conn);
|
||||
|
||||
/* payload processing default functions */
|
||||
int mgcp_rtp_processing_default(struct mgcp_endpoint *endp, struct mgcp_rtp_end *dst_end, struct msgb *msg);
|
||||
|
||||
int mgcp_setup_rtp_processing_default(struct mgcp_endpoint *endp,
|
||||
struct mgcp_conn_rtp *conn_dst,
|
||||
struct mgcp_conn_rtp *conn_src);
|
||||
|
||||
void mgcp_get_net_downlink_format_default(struct mgcp_endpoint *endp,
|
||||
const struct mgcp_rtp_codec **codec,
|
||||
const char **fmtp_extra,
|
||||
struct mgcp_conn_rtp *conn);
|
||||
|
||||
/* internal RTP Annex A counting */
|
||||
void mgcp_rtp_annex_count(const struct mgcp_endpoint *endp, struct mgcp_rtp_state *state,
|
||||
const uint16_t seq, const int32_t transit,
|
||||
const uint32_t ssrc, const bool marker_bit);
|
||||
|
||||
void rtpconn_rate_ctr_add(struct mgcp_conn_rtp *conn_rtp, struct mgcp_endpoint *endp,
|
||||
int id, int inc);
|
||||
void rtpconn_rate_ctr_inc(struct mgcp_conn_rtp *conn_rtp, struct mgcp_endpoint *endp,
|
||||
int id);
|
||||
void forward_data_tap(struct osmo_io_fd *iofd, struct mgcp_rtp_tap *tap, struct msgb *msg);
|
||||
uint32_t mgcp_get_current_ts(unsigned codec_rate);
|
||||
|
||||
int amr_oa_bwe_convert(struct mgcp_endpoint *endp, struct msgb *msg, bool target_is_oa);
|
@@ -1,96 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/core/socket.h>
|
||||
#include <osmocom/mgcp/mgcp_common.h>
|
||||
#include <osmocom/mgcp/mgcp_codec.h>
|
||||
|
||||
|
||||
#define MGCP_PARSE_SDP_PTIME_UNSET (-1)
|
||||
#define MGCP_PARSE_SDP_MAXPTIME_UNSET (-1)
|
||||
#define MGCP_PARSE_SDP_RTP_PORT_UNSET (0)
|
||||
|
||||
struct mgcp_parse_sdp {
|
||||
int ptime;
|
||||
int maxptime;
|
||||
int rtp_port;
|
||||
struct osmo_sockaddr rem_addr; /* Only IP address, port is in rtp_port above */
|
||||
struct mgcp_rtp_codecset cset;
|
||||
};
|
||||
|
||||
static inline void mgcp_parse_sdp_init(struct mgcp_parse_sdp *sdp)
|
||||
{
|
||||
sdp->ptime = MGCP_PARSE_SDP_PTIME_UNSET;
|
||||
sdp->maxptime = MGCP_PARSE_SDP_MAXPTIME_UNSET;
|
||||
sdp->rtp_port = MGCP_PARSE_SDP_RTP_PORT_UNSET;
|
||||
sdp->rem_addr = (struct osmo_sockaddr){ .u.sa.sa_family = AF_UNSPEC };
|
||||
mgcp_codecset_reset(&sdp->cset);
|
||||
}
|
||||
|
||||
|
||||
#define MGCP_PARSE_HDR_PARS_OSMUX_CID_UNSET (-2)
|
||||
#define MGCP_PARSE_HDR_PARS_OSMUX_CID_WILDCARD (-1)
|
||||
|
||||
struct mgcp_parse_hdr_pars {
|
||||
const char *local_options;
|
||||
const char *callid;
|
||||
const char *connid;
|
||||
enum mgcp_connection_mode mode;
|
||||
int remote_osmux_cid;
|
||||
bool have_sdp;
|
||||
/*! MGCP_X_OSMO_IGN_* flags from 'X-Osmo-IGN:' header */
|
||||
uint32_t x_osmo_ign;
|
||||
};
|
||||
|
||||
static inline void mgcp_parse_hdr_pars_init(struct mgcp_parse_hdr_pars *hpars)
|
||||
{
|
||||
*hpars = (struct mgcp_parse_hdr_pars){
|
||||
.local_options = NULL,
|
||||
.callid = NULL,
|
||||
.connid = NULL,
|
||||
.mode = MGCP_CONN_NONE,
|
||||
.remote_osmux_cid = MGCP_PARSE_HDR_PARS_OSMUX_CID_UNSET,
|
||||
.have_sdp = false,
|
||||
.x_osmo_ign = 0,
|
||||
};
|
||||
}
|
||||
|
||||
/* Internal structure while parsing a request */
|
||||
struct mgcp_parse_data {
|
||||
struct mgcp_config *cfg;
|
||||
char *save;
|
||||
/* MGCP Header: */
|
||||
char *epname;
|
||||
char *trans;
|
||||
struct mgcp_parse_hdr_pars hpars;
|
||||
/* MGCP Body: */
|
||||
struct mgcp_parse_sdp sdp;
|
||||
};
|
||||
|
||||
/* Local connection options */
|
||||
struct mgcp_lco {
|
||||
char *string;
|
||||
char *codec;
|
||||
int pkt_period_min; /* time in ms */
|
||||
int pkt_period_max; /* time in ms */
|
||||
};
|
||||
|
||||
char *mgcp_debug_get_last_endpoint_name(void);
|
||||
|
||||
char *get_lco_identifier(const char *options);
|
||||
int check_local_cx_options(void *ctx, const char *options);
|
||||
|
||||
struct mgcp_rtp_end;
|
||||
struct mgcp_endpoint;
|
||||
|
||||
uint32_t mgcp_rtp_packet_duration(const struct mgcp_endpoint *endp,
|
||||
const struct mgcp_rtp_end *rtp);
|
||||
|
||||
extern const struct value_string mgcp_connection_mode_strs[];
|
||||
static inline const char *mgcp_cmode_name(enum mgcp_connection_mode mode)
|
||||
{
|
||||
return get_value_string(mgcp_connection_mode_strs, mode);
|
||||
}
|
@@ -1,109 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
/* Global MCGP general rate counters */
|
||||
enum {
|
||||
MGCP_GENERAL_RX_MSGS_TOTAL,
|
||||
MGCP_GENERAL_RX_MSGS_RETRANSMITTED,
|
||||
MGCP_GENERAL_RX_MSGS_HANDLED,
|
||||
MGCP_GENERAL_RX_MSGS_UNHANDLED,
|
||||
MGCP_GENERAL_RX_FAIL_MSG_PARSE,
|
||||
MGCP_GENERAL_RX_FAIL_NO_ENDPOINT,
|
||||
};
|
||||
|
||||
/* Trunk-global MCGP CRCX related rate counters */
|
||||
enum {
|
||||
MGCP_CRCX_SUCCESS,
|
||||
MGCP_CRCX_FAIL_BAD_ACTION,
|
||||
MGCP_CRCX_FAIL_UNHANDLED_PARAM,
|
||||
MGCP_CRCX_FAIL_MISSING_CALLID,
|
||||
MGCP_CRCX_FAIL_INVALID_MODE,
|
||||
MGCP_CRCX_FAIL_LIMIT_EXCEEDED,
|
||||
MGCP_CRCX_FAIL_UNKNOWN_CALLID,
|
||||
MGCP_CRCX_FAIL_ALLOC_CONN,
|
||||
MGCP_CRCX_FAIL_NO_REMOTE_CONN_DESC,
|
||||
MGCP_CRCX_FAIL_START_RTP,
|
||||
MGCP_CRCX_FAIL_NO_OSMUX,
|
||||
MGCP_CRCX_FAIL_INVALID_CONN_OPTIONS,
|
||||
MGCP_CRCX_FAIL_CODEC_NEGOTIATION,
|
||||
MGCP_CRCX_FAIL_BIND_PORT,
|
||||
MGCP_CRCX_FAIL_AVAIL,
|
||||
MGCP_CRCX_FAIL_CLAIM,
|
||||
};
|
||||
|
||||
/* Trunk-global MCGP MDCX related rate counters */
|
||||
enum {
|
||||
MGCP_MDCX_SUCCESS,
|
||||
MGCP_MDCX_FAIL_WILDCARD,
|
||||
MGCP_MDCX_FAIL_NO_CONN,
|
||||
MGCP_MDCX_FAIL_INVALID_CALLID,
|
||||
MGCP_MDCX_FAIL_INVALID_CONNID,
|
||||
MGCP_MDCX_FAIL_UNHANDLED_PARAM,
|
||||
MGCP_MDCX_FAIL_NO_CONNID,
|
||||
MGCP_MDCX_FAIL_CONN_NOT_FOUND,
|
||||
MGCP_MDCX_FAIL_INVALID_MODE,
|
||||
MGCP_MDCX_FAIL_INVALID_CONN_OPTIONS,
|
||||
MGCP_MDCX_FAIL_NO_REMOTE_CONN_DESC,
|
||||
MGCP_MDCX_FAIL_START_RTP,
|
||||
MGCP_MDCX_FAIL_AVAIL,
|
||||
};
|
||||
|
||||
/* Trunk-global MCGP DLCX related rate counters */
|
||||
enum {
|
||||
MGCP_DLCX_SUCCESS,
|
||||
MGCP_DLCX_FAIL_NO_CONN,
|
||||
MGCP_DLCX_FAIL_INVALID_CALLID,
|
||||
MGCP_DLCX_FAIL_INVALID_CONNID,
|
||||
MGCP_DLCX_FAIL_UNHANDLED_PARAM,
|
||||
MGCP_DLCX_FAIL_AVAIL,
|
||||
};
|
||||
|
||||
/* Trunk-global E1 related counters */
|
||||
enum {
|
||||
E1_I460_TRAU_RX_FAIL_CTR,
|
||||
E1_I460_TRAU_TX_FAIL_CTR,
|
||||
E1_I460_TRAU_MUX_EMPTY_CTR,
|
||||
};
|
||||
|
||||
/* NOTE: When adding counters, also the dump_ratectr_* routines in vty.c must be updated. */
|
||||
|
||||
struct mgcp_ratectr_global {
|
||||
/* Rate counter group which contains stats for generic MGCP events. */
|
||||
struct rate_ctr_group *mgcp_general_ctr_group;
|
||||
};
|
||||
|
||||
struct mgcp_ratectr_trunk {
|
||||
/* Rate counter group which contains stats for processed CRCX commands. */
|
||||
struct rate_ctr_group *mgcp_crcx_ctr_group;
|
||||
/* Rate counter group which contains stats for processed MDCX commands. */
|
||||
struct rate_ctr_group *mgcp_mdcx_ctr_group;
|
||||
/* Rate counter group which contains stats for processed DLCX commands. */
|
||||
struct rate_ctr_group *mgcp_dlcx_ctr_group;
|
||||
/* Rate counter group which aggregates stats of individual RTP connections. */
|
||||
struct rate_ctr_group *all_rtp_conn_stats;
|
||||
/* Rate counter group which aggregates stats of individual Osmux connections. */
|
||||
struct rate_ctr_group *all_osmux_conn_stats;
|
||||
/* Rate counter group which contains stats for E1 events (only valid for E1 trunks) */
|
||||
struct rate_ctr_group *e1_stats;
|
||||
};
|
||||
|
||||
struct mgcp_config;
|
||||
struct mgcp_trunk;
|
||||
|
||||
int mgcp_ratectr_global_alloc(struct mgcp_config *cfg);
|
||||
void mgcp_ratectr_global_free(struct mgcp_config *cfg);
|
||||
int mgcp_ratectr_trunk_alloc(struct mgcp_trunk *trunk);
|
||||
void mgcp_ratectr_trunk_free(struct mgcp_trunk *trunk);
|
||||
|
||||
/* Trunk-global common stat items */
|
||||
enum {
|
||||
TRUNK_STAT_ENDPOINTS_TOTAL,
|
||||
TRUNK_STAT_ENDPOINTS_USED,
|
||||
};
|
||||
|
||||
struct mgcp_stat_trunk {
|
||||
/* Stat item group which contains general status values of the trunk. */
|
||||
struct osmo_stat_item_group *common;
|
||||
};
|
||||
|
||||
int mgcp_stat_trunk_alloc(struct mgcp_trunk *trunk);
|
||||
void mgcp_stat_trunk_free(struct mgcp_trunk *trunk);
|
@@ -1,53 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <osmocom/core/socket.h>
|
||||
#include <osmocom/core/osmo_io.h>
|
||||
|
||||
#include <osmocom/mgcp/mgcp.h>
|
||||
#include <osmocom/mgcp/mgcp_codec.h>
|
||||
|
||||
/* 'mgcp_rtp_end': basically a wrapper around the RTP+RTCP ports */
|
||||
struct mgcp_rtp_end {
|
||||
struct mgcp_conn_rtp *conn_rtp; /* backpointer */
|
||||
/* remote IP address of the RTP socket */
|
||||
struct osmo_sockaddr addr;
|
||||
|
||||
/* in network byte order */
|
||||
uint16_t rtcp_port;
|
||||
|
||||
struct mgcp_rtp_codecset cset;
|
||||
|
||||
/* per endpoint data */
|
||||
int frames_per_packet;
|
||||
uint32_t packet_duration_ms;
|
||||
int maximum_packet_time; /* -1: not set */
|
||||
/* are we transmitting packets (true) or dropping (false) outbound packets */
|
||||
bool output_enabled;
|
||||
/* FIXME: This parameter can be set + printed, but is nowhere used! */
|
||||
int force_output_ptime;
|
||||
|
||||
/* RTP patching */
|
||||
bool force_constant_ssrc;
|
||||
/* should we perform align_rtp_timestamp_offset() (1) or not (0) */
|
||||
int force_aligned_timing;
|
||||
bool rfc5993_hr_convert;
|
||||
|
||||
/* Each end has a separate socket for RTP and RTCP */
|
||||
struct osmo_io_fd *rtp;
|
||||
struct osmo_io_fd *rtcp;
|
||||
|
||||
/* local UDP port number of the RTP socket; RTCP is +1 */
|
||||
int local_port;
|
||||
/* where the endpoint RTP connection binds to, set during CRCX and
|
||||
* possibly updated during MDCX */
|
||||
char local_addr[INET6_ADDRSTRLEN];
|
||||
};
|
||||
|
||||
void mgcp_rtp_end_init(struct mgcp_rtp_end *end, struct mgcp_conn_rtp *conn_rtp);
|
||||
void mgcp_rtp_end_cleanup(struct mgcp_rtp_end *end);
|
||||
void mgcp_rtp_end_set_packet_duration_ms(struct mgcp_rtp_end *end, uint32_t packet_duration_ms);
|
||||
bool mgcp_rtp_end_remote_addr_available(const struct mgcp_rtp_end *rtp_end);
|
||||
void mgcp_rtp_end_free_port(struct mgcp_rtp_end *end);
|
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* SDP generation and parsing
|
||||
*
|
||||
* (C) 2009-2015 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009-2014 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 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
struct mgcp_parse_data;
|
||||
|
||||
int mgcp_parse_sdp_data(struct mgcp_parse_data *p);
|
||||
|
||||
int mgcp_write_response_sdp(const struct mgcp_endpoint *endp,
|
||||
const struct mgcp_conn_rtp *conn, struct msgb *sdp,
|
||||
const char *addr);
|
@@ -1,35 +0,0 @@
|
||||
/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
|
||||
/* The statistics generator */
|
||||
|
||||
/*
|
||||
* (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009-2012 by On-Waves
|
||||
* (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
void mgcp_format_stats(char *str, size_t str_len, struct mgcp_conn *conn);
|
||||
|
||||
/* Exposed for test purposes only, do not use actively */
|
||||
void calc_loss(struct mgcp_conn_rtp *conn, uint32_t *expected, int *loss);
|
||||
|
||||
/* Exposed for test purposes only, do not use actively */
|
||||
uint32_t calc_jitter(struct mgcp_rtp_state *);
|
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* (C) 2021 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Author: Eric Wild
|
||||
*
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct spsc {
|
||||
atomic_uint readptr;
|
||||
atomic_uint writeptr;
|
||||
|
||||
int efd_r, efd_w; /* eventfds used to block/notify readers/writers */
|
||||
|
||||
int count;
|
||||
int size_per_buf;
|
||||
|
||||
void *buf; /* buffer size count*size_per_buf */
|
||||
uintptr_t data[0]; /* count sized array of pointers to size_per_buf chunks in buf array*/
|
||||
};
|
||||
|
||||
struct qchan {
|
||||
struct spsc *a;
|
||||
struct spsc *b;
|
||||
};
|
||||
|
||||
bool spsc_push(struct spsc *q, void *elem);
|
||||
bool spsc_pop(struct spsc *q, void *elem);
|
||||
ssize_t spsc_prep_pop(struct spsc *q);
|
||||
int spsc_get_a_rdfd(struct qchan *q);
|
||||
|
||||
struct qchan spsc_chan_init(void *talloc_ctx, unsigned int count, unsigned int size_per_buf);
|
||||
struct qchan spsc_chan_init_ex(void *talloc_ctx, unsigned int count, unsigned int size_per_buf, bool blockr_a,
|
||||
bool blockw_a, bool blockr_b, bool blockw_b);
|
||||
void spsc_chan_close(struct qchan *q);
|
@@ -1,87 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <osmocom/gsm/i460_mux.h>
|
||||
#include <osmocom/abis/e1_input.h>
|
||||
#include <osmocom/mgcp/mgcp_conn.h>
|
||||
#include <osmocom/mgcp/mgcp_network.h>
|
||||
#include <osmocom/mgcp/mgcp_ratectr.h>
|
||||
|
||||
#define LOGPTRUNK(trunk, cat, level, fmt, args...) \
|
||||
LOGP(cat, level, "trunk:%u " fmt, \
|
||||
trunk ? trunk->trunk_nr : 0, \
|
||||
## args)
|
||||
|
||||
enum mgcp_trunk_type {
|
||||
MGCP_TRUNK_VIRTUAL,
|
||||
MGCP_TRUNK_E1,
|
||||
};
|
||||
|
||||
extern const struct value_string mgcp_trunk_type_strs[];
|
||||
static inline const char *mgcp_trunk_type_strs_str(enum mgcp_trunk_type val)
|
||||
{ return get_value_string(mgcp_trunk_type_strs, val); }
|
||||
|
||||
struct mgcp_trunk {
|
||||
struct llist_head entry;
|
||||
|
||||
struct mgcp_config *cfg;
|
||||
|
||||
unsigned int trunk_nr;
|
||||
enum mgcp_trunk_type trunk_type;
|
||||
|
||||
int audio_send_ptime;
|
||||
int audio_send_name;
|
||||
|
||||
int omit_rtcp;
|
||||
int keepalive_interval;
|
||||
|
||||
/* RTP patching */
|
||||
bool force_constant_ssrc;
|
||||
int force_aligned_timing;
|
||||
bool rfc5993_hr_convert;
|
||||
|
||||
/* spec handling */
|
||||
int force_realloc;
|
||||
|
||||
/* timer */
|
||||
struct osmo_timer_list keepalive_timer;
|
||||
|
||||
/* When set, incoming RTP packets are not filtered
|
||||
* when ports and ip-address do not match (debug) */
|
||||
int rtp_accept_all;
|
||||
|
||||
unsigned int number_endpoints;
|
||||
struct mgcp_endpoint **endpoints;
|
||||
|
||||
/* rate counters and stat items to measure the trunks overall performance and health */
|
||||
struct mgcp_ratectr_trunk ratectr;
|
||||
struct mgcp_stat_trunk stats;
|
||||
|
||||
union {
|
||||
/* Virtual trunk specific */
|
||||
struct {
|
||||
unsigned int vty_number_endpoints;
|
||||
} v;
|
||||
/* E1 specific */
|
||||
struct {
|
||||
unsigned int vty_line_nr;
|
||||
uint8_t ts_usecount[NUM_E1_TS-1];
|
||||
struct osmo_i460_timeslot i460_ts[NUM_E1_TS-1];
|
||||
/* Note: on an E1 line TS 0 is devoted to framing and
|
||||
* alignment and therefore only NUM_E1_TS-1 timeslots
|
||||
* are available for traffic. */
|
||||
} e1;
|
||||
};
|
||||
};
|
||||
|
||||
struct mgcp_trunk *mgcp_trunk_alloc(struct mgcp_config *cfg, enum mgcp_trunk_type ttype, unsigned int nr);
|
||||
int mgcp_trunk_equip(struct mgcp_trunk *trunk);
|
||||
struct mgcp_trunk *mgcp_trunk_by_num(const struct mgcp_config *cfg, enum mgcp_trunk_type ttype, unsigned int nr);
|
||||
struct mgcp_trunk *mgcp_trunk_by_name(const struct mgcp_config *cfg, const char *epname);
|
||||
int e1_trunk_nr_from_epname(unsigned int *trunk_nr, const char *epname);
|
||||
struct mgcp_trunk *mgcp_trunk_by_line_num(const struct mgcp_config *cfg, unsigned int num);
|
||||
int mgcp_trunk_allocate_conn_rtp_ports(struct mgcp_trunk *trunk, struct mgcp_conn_rtp *conn_rtp);
|
||||
|
||||
/* The virtual trunk is always created on trunk id 0 for historical reasons,
|
||||
* use this define constant as ID when allocating a virtual trunk. Other
|
||||
* trunks may be assigned with arbritrary id numbers */
|
||||
#define MGCP_VIRT_TRUNK_ID 0
|
@@ -1,41 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <osmocom/core/socket.h>
|
||||
|
||||
#include <osmocom/netif/osmux.h>
|
||||
struct mgcp_conn_rtp;
|
||||
struct mgcp_trunk;
|
||||
struct mgcp_endpoint;
|
||||
struct mgcp_conn_rtp;
|
||||
|
||||
int osmux_init(struct mgcp_trunk *trunk);
|
||||
int osmux_init_conn(struct mgcp_conn_rtp *conn);
|
||||
int conn_osmux_enable(struct mgcp_conn_rtp *conn);
|
||||
void conn_osmux_disable(struct mgcp_conn_rtp *conn);
|
||||
int conn_osmux_event_rx_crcx_mdcx(struct mgcp_conn_rtp *conn);
|
||||
int conn_osmux_send_rtp(struct mgcp_conn_rtp *conn, struct msgb *msg);
|
||||
int osmux_send_dummy(struct mgcp_conn_rtp *conn);
|
||||
|
||||
void osmux_cid_pool_get(uint8_t osmux_cid);
|
||||
int osmux_cid_pool_get_next(void);
|
||||
void osmux_cid_pool_put(uint8_t osmux_cid);
|
||||
bool osmux_cid_pool_allocated(uint8_t osmux_cid);
|
||||
int osmux_cid_pool_count_used(void);
|
||||
|
||||
enum osmux_state {
|
||||
OSMUX_STATE_DISABLED = 0, /* Osmux not being currently used by endp */
|
||||
OSMUX_STATE_ACTIVATING, /* Osmux was accepted in MGCP CRCX ACK. It can now be enabled by \ref conn_osmux_enable. */
|
||||
OSMUX_STATE_ENABLED, /* Osmux was initialized by \ref conn_osmux_enable and can process frames */
|
||||
};
|
||||
|
||||
extern const struct value_string osmux_state_strs[];
|
||||
static inline const char *osmux_state_str(enum osmux_state val)
|
||||
{ return get_value_string(osmux_state_strs, val); }
|
||||
|
||||
enum osmux_usage {
|
||||
OSMUX_USAGE_OFF = 0,
|
||||
OSMUX_USAGE_ON = 1,
|
||||
OSMUX_USAGE_ONLY = 2,
|
||||
};
|
@@ -1,12 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <osmocom/vty/command.h>
|
||||
|
||||
enum mgcp_vty_node {
|
||||
MGCP_NODE = _LAST_OSMOVTY_NODE + 1,
|
||||
TRUNK_NODE,
|
||||
};
|
||||
|
||||
enum mgw_vty_cmd_attr {
|
||||
MGW_CMD_ATTR_NEWCONN = 0,
|
||||
};
|
@@ -1,14 +0,0 @@
|
||||
BUILT_SOURCES = \
|
||||
mgcp_common.h \
|
||||
$(NULL)
|
||||
|
||||
noinst_HEADERS = \
|
||||
mgcp_client_internal.h \
|
||||
mgcp_client_pool_internal.h \
|
||||
$(NULL)
|
||||
|
||||
mgcp_common.h: $(top_srcdir)/include/osmocom/mgcp/mgcp_common.h
|
||||
echo -e "/*\n\n DO NOT EDIT THIS FILE!\n THIS IS OVERWRITTEN DURING BUILD\n This is an automatic copy of <osmocom/mgcp/mgcp_common.h>\n\n */" > mgcp_common.h
|
||||
cat $(top_srcdir)/include/osmocom/mgcp/mgcp_common.h >> mgcp_common.h
|
||||
|
||||
CLEANFILES = mgcp_common.h
|
@@ -1,7 +0,0 @@
|
||||
#include <osmocom/core/defs.h>
|
||||
|
||||
#if BUILDING_LIBOSMOMGCPCLIENT
|
||||
# define OSMO_DEPRECATED_OUTSIDE_LIBOSMOMGCPCLIENT(text)
|
||||
#else
|
||||
# define OSMO_DEPRECATED_OUTSIDE_LIBOSMOMGCPCLIENT(text) OSMO_DEPRECATED(text)
|
||||
#endif
|
@@ -1,127 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <osmocom/mgcp_client/defs.h>
|
||||
#include <osmocom/mgcp_client/mgcp_common.h>
|
||||
|
||||
/* See also: RFC 3435, chapter 3.5 Transmission over UDP */
|
||||
#define MGCP_CLIENT_LOCAL_ADDR_DEFAULT NULL /* INADDR(6)_ANY */
|
||||
#define MGCP_CLIENT_LOCAL_PORT_DEFAULT 0
|
||||
#define MGCP_CLIENT_REMOTE_ADDR_DEFAULT "127.0.0.1"
|
||||
#define MGCP_CLIENT_REMOTE_PORT_DEFAULT 2427
|
||||
#define MGCP_CLIENT_KEEPALIVE_DEFAULT_ENDP "null"
|
||||
#define MGCP_CLIENT_MGW_STR "Configure MGCP connection to Media Gateway\n"
|
||||
|
||||
struct msgb;
|
||||
struct vty;
|
||||
struct mgcp_client;
|
||||
|
||||
struct mgcp_client_conf {
|
||||
const char *local_addr;
|
||||
int local_port;
|
||||
const char *remote_addr;
|
||||
int remote_port;
|
||||
|
||||
/* By default, we are always addressing the MGW with e.g. 'rtpbridge/123@mgw'.
|
||||
* If this is nonempty, the contained name will be used instead of 'mgw'. */
|
||||
char endpoint_domain_name[MGCP_ENDPOINT_MAXLEN];
|
||||
|
||||
/* The user may configure certain endpoint names that are reset via DLCX
|
||||
* on startup. Usually this will be one wildcarded endpoint e.g.
|
||||
* 'rtpbridge/(wildcard)' or a number of specific E1 like e.g.
|
||||
* 'ds/e1-0/s-3/su16-4' */
|
||||
struct llist_head reset_epnames;
|
||||
|
||||
/* human readable name / description */
|
||||
char *description;
|
||||
|
||||
struct {
|
||||
uint32_t timeout_sec;
|
||||
uint32_t req_interval_sec;
|
||||
char req_endpoint_name[MGCP_ENDPOINT_MAXLEN];
|
||||
} keepalive;
|
||||
};
|
||||
|
||||
typedef unsigned int mgcp_trans_id_t;
|
||||
|
||||
/*! Enumeration of the codec types that mgcp_client is able to handle. */
|
||||
enum mgcp_codecs {
|
||||
CODEC_PCMU_8000_1 = 0,
|
||||
CODEC_GSM_8000_1 = 3,
|
||||
CODEC_PCMA_8000_1 = 8,
|
||||
CODEC_G729_8000_1 = 18,
|
||||
CODEC_GSMEFR_8000_1 = 110, /* 3GPP TS 48.103 table 5.4.2.2.1 */
|
||||
CODEC_GSMHR_8000_1 = 111, /* 3GPP TS 48.103 table 5.4.2.2.1 */
|
||||
CODEC_AMR_8000_1 = 112, /* 3GPP TS 48.103 table 5.4.2.2.1 */
|
||||
CODEC_AMRWB_16000_1 = 113, /* 3GPP TS 48.103 table 5.4.2.2.1 */
|
||||
CODEC_IUFP = 96,
|
||||
CODEC_CLEARMODE = 120, /* 3GPP TS 48.103 table 5.4.2.2.1 */
|
||||
};
|
||||
/* Note: when new codec types are added, the corresponding value strings
|
||||
* in mgcp_client.c (codec_table) must be updated as well. Enumerations
|
||||
* in enum mgcp_codecs must correspond to a valid payload type. However,
|
||||
* this is an internal assumption that is made to avoid lookup tables.
|
||||
* The API-User should not rely on this coincidence! */
|
||||
|
||||
extern const struct value_string osmo_mgcpc_codec_names[];
|
||||
static inline const char *osmo_mgcpc_codec_name(enum mgcp_codecs val)
|
||||
{ return get_value_string(osmo_mgcpc_codec_names, val); }
|
||||
|
||||
/*! Structure to build a payload type map to allow the defiition custom payload
|
||||
* types. */
|
||||
struct ptmap {
|
||||
/*! codec for which a payload type number should be defined */
|
||||
enum mgcp_codecs codec;
|
||||
|
||||
/*! payload type number (96-127) */
|
||||
unsigned int pt;
|
||||
};
|
||||
|
||||
int ptmap_cmp(const struct ptmap *a, const struct ptmap *b);
|
||||
|
||||
enum mgcp_verb {
|
||||
MGCP_VERB_CRCX,
|
||||
MGCP_VERB_MDCX,
|
||||
MGCP_VERB_DLCX,
|
||||
MGCP_VERB_AUEP,
|
||||
MGCP_VERB_RSIP,
|
||||
};
|
||||
|
||||
struct mgcp_client_conf *mgcp_client_conf_alloc(void *ctx);
|
||||
void mgcp_client_conf_init(struct mgcp_client_conf *conf) OSMO_DEPRECATED_OUTSIDE_LIBOSMOMGCPCLIENT("use mgcp_client_conf_alloc() (or even better, switch to the mgcp_client_pool API!)");
|
||||
void mgcp_client_vty_init(void *talloc_ctx, int node, struct mgcp_client_conf *conf);
|
||||
int mgcp_client_config_write(struct vty *vty, const char *indent);
|
||||
struct mgcp_client_conf *mgcp_client_conf_actual(struct mgcp_client *mgcp);
|
||||
|
||||
struct mgcp_client *mgcp_client_init(void *ctx,
|
||||
struct mgcp_client_conf *conf);
|
||||
int mgcp_client_connect(struct mgcp_client *mgcp);
|
||||
int mgcp_client_connect2(struct mgcp_client *mgcp, unsigned int retry_n_ports) OSMO_DEPRECATED("Use mgcp_client_connect() instead");
|
||||
void mgcp_client_disconnect(struct mgcp_client *mgcp);
|
||||
|
||||
const char *mgcp_client_remote_addr_str(struct mgcp_client *mgcp);
|
||||
uint16_t mgcp_client_remote_port(struct mgcp_client *mgcp);
|
||||
uint32_t mgcp_client_remote_addr_n(struct mgcp_client *mgcp) OSMO_DEPRECATED("deprecated, returns 0");
|
||||
|
||||
const char *mgcp_client_endpoint_domain(const struct mgcp_client *mgcp);
|
||||
const char *mgcp_client_rtpbridge_wildcard(const struct mgcp_client *mgcp);
|
||||
const char *mgcp_client_e1_epname(void *ctx, const struct mgcp_client *mgcp, uint8_t trunk_id, uint8_t ts,
|
||||
uint8_t rate, uint8_t offset);
|
||||
|
||||
enum mgcp_connection_mode;
|
||||
|
||||
extern const struct value_string mgcp_client_connection_mode_strs[];
|
||||
static inline const char *mgcp_client_cmode_name(enum mgcp_connection_mode mode)
|
||||
{
|
||||
return get_value_string(mgcp_client_connection_mode_strs, mode);
|
||||
}
|
||||
|
||||
enum mgcp_codecs map_str_to_codec(const char *str);
|
||||
unsigned int map_codec_to_pt(const struct ptmap *ptmap, unsigned int ptmap_len,
|
||||
enum mgcp_codecs codec);
|
||||
enum mgcp_codecs map_pt_to_codec(struct ptmap *ptmap, unsigned int ptmap_len,
|
||||
unsigned int pt);
|
||||
|
||||
const char *mgcp_client_name(const struct mgcp_client *mgcp);
|
@@ -1,55 +0,0 @@
|
||||
/* FSM to manage multiple connections of an MGW endpoint */
|
||||
#pragma once
|
||||
|
||||
#include <osmocom/mgcp_client/mgcp_client_fsm.h>
|
||||
|
||||
#define LOG_MGCPC_EP(ep, level, fmt, args...) do { \
|
||||
LOGPFSML(ep->fi, level, "%s " fmt, \
|
||||
osmo_mgcpc_ep_name(ep), ## args); \
|
||||
} while(0)
|
||||
|
||||
struct osmo_mgcpc_ep;
|
||||
struct osmo_mgcpc_ep_ci;
|
||||
struct osmo_tdef;
|
||||
|
||||
struct osmo_mgcpc_ep *osmo_mgcpc_ep_alloc(struct osmo_fsm_inst *parent, uint32_t parent_term_event,
|
||||
struct mgcp_client *mgcp_client,
|
||||
const struct osmo_tdef *T_defs,
|
||||
const char *fsm_id,
|
||||
const char *endpoint_str_fmt, ...);
|
||||
|
||||
struct osmo_mgcpc_ep_ci *osmo_mgcpc_ep_ci_add(struct osmo_mgcpc_ep *ep, const char *label_fmt, ...);
|
||||
const struct mgcp_conn_peer *osmo_mgcpc_ep_ci_get_rtp_info(const struct osmo_mgcpc_ep_ci *ci);
|
||||
bool osmo_mgcpc_ep_ci_get_crcx_info_to_sockaddr(const struct osmo_mgcpc_ep_ci *ci, struct sockaddr_storage *dest);
|
||||
bool osmo_mgcpc_ep_ci_get_crcx_info_to_osmux_cid(const struct osmo_mgcpc_ep_ci *ci, uint8_t* cid);
|
||||
|
||||
const struct mgcp_conn_peer *osmo_mgcpc_ep_ci_get_remote_rtp_info(const struct osmo_mgcpc_ep_ci *ci);
|
||||
|
||||
void osmo_mgcpc_ep_ci_request(struct osmo_mgcpc_ep_ci *ci,
|
||||
enum mgcp_verb verb, const struct mgcp_conn_peer *verb_info,
|
||||
struct osmo_fsm_inst *notify,
|
||||
uint32_t event_success, uint32_t event_failure,
|
||||
void *notify_data);
|
||||
|
||||
void osmo_mgcpc_ep_cancel_notify(struct osmo_mgcpc_ep *ep, struct osmo_fsm_inst *notify);
|
||||
struct osmo_mgcpc_ep *osmo_mgcpc_ep_ci_ep(struct osmo_mgcpc_ep_ci *ci);
|
||||
|
||||
/*! Dispatch a DLCX for the given connection.
|
||||
* \param ci Connection identifier as obtained from osmo_mgcpc_ep_ci_add().
|
||||
*/
|
||||
static inline void osmo_mgcpc_ep_ci_dlcx(struct osmo_mgcpc_ep_ci *ci)
|
||||
{
|
||||
osmo_mgcpc_ep_ci_request(ci, MGCP_VERB_DLCX, NULL, NULL, 0, 0, NULL);
|
||||
}
|
||||
|
||||
void osmo_mgcpc_ep_clear(struct osmo_mgcpc_ep *ep);
|
||||
|
||||
const char *osmo_mgcpc_ep_name(const struct osmo_mgcpc_ep *ep);
|
||||
const char *osmo_mgcpc_ep_local_name(const struct osmo_mgcpc_ep *ep);
|
||||
const char *osmo_mgcpc_ep_ci_name(const struct osmo_mgcpc_ep_ci *ci);
|
||||
const char *osmo_mgcpc_ep_ci_id(const struct osmo_mgcpc_ep_ci *ci);
|
||||
struct mgcp_client *osmo_mgcpc_ep_client(const struct osmo_mgcpc_ep *ep);
|
||||
|
||||
extern const struct value_string osmo_mgcp_verb_names[];
|
||||
static inline const char *osmo_mgcp_verb_name(enum mgcp_verb val)
|
||||
{ return get_value_string(osmo_mgcp_verb_names, val); }
|
@@ -1,78 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <osmocom/mgcp_client/mgcp_common.h>
|
||||
#include <osmocom/mgcp_client/mgcp_client.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
||||
|
||||
/*! This struct organizes the connection infromation one connection side
|
||||
* (either remote or local). It is used to pass parameters (local) to the FSM
|
||||
* and get responses (remote) from the FSM as pointer attached to the FSM
|
||||
* event.
|
||||
*
|
||||
* When modifiying a connection, the endpoint and call_id members may be left
|
||||
* unpopulated. The call_id field is ignored in this case. If an endpoint
|
||||
* identifier is supplied it is checked against the internal state to make
|
||||
* sure it is correct. */
|
||||
struct mgcp_conn_peer {
|
||||
/*! RTP connection IP-Address (optional, string e.g. "127.0.0.1") */
|
||||
char addr[INET6_ADDRSTRLEN];
|
||||
|
||||
/*! RTP connection IP-Port (optional) */
|
||||
uint16_t port;
|
||||
|
||||
/*! RTP endpoint */
|
||||
char endpoint[MGCP_ENDPOINT_MAXLEN];
|
||||
|
||||
/*! CALL ID (unique per connection) */
|
||||
unsigned int call_id;
|
||||
|
||||
/*! RTP packetization interval (optional) */
|
||||
unsigned int ptime;
|
||||
|
||||
/*! Deprecated. Use only ptmap[].codec in new code. */
|
||||
enum mgcp_codecs codecs[MGCP_MAX_CODECS]
|
||||
OSMO_DEPRECATED_OUTSIDE_LIBOSMOMGCPCLIENT("use ptmap[i].codec instead");
|
||||
unsigned int codecs_len
|
||||
OSMO_DEPRECATED_OUTSIDE_LIBOSMOMGCPCLIENT("use ptmap[] and ptmap_len instead");
|
||||
|
||||
/*! RTP payload type map (optional, only needed when payload types are
|
||||
* used that differ from what IANA/3GPP defines) */
|
||||
struct ptmap ptmap[MGCP_MAX_CODECS];
|
||||
|
||||
/*! RTP payload type map length (optional, only needed when payload
|
||||
* types are used that differ from what IANA/3GPP defines) */
|
||||
unsigned int ptmap_len;
|
||||
|
||||
/*! If nonzero, send 'X-Osmo-IGN:' header. This is useful e.g. for SCCPlite MSCs where the MSC is
|
||||
* known to issue incoherent or unknown CallIDs / to issue CRCX commands with a different domain
|
||||
* name than the BSC. An OsmoMGW will then ignore these and not fail on mismatches. */
|
||||
uint32_t x_osmo_ign;
|
||||
|
||||
/*! send 'X-Osmux: %d' header (or "*" as wildcard). */
|
||||
bool x_osmo_osmux_use;
|
||||
/*! -1 means send wildcard. */
|
||||
int x_osmo_osmux_cid;
|
||||
|
||||
/*! If left MGCP_CONN_NONE, use MGCP_CONN_RECV_ONLY or MGCP_CONN_RECV_SEND, depending on whether an audio RTP
|
||||
* address is set. If != MGCP_CONN_NONE, force this conn mode. */
|
||||
enum mgcp_connection_mode conn_mode;
|
||||
|
||||
/*! If the codec requires additional format parameters (fmtp), those cann be set here, see also
|
||||
* mgcp_common.h */
|
||||
bool param_present;
|
||||
struct mgcp_codec_param param;
|
||||
};
|
||||
|
||||
struct osmo_fsm_inst *mgcp_conn_create(struct mgcp_client *mgcp, struct osmo_fsm_inst *parent_fi, uint32_t parent_term_evt,
|
||||
uint32_t parent_evt, struct mgcp_conn_peer *conn_peer)
|
||||
OSMO_DEPRECATED_OUTSIDE_LIBOSMOMGCPCLIENT("use osmo_mgcpc_ep_alloc() and osmo_mgcpc_ep_ci_add() instead");
|
||||
int mgcp_conn_modify(struct osmo_fsm_inst *fi, uint32_t parent_evt, struct mgcp_conn_peer *conn_peer)
|
||||
OSMO_DEPRECATED_OUTSIDE_LIBOSMOMGCPCLIENT("use osmo_mgcpc_ep_ci_request() instead");
|
||||
void mgcp_conn_delete(struct osmo_fsm_inst *fi)
|
||||
OSMO_DEPRECATED_OUTSIDE_LIBOSMOMGCPCLIENT("use osmo_mgcpc_ep_ci_dlcx() instead");
|
||||
|
||||
const char *mgcp_conn_get_ci(struct osmo_fsm_inst *fi)
|
||||
OSMO_DEPRECATED_OUTSIDE_LIBOSMOMGCPCLIENT("use osmo_mgcpc_ep_ci.mgcp_ci_str instead");
|
||||
struct mgcp_client *mgcp_conn_get_client(struct osmo_fsm_inst *fi);
|
||||
|
||||
const char *osmo_mgcpc_conn_peer_name(const struct mgcp_conn_peer *info);
|
@@ -1,103 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <osmocom/core/osmo_io.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
|
||||
#include <osmocom/mgcp_client/mgcp_client.h>
|
||||
|
||||
#define MSGB_CB_MGCP_TRANS_ID 0
|
||||
|
||||
/* Struct that holds one endpoint name */
|
||||
struct reset_ep {
|
||||
struct llist_head list;
|
||||
char name[MGCP_ENDPOINT_MAXLEN];
|
||||
};
|
||||
|
||||
struct mgcp_client {
|
||||
struct mgcp_client_conf actual;
|
||||
struct osmo_io_fd *iofd;
|
||||
mgcp_trans_id_t next_trans_id;
|
||||
struct llist_head responses_pending;
|
||||
struct mgcp_client_pool_member *pool_member;
|
||||
struct osmo_timer_list keepalive_tx_timer;
|
||||
struct osmo_timer_list keepalive_rx_timer;
|
||||
bool conn_up;
|
||||
};
|
||||
|
||||
struct mgcp_response_head {
|
||||
int response_code;
|
||||
mgcp_trans_id_t trans_id;
|
||||
char comment[MGCP_COMMENT_MAXLEN];
|
||||
char conn_id[MGCP_CONN_ID_MAXLEN];
|
||||
char endpoint[MGCP_ENDPOINT_MAXLEN];
|
||||
bool x_osmo_osmux_use;
|
||||
uint8_t x_osmo_osmux_cid;
|
||||
};
|
||||
|
||||
struct mgcp_response {
|
||||
char *body;
|
||||
struct mgcp_response_head head;
|
||||
uint16_t audio_port;
|
||||
char audio_ip[INET6_ADDRSTRLEN];
|
||||
unsigned int ptime;
|
||||
struct ptmap ptmap[MGCP_MAX_CODECS];
|
||||
unsigned int ptmap_len;
|
||||
};
|
||||
|
||||
/* Invoked when an MGCP response is received or sending failed. When the
|
||||
* response is passed as NULL, this indicates failure during transmission. */
|
||||
typedef void (*mgcp_response_cb_t)(struct mgcp_response *response, void *priv);
|
||||
|
||||
struct mgcp_response_pending {
|
||||
struct llist_head entry;
|
||||
|
||||
mgcp_trans_id_t trans_id;
|
||||
mgcp_response_cb_t response_cb;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
int mgcp_client_rx(struct mgcp_client *mgcp, struct msgb *msg);
|
||||
|
||||
struct mgcp_response_pending * mgcp_client_pending_add(
|
||||
struct mgcp_client *mgcp,
|
||||
mgcp_trans_id_t trans_id,
|
||||
mgcp_response_cb_t response_cb,
|
||||
void *priv);
|
||||
|
||||
#define MGCP_MSG_PRESENCE_ENDPOINT 0x0001
|
||||
#define MGCP_MSG_PRESENCE_CALL_ID 0x0002
|
||||
#define MGCP_MSG_PRESENCE_CONN_ID 0x0004
|
||||
#define MGCP_MSG_PRESENCE_AUDIO_IP 0x0008
|
||||
#define MGCP_MSG_PRESENCE_AUDIO_PORT 0x0010
|
||||
#define MGCP_MSG_PRESENCE_CONN_MODE 0x0020
|
||||
#define MGCP_MSG_PRESENCE_X_OSMO_OSMUX_CID 0x4000
|
||||
#define MGCP_MSG_PRESENCE_X_OSMO_IGN 0x8000
|
||||
|
||||
struct mgcp_msg {
|
||||
enum mgcp_verb verb;
|
||||
/* See MGCP_MSG_PRESENCE_* constants */
|
||||
uint32_t presence;
|
||||
char endpoint[MGCP_ENDPOINT_MAXLEN];
|
||||
unsigned int call_id;
|
||||
char *conn_id;
|
||||
uint16_t audio_port;
|
||||
char *audio_ip;
|
||||
enum mgcp_connection_mode conn_mode;
|
||||
unsigned int ptime;
|
||||
struct ptmap ptmap[MGCP_MAX_CODECS];
|
||||
unsigned int ptmap_len;
|
||||
uint32_t x_osmo_ign;
|
||||
bool x_osmo_osmux_use;
|
||||
int x_osmo_osmux_cid; /* -1 is wildcard */
|
||||
bool param_present;
|
||||
struct mgcp_codec_param param;
|
||||
};
|
||||
|
||||
int mgcp_response_parse_params(struct mgcp_response *r);
|
||||
|
||||
int mgcp_client_tx(struct mgcp_client *mgcp, struct msgb *msg,
|
||||
mgcp_response_cb_t response_cb, void *priv);
|
||||
int mgcp_client_cancel(struct mgcp_client *mgcp, mgcp_trans_id_t trans_id);
|
||||
|
||||
struct msgb *mgcp_msg_gen(struct mgcp_client *mgcp, struct mgcp_msg *mgcp_msg);
|
||||
mgcp_trans_id_t mgcp_msg_trans_id(struct msgb *msg);
|
@@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <osmocom/vty/vty.h>
|
||||
|
||||
struct mgcp_client;
|
||||
struct mgcp_client_pool;
|
||||
struct mgcp_client_pool_member;
|
||||
|
||||
struct mgcp_client_pool *mgcp_client_pool_alloc(void *talloc_ctx);
|
||||
|
||||
void mgcp_client_pool_vty_init(int parent_node, int mgw_node, const char *indent, struct mgcp_client_pool *pool);
|
||||
int mgcp_client_pool_config_write(struct vty *vty, const char *indent);
|
||||
unsigned int mgcp_client_pool_connect(struct mgcp_client_pool *pool);
|
||||
void mgcp_client_pool_register_single(struct mgcp_client_pool *pool, struct mgcp_client *mgcp_client);
|
||||
bool mgcp_client_pool_empty(const struct mgcp_client_pool *pool);
|
||||
|
||||
struct mgcp_client *mgcp_client_pool_get(struct mgcp_client_pool *pool);
|
||||
void mgcp_client_pool_put(struct mgcp_client *mgcp_client);
|
||||
|
||||
struct mgcp_client_pool_member *mgcp_client_pool_find_member_by_nr(struct mgcp_client_pool *pool, unsigned int nr);
|
||||
struct mgcp_client *mgcp_client_pool_member_get(struct mgcp_client_pool_member *pool_member);
|
||||
bool mgcp_client_pool_member_is_blocked(const struct mgcp_client_pool_member *pool_member);
|
@@ -1,52 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
/* Struct to handle a pool of MGWs. (Use _pool functions) */
|
||||
struct mgcp_client_pool {
|
||||
|
||||
/* A pointer to a 'single' mgcp client. This is a non-pooled MGCP client that is configured using
|
||||
* mgcp_client_vty_init() and actively registered by the API user using mgcp_client_pool_register_single() */
|
||||
struct mgcp_client *mgcp_client_single;
|
||||
|
||||
/* A list that manages the pool members (see mgcp_client_pool_member->list above) */
|
||||
struct llist_head member_list;
|
||||
|
||||
/* String to use for indentation when writing the configuration file to the VTY. This field is populated by
|
||||
* mgcp_client_pool_vty_init() */
|
||||
char *vty_indent;
|
||||
|
||||
/* VTY node specification used with this pool. This field is populated by mgcp_client_pool_vty_init() */
|
||||
struct cmd_node *vty_node;
|
||||
};
|
||||
|
||||
/* Struct to handle a member of a pool of MGWs. */
|
||||
struct mgcp_client_pool_member {
|
||||
/* Entry in llist mgcp_client_pool->pool. */
|
||||
struct llist_head list;
|
||||
|
||||
/* The pool managing this object: */
|
||||
struct mgcp_client_pool *pool;
|
||||
|
||||
/* Reference number assinged by VTY. This number is used to manage the pool from the VTY and to identify it in
|
||||
* the log. */
|
||||
unsigned int nr;
|
||||
|
||||
/* MGCP client configuration, this is not the running configuration, when mgcp_client_init() is executed, a
|
||||
* copy of this config is created. */
|
||||
struct mgcp_client_conf conf;
|
||||
|
||||
/* MGCP client descriptor, will be automatically allocated when mgcp_client_pool_connect() is called. (the MGCP
|
||||
* client is connected when this pointer is populated) */
|
||||
struct mgcp_client *client;
|
||||
|
||||
/* A pool member may be set as 'blocked' from the VTY, this means that the pool member may still work and serve
|
||||
* ongoing calls, but it won't be picked from the pool anymore. */
|
||||
bool blocked;
|
||||
|
||||
/* Reference counter to count how often this pool member is currently picked. */
|
||||
unsigned int refcount;
|
||||
};
|
||||
|
||||
struct mgcp_client_pool_member *mgcp_client_pool_member_alloc(struct mgcp_client_pool *pool, unsigned int nr);
|
||||
void mgcp_client_pool_member_free(struct mgcp_client_pool_member *pool_member);
|
||||
int mgcp_client_pool_member_reinit_client(struct mgcp_client_pool_member *pool_member);
|
||||
const char *mgcp_client_pool_member_name(const struct mgcp_client_pool_member *pool_member);
|
@@ -1,10 +0,0 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: Osmocom Media Gateway Control Protocol Client library
|
||||
Description: C Utility Library
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -losmo-mgcp-client
|
||||
Cflags: -I${includedir}/
|
144
linux-kernel/linux-2.6.27.4-misdn-abis.diff
Normal file
144
linux-kernel/linux-2.6.27.4-misdn-abis.diff
Normal file
@@ -0,0 +1,144 @@
|
||||
diff -Nru --exclude-from /sunbeam/home/laforge/scripts/dontdiff linux-2.6.27.4-clean/drivers/isdn/mISDN/layer2.c linux-2.6.27.4/drivers/isdn/mISDN/layer2.c
|
||||
--- linux-2.6.27.4-clean/drivers/isdn/mISDN/layer2.c 2008-10-26 00:05:07.000000000 +0200
|
||||
+++ linux-2.6.27.4/drivers/isdn/mISDN/layer2.c 2008-12-23 16:16:29.000000000 +0100
|
||||
@@ -94,8 +94,10 @@
|
||||
struct layer2 *l2 = fi->userdata;
|
||||
va_list va;
|
||||
|
||||
+#if 0
|
||||
if (!(*debug & DEBUG_L2_FSM))
|
||||
return;
|
||||
+#endif
|
||||
va_start(va, fmt);
|
||||
printk(KERN_DEBUG "l2 (tei %d): ", l2->tei);
|
||||
vprintk(fmt, va);
|
||||
@@ -882,6 +884,8 @@
|
||||
l2->va = 0;
|
||||
l2->vr = 0;
|
||||
l2->sow = 0;
|
||||
+ l2->sapi = skb->data[0] >> 2;
|
||||
+ set_channel_address(&l2->ch, l2->sapi, l2->tei);
|
||||
clear_exception(l2);
|
||||
send_uframe(l2, NULL, UA | get_PollFlag(l2, skb), RSP);
|
||||
mISDN_FsmChangeState(fi, ST_L2_7);
|
||||
@@ -898,6 +902,7 @@
|
||||
struct layer2 *l2 = fi->userdata;
|
||||
struct sk_buff *skb = arg;
|
||||
|
||||
+ printk(KERN_DEBUG "l2_send_UA()\n");
|
||||
send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);
|
||||
}
|
||||
|
||||
@@ -931,6 +936,8 @@
|
||||
l2->va = 0;
|
||||
l2->vr = 0;
|
||||
l2->sow = 0;
|
||||
+ l2->sapi = skb->data[0] >> 2;
|
||||
+ set_channel_address(&l2->ch, l2->sapi, l2->tei);
|
||||
mISDN_FsmChangeState(fi, ST_L2_7);
|
||||
stop_t200(l2, 3);
|
||||
mISDN_FsmRestartTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3);
|
||||
@@ -982,6 +989,8 @@
|
||||
} else if (l2->vs != l2->va) {
|
||||
skb_queue_purge(&l2->i_queue);
|
||||
pr = DL_ESTABLISH_IND;
|
||||
+ //l2->sapi = skb->data[0] >> 2;
|
||||
+ //set_channel_address(&l2->ch, l2->sapi, l2->tei);
|
||||
}
|
||||
stop_t200(l2, 5);
|
||||
l2->vr = 0;
|
||||
@@ -1841,11 +1850,14 @@
|
||||
u_int l;
|
||||
int c = 0;
|
||||
|
||||
+ printk(KERN_DEBUG "ph_data_indication 0x%x 0x%x 0x%x\n", datap[0], datap[1], datap[2]);
|
||||
+
|
||||
l = l2addrsize(l2);
|
||||
if (skb->len <= l) {
|
||||
mISDN_FsmEvent(&l2->l2m, EV_L2_FRAME_ERROR, (void *) 'N');
|
||||
return ret;
|
||||
}
|
||||
+#if 0
|
||||
if (test_bit(FLG_LAPD, &l2->flag)) { /* Maybe not needed */
|
||||
psapi = *datap++;
|
||||
ptei = *datap++;
|
||||
@@ -1875,6 +1887,7 @@
|
||||
return 0;
|
||||
}
|
||||
} else
|
||||
+#endif
|
||||
datap += l;
|
||||
if (!(*datap & 1)) { /* I-Frame */
|
||||
c = iframe_error(l2, skb);
|
||||
@@ -1890,6 +1903,7 @@
|
||||
ret = mISDN_FsmEvent(&l2->l2m, EV_L2_UI, skb);
|
||||
} else if (IsSABME(datap, l2)) {
|
||||
c = unnum_error(l2, skb, CMD);
|
||||
+ printk(KERN_DEBUG "IsSABME() returned true, unnum_error=%d\n", c);
|
||||
if (!c)
|
||||
ret = mISDN_FsmEvent(&l2->l2m, EV_L2_SABME, skb);
|
||||
} else if (IsUA(datap)) {
|
||||
@@ -2087,7 +2101,7 @@
|
||||
test_and_set_bit(FLG_LAPD, &l2->flag);
|
||||
test_and_set_bit(FLG_LAPD_NET, &l2->flag);
|
||||
test_and_set_bit(FLG_MOD128, &l2->flag);
|
||||
- l2->sapi = 0;
|
||||
+ l2->sapi = 62;
|
||||
l2->maxlen = MAX_DFRAME_LEN;
|
||||
if (test_bit(OPTION_L2_PMX, &options))
|
||||
l2->window = 7;
|
||||
diff -Nru --exclude-from /sunbeam/home/laforge/scripts/dontdiff linux-2.6.27.4-clean/drivers/isdn/mISDN/tei.c linux-2.6.27.4/drivers/isdn/mISDN/tei.c
|
||||
--- linux-2.6.27.4-clean/drivers/isdn/mISDN/tei.c 2008-10-26 00:05:07.000000000 +0200
|
||||
+++ linux-2.6.27.4/drivers/isdn/mISDN/tei.c 2008-12-23 16:32:59.000000000 +0100
|
||||
@@ -830,18 +830,29 @@
|
||||
int tei, ri;
|
||||
struct layer2 *l2;
|
||||
|
||||
+ printk(KERN_DEBUG "new tei request: tei=%d\n", dp[3] >> 1);
|
||||
+
|
||||
ri = dp[0] << 8;
|
||||
ri += dp[1];
|
||||
- if (!mgr->up)
|
||||
- goto denied;
|
||||
- tei = get_free_tei(mgr);
|
||||
- if (tei < 0) {
|
||||
- printk(KERN_WARNING "%s:No free tei\n", __func__);
|
||||
+ if (!mgr->up) {
|
||||
+ printk(KERN_DEBUG "mgr->up == NULL\n");
|
||||
goto denied;
|
||||
}
|
||||
+ if (dp[3] != 0xff) {
|
||||
+ /* This is a TEI request according to 3GPP TS 08.56 6.1.11.2 */
|
||||
+ tei = dp[3] >> 1;
|
||||
+ } else {
|
||||
+ tei = get_free_tei(mgr);
|
||||
+ if (tei < 0) {
|
||||
+ printk(KERN_WARNING "%s:No free tei\n", __func__);
|
||||
+ goto denied;
|
||||
+ }
|
||||
+ }
|
||||
l2 = create_new_tei(mgr, tei);
|
||||
- if (!l2)
|
||||
+ if (!l2) {
|
||||
+ printk(KERN_DEBUG "create_new_tei == NULL\n");
|
||||
goto denied;
|
||||
+ }
|
||||
else
|
||||
mISDN_FsmEvent(&l2->tm->tei_m, EV_ASSIGN_REQ, dp);
|
||||
return;
|
||||
@@ -1159,12 +1170,14 @@
|
||||
return -ENOTCONN;
|
||||
if (skb->len != 3)
|
||||
return -ENOTCONN;
|
||||
+#if 0
|
||||
if (skb->data[0] != 0)
|
||||
/* only SAPI 0 command */
|
||||
return -ENOTCONN;
|
||||
+#endif
|
||||
if (!(skb->data[1] & 1)) /* invalid EA1 */
|
||||
return -EINVAL;
|
||||
- tei = skb->data[1] >> 0;
|
||||
+ tei = skb->data[1] >> 1;
|
||||
if (tei > 63) /* not a fixed tei */
|
||||
return -ENOTCONN;
|
||||
if ((skb->data[2] & ~0x10) != SABME)
|
486
linux-kernel/linux-2.6.30-hfcmulti-multibts.patch
Normal file
486
linux-kernel/linux-2.6.30-hfcmulti-multibts.patch
Normal file
@@ -0,0 +1,486 @@
|
||||
This experimental patch splits one E1 card into three virtual cards,
|
||||
|
||||
TS 1,2,3,4,5 is card 0
|
||||
TS 6,7,8,9,10 is card 1
|
||||
TS 11,12,13,14 is card 2
|
||||
|
||||
This allows you to run one L2 TEI handler on each of the virtual cards,
|
||||
which is required if you want to run multiple BTS on a single E1 link.
|
||||
|
||||
Thanks to Andreas Eversberg for this patch.
|
||||
|
||||
diff --git a/drivers/isdn/hardware/mISDN/hfc_multi.h b/drivers/isdn/hardware/mISDN/hfc_multi.h
|
||||
index 0c77386..02dd4a1 100644
|
||||
--- a/drivers/isdn/hardware/mISDN/hfc_multi.h
|
||||
+++ b/drivers/isdn/hardware/mISDN/hfc_multi.h
|
||||
@@ -209,14 +209,17 @@ struct hfc_multi {
|
||||
u_long ledstate; /* save last state of leds */
|
||||
int opticalsupport; /* has the e1 board */
|
||||
/* an optical Interface */
|
||||
- int dslot; /* channel # of d-channel (E1) default 16 */
|
||||
+
|
||||
+ u_int bmask[32]; /* bitmask of bchannels for port */
|
||||
+ u_char dnum[32]; /* array of used dchannel numbers for port */
|
||||
+ u_char created[32]; /* what port is created */
|
||||
+ u_int activity[32]; /* if there is any action on this */
|
||||
+ /* port (will be cleared after */
|
||||
+ /* showing led-states) */
|
||||
|
||||
u_long wdcount; /* every 500 ms we need to */
|
||||
/* send the watchdog a signal */
|
||||
u_char wdbyte; /* watchdog toggle byte */
|
||||
- u_int activity[8]; /* if there is any action on this */
|
||||
- /* port (will be cleared after */
|
||||
- /* showing led-states) */
|
||||
int e1_state; /* keep track of last state */
|
||||
int e1_getclock; /* if sync is retrieved from interface */
|
||||
int syncronized; /* keep track of existing sync interface */
|
||||
@@ -233,7 +236,6 @@ struct hfc_multi {
|
||||
* the bch->channel is equvalent to the hfc-channel
|
||||
*/
|
||||
struct hfc_chan chan[32];
|
||||
- u_char created[8]; /* what port is created */
|
||||
signed char slot_owner[256]; /* owner channel of slot */
|
||||
};
|
||||
|
||||
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
|
||||
index e1dab30..4fe2d27 100644
|
||||
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
|
||||
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
|
||||
@@ -1619,8 +1619,8 @@ hfcmulti_leds(struct hfc_multi *hc)
|
||||
* left red: frame sync, but no L1
|
||||
* right green: L2 active
|
||||
*/
|
||||
- if (hc->chan[hc->dslot].sync != 2) { /* no frame sync */
|
||||
- if (hc->chan[hc->dslot].dch->dev.D.protocol
|
||||
+ if (hc->chan[hc->dnum[0]].sync != 2) { /* no frame sync */
|
||||
+ if (hc->chan[hc->dnum[0]].dch->dev.D.protocol
|
||||
!= ISDN_P_NT_E1) {
|
||||
led[0] = 1;
|
||||
led[1] = 1;
|
||||
@@ -2428,55 +2428,56 @@ handle_timer_irq(struct hfc_multi *hc)
|
||||
}
|
||||
}
|
||||
if (hc->ctype == HFC_TYPE_E1 && hc->created[0]) {
|
||||
- dch = hc->chan[hc->dslot].dch;
|
||||
- if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) {
|
||||
+#warning todo: put interface parameters to hc
|
||||
+ dch = hc->chan[hc->dnum[0]].dch;
|
||||
+ if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[0]].cfg)) {
|
||||
/* LOS */
|
||||
temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_SIG_LOS;
|
||||
- if (!temp && hc->chan[hc->dslot].los)
|
||||
+ if (!temp && hc->chan[hc->dnum[0]].los)
|
||||
signal_state_up(dch, L1_SIGNAL_LOS_ON,
|
||||
"LOS detected");
|
||||
- if (temp && !hc->chan[hc->dslot].los)
|
||||
+ if (temp && !hc->chan[hc->dnum[0]].los)
|
||||
signal_state_up(dch, L1_SIGNAL_LOS_OFF,
|
||||
"LOS gone");
|
||||
- hc->chan[hc->dslot].los = temp;
|
||||
+ hc->chan[hc->dnum[0]].los = temp;
|
||||
}
|
||||
- if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dslot].cfg)) {
|
||||
+ if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dnum[0]].cfg)) {
|
||||
/* AIS */
|
||||
temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_AIS;
|
||||
- if (!temp && hc->chan[hc->dslot].ais)
|
||||
+ if (!temp && hc->chan[hc->dnum[0]].ais)
|
||||
signal_state_up(dch, L1_SIGNAL_AIS_ON,
|
||||
"AIS detected");
|
||||
- if (temp && !hc->chan[hc->dslot].ais)
|
||||
+ if (temp && !hc->chan[hc->dnum[0]].ais)
|
||||
signal_state_up(dch, L1_SIGNAL_AIS_OFF,
|
||||
"AIS gone");
|
||||
- hc->chan[hc->dslot].ais = temp;
|
||||
+ hc->chan[hc->dnum[0]].ais = temp;
|
||||
}
|
||||
- if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dslot].cfg)) {
|
||||
+ if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dnum[0]].cfg)) {
|
||||
/* SLIP */
|
||||
temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_RX;
|
||||
- if (!temp && hc->chan[hc->dslot].slip_rx)
|
||||
+ if (!temp && hc->chan[hc->dnum[0]].slip_rx)
|
||||
signal_state_up(dch, L1_SIGNAL_SLIP_RX,
|
||||
" bit SLIP detected RX");
|
||||
- hc->chan[hc->dslot].slip_rx = temp;
|
||||
+ hc->chan[hc->dnum[0]].slip_rx = temp;
|
||||
temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_TX;
|
||||
- if (!temp && hc->chan[hc->dslot].slip_tx)
|
||||
+ if (!temp && hc->chan[hc->dnum[0]].slip_tx)
|
||||
signal_state_up(dch, L1_SIGNAL_SLIP_TX,
|
||||
" bit SLIP detected TX");
|
||||
- hc->chan[hc->dslot].slip_tx = temp;
|
||||
+ hc->chan[hc->dnum[0]].slip_tx = temp;
|
||||
}
|
||||
- if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dslot].cfg)) {
|
||||
+ if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dnum[0]].cfg)) {
|
||||
/* RDI */
|
||||
temp = HFC_inb_nodebug(hc, R_RX_SL0_0) & V_A;
|
||||
- if (!temp && hc->chan[hc->dslot].rdi)
|
||||
+ if (!temp && hc->chan[hc->dnum[0]].rdi)
|
||||
signal_state_up(dch, L1_SIGNAL_RDI_ON,
|
||||
"RDI detected");
|
||||
- if (temp && !hc->chan[hc->dslot].rdi)
|
||||
+ if (temp && !hc->chan[hc->dnum[0]].rdi)
|
||||
signal_state_up(dch, L1_SIGNAL_RDI_OFF,
|
||||
"RDI gone");
|
||||
- hc->chan[hc->dslot].rdi = temp;
|
||||
+ hc->chan[hc->dnum[0]].rdi = temp;
|
||||
}
|
||||
temp = HFC_inb_nodebug(hc, R_JATT_DIR);
|
||||
- switch (hc->chan[hc->dslot].sync) {
|
||||
+ switch (hc->chan[hc->dnum[0]].sync) {
|
||||
case 0:
|
||||
if ((temp & 0x60) == 0x60) {
|
||||
if (debug & DEBUG_HFCMULTI_SYNC)
|
||||
@@ -2485,10 +2486,10 @@ handle_timer_irq(struct hfc_multi *hc)
|
||||
"in clock sync\n",
|
||||
__func__, hc->id);
|
||||
HFC_outb(hc, R_RX_OFF,
|
||||
- hc->chan[hc->dslot].jitter | V_RX_INIT);
|
||||
+ hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
|
||||
HFC_outb(hc, R_TX_OFF,
|
||||
- hc->chan[hc->dslot].jitter | V_RX_INIT);
|
||||
- hc->chan[hc->dslot].sync = 1;
|
||||
+ hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
|
||||
+ hc->chan[hc->dnum[0]].sync = 1;
|
||||
goto check_framesync;
|
||||
}
|
||||
break;
|
||||
@@ -2499,7 +2500,7 @@ handle_timer_irq(struct hfc_multi *hc)
|
||||
"%s: (id=%d) E1 "
|
||||
"lost clock sync\n",
|
||||
__func__, hc->id);
|
||||
- hc->chan[hc->dslot].sync = 0;
|
||||
+ hc->chan[hc->dnum[0]].sync = 0;
|
||||
break;
|
||||
}
|
||||
check_framesync:
|
||||
@@ -2510,7 +2511,7 @@ check_framesync:
|
||||
"%s: (id=%d) E1 "
|
||||
"now in frame sync\n",
|
||||
__func__, hc->id);
|
||||
- hc->chan[hc->dslot].sync = 2;
|
||||
+ hc->chan[hc->dnum[0]].sync = 2;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
@@ -2520,7 +2521,7 @@ check_framesync:
|
||||
"%s: (id=%d) E1 lost "
|
||||
"clock & frame sync\n",
|
||||
__func__, hc->id);
|
||||
- hc->chan[hc->dslot].sync = 0;
|
||||
+ hc->chan[hc->dnum[0]].sync = 0;
|
||||
break;
|
||||
}
|
||||
temp = HFC_inb_nodebug(hc, R_SYNC_STA);
|
||||
@@ -2530,7 +2531,7 @@ check_framesync:
|
||||
"%s: (id=%d) E1 "
|
||||
"lost frame sync\n",
|
||||
__func__, hc->id);
|
||||
- hc->chan[hc->dslot].sync = 1;
|
||||
+ hc->chan[hc->dnum[0]].sync = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2746,7 +2747,8 @@ hfcmulti_interrupt(int intno, void *dev_id)
|
||||
if (r_irq_misc & V_STA_IRQ) {
|
||||
if (hc->ctype == HFC_TYPE_E1) {
|
||||
/* state machine */
|
||||
- dch = hc->chan[hc->dslot].dch;
|
||||
+#warning todo
|
||||
+ dch = hc->chan[hc->dnum[0]].dch;
|
||||
e1_syncsta = HFC_inb_nodebug(hc, R_SYNC_STA);
|
||||
if (test_bit(HFC_CHIP_PLXSD, &hc->chip)
|
||||
&& hc->e1_getclock) {
|
||||
@@ -2768,7 +2770,15 @@ hfcmulti_interrupt(int intno, void *dev_id)
|
||||
}
|
||||
dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA)
|
||||
& 0x7;
|
||||
+#warning todo hack!!! broadcast state change!!!
|
||||
+ dch = hc->chan[hc->dnum[0]].dch;
|
||||
schedule_event(dch, FLG_PHCHANGE);
|
||||
+ dch = hc->chan[hc->dnum[1]].dch;
|
||||
+ dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA)
|
||||
+ & 0x7;
|
||||
+ schedule_event(dch, FLG_PHCHANGE);
|
||||
+
|
||||
+
|
||||
if (debug & DEBUG_HFCMULTI_STATE)
|
||||
printk(KERN_DEBUG
|
||||
"%s: E1 (id=%d) newstate %x\n",
|
||||
@@ -3851,31 +3861,35 @@ hfcmulti_initmode(struct dchannel *dch)
|
||||
if (debug & DEBUG_HFCMULTI_INIT)
|
||||
printk(KERN_DEBUG "%s: entered\n", __func__);
|
||||
|
||||
+ i = dch->slot;
|
||||
+ pt = hc->chan[i].port;
|
||||
if (hc->ctype == HFC_TYPE_E1) {
|
||||
- hc->chan[hc->dslot].slot_tx = -1;
|
||||
- hc->chan[hc->dslot].slot_rx = -1;
|
||||
- hc->chan[hc->dslot].conf = -1;
|
||||
- if (hc->dslot) {
|
||||
- mode_hfcmulti(hc, hc->dslot, dch->dev.D.protocol,
|
||||
+ /* E1 */
|
||||
+#warning todo: don''t do it if dnum == 0
|
||||
+ hc->chan[hc->dnum[pt]].slot_tx = -1;
|
||||
+ hc->chan[hc->dnum[pt]].slot_rx = -1;
|
||||
+ hc->chan[hc->dnum[pt]].conf = -1;
|
||||
+ if (hc->dnum[pt]) {
|
||||
+ mode_hfcmulti(hc, dch->slot, dch->dev.D.protocol,
|
||||
-1, 0, -1, 0);
|
||||
dch->timer.function = (void *) hfcmulti_dbusy_timer;
|
||||
dch->timer.data = (long) dch;
|
||||
init_timer(&dch->timer);
|
||||
}
|
||||
for (i = 1; i <= 31; i++) {
|
||||
- if (i == hc->dslot)
|
||||
+ if (!((1 << i) & hc->bmask[pt])) /* skip unused channel */
|
||||
continue;
|
||||
hc->chan[i].slot_tx = -1;
|
||||
hc->chan[i].slot_rx = -1;
|
||||
hc->chan[i].conf = -1;
|
||||
mode_hfcmulti(hc, i, ISDN_P_NONE, -1, 0, -1, 0);
|
||||
}
|
||||
- /* E1 */
|
||||
- if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) {
|
||||
+#warning todo (global)
|
||||
+ if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[pt]].cfg)) {
|
||||
HFC_outb(hc, R_LOS0, 255); /* 2 ms */
|
||||
HFC_outb(hc, R_LOS1, 255); /* 512 ms */
|
||||
}
|
||||
- if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dslot].cfg)) {
|
||||
+ if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dnum[pt]].cfg)) {
|
||||
HFC_outb(hc, R_RX0, 0);
|
||||
hc->hw.r_tx0 = 0 | V_OUT_EN;
|
||||
} else {
|
||||
@@ -3888,12 +3902,12 @@ hfcmulti_initmode(struct dchannel *dch)
|
||||
HFC_outb(hc, R_TX_FR0, 0x00);
|
||||
HFC_outb(hc, R_TX_FR1, 0xf8);
|
||||
|
||||
- if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg))
|
||||
+ if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[pt]].cfg))
|
||||
HFC_outb(hc, R_TX_FR2, V_TX_MF | V_TX_E | V_NEG_E);
|
||||
|
||||
HFC_outb(hc, R_RX_FR0, V_AUTO_RESYNC | V_AUTO_RECO | 0);
|
||||
|
||||
- if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg))
|
||||
+ if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[pt]].cfg))
|
||||
HFC_outb(hc, R_RX_FR1, V_RX_MF | V_RX_MF_SYNC);
|
||||
|
||||
if (dch->dev.D.protocol == ISDN_P_NT_E1) {
|
||||
@@ -3957,7 +3971,7 @@ hfcmulti_initmode(struct dchannel *dch)
|
||||
plxsd_checksync(hc, 0);
|
||||
}
|
||||
} else {
|
||||
- i = dch->slot;
|
||||
+ /* ST */
|
||||
hc->chan[i].slot_tx = -1;
|
||||
hc->chan[i].slot_rx = -1;
|
||||
hc->chan[i].conf = -1;
|
||||
@@ -3973,8 +3987,6 @@ hfcmulti_initmode(struct dchannel *dch)
|
||||
hc->chan[i - 1].slot_rx = -1;
|
||||
hc->chan[i - 1].conf = -1;
|
||||
mode_hfcmulti(hc, i - 1, ISDN_P_NONE, -1, 0, -1, 0);
|
||||
- /* ST */
|
||||
- pt = hc->chan[i].port;
|
||||
/* select interface */
|
||||
HFC_outb(hc, R_ST_SEL, pt);
|
||||
/* undocumented: delay after R_ST_SEL */
|
||||
@@ -4557,6 +4569,8 @@ release_port(struct hfc_multi *hc, struct dchannel *dch)
|
||||
}
|
||||
/* free channels */
|
||||
for (i = 0; i <= 31; i++) {
|
||||
+ if (!((1 << i) & hc->bmask[pt])) /* skip unused channel */
|
||||
+ continue;
|
||||
if (hc->chan[i].bch) {
|
||||
if (debug & DEBUG_HFCMULTI_INIT)
|
||||
printk(KERN_DEBUG
|
||||
@@ -4680,12 +4694,13 @@ release_card(struct hfc_multi *hc)
|
||||
}
|
||||
|
||||
static int
|
||||
-init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
+init_e1_port(struct hfc_multi *hc, struct hm_map *m, int pt)
|
||||
{
|
||||
struct dchannel *dch;
|
||||
struct bchannel *bch;
|
||||
int ch, ret = 0;
|
||||
char name[MISDN_MAX_IDLEN];
|
||||
+ int bcount = 0;
|
||||
|
||||
dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL);
|
||||
if (!dch)
|
||||
@@ -4698,13 +4713,12 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
|
||||
dch->dev.D.send = handle_dmsg;
|
||||
dch->dev.D.ctrl = hfcm_dctrl;
|
||||
- dch->dev.nrbchan = (hc->dslot) ? 30 : 31;
|
||||
- dch->slot = hc->dslot;
|
||||
- hc->chan[hc->dslot].dch = dch;
|
||||
- hc->chan[hc->dslot].port = 0;
|
||||
- hc->chan[hc->dslot].nt_timer = -1;
|
||||
+ dch->slot = hc->dnum[pt];
|
||||
+ hc->chan[hc->dnum[pt]].dch = dch;
|
||||
+ hc->chan[hc->dnum[pt]].port = pt;
|
||||
+ hc->chan[hc->dnum[pt]].nt_timer = -1;
|
||||
for (ch = 1; ch <= 31; ch++) {
|
||||
- if (ch == hc->dslot) /* skip dchannel */
|
||||
+ if (!((1 << ch) & hc->bmask[pt])) /* skip unused channel */
|
||||
continue;
|
||||
bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL);
|
||||
if (!bch) {
|
||||
@@ -4733,7 +4747,10 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
hc->chan[ch].bch = bch;
|
||||
hc->chan[ch].port = 0;
|
||||
set_channelmap(bch->nr, dch->dev.channelmap);
|
||||
+ bcount++;
|
||||
}
|
||||
+ dch->dev.nrbchan = bcount;
|
||||
+#warning todo: must be set globally, and must be a seperate function
|
||||
/* set optical line type */
|
||||
if (port[Port_cnt] & 0x001) {
|
||||
if (!m->opticalsupport) {
|
||||
@@ -4749,7 +4766,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
__func__,
|
||||
HFC_cnt + 1, 1);
|
||||
test_and_set_bit(HFC_CFG_OPTICAL,
|
||||
- &hc->chan[hc->dslot].cfg);
|
||||
+ &hc->chan[hc->dnum[pt]].cfg);
|
||||
}
|
||||
}
|
||||
/* set LOS report */
|
||||
@@ -4759,7 +4776,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
"LOS report: card(%d) port(%d)\n",
|
||||
__func__, HFC_cnt + 1, 1);
|
||||
test_and_set_bit(HFC_CFG_REPORT_LOS,
|
||||
- &hc->chan[hc->dslot].cfg);
|
||||
+ &hc->chan[hc->dnum[pt]].cfg);
|
||||
}
|
||||
/* set AIS report */
|
||||
if (port[Port_cnt] & 0x008) {
|
||||
@@ -4768,7 +4785,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
"AIS report: card(%d) port(%d)\n",
|
||||
__func__, HFC_cnt + 1, 1);
|
||||
test_and_set_bit(HFC_CFG_REPORT_AIS,
|
||||
- &hc->chan[hc->dslot].cfg);
|
||||
+ &hc->chan[hc->dnum[pt]].cfg);
|
||||
}
|
||||
/* set SLIP report */
|
||||
if (port[Port_cnt] & 0x010) {
|
||||
@@ -4778,7 +4795,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
"card(%d) port(%d)\n",
|
||||
__func__, HFC_cnt + 1, 1);
|
||||
test_and_set_bit(HFC_CFG_REPORT_SLIP,
|
||||
- &hc->chan[hc->dslot].cfg);
|
||||
+ &hc->chan[hc->dnum[pt]].cfg);
|
||||
}
|
||||
/* set RDI report */
|
||||
if (port[Port_cnt] & 0x020) {
|
||||
@@ -4788,7 +4805,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
"card(%d) port(%d)\n",
|
||||
__func__, HFC_cnt + 1, 1);
|
||||
test_and_set_bit(HFC_CFG_REPORT_RDI,
|
||||
- &hc->chan[hc->dslot].cfg);
|
||||
+ &hc->chan[hc->dnum[pt]].cfg);
|
||||
}
|
||||
/* set CRC-4 Mode */
|
||||
if (!(port[Port_cnt] & 0x100)) {
|
||||
@@ -4797,7 +4814,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
" card(%d) port(%d)\n",
|
||||
__func__, HFC_cnt + 1, 1);
|
||||
test_and_set_bit(HFC_CFG_CRC4,
|
||||
- &hc->chan[hc->dslot].cfg);
|
||||
+ &hc->chan[hc->dnum[pt]].cfg);
|
||||
} else {
|
||||
if (debug & DEBUG_HFCMULTI_INIT)
|
||||
printk(KERN_DEBUG "%s: PORT turn off CRC4"
|
||||
@@ -4829,20 +4846,23 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
}
|
||||
/* set elastic jitter buffer */
|
||||
if (port[Port_cnt] & 0x3000) {
|
||||
- hc->chan[hc->dslot].jitter = (port[Port_cnt]>>12) & 0x3;
|
||||
+ hc->chan[hc->dnum[pt]].jitter = (port[Port_cnt]>>12) & 0x3;
|
||||
if (debug & DEBUG_HFCMULTI_INIT)
|
||||
printk(KERN_DEBUG
|
||||
"%s: PORT set elastic "
|
||||
"buffer to %d: card(%d) port(%d)\n",
|
||||
- __func__, hc->chan[hc->dslot].jitter,
|
||||
+ __func__, hc->chan[hc->dnum[pt]].jitter,
|
||||
HFC_cnt + 1, 1);
|
||||
} else
|
||||
- hc->chan[hc->dslot].jitter = 2; /* default */
|
||||
- snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1);
|
||||
+ hc->chan[hc->dnum[pt]].jitter = 2; /* default */
|
||||
+ if (hc->ports > 1)
|
||||
+ snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d-%d", HFC_cnt + 1, pt+1);
|
||||
+ else
|
||||
+ snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1);
|
||||
ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name);
|
||||
if (ret)
|
||||
goto free_chan;
|
||||
- hc->created[0] = 1;
|
||||
+ hc->created[pt] = 1;
|
||||
return ret;
|
||||
free_chan:
|
||||
release_port(hc, dch);
|
||||
@@ -5009,18 +5029,30 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
|
||||
hc->id = HFC_cnt;
|
||||
hc->pcm = pcm[HFC_cnt];
|
||||
hc->io_mode = iomode[HFC_cnt];
|
||||
+#warning todo: rework module parameters for customizing e1 fragments.... yea, let''s call it: fragments
|
||||
if (dslot[HFC_cnt] < 0 && hc->ctype == HFC_TYPE_E1) {
|
||||
- hc->dslot = 0;
|
||||
+ hc->dnum[0] = 0;
|
||||
printk(KERN_INFO "HFC-E1 card has disabled D-channel, but "
|
||||
"31 B-channels\n");
|
||||
}
|
||||
if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32
|
||||
&& hc->ctype == HFC_TYPE_E1) {
|
||||
- hc->dslot = dslot[HFC_cnt];
|
||||
+ hc->dnum[0] = dslot[HFC_cnt];
|
||||
printk(KERN_INFO "HFC-E1 card has alternating D-channel on "
|
||||
"time slot %d\n", dslot[HFC_cnt]);
|
||||
} else
|
||||
- hc->dslot = 16;
|
||||
+ hc->dnum[0] = 16;
|
||||
+
|
||||
+#warning todo HACK!!! just a small map of two "fragments"
|
||||
+ if (hc->ctype == HFC_TYPE_E1) {
|
||||
+ hc->dnum[0] = 1;
|
||||
+ hc->bmask[0] = 0x0000003c;
|
||||
+ hc->dnum[1] = 6;
|
||||
+ hc->bmask[1] = 0x00000780;
|
||||
+ hc->dnum[2] = 11;
|
||||
+ hc->bmask[2] = 0x00007800;
|
||||
+ hc->ports = 3;
|
||||
+ }
|
||||
|
||||
/* set chip specific features */
|
||||
hc->masterclk = -1;
|
||||
@@ -5103,7 +5135,7 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
|
||||
goto free_card;
|
||||
}
|
||||
if (hc->ctype == HFC_TYPE_E1)
|
||||
- ret_err = init_e1_port(hc, m);
|
||||
+ ret_err = init_e1_port(hc, m, pt);
|
||||
else
|
||||
ret_err = init_multi_port(hc, pt);
|
||||
if (debug & DEBUG_HFCMULTI_INIT)
|
||||
@@ -5115,10 +5147,14 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
|
||||
if (ret_err) {
|
||||
while (pt) { /* release already registered ports */
|
||||
pt--;
|
||||
- release_port(hc, hc->chan[(pt << 2) + 2].dch);
|
||||
+ if (hc->ctype == HFC_TYPE_E1)
|
||||
+ release_port(hc, hc->chan[hc->dnum[pt]].dch);
|
||||
+ else
|
||||
+ release_port(hc, hc->chan[(pt << 2) + 2].dch);
|
||||
}
|
||||
goto free_card;
|
||||
}
|
||||
+#warning todo: count it right, add additional "fragment" counter...
|
||||
Port_cnt++;
|
||||
}
|
||||
|
@@ -1,3 +0,0 @@
|
||||
We want to avoid creating too many external build-time dependencies
|
||||
like this one to autoconf-archive. This directory provides a local
|
||||
copy of required m4 rules.
|
39
openbsc/.gitignore
vendored
Normal file
39
openbsc/.gitignore
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
*.o
|
||||
*.a
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
bsc_hack
|
||||
bsc_msc_ip
|
||||
*.*~
|
||||
*.sw?
|
||||
|
||||
#configure
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
config.log
|
||||
config.status
|
||||
configure
|
||||
depcomp
|
||||
install-sh
|
||||
missing
|
||||
stamp-h1
|
||||
|
||||
|
||||
|
||||
# apps and app data
|
||||
hlr.sqlite3
|
||||
bs11_config
|
||||
ipaccess-config
|
||||
ipaccess-find
|
||||
isdnsync
|
||||
|
||||
#tests
|
||||
tests/channel/channel_test
|
||||
tests/db/db_test
|
||||
tests/debug/debug_test
|
||||
tests/gsm0408/gsm0408_test
|
||||
tests/sccp/sccp_test
|
||||
tests/sms/sms_test
|
||||
tests/timer/timer_test
|
||||
|
@@ -3,7 +3,3 @@ Holger Freyther <zecke@selfish.org>
|
||||
Jan Luebbe <jluebbe@debian.org>
|
||||
Stefan Schmidt <stefan@datenfreihafen.org>
|
||||
Daniel Willmann <daniel@totalueberwachung.de>
|
||||
Andreas Eversberg <Andreas.Eversberg@versatel.de>
|
||||
Sylvain Munaut <246tnt@gmail.com>
|
||||
Jacob Erlbeck <jerlbeck@sysmocom.de>
|
||||
Neels Hofmeyr <nhofmeyr@sysmocom.de>
|
339
openbsc/COPYING
Normal file
339
openbsc/COPYING
Normal 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.
|
10
openbsc/Makefile.am
Normal file
10
openbsc/Makefile.am
Normal file
@@ -0,0 +1,10 @@
|
||||
AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6
|
||||
|
||||
INCLUDES = $(all_includes) -I$(top_srcdir)/include
|
||||
SUBDIRS = include src tests
|
||||
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = openbsc.pc
|
||||
|
||||
#dist-hook:
|
||||
# rm -rf `find $(distdir) -name .svn`
|
18
openbsc/README
Normal file
18
openbsc/README
Normal file
@@ -0,0 +1,18 @@
|
||||
About OpenBSC
|
||||
=============
|
||||
|
||||
OpenBSC is a minimalistic implementation of the GSM Network, with particular
|
||||
emphasis on the functionality typically provided by the BSC, MSC, HLR, VLR.
|
||||
|
||||
Its only current interface is a mISDN based E1 interface utilizing the A-bis
|
||||
protocol between BSC and BTS. In other words, you can connect an existing
|
||||
GSM Base Transceiver Station (BTS) through E1 to OpenBSC.
|
||||
|
||||
So far, it has only been tested with the Siemens microBTS BS-11. Test reports
|
||||
with other BTS are appreciated!
|
||||
|
||||
This project is still in its early days, and there are lots of areas where it
|
||||
doesn't behave as per GSM spec.
|
||||
|
||||
December 29, 2008
|
||||
Harald Welte <laforge@gnumonks.org>
|
54
openbsc/configure.in
Normal file
54
openbsc/configure.in
Normal file
@@ -0,0 +1,54 @@
|
||||
dnl Process this file with autoconf to produce a configure script
|
||||
AC_INIT
|
||||
|
||||
AM_INIT_AUTOMAKE(openbsc, 0.1onwaves)
|
||||
|
||||
dnl kernel style compile messages
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
dnl checks for programs
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_RANLIB
|
||||
|
||||
dnl checks for libraries
|
||||
AC_SEARCH_LIBS(crypt, crypt,
|
||||
[LIBCRYPT="-lcrypt"; AC_DEFINE([VTY_CRYPT_PW], [], [Use crypt functionality of vty.])])
|
||||
|
||||
dnl checks for header files
|
||||
AC_HEADER_STDC
|
||||
|
||||
dnl Checks for typedefs, structures and compiler characteristics
|
||||
|
||||
# The following test is taken from WebKit's webkit.m4
|
||||
saved_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -fvisibility=hidden "
|
||||
AC_MSG_CHECKING([if ${CC} supports -fvisibility=hidden])
|
||||
AC_COMPILE_IFELSE([char foo;],
|
||||
[ AC_MSG_RESULT([yes])
|
||||
SYMBOL_VISIBILITY="-fvisibility=hidden"],
|
||||
AC_MSG_RESULT([no]))
|
||||
CFLAGS="$saved_CFLAGS"
|
||||
AC_SUBST(SYMBOL_VISIBILITY)
|
||||
|
||||
|
||||
dnl Generate the output
|
||||
AM_CONFIG_HEADER(bscconfig.h)
|
||||
|
||||
AC_OUTPUT(
|
||||
openbsc.pc
|
||||
include/openbsc/Makefile
|
||||
include/vty/Makefile
|
||||
include/sccp/Makefile
|
||||
include/Makefile
|
||||
src/Makefile
|
||||
tests/Makefile
|
||||
tests/debug/Makefile
|
||||
tests/timer/Makefile
|
||||
tests/sms/Makefile
|
||||
tests/gsm0408/Makefile
|
||||
tests/db/Makefile
|
||||
tests/channel/Makefile
|
||||
tests/sccp/Makefile
|
||||
Makefile)
|
2
openbsc/contrib/README
Normal file
2
openbsc/contrib/README
Normal file
@@ -0,0 +1,2 @@
|
||||
This contains a set of scripts used for the development of the
|
||||
MSC functionality.
|
33
openbsc/contrib/bt.py
Executable file
33
openbsc/contrib/bt.py
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
|
||||
f = open("unbalanced")
|
||||
lines = []
|
||||
for line in f:
|
||||
lines.append(line)
|
||||
|
||||
filenames = {}
|
||||
|
||||
output = []
|
||||
for line in lines:
|
||||
if "[0x" in line:
|
||||
start = line.find("[")
|
||||
end = line.find("]")
|
||||
addr = line[start+1:end]
|
||||
try:
|
||||
file = filenames[addr]
|
||||
except KeyError:
|
||||
r = os.popen("addr2line -fs -e ./bsc_hack %s" % addr)
|
||||
all = r.read().replace("\n", ",")
|
||||
file = all
|
||||
filenames[addr] = file
|
||||
|
||||
line = line.replace(addr, file)
|
||||
output.append(line)
|
||||
|
||||
g = open("unbalanced.2", "w")
|
||||
g.write("".join(output))
|
||||
|
||||
|
||||
|
37
openbsc/contrib/convert_to_enum.py
Executable file
37
openbsc/contrib/convert_to_enum.py
Executable file
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#
|
||||
# Convert ETSI documents to an enum
|
||||
#
|
||||
|
||||
import re, sys
|
||||
|
||||
def convert(string):
|
||||
string = string.strip().replace(" ", "").rjust(8, "0")
|
||||
var = 0
|
||||
offset = 7
|
||||
for char in string:
|
||||
assert offset >= 0
|
||||
var = var | (int(char) << offset)
|
||||
offset = offset - 1
|
||||
|
||||
return var
|
||||
|
||||
def string(name):
|
||||
name = name.replace(" ", "_")
|
||||
name = name.replace('"', "")
|
||||
name = name.replace('/', '_')
|
||||
name = name.replace('(', '_')
|
||||
name = name.replace(')', '_')
|
||||
return "%s_%s" % (sys.argv[2], name.upper())
|
||||
|
||||
file = open(sys.argv[1])
|
||||
|
||||
|
||||
for line in file:
|
||||
m = re.match(r"[ \t]*(?P<value>[01 ]+)[ ]+(?P<name>[a-zA-Z /0-9()]+)", line[:-1])
|
||||
|
||||
if m:
|
||||
print "\t%s\t\t= %d," % (string(m.groupdict()["name"]), convert(m.groupdict()["value"]))
|
||||
else:
|
||||
print line[:-1]
|
@@ -10,7 +10,7 @@ rsip_resp = """200 321321332\r\n"""
|
||||
audit_packet = """AUEP %d 13@mgw MGCP 1.0\r\n"""
|
||||
crcx_packet = """CRCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nL: p:20, a:GSM-EFR, nt:IN\r\nM: recvonly\r\n"""
|
||||
dlcx_packet = """DLCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nI: %d\r\n"""
|
||||
mdcx_packet = """MDCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nI: %d\r\nL: p:20, a:GSM-EFR, nt:IN\r\nM: recvonly\r\n\r\nv=0\r\no=- 258696477 0 IN IP4 172.16.1.107\r\ns=-\r\nc=IN IP4 172.16.1.107\r\nt=0 0\r\nm=audio 6666 RTP/AVP 127\r\na=rtpmap:127 GSM-EFR/8000/1\r\na=ptime:20\r\na=recvonly\r\nm=image 4402 udptl t38\r\na=T38FaxVersion:0\r\na=T38MaxBitRate:14400\r\n"""
|
||||
mdcx_packet = """MDCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nI: %d\r\nL: p:20, a:GSM-EFR, nt:IN\r\nM: recvonly\r\n\r\nv=0\r\no=- 258696477 0 IN IP4 172.16.1.107\r\ns=-\r\nc=IN IP4 172.16.1.107\r\nt=0 0\r\nm=audio 4400 RTP/AVP 127\r\na=rtpmap:127 GSM-EFR/8000/1\r\na=ptime:20\r\na=recvonly\r\nm=image 4402 udptl t38\r\na=T38FaxVersion:0\r\na=T38MaxBitRate:14400\r\n"""
|
||||
|
||||
def hexdump(src, length=8):
|
||||
"""Recipe is from http://code.activestate.com/recipes/142812/"""
|
||||
@@ -25,24 +25,15 @@ def hexdump(src, length=8):
|
||||
|
||||
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
server_socket.bind(("127.0.0.1", MGCP_CALLAGENT_PORT))
|
||||
server_socket.setblocking(1)
|
||||
server_socket.setblocking(0)
|
||||
|
||||
last_ci = 1
|
||||
def send_and_receive(packet):
|
||||
global last_ci
|
||||
|
||||
def send_receive(packet):
|
||||
server_socket.sendto(packet, ("127.0.0.1", MGCP_GATEWAY_PORT))
|
||||
try:
|
||||
data, addr = server_socket.recvfrom(4096)
|
||||
|
||||
# attempt to store the CI of the response
|
||||
list = data.split("\n")
|
||||
for item in list:
|
||||
if item.startswith("I: "):
|
||||
last_ci = int(item[3:])
|
||||
|
||||
print hexdump(data), addr
|
||||
except socket.error, e:
|
||||
print e
|
||||
except socket.error:
|
||||
pass
|
||||
|
||||
def generate_tid():
|
||||
@@ -51,10 +42,13 @@ def generate_tid():
|
||||
|
||||
|
||||
|
||||
i = 1
|
||||
while True:
|
||||
send_and_receive(audit_packet % generate_tid())
|
||||
send_and_receive(crcx_packet % generate_tid() )
|
||||
send_and_receive(mdcx_packet % (generate_tid(), last_ci))
|
||||
send_and_receive(dlcx_packet % (generate_tid(), last_ci))
|
||||
send_receive(rsip_resp)
|
||||
send_receive(audit_packet)
|
||||
send_receive(crcx_packet % generate_tid() )
|
||||
send_receive(mdcx_packet % (generate_tid(), i))
|
||||
send_receive(dlcx_packet % (generate_tid(), i))
|
||||
i = i + 1
|
||||
|
||||
time.sleep(3)
|
30
openbsc/contrib/send_handshake.py
Executable file
30
openbsc/contrib/send_handshake.py
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
|
||||
# packages
|
||||
ACK ="\x00\x01\xfe\x06"
|
||||
RESET_ACK = "\x00\x13\xfd\x09\x00\x03\x07\x0b\x04\x43\x01\x00\xfe\x04\x43\x5c\x00\xfe\x03\x00\x01\x31"
|
||||
PAGE = "\x00\x20\xfd\x09\x00\x03\x07\x0b\x04\x43\x01\x00\xfe\x04\x43\x5c\x00\xfe\x10\x00\x0e\x52\x08\x08\x29\x42\x08\x05\x03\x12\x23\x42\x1a\x01\x06"
|
||||
|
||||
|
||||
# simple handshake...
|
||||
sys.stdout.write(ACK)
|
||||
sys.stdout.flush()
|
||||
sys.stdin.read(4)
|
||||
|
||||
# wait for some data and send reset ack
|
||||
sys.stdin.read(21)
|
||||
sys.stdout.write(RESET_ACK)
|
||||
sys.stdout.flush()
|
||||
|
||||
sys.stdout.write(RESET_ACK)
|
||||
sys.stdout.flush()
|
||||
|
||||
# page a subscriber
|
||||
sys.stdout.write(PAGE)
|
||||
sys.stdout.flush()
|
||||
|
||||
while True:
|
||||
sys.stdin.read(1)
|
||||
|
31
openbsc/doc/BS11-OML.txt
Normal file
31
openbsc/doc/BS11-OML.txt
Normal file
@@ -0,0 +1,31 @@
|
||||
The Siemens BS-11 supports the following additional GSM 12.21 OML operations:
|
||||
|
||||
|
||||
CREATE OBJECT
|
||||
|
||||
abis_om_fom_hdr.obj_class can be
|
||||
A3:
|
||||
A5: ALCO, BBSIG, CCLK, GPSU, LI, PA
|
||||
A8: EnvaBTSE
|
||||
A9: BPORT
|
||||
|
||||
the abis_om_obj_inst.trx_nr field indicates the index of object, whereas the
|
||||
abis_om_fom_hdr.bts_nr indicates the type of the object.
|
||||
|
||||
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*/
|
||||
};
|
||||
|
||||
In case of CREATE ENVABTSE, the abis_om_obj_inst.trx_nr indicates the EnvaBTSEx
|
||||
number.
|
||||
|
||||
In case of A9 (CREAETE BPORT), the abis_om_obj_inst.bts_nr indicates which BPORT
|
||||
shall be used.
|
||||
|
||||
|
25
openbsc/doc/call-routing.txt
Normal file
25
openbsc/doc/call-routing.txt
Normal file
@@ -0,0 +1,25 @@
|
||||
Call routing in OpenBSC
|
||||
|
||||
Flow of events:
|
||||
|
||||
# MO call initiated by MS, CHANNEL RQD, IMMEDIATE ASSIGN
|
||||
# MS sends CC SETUP message, we assume already on TCH/H FACCH
|
||||
# OpenBSC does a subscriber lookup based on the target extension
|
||||
* If a subscriber is found:
|
||||
# send CALL PROCEEDING message to MO
|
||||
# page the MT subscriber and ask itI to ask for TCH/H
|
||||
# once paging completes, we have the TCH/H for the MT end
|
||||
# send SETUP to MT
|
||||
# receive CALL CONFIRMED from MT
|
||||
# set-up the TRAU mux mapping between the E1 subslots for both TCH/H
|
||||
# receive ALERTING from MT, route ALERTING to MO
|
||||
# receive CONNECT from MT, confirm to MT with CONNECT_ACK
|
||||
# send a CONNECT message to MO, receive CONNECT_ACK from MO
|
||||
* If subscriber is not found:
|
||||
# send RELEASE COMPLETE with apropriate cause to MO (1: unalloacated 3: no route)
|
||||
|
||||
|
||||
|
||||
Thoughts about RR/MM:
|
||||
|
||||
* we allocate RR/MM entities on demand, when we need them
|
74
openbsc/doc/channel_release.txt
Normal file
74
openbsc/doc/channel_release.txt
Normal file
@@ -0,0 +1,74 @@
|
||||
|
||||
GSM 04.08 7.1.7 / 9.1.7 RR CHANNEL RELESE
|
||||
|
||||
RSL 08.58 3.4 / ? RLL Link Release Request
|
||||
|
||||
RSL 08.58 4.6 / 8.4.5 DEACTivate SACCH
|
||||
* Deactivate SACCH according to Channel Release Proc 04.08
|
||||
* to be sent after RR CHANNEL RELEASE is sent to MS
|
||||
|
||||
RSL 08.58 4.7 / 8.4.14 RF CHANnel RELease
|
||||
* tells the BTS to release a radio channel
|
||||
* "when an activated radio channel is no longer needed"
|
||||
* BTS responds with RF CHANnel RELease ACKnowledge
|
||||
|
||||
|
||||
GSM 04.08 3.4.13: RR connection release procedure
|
||||
|
||||
* network sends RR CHANNEL RELEASE to MS on the DCCH
|
||||
* start T3109
|
||||
* deactivate SACCH
|
||||
* MS disconnects main signalling link (by sending DISC)
|
||||
* all other data links are disconnected by local end link release
|
||||
* network receives DISC (BTS sends RLL REL IND to BSC)
|
||||
* stop T3109
|
||||
* start T3111
|
||||
* when T3111 times out, the network can reuse the channls
|
||||
* if T3109 times out, the network deactivates the channels
|
||||
and can reuse them
|
||||
* this probably means simply RF CHANnel RELease
|
||||
|
||||
|
||||
== Implementation in OpenBSC ==
|
||||
|
||||
chan_alloc.c:lchan_auto_release()
|
||||
* checks if use count still > 0 (abort)
|
||||
* calls gsm48_send_rr_release()
|
||||
* which calls rsl_deact_sacch()
|
||||
* calls rsl_release_request()
|
||||
* which sends RLL Link Release request
|
||||
|
||||
RX of RELease INDication:
|
||||
* call rsl_rf_chan_release() (send RF_CHAN_REL)
|
||||
|
||||
RX of RELease CONFimem:
|
||||
* call rsl_rf_chan_release() (send RF_CHAN_REL)
|
||||
|
||||
* RX of RF_CHAN_REL_ACK
|
||||
* call lchan_free()
|
||||
* subscr_put()
|
||||
* delete release_timer
|
||||
|
||||
|
||||
=== Integration with SMS ===
|
||||
|
||||
* RX of CP_ERROR or unimplemented MT
|
||||
* trigger trans_free() which will lchan_auto_release()
|
||||
|
||||
* CP TC1* expired while waiting for CP-ACK
|
||||
* trigger trans_free() which will lchan_auto_release()
|
||||
|
||||
* RX of RP_ERROR
|
||||
* trigger trans_free() which will lchan_auto_release()
|
||||
|
||||
* TX of CP-ACK in MT DELIVER
|
||||
* trigger trans_free() which will lchan_auto_release()
|
||||
|
||||
* RX of CP-ACK in MO SUBMIT
|
||||
* trigger trans_free() which will lchan_auto_release()
|
||||
|
||||
* RX of RP-ACK in MT DELIVER (and no more messages)
|
||||
* trigger rsl_release_request() for SAPI3
|
||||
|
||||
* RX of RP-SMMA in MT DELIVER (and no more messages)
|
||||
* trigger rsl_release_request() for SAPI3
|
172
openbsc/doc/e1-data-model.txt
Normal file
172
openbsc/doc/e1-data-model.txt
Normal file
@@ -0,0 +1,172 @@
|
||||
E1 related data model
|
||||
|
||||
This data model describes the physical relationship of the individual
|
||||
parts in the network, it is not the logical/protocol side of the GSM
|
||||
network.
|
||||
|
||||
A BTS is connected to the BSC by some physical link. It could be an actual
|
||||
E1 link, but it could also be abis-over-IP with a mixture of TCP and RTP/UDP.
|
||||
|
||||
To further complicate the fact, multiple BTS can share one such pysical
|
||||
link. On a single E1 line, we can easily accomodate up to three BTS with
|
||||
two TRX each.
|
||||
|
||||
Thus, it is best for OpenBSC to have some kind of abstraction layer. The BSC's
|
||||
view of a BTS connected to it. We call this 'bts_link'. A bts_link can be
|
||||
* all the TCP and UDP streams of a Abis-over-IP BTS
|
||||
* a set of E1 timeslots for OML, RSL and TRAU connections on a E1 link
|
||||
* a serial line exclusively used for OML messages (T-Link)
|
||||
|
||||
A bts_link can be registered with the OpenBSC core at runtime.
|
||||
|
||||
struct trx_link {
|
||||
struct gsm_bts_trx *trx;
|
||||
};
|
||||
|
||||
struct bts_link {
|
||||
struct gsm_bts *bts;
|
||||
struct trx_link trx_links[NUM_TRX];
|
||||
};
|
||||
|
||||
Interface from stack to input core:
|
||||
======================================================================
|
||||
int abis_rsl_sendmsg(struct msgb *msg);
|
||||
send a message through a RSL link to the TRX specified by the caller in
|
||||
msg->trx.
|
||||
|
||||
int abis_rsl_rcvmsg(struct msgb *msg);
|
||||
receive a message from a RSL link from the TRX specified by the
|
||||
caller in msg->trx.
|
||||
|
||||
int abis_nm_sendmsg(struct msgb *msg);
|
||||
send a message through a OML link to the BTS specified by the caller in
|
||||
msg->trx->bts. The caller can just use bts->c0 to get the first TRX
|
||||
in a BTS. (OML messages are not really sent to a TRX but to the BTS)
|
||||
|
||||
int abis_nm_rcvmsg(struct msgb *msg);
|
||||
receive a message from a OML link from the BTS specified by the caller
|
||||
in msg->trx->bts. The caller can just use bts->c0 to get the first
|
||||
TRX in a BTS.
|
||||
|
||||
int abis_link_event(int event, void *data);
|
||||
signal some event (such as layer 1 connect/disconnect) from the
|
||||
input core to the stack.
|
||||
|
||||
int subch_demux_in(mx, const u_int8_t *data, int len);
|
||||
receive 'len' bytes from a given E1 timeslot (TRAU frames)
|
||||
|
||||
int subchan_mux_out(mx, u_int8_t *data, int len);
|
||||
obtain 'len' bytes of output data to be sent on E1 timeslot
|
||||
|
||||
Intrface by Input Core for Input Plugins
|
||||
======================================================================
|
||||
|
||||
int btslink_register_plugin();
|
||||
|
||||
|
||||
Configuration for the E1 input module
|
||||
======================================================================
|
||||
|
||||
BTS
|
||||
BTS number
|
||||
number of TRX
|
||||
OML link
|
||||
E1 line number
|
||||
timeslot number
|
||||
[subslot number]
|
||||
SAPI
|
||||
TEI
|
||||
for each TRX
|
||||
RSL link
|
||||
E1 line number
|
||||
timeslot number
|
||||
[subslot number]
|
||||
SAPI
|
||||
TEI
|
||||
for each TS
|
||||
E1 line number
|
||||
timeslot number
|
||||
subslot number
|
||||
|
||||
|
||||
E1 input module data model
|
||||
======================================================================
|
||||
|
||||
|
||||
enum e1inp_sign_type {
|
||||
E1INP_SIGN_NONE,
|
||||
E1INP_SIGN_OML,
|
||||
E1INP_SIGN_RSL,
|
||||
};
|
||||
|
||||
struct e1inp_sign_link {
|
||||
/* list of signalling links */
|
||||
struct llist_head list;
|
||||
|
||||
enum e1inp_sign_type type;
|
||||
|
||||
/* trx for msg->trx of received msgs */
|
||||
struct gsm_bts_trx *trx;
|
||||
|
||||
/* msgb queue of to-be-transmitted msgs */
|
||||
struct llist_head tx_list;
|
||||
|
||||
/* SAPI and TEI on the E1 TS */
|
||||
u_int8_t sapi;
|
||||
u_int8_t tei;
|
||||
}
|
||||
|
||||
enum e1inp_ts_type {
|
||||
E1INP_TS_TYPE_NONE,
|
||||
E1INP_TS_TYPE_SIGN,
|
||||
E1INP_TS_TYPE_TRAU,
|
||||
};
|
||||
|
||||
/* A timeslot in the E1 interface */
|
||||
struct e1inp_ts {
|
||||
enum e1inp_ts_type type;
|
||||
struct e1inp_line *line;
|
||||
union {
|
||||
struct {
|
||||
struct llist_head sign_links;
|
||||
} sign;
|
||||
struct {
|
||||
/* subchannel demuxer for frames from E1 */
|
||||
struct subch_demux demux;
|
||||
/* subchannel muxer for frames to E1 */
|
||||
struct subch_mux mux;
|
||||
} trau;
|
||||
};
|
||||
union {
|
||||
struct {
|
||||
/* mISDN driver has one fd for each ts */
|
||||
struct bsc_fd;
|
||||
} misdn;
|
||||
} driver;
|
||||
};
|
||||
|
||||
struct e1inp_line {
|
||||
unsigned int num;
|
||||
char *name;
|
||||
|
||||
struct e1inp_ts ts[NR_E1_TS];
|
||||
|
||||
char *e1inp_driver;
|
||||
void *driver_data;
|
||||
};
|
||||
|
||||
/* Call from the Stack: configuration of this TS has changed */
|
||||
int e1inp_update_ts(struct e1inp_ts *ts);
|
||||
|
||||
/* Receive a packet from the E1 driver */
|
||||
int e1inp_rx_ts(struct e1inp_ts *ts, struct msgb *msg,
|
||||
u_int8_t tei, u_int8_t sapi);
|
||||
|
||||
/* Send a packet, callback function in the driver */
|
||||
int e1driver_tx_ts(struct e1inp_ts *ts, struct msgb *msg)
|
||||
|
||||
|
||||
struct e1inp_driver {
|
||||
const char *name;
|
||||
int (*want_write)(struct e1inp_ts *ts);
|
||||
};
|
54
openbsc/doc/gsm-hopping.txt
Normal file
54
openbsc/doc/gsm-hopping.txt
Normal file
@@ -0,0 +1,54 @@
|
||||
according to GSM 05.02:
|
||||
|
||||
general parameters from CCCH:
|
||||
* CA cell allocation of ARFCN's (System Information / BCCH)
|
||||
* FN: TDMA frame number (t1,t2,t3') in SCH
|
||||
|
||||
specific parameters from channel assignment:
|
||||
* MA: mobile allocation, defines set of ARFCN's, up to 64
|
||||
* MAIO: index
|
||||
* HSN: hopping sequence generator number (0..64)
|
||||
|
||||
|
||||
hopping sequence generation (6.2.3):
|
||||
|
||||
u_int8_t rntable[114] = {
|
||||
48, 98, 63, 1, 36, 95, 78, 102, 94, 73,
|
||||
0, 64, 25, 81, 76, 59, 124, 23, 104, 100,
|
||||
101, 47, 118, 85, 18, 56, 96, 86, 54, 2,
|
||||
80, 34, 127, 13, 6, 89, 57, 103, 12, 74,
|
||||
55, 111, 75, 38, 109, 71, 112, 29, 11, 88,
|
||||
87, 19, 3, 68, 110, 26, 33, 31, 8, 45,
|
||||
82, 58, 40, 107, 32, 5, 106, 92, 62, 67,
|
||||
77, 108, 122, 37, 60, 66, 121, 42, 51, 126,
|
||||
117, 114, 4, 90, 43, 52, 53, 113, 120, 72,
|
||||
16, 49, 7, 79, 119, 61, 22, 84, 9, 97,
|
||||
125, 99, 17, 123
|
||||
};
|
||||
|
||||
/* mai=0 represents lowest ARFCN in the MA */
|
||||
|
||||
|
||||
u_int8_t hopping_mai(u_int8_t hsn, u_int32_t fn, u_int8_t maio,
|
||||
u_int8_t t1, u_int8_t t2, u_int8_t t3_)
|
||||
{
|
||||
u_int8_t mai;
|
||||
|
||||
if (hsn == 0) /* cyclic hopping */
|
||||
mai = (fn + maio) % n;
|
||||
else {
|
||||
u_int32_t m, m_, t_, s;
|
||||
|
||||
m = t2 + rntable[(hsn xor (t1 % 64)) + t3];
|
||||
m_ = m % (2^NBIN);
|
||||
t_ = t3 % (2^NBIN);
|
||||
if (m_ < n then)
|
||||
s = m_;
|
||||
else
|
||||
s = (m_ + t_) % n;
|
||||
mai = (s + maio) % n;
|
||||
}
|
||||
|
||||
return mai;
|
||||
}
|
||||
|
21
openbsc/doc/oml-interface.txt
Normal file
21
openbsc/doc/oml-interface.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
oml interface design notes
|
||||
|
||||
problems:
|
||||
|
||||
* there is no way how to tag a command sent to the BTS, with the response
|
||||
having the same tag to identify the originator of the command
|
||||
* therefore, we can have e.g. both the BSC and the OML interface send a
|
||||
SET ATTRIBUTE message, where the responses would end up at the wrong
|
||||
query.
|
||||
|
||||
the only possible solutions i can imagine:
|
||||
* have some kind of exclusive locking, where the OML interface gets blocked
|
||||
from the BSC and is exclusively assigned to the OML console until all commands
|
||||
of the OML console have terminated. This can either be done explicitly
|
||||
dynamically or on demand
|
||||
|
||||
* use the OML interface synchronously, i.e. always wait for the response from
|
||||
the BTS before
|
||||
|
||||
* unilateral / unsolicited messages need to be broadcasted to both the BSC and
|
||||
the OML console
|
3
openbsc/include/Makefile.am
Normal file
3
openbsc/include/Makefile.am
Normal file
@@ -0,0 +1,3 @@
|
||||
SUBDIRS = openbsc vty sccp
|
||||
|
||||
noinst_HEADERS = mISDNif.h compat_af_isdn.h
|
39
openbsc/include/compat_af_isdn.h
Normal file
39
openbsc/include/compat_af_isdn.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifdef MISDN_OLD_AF_COMPATIBILITY
|
||||
#undef AF_ISDN
|
||||
#undef PF_ISDN
|
||||
|
||||
extern int AF_ISDN;
|
||||
#define PF_ISDN AF_ISDN
|
||||
|
||||
int AF_ISDN;
|
||||
|
||||
#endif
|
||||
|
||||
extern void init_af_isdn(void);
|
||||
|
||||
#ifdef AF_COMPATIBILITY_FUNC
|
||||
#ifdef MISDN_OLD_AF_COMPATIBILITY
|
||||
void init_af_isdn(void)
|
||||
{
|
||||
int s;
|
||||
|
||||
/* test for new value */
|
||||
AF_ISDN = 34;
|
||||
s = socket(AF_ISDN, SOCK_RAW, ISDN_P_BASE);
|
||||
if (s >= 0) {
|
||||
close(s);
|
||||
return;
|
||||
}
|
||||
AF_ISDN = 27;
|
||||
s = socket(AF_ISDN, SOCK_RAW, ISDN_P_BASE);
|
||||
if (s >= 0) {
|
||||
close(s);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
void init_af_isdn(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
#endif
|
387
openbsc/include/mISDNif.h
Normal file
387
openbsc/include/mISDNif.h
Normal file
@@ -0,0 +1,387 @@
|
||||
/*
|
||||
*
|
||||
* Author Karsten Keil <kkeil@novell.com>
|
||||
*
|
||||
* Copyright 2008 by Karsten Keil <kkeil@novell.com>
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE
|
||||
* version 2.1 as published by the Free Software Foundation.
|
||||
*
|
||||
* This code 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef mISDNIF_H
|
||||
#define mISDNIF_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#ifdef linux
|
||||
#include <linux/types.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/socket.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ABI Version 32 bit
|
||||
*
|
||||
* <8 bit> Major version
|
||||
* - changed if any interface become backwards incompatible
|
||||
*
|
||||
* <8 bit> Minor version
|
||||
* - changed if any interface is extended but backwards compatible
|
||||
*
|
||||
* <16 bit> Release number
|
||||
* - should be incremented on every checkin
|
||||
*/
|
||||
#define MISDN_MAJOR_VERSION 1
|
||||
#define MISDN_MINOR_VERSION 1
|
||||
#define MISDN_RELEASE 20
|
||||
|
||||
/* primitives for information exchange
|
||||
* generell format
|
||||
* <16 bit 0 >
|
||||
* <8 bit command>
|
||||
* BIT 8 = 1 LAYER private
|
||||
* BIT 7 = 1 answer
|
||||
* BIT 6 = 1 DATA
|
||||
* <8 bit target layer mask>
|
||||
*
|
||||
* Layer = 00 is reserved for general commands
|
||||
Layer = 01 L2 -> HW
|
||||
Layer = 02 HW -> L2
|
||||
Layer = 04 L3 -> L2
|
||||
Layer = 08 L2 -> L3
|
||||
* Layer = FF is reserved for broadcast commands
|
||||
*/
|
||||
|
||||
#define MISDN_CMDMASK 0xff00
|
||||
#define MISDN_LAYERMASK 0x00ff
|
||||
|
||||
/* generell commands */
|
||||
#define OPEN_CHANNEL 0x0100
|
||||
#define CLOSE_CHANNEL 0x0200
|
||||
#define CONTROL_CHANNEL 0x0300
|
||||
#define CHECK_DATA 0x0400
|
||||
|
||||
/* layer 2 -> layer 1 */
|
||||
#define PH_ACTIVATE_REQ 0x0101
|
||||
#define PH_DEACTIVATE_REQ 0x0201
|
||||
#define PH_DATA_REQ 0x2001
|
||||
#define MPH_ACTIVATE_REQ 0x0501
|
||||
#define MPH_DEACTIVATE_REQ 0x0601
|
||||
#define MPH_INFORMATION_REQ 0x0701
|
||||
#define PH_CONTROL_REQ 0x0801
|
||||
|
||||
/* layer 1 -> layer 2 */
|
||||
#define PH_ACTIVATE_IND 0x0102
|
||||
#define PH_ACTIVATE_CNF 0x4102
|
||||
#define PH_DEACTIVATE_IND 0x0202
|
||||
#define PH_DEACTIVATE_CNF 0x4202
|
||||
#define PH_DATA_IND 0x2002
|
||||
#define PH_DATA_E_IND 0x3002
|
||||
#define MPH_ACTIVATE_IND 0x0502
|
||||
#define MPH_DEACTIVATE_IND 0x0602
|
||||
#define MPH_INFORMATION_IND 0x0702
|
||||
#define PH_DATA_CNF 0x6002
|
||||
#define PH_CONTROL_IND 0x0802
|
||||
#define PH_CONTROL_CNF 0x4802
|
||||
|
||||
/* layer 3 -> layer 2 */
|
||||
#define DL_ESTABLISH_REQ 0x1004
|
||||
#define DL_RELEASE_REQ 0x1104
|
||||
#define DL_DATA_REQ 0x3004
|
||||
#define DL_UNITDATA_REQ 0x3104
|
||||
#define DL_INFORMATION_REQ 0x0004
|
||||
|
||||
/* layer 2 -> layer 3 */
|
||||
#define DL_ESTABLISH_IND 0x1008
|
||||
#define DL_ESTABLISH_CNF 0x5008
|
||||
#define DL_RELEASE_IND 0x1108
|
||||
#define DL_RELEASE_CNF 0x5108
|
||||
#define DL_DATA_IND 0x3008
|
||||
#define DL_UNITDATA_IND 0x3108
|
||||
#define DL_INFORMATION_IND 0x0008
|
||||
|
||||
/* intern layer 2 managment */
|
||||
#define MDL_ASSIGN_REQ 0x1804
|
||||
#define MDL_ASSIGN_IND 0x1904
|
||||
#define MDL_REMOVE_REQ 0x1A04
|
||||
#define MDL_REMOVE_IND 0x1B04
|
||||
#define MDL_STATUS_UP_IND 0x1C04
|
||||
#define MDL_STATUS_DOWN_IND 0x1D04
|
||||
#define MDL_STATUS_UI_IND 0x1E04
|
||||
#define MDL_ERROR_IND 0x1F04
|
||||
#define MDL_ERROR_RSP 0x5F04
|
||||
|
||||
/* DL_INFORMATION_IND types */
|
||||
#define DL_INFO_L2_CONNECT 0x0001
|
||||
#define DL_INFO_L2_REMOVED 0x0002
|
||||
|
||||
/* PH_CONTROL types */
|
||||
/* TOUCH TONE IS 0x20XX XX "0"..."9", "A","B","C","D","*","#" */
|
||||
#define DTMF_TONE_VAL 0x2000
|
||||
#define DTMF_TONE_MASK 0x007F
|
||||
#define DTMF_TONE_START 0x2100
|
||||
#define DTMF_TONE_STOP 0x2200
|
||||
#define DTMF_HFC_COEF 0x4000
|
||||
#define DSP_CONF_JOIN 0x2403
|
||||
#define DSP_CONF_SPLIT 0x2404
|
||||
#define DSP_RECEIVE_OFF 0x2405
|
||||
#define DSP_RECEIVE_ON 0x2406
|
||||
#define DSP_ECHO_ON 0x2407
|
||||
#define DSP_ECHO_OFF 0x2408
|
||||
#define DSP_MIX_ON 0x2409
|
||||
#define DSP_MIX_OFF 0x240a
|
||||
#define DSP_DELAY 0x240b
|
||||
#define DSP_JITTER 0x240c
|
||||
#define DSP_TXDATA_ON 0x240d
|
||||
#define DSP_TXDATA_OFF 0x240e
|
||||
#define DSP_TX_DEJITTER 0x240f
|
||||
#define DSP_TX_DEJ_OFF 0x2410
|
||||
#define DSP_TONE_PATT_ON 0x2411
|
||||
#define DSP_TONE_PATT_OFF 0x2412
|
||||
#define DSP_VOL_CHANGE_TX 0x2413
|
||||
#define DSP_VOL_CHANGE_RX 0x2414
|
||||
#define DSP_BF_ENABLE_KEY 0x2415
|
||||
#define DSP_BF_DISABLE 0x2416
|
||||
#define DSP_BF_ACCEPT 0x2416
|
||||
#define DSP_BF_REJECT 0x2417
|
||||
#define DSP_PIPELINE_CFG 0x2418
|
||||
#define HFC_VOL_CHANGE_TX 0x2601
|
||||
#define HFC_VOL_CHANGE_RX 0x2602
|
||||
#define HFC_SPL_LOOP_ON 0x2603
|
||||
#define HFC_SPL_LOOP_OFF 0x2604
|
||||
|
||||
/* DSP_TONE_PATT_ON parameter */
|
||||
#define TONE_OFF 0x0000
|
||||
#define TONE_GERMAN_DIALTONE 0x0001
|
||||
#define TONE_GERMAN_OLDDIALTONE 0x0002
|
||||
#define TONE_AMERICAN_DIALTONE 0x0003
|
||||
#define TONE_GERMAN_DIALPBX 0x0004
|
||||
#define TONE_GERMAN_OLDDIALPBX 0x0005
|
||||
#define TONE_AMERICAN_DIALPBX 0x0006
|
||||
#define TONE_GERMAN_RINGING 0x0007
|
||||
#define TONE_GERMAN_OLDRINGING 0x0008
|
||||
#define TONE_AMERICAN_RINGPBX 0x000b
|
||||
#define TONE_GERMAN_RINGPBX 0x000c
|
||||
#define TONE_GERMAN_OLDRINGPBX 0x000d
|
||||
#define TONE_AMERICAN_RINGING 0x000e
|
||||
#define TONE_GERMAN_BUSY 0x000f
|
||||
#define TONE_GERMAN_OLDBUSY 0x0010
|
||||
#define TONE_AMERICAN_BUSY 0x0011
|
||||
#define TONE_GERMAN_HANGUP 0x0012
|
||||
#define TONE_GERMAN_OLDHANGUP 0x0013
|
||||
#define TONE_AMERICAN_HANGUP 0x0014
|
||||
#define TONE_SPECIAL_INFO 0x0015
|
||||
#define TONE_GERMAN_GASSENBESETZT 0x0016
|
||||
#define TONE_GERMAN_AUFSCHALTTON 0x0016
|
||||
|
||||
/* MPH_INFORMATION_IND */
|
||||
#define L1_SIGNAL_LOS_OFF 0x0010
|
||||
#define L1_SIGNAL_LOS_ON 0x0011
|
||||
#define L1_SIGNAL_AIS_OFF 0x0012
|
||||
#define L1_SIGNAL_AIS_ON 0x0013
|
||||
#define L1_SIGNAL_RDI_OFF 0x0014
|
||||
#define L1_SIGNAL_RDI_ON 0x0015
|
||||
#define L1_SIGNAL_SLIP_RX 0x0020
|
||||
#define L1_SIGNAL_SLIP_TX 0x0021
|
||||
|
||||
/*
|
||||
* protocol ids
|
||||
* D channel 1-31
|
||||
* B channel 33 - 63
|
||||
*/
|
||||
|
||||
#define ISDN_P_NONE 0
|
||||
#define ISDN_P_BASE 0
|
||||
#define ISDN_P_TE_S0 0x01
|
||||
#define ISDN_P_NT_S0 0x02
|
||||
#define ISDN_P_TE_E1 0x03
|
||||
#define ISDN_P_NT_E1 0x04
|
||||
#define ISDN_P_TE_UP0 0x05
|
||||
#define ISDN_P_NT_UP0 0x06
|
||||
|
||||
#define IS_ISDN_P_TE(p) ((p == ISDN_P_TE_S0) || (p == ISDN_P_TE_E1) || \
|
||||
(p == ISDN_P_TE_UP0) || (p == ISDN_P_LAPD_TE))
|
||||
#define IS_ISDN_P_NT(p) ((p == ISDN_P_NT_S0) || (p == ISDN_P_NT_E1) || \
|
||||
(p == ISDN_P_NT_UP0) || (p == ISDN_P_LAPD_NT))
|
||||
#define IS_ISDN_P_S0(p) ((p == ISDN_P_TE_S0) || (p == ISDN_P_NT_S0))
|
||||
#define IS_ISDN_P_E1(p) ((p == ISDN_P_TE_E1) || (p == ISDN_P_NT_E1))
|
||||
#define IS_ISDN_P_UP0(p) ((p == ISDN_P_TE_UP0) || (p == ISDN_P_NT_UP0))
|
||||
|
||||
|
||||
#define ISDN_P_LAPD_TE 0x10
|
||||
#define ISDN_P_LAPD_NT 0x11
|
||||
|
||||
#define ISDN_P_B_MASK 0x1f
|
||||
#define ISDN_P_B_START 0x20
|
||||
|
||||
#define ISDN_P_B_RAW 0x21
|
||||
#define ISDN_P_B_HDLC 0x22
|
||||
#define ISDN_P_B_X75SLP 0x23
|
||||
#define ISDN_P_B_L2DTMF 0x24
|
||||
#define ISDN_P_B_L2DSP 0x25
|
||||
#define ISDN_P_B_L2DSPHDLC 0x26
|
||||
|
||||
#define OPTION_L2_PMX 1
|
||||
#define OPTION_L2_PTP 2
|
||||
#define OPTION_L2_FIXEDTEI 3
|
||||
#define OPTION_L2_CLEANUP 4
|
||||
|
||||
/* should be in sync with linux/kobject.h:KOBJ_NAME_LEN */
|
||||
#define MISDN_MAX_IDLEN 20
|
||||
|
||||
struct mISDNhead {
|
||||
unsigned int prim;
|
||||
unsigned int id;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define MISDN_HEADER_LEN sizeof(struct mISDNhead)
|
||||
#define MAX_DATA_SIZE 2048
|
||||
#define MAX_DATA_MEM (MAX_DATA_SIZE + MISDN_HEADER_LEN)
|
||||
#define MAX_DFRAME_LEN 260
|
||||
|
||||
#define MISDN_ID_ADDR_MASK 0xFFFF
|
||||
#define MISDN_ID_TEI_MASK 0xFF00
|
||||
#define MISDN_ID_SAPI_MASK 0x00FF
|
||||
#define MISDN_ID_TEI_ANY 0x7F00
|
||||
|
||||
#define MISDN_ID_ANY 0xFFFF
|
||||
#define MISDN_ID_NONE 0xFFFE
|
||||
|
||||
#define GROUP_TEI 127
|
||||
#define TEI_SAPI 63
|
||||
#define CTRL_SAPI 0
|
||||
|
||||
#define MISDN_MAX_CHANNEL 127
|
||||
#define MISDN_CHMAP_SIZE ((MISDN_MAX_CHANNEL + 1) >> 3)
|
||||
|
||||
#define SOL_MISDN 0
|
||||
|
||||
struct sockaddr_mISDN {
|
||||
sa_family_t family;
|
||||
unsigned char dev;
|
||||
unsigned char channel;
|
||||
unsigned char sapi;
|
||||
unsigned char tei;
|
||||
};
|
||||
|
||||
struct mISDNversion {
|
||||
unsigned char major;
|
||||
unsigned char minor;
|
||||
unsigned short release;
|
||||
};
|
||||
|
||||
#define MAX_DEVICE_ID 63
|
||||
|
||||
struct mISDN_devinfo {
|
||||
u_int id;
|
||||
u_int Dprotocols;
|
||||
u_int Bprotocols;
|
||||
u_int protocol;
|
||||
u_char channelmap[MISDN_CHMAP_SIZE];
|
||||
u_int nrbchan;
|
||||
char name[MISDN_MAX_IDLEN];
|
||||
};
|
||||
|
||||
struct mISDN_devrename {
|
||||
u_int id;
|
||||
char name[MISDN_MAX_IDLEN];
|
||||
};
|
||||
|
||||
struct ph_info_ch {
|
||||
int32_t protocol;
|
||||
int64_t Flags;
|
||||
};
|
||||
|
||||
struct ph_info_dch {
|
||||
struct ph_info_ch ch;
|
||||
int16_t state;
|
||||
int16_t num_bch;
|
||||
};
|
||||
|
||||
struct ph_info {
|
||||
struct ph_info_dch dch;
|
||||
struct ph_info_ch bch[];
|
||||
};
|
||||
|
||||
/* timer device ioctl */
|
||||
#define IMADDTIMER _IOR('I', 64, int)
|
||||
#define IMDELTIMER _IOR('I', 65, int)
|
||||
/* socket ioctls */
|
||||
#define IMGETVERSION _IOR('I', 66, int)
|
||||
#define IMGETCOUNT _IOR('I', 67, int)
|
||||
#define IMGETDEVINFO _IOR('I', 68, int)
|
||||
#define IMCTRLREQ _IOR('I', 69, int)
|
||||
#define IMCLEAR_L2 _IOR('I', 70, int)
|
||||
#define IMSETDEVNAME _IOR('I', 71, struct mISDN_devrename)
|
||||
|
||||
static inline int
|
||||
test_channelmap(u_int nr, u_char *map)
|
||||
{
|
||||
if (nr <= MISDN_MAX_CHANNEL)
|
||||
return map[nr >> 3] & (1 << (nr & 7));
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_channelmap(u_int nr, u_char *map)
|
||||
{
|
||||
map[nr >> 3] |= (1 << (nr & 7));
|
||||
}
|
||||
|
||||
static inline void
|
||||
clear_channelmap(u_int nr, u_char *map)
|
||||
{
|
||||
map[nr >> 3] &= ~(1 << (nr & 7));
|
||||
}
|
||||
|
||||
/* CONTROL_CHANNEL parameters */
|
||||
#define MISDN_CTRL_GETOP 0x0000
|
||||
#define MISDN_CTRL_LOOP 0x0001
|
||||
#define MISDN_CTRL_CONNECT 0x0002
|
||||
#define MISDN_CTRL_DISCONNECT 0x0004
|
||||
#define MISDN_CTRL_PCMCONNECT 0x0010
|
||||
#define MISDN_CTRL_PCMDISCONNECT 0x0020
|
||||
#define MISDN_CTRL_SETPEER 0x0040
|
||||
#define MISDN_CTRL_UNSETPEER 0x0080
|
||||
#define MISDN_CTRL_RX_OFF 0x0100
|
||||
#define MISDN_CTRL_FILL_EMPTY 0x0200
|
||||
#define MISDN_CTRL_GETPEER 0x0400
|
||||
#define MISDN_CTRL_HW_FEATURES_OP 0x2000
|
||||
#define MISDN_CTRL_HW_FEATURES 0x2001
|
||||
#define MISDN_CTRL_HFC_OP 0x4000
|
||||
#define MISDN_CTRL_HFC_PCM_CONN 0x4001
|
||||
#define MISDN_CTRL_HFC_PCM_DISC 0x4002
|
||||
#define MISDN_CTRL_HFC_CONF_JOIN 0x4003
|
||||
#define MISDN_CTRL_HFC_CONF_SPLIT 0x4004
|
||||
#define MISDN_CTRL_HFC_RECEIVE_OFF 0x4005
|
||||
#define MISDN_CTRL_HFC_RECEIVE_ON 0x4006
|
||||
#define MISDN_CTRL_HFC_ECHOCAN_ON 0x4007
|
||||
#define MISDN_CTRL_HFC_ECHOCAN_OFF 0x4008
|
||||
|
||||
|
||||
/* socket options */
|
||||
#define MISDN_TIME_STAMP 0x0001
|
||||
|
||||
struct mISDN_ctrl_req {
|
||||
int op;
|
||||
int channel;
|
||||
int p1;
|
||||
int p2;
|
||||
};
|
||||
|
||||
/* muxer options */
|
||||
#define MISDN_OPT_ALL 1
|
||||
#define MISDN_OPT_TEIMGR 2
|
||||
|
||||
#endif /* mISDNIF_H */
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user