summaryrefslogtreecommitdiffstats
path: root/Src/osmoconbb/src/host
diff options
context:
space:
mode:
Diffstat (limited to 'Src/osmoconbb/src/host')
-rwxr-xr-xSrc/osmoconbb/src/host/calypso_pll/pll.pl10
-rw-r--r--Src/osmoconbb/src/host/gsm48-andreas/issues.txt23
-rw-r--r--Src/osmoconbb/src/host/gsmmap/.gitignore35
-rw-r--r--Src/osmoconbb/src/host/gsmmap/Makefile.am17
-rw-r--r--Src/osmoconbb/src/host/gsmmap/configure.ac26
-rw-r--r--Src/osmoconbb/src/host/gsmmap/geo.c47
-rw-r--r--Src/osmoconbb/src/host/gsmmap/geo.h12
-rwxr-xr-xSrc/osmoconbb/src/host/gsmmap/git-version-gen151
-rw-r--r--Src/osmoconbb/src/host/gsmmap/gsmmap.c658
-rw-r--r--Src/osmoconbb/src/host/gsmmap/locate.c182
-rw-r--r--Src/osmoconbb/src/host/gsmmap/locate.h8
-rw-r--r--Src/osmoconbb/src/host/gsmmap/log.c377
-rw-r--r--Src/osmoconbb/src/host/gsmmap/log.h80
-rw-r--r--Src/osmoconbb/src/host/layer23/.gitignore36
-rw-r--r--Src/osmoconbb/src/host/layer23/COPYING339
-rw-r--r--Src/osmoconbb/src/host/layer23/Makefile.am3
-rw-r--r--Src/osmoconbb/src/host/layer23/README42
-rw-r--r--Src/osmoconbb/src/host/layer23/configure.ac38
-rw-r--r--Src/osmoconbb/src/host/layer23/include/Makefile.am2
l---------Src/osmoconbb/src/host/layer23/include/l1ctl_proto.h1
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/Makefile.am1
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/Makefile.am1
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/Makefile.am2
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/gps.h53
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/l1ctl.h76
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/l1l2_interface.h8
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/l23_app.h35
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/lapdm.h186
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/logging.h29
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/networks.h24
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/osmocom_data.h129
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/sap_interface.h11
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/sim.h274
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/sysinfo.h158
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/misc/Makefile.am1
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/misc/cell_log.h25
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/misc/layer3.h17
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/misc/rslms.h23
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/Makefile.am2
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/app_mobile.h17
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/gsm322.h255
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/gsm48_cc.h17
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h230
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h203
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/mncc.h181
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/settings.h120
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/subscriber.h107
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/support.h122
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/transaction.h71
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/voice.h7
-rw-r--r--Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/vty.h20
-rw-r--r--Src/osmoconbb/src/host/layer23/src/Makefile.am1
-rw-r--r--Src/osmoconbb/src/host/layer23/src/common/Makefile.am6
-rw-r--r--Src/osmoconbb/src/host/layer23/src/common/gps.c381
-rw-r--r--Src/osmoconbb/src/host/layer23/src/common/l1ctl.c965
-rw-r--r--Src/osmoconbb/src/host/layer23/src/common/l1ctl_lapdm_glue.c62
-rw-r--r--Src/osmoconbb/src/host/layer23/src/common/l1l2_interface.c179
-rw-r--r--Src/osmoconbb/src/host/layer23/src/common/lapdm.c2510
-rw-r--r--Src/osmoconbb/src/host/layer23/src/common/logging.c136
-rw-r--r--Src/osmoconbb/src/host/layer23/src/common/main.c289
-rw-r--r--Src/osmoconbb/src/host/layer23/src/common/networks.c1986
-rw-r--r--Src/osmoconbb/src/host/layer23/src/common/sap_interface.c189
-rw-r--r--Src/osmoconbb/src/host/layer23/src/common/sim.c1236
-rw-r--r--Src/osmoconbb/src/host/layer23/src/common/sysinfo.c859
-rw-r--r--Src/osmoconbb/src/host/layer23/src/misc/Makefile.am16
-rw-r--r--Src/osmoconbb/src/host/layer23/src/misc/app_bcch_scan.c70
-rw-r--r--Src/osmoconbb/src/host/layer23/src/misc/app_catcher.c195
-rw-r--r--Src/osmoconbb/src/host/layer23/src/misc/app_cbch_sniff.c202
-rw-r--r--Src/osmoconbb/src/host/layer23/src/misc/app_ccch_scan.c483
-rw-r--r--Src/osmoconbb/src/host/layer23/src/misc/app_cell_log.c195
-rw-r--r--Src/osmoconbb/src/host/layer23/src/misc/app_echo_test.c66
-rw-r--r--Src/osmoconbb/src/host/layer23/src/misc/bcch_scan.c318
-rw-r--r--Src/osmoconbb/src/host/layer23/src/misc/catcher.c820
-rw-r--r--Src/osmoconbb/src/host/layer23/src/misc/cell_log.c820
-rw-r--r--Src/osmoconbb/src/host/layer23/src/misc/rslms.c151
-rw-r--r--Src/osmoconbb/src/host/layer23/src/mobile/Makefile.am15
-rw-r--r--Src/osmoconbb/src/host/layer23/src/mobile/app_mobile.c404
-rw-r--r--Src/osmoconbb/src/host/layer23/src/mobile/gsm322.c5168
-rw-r--r--Src/osmoconbb/src/host/layer23/src/mobile/gsm48_cc.c2181
-rw-r--r--Src/osmoconbb/src/host/layer23/src/mobile/gsm48_mm.c4279
-rw-r--r--Src/osmoconbb/src/host/layer23/src/mobile/gsm48_rr.c5265
-rw-r--r--Src/osmoconbb/src/host/layer23/src/mobile/main.c209
-rw-r--r--Src/osmoconbb/src/host/layer23/src/mobile/mnccms.c777
-rw-r--r--Src/osmoconbb/src/host/layer23/src/mobile/settings.c189
-rw-r--r--Src/osmoconbb/src/host/layer23/src/mobile/subscriber.c1207
-rw-r--r--Src/osmoconbb/src/host/layer23/src/mobile/support.c182
-rw-r--r--Src/osmoconbb/src/host/layer23/src/mobile/transaction.c143
-rw-r--r--Src/osmoconbb/src/host/layer23/src/mobile/voice.c78
-rw-r--r--Src/osmoconbb/src/host/layer23/src/mobile/vty_interface.c2798
-rw-r--r--Src/osmoconbb/src/host/osmocon/.gitignore36
-rw-r--r--Src/osmoconbb/src/host/osmocon/COPYING339
-rw-r--r--Src/osmoconbb/src/host/osmocon/Makefile.am21
-rw-r--r--Src/osmoconbb/src/host/osmocon/configure.ac25
-rwxr-xr-xSrc/osmoconbb/src/host/osmocon/git-version-gen151
-rwxr-xr-xSrc/osmoconbb/src/host/osmocon/memdump_convert.pl29
-rw-r--r--Src/osmoconbb/src/host/osmocon/osmocon.c1558
-rw-r--r--Src/osmoconbb/src/host/osmocon/osmoload.c1216
-rw-r--r--Src/osmoconbb/src/host/osmocon/tpu_debug.c138
-rwxr-xr-xSrc/osmoconbb/src/host/rita_pll/mtk_pll.pl79
-rw-r--r--Src/osmoconbb/src/host/rita_pll/mtk_pll.txt4461
-rwxr-xr-xSrc/osmoconbb/src/host/rita_pll/rita_pll.pl115
-rw-r--r--Src/osmoconbb/src/host/rita_pll/rita_pll.txt3625
-rw-r--r--Src/osmoconbb/src/host/rita_pll/rita_pll_notes.txt19
103 files changed, 0 insertions, 51334 deletions
diff --git a/Src/osmoconbb/src/host/calypso_pll/pll.pl b/Src/osmoconbb/src/host/calypso_pll/pll.pl
deleted file mode 100755
index 52c9131..0000000
--- a/Src/osmoconbb/src/host/calypso_pll/pll.pl
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/perl
-
-my $f_in = 26*1000*1000;
-
-for (my $mult = 1; $mult < 31; $mult++) {
- for (my $div = 0; $div < 3; $div++) {
- my $fout = $f_in * ($mult / ($div+1));
- printf("%03.1f MHz (mult=%2u, div=%1u)\n", $fout/(1000*1000), $mult, $div);
- }
-}
diff --git a/Src/osmoconbb/src/host/gsm48-andreas/issues.txt b/Src/osmoconbb/src/host/gsm48-andreas/issues.txt
deleted file mode 100644
index 49a796b..0000000
--- a/Src/osmoconbb/src/host/gsm48-andreas/issues.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-Location updating procedure:
-
-OpenBSC:
-If tx_setup fails during process, the msg must be freed to avoid memory leak.
-
-OpenBSC:
-Must use *_LOC_PRN_S_LU on protocol side.
-Or it uses *_LOC_PUN_S_LU to hide private network type (maybe some cfg option)
-
-OpenBSC:
-Wrong channel is assigned when mobile supports TCH only.
-
-LCR:
-Also LCR must use correct location.
-For MS support, it must use *_LOC_USER
-
-mncc.h of openbsc / layer23:
-What about putting all (except call structure) to osmocore?
-
-
-
-
-
diff --git a/Src/osmoconbb/src/host/gsmmap/.gitignore b/Src/osmoconbb/src/host/gsmmap/.gitignore
deleted file mode 100644
index 661fd13..0000000
--- a/Src/osmoconbb/src/host/gsmmap/.gitignore
+++ /dev/null
@@ -1,35 +0,0 @@
-# autoreconf by-products
-*.in
-
-aclocal.m4
-autom4te.cache/
-configure
-depcomp
-install-sh
-missing
-
-# configure by-products
-.deps/
-Makefile
-
-config.status
-version.h
-
-# build by-products
-*.o
-
-gsmmap
-
-# various
-.version
-.tarball-version
-
-# IDA file
-*.id*
-*.nam
-*.til
-
-# Other test files
-*.dump
-*.bin
-*.log
diff --git a/Src/osmoconbb/src/host/gsmmap/Makefile.am b/Src/osmoconbb/src/host/gsmmap/Makefile.am
deleted file mode 100644
index 29be15c..0000000
--- a/Src/osmoconbb/src/host/gsmmap/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6
-
-# versioning magic
-BUILT_SOURCES = $(top_srcdir)/.version
-$(top_srcdir)/.version:
- echo $(VERSION) > $@-t && mv $@-t $@
-dist-hook:
- echo $(VERSION) > $(distdir)/.tarball-version
-
-INCLUDES = $(all_includes) -I../layer23/include -DHOST_BUILD
-AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS)
-
-sbin_PROGRAMS = gsmmap
-
-gsmmap_SOURCES = gsmmap.c geo.c locate.c log.c ../layer23/src/common/sysinfo.c ../layer23/src/common/networks.c ../layer23/src/common/logging.c
-gsmmap_LDADD = $(LIBOSMOGSM_LIBS) $(LIBOSMOCORE_LIBS) -lm
-
diff --git a/Src/osmoconbb/src/host/gsmmap/configure.ac b/Src/osmoconbb/src/host/gsmmap/configure.ac
deleted file mode 100644
index 3a42d4c..0000000
--- a/Src/osmoconbb/src/host/gsmmap/configure.ac
+++ /dev/null
@@ -1,26 +0,0 @@
-dnl Process this file with autoconf to produce a configure script
-AC_INIT([gsmmap],
- m4_esyscmd([./git-version-gen .tarball-version]),
- [baseband-devel@lists.osmocom.org])
-
-AM_INIT_AUTOMAKE([dist-bzip2])
-
-dnl kernel style compile messages
-m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
-
-dnl checks for programs
-AC_PROG_MAKE_SET
-AC_PROG_CC
-AC_PROG_INSTALL
-
-dnl checks for libraries
-PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore)
-PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm)
-
-dnl checks for header files
-AC_HEADER_STDC
-
-dnl Checks for typedefs, structures and compiler characteristics
-
-AC_OUTPUT(
- Makefile)
diff --git a/Src/osmoconbb/src/host/gsmmap/geo.c b/Src/osmoconbb/src/host/gsmmap/geo.c
deleted file mode 100644
index 65633d2..0000000
--- a/Src/osmoconbb/src/host/gsmmap/geo.c
+++ /dev/null
@@ -1,47 +0,0 @@
-#include <math.h>
-#include "geo.h"
-
-void geo2space(double *x, double *y, double *z, double lon, double lat)
-{
- *z = sin(lat / 180.0 * PI) * POLE_RADIUS;
- *x = sin(lon / 180.0 * PI) * cos(lat / 180.0 * PI) * EQUATOR_RADIUS;
- *y = -cos(lon / 180.0 * PI) * cos(lat / 180.0 * PI) * EQUATOR_RADIUS;
-}
-
-void space2geo(double *lon, double *lat, double x, double y, double z)
-{
- double r;
-
- /* bring geoid to 1m radius */
- z = z / POLE_RADIUS;
- x = x / EQUATOR_RADIUS;
- y = y / EQUATOR_RADIUS;
-
- /* normalize */
- r = sqrt(x * x + y * y + z * z);
- z = z / r;
- x = x / r;
- y = y / r;
-
- *lat = asin(z) / PI * 180;
- *lon = atan2(x, -y) / PI * 180;
-}
-
-double distinspace(double x1, double y1, double z1, double x2, double y2,
- double z2)
-{
- double x = x1 - x2;
- double y = y1 - y2;
- double z = z1 - z2;
-
- return sqrt(x * x + y * y + z * z);
-}
-
-double distonplane(double x1, double y1, double x2, double y2)
-{
- double x = x1 - x2;
- double y = y1 - y2;
-
- return sqrt(x * x + y * y);
-}
-
diff --git a/Src/osmoconbb/src/host/gsmmap/geo.h b/Src/osmoconbb/src/host/gsmmap/geo.h
deleted file mode 100644
index 25e26cb..0000000
--- a/Src/osmoconbb/src/host/gsmmap/geo.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* WGS 84 */
-#define EQUATOR_RADIUS 6378137.0
-#define POLE_RADIUS 6356752.314
-
-#define PI 3.1415926536
-
-void geo2space(double *x, double *y, double *z, double lat, double lon);
-void space2geo(double *lat, double *lon, double x, double y, double z);
-double distinspace(double x1, double y1, double z1, double x2, double y2,
- double z2);
-double distonplane(double x1, double y1, double x2, double y2);
-
diff --git a/Src/osmoconbb/src/host/gsmmap/git-version-gen b/Src/osmoconbb/src/host/gsmmap/git-version-gen
deleted file mode 100755
index 652fac6..0000000
--- a/Src/osmoconbb/src/host/gsmmap/git-version-gen
+++ /dev/null
@@ -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='osmocon_v*' HEAD 2>/dev/null \
- || git describe --abbrev=4 HEAD 2>/dev/null` \
- && case $v in
- osmocon_[0-9]*) ;;
- osmocon_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-/;s/^osmocon_//'`;
-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:
diff --git a/Src/osmoconbb/src/host/gsmmap/gsmmap.c b/Src/osmoconbb/src/host/gsmmap/gsmmap.c
deleted file mode 100644
index 83f0d01..0000000
--- a/Src/osmoconbb/src/host/gsmmap/gsmmap.c
+++ /dev/null
@@ -1,658 +0,0 @@
-/* Conversion of logged cells to KML file */
-
-/* (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-#warning todo bsic
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <math.h>
-#include <time.h>
-
-#define GSM_TA_M 553.85
-#define PI 3.1415926536
-
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/networks.h>
-#include <osmocom/bb/common/logging.h>
-
-#include "log.h"
-#include "geo.h"
-#include "locate.h"
-
-/*
- * structure of power and cell infos
- */
-
-struct power power;
-struct sysinfo sysinfo;
-static struct node_power *node_power_first = NULL;
-static struct node_power **node_power_last_p = &node_power_first;
-struct node_mcc *node_mcc_first = NULL;
-int log_lines = 0, log_debug = 0;
-
-
-static void nomem(void)
-{
- fprintf(stderr, "No mem!\n");
- exit(-ENOMEM);
-}
-
-static void add_power()
-{
- struct node_power *node_power;
-
-// printf("New Power\n");
- /* append or insert to list */
- node_power = calloc(1, sizeof(struct node_power));
- if (!node_power)
- nomem();
- *node_power_last_p = node_power;
- node_power_last_p = &node_power->next;
- memcpy(&node_power->power, &power, sizeof(power));
-}
-
-static void print_si(void *priv, const char *fmt, ...)
-{
- char buffer[1000];
- FILE *outfp = (FILE *)priv;
- va_list args;
-
- va_start(args, fmt);
- vsnprintf(buffer, sizeof(buffer) - 1, fmt, args);
- buffer[sizeof(buffer) - 1] = '\0';
- va_end(args);
-
- if (buffer[0])
- fprintf(outfp, "%s", buffer);
-}
-
-static void add_sysinfo()
-{
- struct gsm48_sysinfo s;
- struct node_mcc *mcc;
- struct node_mnc *mnc;
- struct node_lac *lac;
- struct node_cell *cell;
- struct node_meas *meas;
-
- memset(&s, 0, sizeof(s));
-
- /* decode sysinfo */
- if (sysinfo.si1[2])
- gsm48_decode_sysinfo1(&s,
- (struct gsm48_system_information_type_1 *) sysinfo.si1,
- 23);
- if (sysinfo.si2[2])
- gsm48_decode_sysinfo2(&s,
- (struct gsm48_system_information_type_2 *) sysinfo.si2,
- 23);
- if (sysinfo.si2bis[2])
- gsm48_decode_sysinfo2bis(&s,
- (struct gsm48_system_information_type_2bis *)
- sysinfo.si2bis,
- 23);
- if (sysinfo.si2ter[2])
- gsm48_decode_sysinfo2ter(&s,
- (struct gsm48_system_information_type_2ter *)
- sysinfo.si2ter,
- 23);
- if (sysinfo.si3[2])
- gsm48_decode_sysinfo3(&s,
- (struct gsm48_system_information_type_3 *) sysinfo.si3,
- 23);
- if (sysinfo.si4[2])
- gsm48_decode_sysinfo4(&s,
- (struct gsm48_system_information_type_4 *) sysinfo.si4,
- 23);
- printf("--------------------------------------------------------------------------\n");
- gsm48_sysinfo_dump(&s, sysinfo.arfcn, print_si, stdout, NULL);
- mcc = get_node_mcc(s.mcc);
- if (!mcc)
- nomem();
- mnc = get_node_mnc(mcc, s.mnc);
- if (!mnc)
- nomem();
- lac = get_node_lac(mnc, s.lac);
- if (!lac)
- nomem();
- cell = get_node_cell(lac, s.cell_id);
- if (!cell)
- nomem();
- meas = add_node_meas(cell);
- if (!meas)
- nomem();
- if (!cell->content) {
- cell->content = 1;
- memcpy(&cell->sysinfo, &sysinfo, sizeof(sysinfo));
- memcpy(&cell->s, &s, sizeof(s));
- } else {
- if (memcmp(&cell->sysinfo.si1, sysinfo.si1,
- sizeof(sysinfo.si1))) {
-new_sysinfo:
- fprintf(stderr, "FIXME: the cell changed sysinfo\n");
- return;
- }
- if (memcmp(&cell->sysinfo.si2, sysinfo.si2,
- sizeof(sysinfo.si2)))
- goto new_sysinfo;
- if (memcmp(&cell->sysinfo.si2bis, sysinfo.si2bis,
- sizeof(sysinfo.si2bis)))
- goto new_sysinfo;
- if (memcmp(&cell->sysinfo.si2ter, sysinfo.si2ter,
- sizeof(sysinfo.si2ter)))
- goto new_sysinfo;
- if (memcmp(&cell->sysinfo.si3, sysinfo.si3,
- sizeof(sysinfo.si3)))
- goto new_sysinfo;
- if (memcmp(&cell->sysinfo.si4, sysinfo.si4,
- sizeof(sysinfo.si4)))
- goto new_sysinfo;
- }
-}
-
-void kml_header(FILE *outfp, char *name)
-{
- /* XML header */
- fprintf(outfp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
-
- /* KML open tag */
- fprintf(outfp, "<kml xmlns=\"http://www.opengis.net/kml/2.2\" "
- "xmlns:gx=\"http://www.google.com/kml/ext/2.2\" "
- "xmlns:kml=\"http://www.opengis.net/kml/2.2\" "
- "xmlns:atom=\"http://www.w3.org/2005/Atom\">\n");
-
- /* document open tag */
- fprintf(outfp, "<Document>\n");
-
- /* pushpin */
- fprintf(outfp, "\t<Style id=\"sn_placemark_red_pushpin\">\n");
- fprintf(outfp, "\t\t<IconStyle>\n");
- fprintf(outfp, "\t\t\t<scale>1.1</scale>\n");
- fprintf(outfp, "\t\t\t<Icon>\n");
- fprintf(outfp, "\t\t\t\t<href>http://maps.google.com/mapfiles/kml/"
- "pushpin/red-pushpin.png</href>\n");
- fprintf(outfp, "\t\t\t</Icon>\n");
- fprintf(outfp, "\t\t</IconStyle>\n");
- fprintf(outfp, "\t\t<ListStyle>\n");
- fprintf(outfp, "\t\t</ListStyle>\n");
- fprintf(outfp, "\t</Style>\n");
- fprintf(outfp, "\t<Style id=\"sh_placemark_red_pushpin_highlight\">\n");
- fprintf(outfp, "\t\t<IconStyle>\n");
- fprintf(outfp, "\t\t\t<scale>1.3</scale>\n");
- fprintf(outfp, "\t\t\t<Icon>\n");
- fprintf(outfp, "\t\t\t\t<href>http://maps.google.com/mapfiles/kml/"
- "pushpin/red-pushpin.png</href>\n");
- fprintf(outfp, "\t\t\t</Icon>\n");
- fprintf(outfp, "\t\t</IconStyle>\n");
- fprintf(outfp, "\t\t<ListStyle>\n");
- fprintf(outfp, "\t\t</ListStyle>\n");
- fprintf(outfp, "\t</Style>\n");
- fprintf(outfp, "\t<StyleMap id=\"msn_placemark_red_pushpin\">\n");
- fprintf(outfp, "\t\t<Pair>\n");
- fprintf(outfp, "\t\t\t<key>normal</key>\n");
- fprintf(outfp, "\t\t\t<styleUrl>#sn_placemark_red_pushpin"
- "</styleUrl>\n");
- fprintf(outfp, "\t\t</Pair>\n");
- fprintf(outfp, "\t\t<Pair>\n");
- fprintf(outfp, "\t\t\t<key>highlight</key>\n");
- fprintf(outfp, "\t\t\t<styleUrl>#sh_placemark_red_pushpin_highlight"
- "</styleUrl>\n");
- fprintf(outfp, "\t\t</Pair>\n");
- fprintf(outfp, "\t</StyleMap>\n");
-
- fprintf(outfp, "\t<Style id=\"sn_placemark_grn_pushpin\">\n");
- fprintf(outfp, "\t\t<IconStyle>\n");
- fprintf(outfp, "\t\t\t<scale>1.1</scale>\n");
- fprintf(outfp, "\t\t\t<Icon>\n");
- fprintf(outfp, "\t\t\t\t<href>http://maps.google.com/mapfiles/kml/"
- "pushpin/grn-pushpin.png</href>\n");
- fprintf(outfp, "\t\t\t</Icon>\n");
- fprintf(outfp, "\t\t</IconStyle>\n");
- fprintf(outfp, "\t\t<ListStyle>\n");
- fprintf(outfp, "\t\t</ListStyle>\n");
- fprintf(outfp, "\t</Style>\n");
- fprintf(outfp, "\t<Style id=\"sh_placemark_grn_pushpin_highlight\">\n");
- fprintf(outfp, "\t\t<IconStyle>\n");
- fprintf(outfp, "\t\t\t<scale>1.3</scale>\n");
- fprintf(outfp, "\t\t\t<Icon>\n");
- fprintf(outfp, "\t\t\t\t<href>http://maps.google.com/mapfiles/kml/"
- "pushpin/grn-pushpin.png</href>\n");
- fprintf(outfp, "\t\t\t</Icon>\n");
- fprintf(outfp, "\t\t</IconStyle>\n");
- fprintf(outfp, "\t\t<ListStyle>\n");
- fprintf(outfp, "\t\t</ListStyle>\n");
- fprintf(outfp, "\t</Style>\n");
- fprintf(outfp, "\t<StyleMap id=\"msn_placemark_grn_pushpin\">\n");
- fprintf(outfp, "\t\t<Pair>\n");
- fprintf(outfp, "\t\t\t<key>normal</key>\n");
- fprintf(outfp, "\t\t\t<styleUrl>#sn_placemark_grn_pushpin"
- "</styleUrl>\n");
- fprintf(outfp, "\t\t</Pair>\n");
- fprintf(outfp, "\t\t<Pair>\n");
- fprintf(outfp, "\t\t\t<key>highlight</key>\n");
- fprintf(outfp, "\t\t\t<styleUrl>#sh_placemark_grn_pushpin_highlight"
- "</styleUrl>\n");
- fprintf(outfp, "\t\t</Pair>\n");
- fprintf(outfp, "\t</StyleMap>\n");
-
- /* circle */
- fprintf(outfp, "\t<Style id=\"sn_placemark_circle\">\n");
- fprintf(outfp, "\t\t<IconStyle>\n");
- fprintf(outfp, "\t\t\t<scale>1.0</scale>\n");
- fprintf(outfp, "\t\t\t<Icon>\n");
- fprintf(outfp, "\t\t\t\t<href>http://maps.google.com/mapfiles/kml/"
- "shapes/placemark_circle.png</href>\n");
- fprintf(outfp, "\t\t\t</Icon>\n");
- fprintf(outfp, "\t\t</IconStyle>\n");
- fprintf(outfp, "\t\t<ListStyle>\n");
- fprintf(outfp, "\t\t</ListStyle>\n");
- fprintf(outfp, "\t</Style>\n");
- fprintf(outfp, "\t<Style id=\"sh_placemark_circle_highlight\">\n");
- fprintf(outfp, "\t\t<IconStyle>\n");
- fprintf(outfp, "\t\t\t<scale>1.2</scale>\n");
- fprintf(outfp, "\t\t\t<Icon>\n");
- fprintf(outfp, "\t\t\t\t<href>http://maps.google.com/mapfiles/kml/"
- "shapes/placemark_circle_highlight.png</href>\n");
- fprintf(outfp, "\t\t\t</Icon>\n");
- fprintf(outfp, "\t\t</IconStyle>\n");
- fprintf(outfp, "\t\t<ListStyle>\n");
- fprintf(outfp, "\t\t</ListStyle>\n");
- fprintf(outfp, "\t</Style>\n");
- fprintf(outfp, "\t<StyleMap id=\"msn_placemark_circle\">\n");
- fprintf(outfp, "\t\t<Pair>\n");
- fprintf(outfp, "\t\t\t<key>normal</key>\n");
- fprintf(outfp, "\t\t\t<styleUrl>#sn_placemark_circle</styleUrl>\n");
- fprintf(outfp, "\t\t</Pair>\n");
- fprintf(outfp, "\t\t<Pair>\n");
- fprintf(outfp, "\t\t\t<key>highlight</key>\n");
- fprintf(outfp, "\t\t\t<styleUrl>#sh_placemark_circle_highlight"
- "</styleUrl>\n");
- fprintf(outfp, "\t\t</Pair>\n");
- fprintf(outfp, "\t</StyleMap>\n");
-}
-
-void kml_footer(FILE *outfp)
-{
- /* document close tag */
- fprintf(outfp, "</Document>\n");
-
- /* KML close tag */
- fprintf(outfp, "</kml>\n");
-
-}
-
-void kml_meas(FILE *outfp, struct node_meas *meas, int n, uint16_t mcc,
- uint16_t mnc, uint16_t lac, uint16_t cellid)
-{
- struct tm *tm = localtime(&meas->gmt);
-
- fprintf(outfp, "\t\t\t\t\t<Placemark>\n");
- fprintf(outfp, "\t\t\t\t\t\t<name>%d: %d</name>\n", n, meas->rxlev);
- fprintf(outfp, "\t\t\t\t\t\t<description>\n");
- fprintf(outfp, "MCC=%s MNC=%s\nLAC=%04x CELL-ID=%04x\n(%s %s)\n",
- gsm_print_mcc(mcc), gsm_print_mnc(mnc), lac, cellid,
- gsm_get_mcc(mcc), gsm_get_mnc(mcc, mnc));
- fprintf(outfp, "\n%s", asctime(tm));
- fprintf(outfp, "RX-LEV %d dBm\n", meas->rxlev);
- if (meas->ta_valid)
- fprintf(outfp, "TA=%d (%d-%d meter)\n", meas->ta,
- (int)(GSM_TA_M * meas->ta),
- (int)(GSM_TA_M * (meas->ta + 1)));
- fprintf(outfp, "\t\t\t\t\t\t</description>\n");
- fprintf(outfp, "\t\t\t\t\t\t<LookAt>\n");
- fprintf(outfp, "\t\t\t\t\t\t\t<longitude>%.8f</longitude>\n",
- meas->longitude);
- fprintf(outfp, "\t\t\t\t\t\t\t<latitude>%.8f</latitude>\n",
- meas->latitude);
- fprintf(outfp, "\t\t\t\t\t\t\t<altitude>0</altitude>\n");
- fprintf(outfp, "\t\t\t\t\t\t\t<tilt>0</tilt>\n");
- fprintf(outfp, "\t\t\t\t\t\t\t<altitudeMode>relativeToGround"
- "</altitudeMode>\n");
- fprintf(outfp, "\t\t\t\t\t\t\t<gx:altitudeMode>relativeToSeaFloor"
- "</gx:altitudeMode>\n");
- fprintf(outfp, "\t\t\t\t\t\t</LookAt>\n");
- fprintf(outfp, "\t\t\t\t\t\t<styleUrl>#msn_placemark_circle"
- "</styleUrl>\n");
- fprintf(outfp, "\t\t\t\t\t\t<Point>\n");
- fprintf(outfp, "\t\t\t\t\t\t\t<coordinates>%.8f,%.8f</coordinates>\n",
- meas->longitude, meas->latitude);
- fprintf(outfp, "\t\t\t\t\t\t</Point>\n");
- fprintf(outfp, "\t\t\t\t\t</Placemark>\n");
-}
-
-double debug_long, debug_lat, debug_x_scale;
-FILE *debug_fp;
-
-void kml_cell(FILE *outfp, struct node_cell *cell)
-{
- struct node_meas *meas;
- double x, y, z, sum_x = 0, sum_y = 0, sum_z = 0, longitude, latitude;
- int n, known = 0;
-
- meas = cell->meas;
- n = 0;
- while (meas) {
- if (meas->gps_valid && meas->ta_valid) {
- geo2space(&x, &y, &z, meas->longitude, meas->latitude);
- sum_x += x;
- sum_y += y;
- sum_z += z;
- n++;
- }
- meas = meas->next;
- }
- if (!n)
- return;
- if (n < 3) {
- x = sum_x / n;
- y = sum_y / n;
- z = sum_z / n;
- space2geo(&longitude, &latitude, x, y, z);
- } else {
- struct probe *probe_first = NULL, *probe,
- **probe_last_p = &probe_first;
- double x_scale;
-
- /* translate to flat surface */
- meas = cell->meas;
- x_scale = 1.0 / cos(meas->latitude / 180.0 * PI);
- longitude = meas->longitude;
- latitude = meas->latitude;
- debug_x_scale = x_scale;
- debug_long = longitude;
- debug_lat = latitude;
- debug_fp = outfp;
- while (meas) {
- if (meas->gps_valid && meas->ta_valid) {
- probe = calloc(1, sizeof(struct probe));
- if (!probe)
- nomem();
- probe->x = (meas->longitude - longitude) /
- x_scale;
- if (x < -180)
- x += 360;
- else if (x > 180)
- x -= 360;
- probe->y = meas->latitude - latitude;
- probe->dist = GSM_TA_M * (0.5 +
- (double)meas->ta) /
- (EQUATOR_RADIUS * PI / 180.0);
- *probe_last_p = probe;
- probe_last_p = &probe->next;
- }
- meas = meas->next;
- }
-
- /* locate */
- locate_cell(probe_first, &x, &y);
-
- /* translate from flat surface */
- longitude += x * x_scale;
- if (longitude < 0)
- longitude += 360;
- else if (longitude >= 360)
- longitude -= 360;
- latitude += y;
-
- /* remove probes */
- while (probe_first) {
- probe = probe_first;
- probe_first = probe->next;
- free(probe);
- }
-
- known = 1;
- }
-
- if (!known)
- return;
-
- fprintf(outfp, "\t\t\t\t\t<Placemark>\n");
- fprintf(outfp, "\t\t\t\t\t\t<name>MCC=%s MNC=%s\nLAC=%04x "
- "CELL-ID=%04x\n(%s %s)</name>\n", gsm_print_mcc(cell->s.mcc),
- gsm_print_mnc(cell->s.mnc), cell->s.lac, cell->s.cell_id,
- gsm_get_mcc(cell->s.mcc),
- gsm_get_mnc(cell->s.mcc, cell->s.mnc));
- fprintf(outfp, "\t\t\t\t\t\t<description>\n");
- gsm48_sysinfo_dump(&cell->s, cell->sysinfo.arfcn, print_si, outfp,
- NULL);
- fprintf(outfp, "\t\t\t\t\t\t</description>\n");
- fprintf(outfp, "\t\t\t\t\t\t<LookAt>\n");
- fprintf(outfp, "\t\t\t\t\t\t\t<longitude>%.8f</longitude>\n",
- longitude);
- fprintf(outfp, "\t\t\t\t\t\t\t<latitude>%.8f</latitude>\n", latitude);
- fprintf(outfp, "\t\t\t\t\t\t\t<altitude>0</altitude>\n");
- fprintf(outfp, "\t\t\t\t\t\t\t<tilt>0</tilt>\n");
- fprintf(outfp, "\t\t\t\t\t\t\t<altitudeMode>relativeToGround"
- "</altitudeMode>\n");
- fprintf(outfp, "\t\t\t\t\t\t\t<gx:altitudeMode>relativeToSeaFloor"
- "</gx:altitudeMode>\n");
- fprintf(outfp, "\t\t\t\t\t\t</LookAt>\n");
- if (known)
- fprintf(outfp, "\t\t\t\t\t\t<styleUrl>#msn_placemark_grn_"
- "pushpin</styleUrl>\n");
- else
- fprintf(outfp, "\t\t\t\t\t\t<styleUrl>#msn_placemark_red_"
- "pushpin</styleUrl>\n");
- fprintf(outfp, "\t\t\t\t\t\t<Point>\n");
- fprintf(outfp, "\t\t\t\t\t\t\t<coordinates>%.8f,%.8f</coordinates>\n",
- longitude, latitude);
- fprintf(outfp, "\t\t\t\t\t\t</Point>\n");
- fprintf(outfp, "\t\t\t\t\t</Placemark>\n");
-
- if (!log_lines)
- return;
-
- fprintf(outfp, "\t<Folder>\n");
- fprintf(outfp, "\t\t<name>Lines</name>\n");
- fprintf(outfp, "\t\t<open>0</open>\n");
- fprintf(outfp, "\t\t<visibility>0</visibility>\n");
-
- geo2space(&x, &y, &z, longitude, latitude);
- meas = cell->meas;
- n = 0;
- while (meas) {
- if (meas->gps_valid) {
- double mx, my, mz, dist;
-
- geo2space(&mx, &my, &mz, meas->longitude,
- meas->latitude);
- dist = distinspace(x, y, z, mx, my, mz);
- fprintf(outfp, "\t\t<Placemark>\n");
- fprintf(outfp, "\t\t\t<name>Range</name>\n");
- fprintf(outfp, "\t\t\t<description>\n");
- fprintf(outfp, "Distance: %d\n", (int)dist);
- fprintf(outfp, "TA=%d (%d-%d meter)\n", meas->ta,
- (int)(GSM_TA_M * meas->ta),
- (int)(GSM_TA_M * (meas->ta + 1)));
- fprintf(outfp, "\t\t\t</description>\n");
- fprintf(outfp, "\t\t\t<visibility>0</visibility>\n");
- fprintf(outfp, "\t\t\t<LineString>\n");
- fprintf(outfp, "\t\t\t\t<tessellate>1</tessellate>\n");
- fprintf(outfp, "\t\t\t\t<coordinates>\n");
- fprintf(outfp, "%.8f,%.8f\n", longitude, latitude);
- fprintf(outfp, "%.8f,%.8f\n", meas->longitude,
- meas->latitude);
- fprintf(outfp, "\t\t\t\t</coordinates>\n");
- fprintf(outfp, "\t\t\t</LineString>\n");
- fprintf(outfp, "\t\t</Placemark>\n");
- }
- meas = meas->next;
- }
- fprintf(outfp, "\t</Folder>\n");
-}
-
-struct log_target *stderr_target;
-
-int main(int argc, char *argv[])
-{
- FILE *infp, *outfp;
- int type, n, i;
- char *p;
- struct node_mcc *mcc;
- struct node_mnc *mnc;
- struct node_lac *lac;
- struct node_cell *cell;
- struct node_meas *meas;
-
- log_init(&log_info, NULL);
- stderr_target = log_target_create_stderr();
- log_add_target(stderr_target);
- log_set_all_filter(stderr_target, 1);
- log_parse_category_mask(stderr_target, "Dxxx");
- log_set_log_level(stderr_target, LOGL_INFO);
-
- if (argc <= 2) {
-usage:
- fprintf(stderr, "Usage: %s <file.log> <file.kml> "
- "[lines] [debug]\n", argv[0]);
- fprintf(stderr, "lines: Add lines between cell and "
- "Measurement point\n");
- fprintf(stderr, "debug: Add debugging of location algorithm.\n"
- );
- return 0;
- }
-
- for (i = 3; i < argc; i++) {
- if (!strcmp(argv[i], "lines"))
- log_lines = 1;
- else if (!strcmp(argv[i], "debug"))
- log_debug = 1;
- else goto usage;
- }
-
- infp = fopen(argv[1], "r");
- if (!infp) {
- fprintf(stderr, "Failed to open '%s' for reading\n", argv[1]);
- return -EIO;
- }
-
- while ((type = read_log(infp))) {
- switch (type) {
- case LOG_TYPE_SYSINFO:
- add_sysinfo();
- break;
- case LOG_TYPE_POWER:
- add_power();
- break;
- }
- }
-
- fclose(infp);
-
- if (!strcmp(argv[2], "-"))
- outfp = stdout;
- else
- outfp = fopen(argv[2], "w");
- if (!outfp) {
- fprintf(stderr, "Failed to open '%s' for writing\n", argv[2]);
- return -EIO;
- }
-
- /* document name */
- p = argv[2];
- while (strchr(p, '/'))
- p = strchr(p, '/') + 1;
-
- kml_header(outfp, p);
- mcc = node_mcc_first;
- while (mcc) {
- printf("MCC: %02x\n", mcc->mcc);
- /* folder open */
- fprintf(outfp, "\t<Folder>\n");
- fprintf(outfp, "\t\t<name>MCC %s (%s)</name>\n",
- gsm_print_mcc(mcc->mcc), gsm_get_mcc(mcc->mcc));
- fprintf(outfp, "\t\t<open>0</open>\n");
- mnc = mcc->mnc;
- while (mnc) {
- printf(" MNC: %02x\n", mnc->mnc);
- /* folder open */
- fprintf(outfp, "\t\t<Folder>\n");
- fprintf(outfp, "\t\t\t<name>MNC %s (%s)</name>\n",
- gsm_print_mnc(mnc->mnc), gsm_get_mnc(mcc->mcc, mnc->mnc));
- fprintf(outfp, "\t\t\t<open>0</open>\n");
- lac = mnc->lac;
- while (lac) {
- printf(" LAC: %04x\n", lac->lac);
- /* folder open */
- fprintf(outfp, "\t\t\t<Folder>\n");
- fprintf(outfp, "\t\t\t\t<name>LAC %04x</name>\n", lac->lac);
- fprintf(outfp, "\t\t\t\t<open>0</open>\n");
- cell = lac->cell;
- while (cell) {
- printf(" CELL: %04x\n", cell->cellid);
- fprintf(outfp, "\t\t\t\t<Folder>\n");
- fprintf(outfp, "\t\t\t\t\t<name>CELL-ID %04x</name>\n", cell->cellid);
- fprintf(outfp, "\t\t\t\t\t<open>0</open>\n");
- meas = cell->meas;
- n = 0;
- while (meas) {
- if (meas->ta_valid)
- printf(" TA: %d\n", meas->ta);
- if (meas->gps_valid)
- kml_meas(outfp, meas, ++n, mcc->mcc, mnc->mnc,
- lac->lac, cell->cellid);
- meas = meas->next;
- }
- kml_cell(outfp, cell);
- /* folder close */
- fprintf(outfp, "\t\t\t\t</Folder>\n");
- cell = cell->next;
- }
- /* folder close */
- fprintf(outfp, "\t\t\t</Folder>\n");
- lac = lac->next;
- }
- /* folder close */
- fprintf(outfp, "\t\t</Folder>\n");
- mnc = mnc->next;
- }
- /* folder close */
- fprintf(outfp, "\t</Folder>\n");
- mcc = mcc->next;
- }
-#if 0
- FIXME: power
- /* folder open */
- fprintf(outfp, "\t<Folder>\n");
- fprintf(outfp, "\t\t<name>Power</name>\n");
- fprintf(outfp, "\t\t<open>0</open>\n");
- power = node_power_first;
- n = 0;
- while (power) {
- /* folder open */
- fprintf(outfp, "\t\t<Folder>\n");
- fprintf(outfp, "\t\t\t<name>Power %d</name>\n", ++n);
- fprintf(outfp, "\t\t\t<open>0</open>\n");
- /* folder close */
- fprintf(outfp, "\t\t</Folder>\n");
- power = power->next;
- }
- /* folder close */
- fprintf(outfp, "\t</Folder>\n");
-#endif
- kml_footer(outfp);
-
- fclose(outfp);
-
- return 0;
-}
diff --git a/Src/osmoconbb/src/host/gsmmap/locate.c b/Src/osmoconbb/src/host/gsmmap/locate.c
deleted file mode 100644
index ed0ac93..0000000
--- a/Src/osmoconbb/src/host/gsmmap/locate.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/* Algorithm to locate a destination by distance measurement:
- */
-
-#include <stdio.h>
-#include <errno.h>
-#include <math.h>
-
-#include "geo.h"
-#include "locate.h"
-
-#define CIRCLE_PROBE 30.0
-#define FINETUNE_RADIUS 5.0
-
-extern double debug_long, debug_lat, debug_x_scale;
-extern FILE *debug_fp;
-extern int log_debug;
-
-static double finetune_x[6], finetune_y[6], finetune_dist[6];
-
-int locate_cell(struct probe *probe_first, double *min_x, double *min_y)
-{
- struct probe *probe, *min_probe;
- int i, test_steps, optimized;
- double min_dist, dist, x, y, rad, temp;
- double circle_probe, finetune_radius;
-
- /* convert meters into degrees */
- circle_probe = CIRCLE_PROBE / (EQUATOR_RADIUS * PI / 180.0);
- finetune_radius = FINETUNE_RADIUS / (EQUATOR_RADIUS * PI / 180.0);
-
- if (log_debug) {
- fprintf(debug_fp, "<Folder>\n");
- fprintf(debug_fp, "\t<name>Debug Locator</name>\n");
- fprintf(debug_fp, "\t<open>0</open>\n");
- fprintf(debug_fp, "\t<visibility>0</visibility>\n");
- }
-
- /* get probe of minimum distance */
- min_probe = NULL;
- probe = probe_first;
- min_dist = 42;
- i = 0;
- while (probe) {
- if (log_debug) {
- fprintf(debug_fp, "\t<Placemark>\n");
- fprintf(debug_fp, "\t\t<name>MEAS</name>\n");
- fprintf(debug_fp, "\t\t<visibility>0</visibility>\n");
- fprintf(debug_fp, "\t\t<LineString>\n");
- fprintf(debug_fp, "\t\t\t<tessellate>1</tessellate>\n");
- fprintf(debug_fp, "\t\t\t<coordinates>\n");
- rad = 2.0 * 3.1415927 / 35;
- for (i = 0; i < 35; i++) {
- x = probe->x + probe->dist * sin(rad * i);
- y = probe->y + probe->dist * cos(rad * i);
- fprintf(debug_fp, "%.8f,%.8f\n", debug_long +
- x * debug_x_scale, debug_lat + y);
- }
- fprintf(debug_fp, "\t\t\t</coordinates>\n");
- fprintf(debug_fp, "\t\t</LineString>\n");
- fprintf(debug_fp, "\t</Placemark>\n");
- }
-
- if (!min_probe || probe->dist < min_dist) {
- min_probe = probe;
- min_dist = probe->dist;
- }
- probe = probe->next;
- i++;
- }
-
- if (i < 3) {
- fprintf(stderr, "Need at least 3 points\n");
- return -EINVAL;
- }
-
- /* calculate the number of steps to search for destination point */
- test_steps = 2.0 * 3.1415927 * min_probe->dist / circle_probe;
- rad = 2.0 * 3.1415927 / test_steps;
-
- if (log_debug) {
- fprintf(debug_fp, "\t<Placemark>\n");
- fprintf(debug_fp, "\t\t<name>Smallest MEAS</name>\n");
- fprintf(debug_fp, "\t\t<visibility>0</visibility>\n");
- fprintf(debug_fp, "\t\t<LineString>\n");
- fprintf(debug_fp, "\t\t\t<tessellate>1</tessellate>\n");
- fprintf(debug_fp, "\t\t\t<coordinates>\n");
- }
-
- /* search on a circle for the location of the lowest distance
- * to the radius with the greatest distance */
- min_dist = 42;
- *min_x = *min_y = 42;
- for (i = 0; i < test_steps; i++) {
- x = min_probe->x + min_probe->dist * sin(rad * i);
- y = min_probe->y + min_probe->dist * cos(rad * i);
- if (log_debug)
- fprintf(debug_fp, "%.8f,%.8f\n", debug_long +
- x * debug_x_scale, debug_lat + y);
- /* look for greatest distance */
- dist = 0;
- probe = probe_first;
- while (probe) {
- if (probe != min_probe) {
- /* distance to the radius */
- temp = distonplane(probe->x, probe->y, x, y);
- temp -= probe->dist;
- if (temp < 0)
- temp = -temp;
- if (temp > dist)
- dist = temp;
- }
- probe = probe->next;
- }
- if (i == 0 || dist < min_dist) {
- min_dist = dist;
- *min_x = x;
- *min_y = y;
- }
- }
-
- if (log_debug) {
- fprintf(debug_fp, "\t\t\t</coordinates>\n");
- fprintf(debug_fp, "\t\t</LineString>\n");
- fprintf(debug_fp, "\t</Placemark>\n");
-
- fprintf(debug_fp, "\t<Placemark>\n");
- fprintf(debug_fp, "\t\t<name>Finetune</name>\n");
- fprintf(debug_fp, "\t\t<visibility>0</visibility>\n");
- fprintf(debug_fp, "\t\t<LineString>\n");
- fprintf(debug_fp, "\t\t\t<tessellate>1</tessellate>\n");
- fprintf(debug_fp, "\t\t\t<coordinates>\n");
- }
-
- min_dist = 9999999999.0;
-tune_again:
- if (log_debug)
- fprintf(debug_fp, "%.8f,%.8f\n", debug_long +
- *min_x * debug_x_scale, debug_lat + *min_y);
-
- /* finetune the point */
- rad = 2.0 * 3.1415927 / 6;
- for (i = 0; i < 6; i++) {
- x = *min_x + finetune_radius * sin(rad * i);
- y = *min_y + finetune_radius * cos(rad * i);
- /* search for the point with the lowest sum of distances */
- dist = 0;
- probe = probe_first;
- while (probe) {
- /* distance to the radius */
- temp = distonplane(probe->x, probe->y, x, y);
- temp -= probe->dist;
- if (temp < 0)
- temp = -temp;
- dist += temp;
- probe = probe->next;
- }
- finetune_dist[i] = dist;
- finetune_x[i] = x;
- finetune_y[i] = y;
- }
-
- optimized = 0;
- for (i = 0; i < 6; i++) {
- if (finetune_dist[i] < min_dist) {
- min_dist = finetune_dist[i];
- *min_x = finetune_x[i];
- *min_y = finetune_y[i];
- optimized = 1;
- }
- }
- if (optimized)
- goto tune_again;
-
- if (log_debug) {
- fprintf(debug_fp, "\t\t\t</coordinates>\n");
- fprintf(debug_fp, "\t\t</LineString>\n");
- fprintf(debug_fp, "\t</Placemark>\n");
- fprintf(debug_fp, "</Folder>\n");
- }
-
- return 0;
-}
diff --git a/Src/osmoconbb/src/host/gsmmap/locate.h b/Src/osmoconbb/src/host/gsmmap/locate.h
deleted file mode 100644
index 2613345..0000000
--- a/Src/osmoconbb/src/host/gsmmap/locate.h
+++ /dev/null
@@ -1,8 +0,0 @@
-
-struct probe {
- struct probe *next;
- double x, y, dist;
-};
-
-int locate_cell(struct probe *probe_first, double *min_x, double *min_y);
-
diff --git a/Src/osmoconbb/src/host/gsmmap/log.c b/Src/osmoconbb/src/host/gsmmap/log.c
deleted file mode 100644
index c2db801..0000000
--- a/Src/osmoconbb/src/host/gsmmap/log.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/* Conversion of logged cells to KML file */
-
-/* (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <osmocom/bb/common/osmocom_data.h>
-
-#include "log.h"
-
-extern struct power power;
-extern struct sysinfo sysinfo;
-extern struct node_power *node_power_first;
-extern struct node_power **node_power_last_p;
-extern struct node_mcc *node_mcc_first;
-
-struct node_mcc *get_node_mcc(uint16_t mcc)
-{
- struct node_mcc *node_mcc;
- struct node_mcc **node_mcc_p = &node_mcc_first;
-
-//printf("add mcc %d\n", mcc);
- while (*node_mcc_p) {
- /* found in list */
- if ((*node_mcc_p)->mcc == mcc)
- return *node_mcc_p;
- /* insert into list */
- if ((*node_mcc_p)->mcc > mcc)
- break;
- node_mcc_p = &((*node_mcc_p)->next);
- }
-
-//printf("new mcc %d\n", mcc);
- /* append or insert to list */
- node_mcc = calloc(1, sizeof(struct node_mcc));
- if (!node_mcc)
- return NULL;
- node_mcc->mcc = mcc;
- node_mcc->next = *node_mcc_p;
- *node_mcc_p = node_mcc;
- return node_mcc;
-}
-
-struct node_mnc *get_node_mnc(struct node_mcc *mcc, uint16_t mnc)
-{
- struct node_mnc *node_mnc;
- struct node_mnc **node_mnc_p = &mcc->mnc;
-
- while (*node_mnc_p) {
- /* found in list */
- if ((*node_mnc_p)->mnc == mnc)
- return *node_mnc_p;
- /* insert into list */
- if ((*node_mnc_p)->mnc > mnc)
- break;
- node_mnc_p = &((*node_mnc_p)->next);
- }
-
- /* append or insert to list */
- node_mnc = calloc(1, sizeof(struct node_mnc));
- if (!node_mnc)
- return NULL;
- node_mnc->mnc = mnc;
- node_mnc->next = *node_mnc_p;
- *node_mnc_p = node_mnc;
- return node_mnc;
-}
-
-struct node_lac *get_node_lac(struct node_mnc *mnc, uint16_t lac)
-{
- struct node_lac *node_lac;
- struct node_lac **node_lac_p = &mnc->lac;
-
- while (*node_lac_p) {
- /* found in list */
- if ((*node_lac_p)->lac == lac)
- return *node_lac_p;
- /* insert into list */
- if ((*node_lac_p)->lac > lac)
- break;
- node_lac_p = &((*node_lac_p)->next);
- }
-
- /* append or insert to list */
- node_lac = calloc(1, sizeof(struct node_lac));
- if (!node_lac)
- return NULL;
- node_lac->lac = lac;
- node_lac->next = *node_lac_p;
- *node_lac_p = node_lac;
- return node_lac;
-}
-
-struct node_cell *get_node_cell(struct node_lac *lac, uint16_t cellid)
-{
- struct node_cell *node_cell;
- struct node_cell **node_cell_p = &lac->cell;
-
- while (*node_cell_p) {
- /* found in list */
- if ((*node_cell_p)->cellid == cellid)
- return *node_cell_p;
- /* insert into list */
- if ((*node_cell_p)->cellid > cellid)
- break;
- node_cell_p = &((*node_cell_p)->next);
- }
-
- /* append or insert to list */
- node_cell = calloc(1, sizeof(struct node_cell));
- if (!node_cell)
- return NULL;
- node_cell->meas_last_p = &node_cell->meas;
- node_cell->cellid = cellid;
- node_cell->next = *node_cell_p;
- *node_cell_p = node_cell;
- return node_cell;
-}
-
-struct node_meas *add_node_meas(struct node_cell *cell)
-{
- struct node_meas *node_meas;
-
- /* append to list */
- node_meas = calloc(1, sizeof(struct node_meas));
- if (!node_meas)
- return NULL;
- node_meas->gmt = sysinfo.gmt;
- node_meas->rxlev = sysinfo.rxlev;
- if (sysinfo.ta_valid) {
- node_meas->ta_valid = 1;
- node_meas->ta = sysinfo.ta;
- }
- if (sysinfo.gps_valid) {
- node_meas->gps_valid = 1;
- node_meas->longitude = sysinfo.longitude;
- node_meas->latitude = sysinfo.latitude;
- }
- *cell->meas_last_p = node_meas;
- cell->meas_last_p = &node_meas->next;
- return node_meas;
-}
-
-/* read "<ncc>,<bcc>" */
-static void read_log_bsic(char *buffer)
-{
- char *p;
- uint8_t bsic;
-
- /* skip first spaces */
- while (*buffer == ' ')
- buffer++;
-
- /* read ncc */
- p = buffer;
- while (*p > ' ' && *p != ',')
- p++;
- if (*p == '\0')
- return; /* no value */
- *p++ = '\0';
- bsic = atoi(buffer) << 3;
- buffer = p;
-
- /* read latitude */
- bsic |= atoi(buffer);
-
- sysinfo.bsic = bsic;
-}
-
-/* read "<longitude> <latitude>" */
-static void read_log_pos(char *buffer, double *longitude, double *latitude,
- uint8_t *valid)
-{
- char *p;
-
- /* skip first spaces */
- while (*buffer == ' ')
- buffer++;
-
- /* read longitude */
- p = buffer;
- while (*p > ' ')
- p++;
- if (*p == '\0')
- return; /* no value after longitude */
- *p++ = '\0';
- *longitude = atof(buffer);
- buffer = p;
-
- /* skip second spaces */
- while (*buffer == ' ')
- buffer++;
-
- /* read latitude */
- *latitude = atof(buffer);
-
- *valid = 1;
-}
-
-/* read "<arfcn> <value> <next value> ...." */
-static void read_log_power(char *buffer)
-{
- char *p;
- int arfcn;
-
- /* skip first spaces */
- while (*buffer == ' ')
- buffer++;
-
- /* read arfcn */
- p = buffer;
- while (*p > ' ')
- p++;
- if (*p == '\0')
- return; /* no value after arfcn */
- *p++ = '\0';
- arfcn = atoi(buffer);
- buffer = p;
-
- while (*buffer) {
- /* wrong arfcn */
- if (arfcn < 0 || arfcn > 1023)
- break;
- /* skip spaces */
- while (*buffer == ' ')
- buffer++;
- /* get value */
- p = buffer;
- while (*p > ' ')
- p++;
- /* last value */
- if (*p == '\0') {
- power.rxlev[arfcn] = atoi(buffer);
- break;
- }
- *p++ = '\0';
- power.rxlev[arfcn] = atoi(buffer);
- arfcn++;
- buffer = p;
- }
-}
-
-/* read "xx xx xx xx xx...." */
-static void read_log_si(char *buffer, uint8_t *data)
-{
- uint8_t si[23];
- int i;
-
-// printf("%s ", buffer);
- for (i = 0; i < 23; i++) {
- while (*buffer == ' ')
- buffer++;
- if (*buffer >= '0' && *buffer <= '9')
- si[i] = (*buffer - '0') << 4;
- else if (*buffer >= 'a' && *buffer <= 'f')
- si[i] = (*buffer - 'a' + 10) << 4;
- else if (*buffer >= 'A' && *buffer <= 'F')
- si[i] = (*buffer - 'A' + 10) << 4;
- else
- break;
- buffer++;
- if (*buffer >= '0' && *buffer <= '9')
- si[i] += *buffer - '0';
- else if (*buffer >= 'a' && *buffer <= 'f')
- si[i] += *buffer - 'a' + 10;
- else if (*buffer >= 'A' && *buffer <= 'F')
- si[i] += *buffer - 'A' + 10;
- else
- break;
- buffer++;
-// printf("%02x ", si[i]);
- }
-// printf("\n");
-
- if (i == 23)
- memcpy(data, si, 23);
-}
-
-/* read next record from log file */
-int read_log(FILE *infp)
-{
- static int type = LOG_TYPE_NONE, ret;
- char buffer[256];
-
- memset(&sysinfo, 0, sizeof(sysinfo));
- memset(&power, 0, sizeof(power));
- memset(&power.rxlev, -128, sizeof(power.rxlev));
-
- if (feof(infp))
- return LOG_TYPE_NONE;
-
- while (fgets(buffer, sizeof(buffer), infp)) {
- buffer[sizeof(buffer) - 1] = 0;
- if (buffer[0])
- buffer[strlen(buffer) - 1] = '\0';
- if (buffer[0] == '[') {
- if (!strcmp(buffer, "[sysinfo]")) {
- ret = type;
- type = LOG_TYPE_SYSINFO;
- if (ret != LOG_TYPE_NONE)
- return ret;
- } else
- if (!strcmp(buffer, "[power]")) {
- ret = type;
- type = LOG_TYPE_POWER;
- if (ret != LOG_TYPE_NONE)
- return ret;
- } else {
- type = LOG_TYPE_NONE;
- }
- continue;
- }
- switch (type) {
- case LOG_TYPE_SYSINFO:
- if (!strncmp(buffer, "arfcn ", 6))
- sysinfo.arfcn = atoi(buffer + 6);
- else if (!strncmp(buffer, "si1 ", 4))
- read_log_si(buffer + 4, sysinfo.si1);
- else if (!strncmp(buffer, "si2 ", 4))
- read_log_si(buffer + 4, sysinfo.si2);
- else if (!strncmp(buffer, "si2bis ", 7))
- read_log_si(buffer + 7, sysinfo.si2bis);
- else if (!strncmp(buffer, "si2ter ", 7))
- read_log_si(buffer + 7, sysinfo.si2ter);
- else if (!strncmp(buffer, "si3 ", 4))
- read_log_si(buffer + 4, sysinfo.si3);
- else if (!strncmp(buffer, "si4 ", 4))
- read_log_si(buffer + 4, sysinfo.si4);
- else if (!strncmp(buffer, "time ", 5))
- sysinfo.gmt = strtoul(buffer + 5, NULL, 0);
- else if (!strncmp(buffer, "position ", 9))
- read_log_pos(buffer + 9, &sysinfo.longitude,
- &sysinfo.latitude, &sysinfo.gps_valid);
- else if (!strncmp(buffer, "rxlev ", 5))
- sysinfo.rxlev =
- strtoul(buffer + 5, NULL, 0);
- else if (!strncmp(buffer, "bsic ", 5))
- read_log_bsic(buffer + 5);
- else if (!strncmp(buffer, "ta ", 3)) {
- sysinfo.ta_valid = 1;
- sysinfo.ta = atoi(buffer + 3);
- }
- break;
- case LOG_TYPE_POWER:
- if (!strncmp(buffer, "arfcn ", 6))
- read_log_power(buffer + 6);
- else if (!strncmp(buffer, "time ", 5))
- power.gmt = strtoul(buffer + 5, NULL, 0);
- else if (!strncmp(buffer, "position ", 9))
- read_log_pos(buffer + 9, &power.longitude,
- &power.latitude, &sysinfo.gps_valid);
- break;
- }
- }
-
- return type;
-}
-
diff --git a/Src/osmoconbb/src/host/gsmmap/log.h b/Src/osmoconbb/src/host/gsmmap/log.h
deleted file mode 100644
index d152010..0000000
--- a/Src/osmoconbb/src/host/gsmmap/log.h
+++ /dev/null
@@ -1,80 +0,0 @@
-
-enum {
- LOG_TYPE_NONE = 0,
- LOG_TYPE_SYSINFO,
- LOG_TYPE_POWER,
-};
-
-struct power {
- uint8_t gps_valid;
- double longitude, latitude;
- time_t gmt;
- int8_t rxlev[1024];
-};
-
-struct node_power {
- struct node_power *next;
- struct power power;
-};
-
-struct node_mcc {
- struct node_mcc *next;
- uint16_t mcc;
- struct node_mnc *mnc;
-};
-
-struct node_mnc {
- struct node_mnc *next;
- uint16_t mnc;
- struct node_lac *lac;
-};
-
-struct node_lac {
- struct node_lac *next;
- uint16_t lac;
- struct node_cell *cell;
-};
-
-struct sysinfo {
- uint16_t arfcn;
- int8_t rxlev;
- uint8_t bsic;
- uint8_t gps_valid;
- double longitude, latitude;
- time_t gmt;
- uint8_t si1[23];
- uint8_t si2[23];
- uint8_t si2bis[23];
- uint8_t si2ter[23];
- uint8_t si3[23];
- uint8_t si4[23];
- uint8_t ta_valid;
- uint8_t ta;
-};
-
-struct node_cell {
- struct node_cell *next;
- uint16_t cellid;
- uint8_t content; /* indicates, if sysinfo is already applied */
- struct node_meas *meas, **meas_last_p;
- struct sysinfo sysinfo;
- struct gsm48_sysinfo s;
-};
-
-struct node_meas {
- struct node_meas *next;
- time_t gmt;
- int8_t rxlev;
- uint8_t gps_valid;
- double longitude, latitude;
- uint8_t ta_valid;
- uint8_t ta;
-};
-
-struct node_mcc *get_node_mcc(uint16_t mcc);
-struct node_mnc *get_node_mnc(struct node_mcc *mcc, uint16_t mnc);
-struct node_lac *get_node_lac(struct node_mnc *mnc, uint16_t lac);
-struct node_cell *get_node_cell(struct node_lac *lac, uint16_t cellid);
-struct node_meas *add_node_meas(struct node_cell *cell);
-int read_log(FILE *infp);
-
diff --git a/Src/osmoconbb/src/host/layer23/.gitignore b/Src/osmoconbb/src/host/layer23/.gitignore
deleted file mode 100644
index 8fb93f7..0000000
--- a/Src/osmoconbb/src/host/layer23/.gitignore
+++ /dev/null
@@ -1,36 +0,0 @@
-# autoreconf by-products
-*.in
-
-aclocal.m4
-autom4te.cache/
-config.h.in
-configure
-depcomp
-install-sh
-missing
-
-# configure by-products
-.deps
-Makefile
-
-config.h
-config.log
-config.status
-
-# build by-products
-*.o
-*.a
-
-# various
-*.sw?
-*.deps
-
-# final executables
-src/misc/bcch_scan
-src/misc/cbch_sniff
-src/misc/cell_log
-src/misc/echo_test
-src/misc/cbch_sniff
-src/misc/ccch_scan
-src/misc/layer23
-src/mobile/mobile
diff --git a/Src/osmoconbb/src/host/layer23/COPYING b/Src/osmoconbb/src/host/layer23/COPYING
deleted file mode 100644
index d511905..0000000
--- a/Src/osmoconbb/src/host/layer23/COPYING
+++ /dev/null
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/Src/osmoconbb/src/host/layer23/Makefile.am b/Src/osmoconbb/src/host/layer23/Makefile.am
deleted file mode 100644
index bc3910f..0000000
--- a/Src/osmoconbb/src/host/layer23/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
-AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6
-
-SUBDIRS = include src
diff --git a/Src/osmoconbb/src/host/layer23/README b/Src/osmoconbb/src/host/layer23/README
deleted file mode 100644
index dd59823..0000000
--- a/Src/osmoconbb/src/host/layer23/README
+++ /dev/null
@@ -1,42 +0,0 @@
-= OsmocomBB layer23 architecture =
-
-layer23 is an (incomplete) MS-side implementation of the L2 and L3 GSM
-protocols as described in GSM TS 04.06, 04.08 and others.
-
-== Interfaces ==
-
-L1 (on the phone) uses the L1CTL protocol to talk with layer23 (on the PC).
-
-L2 (inside layer23) uses the RSLms protocol to talk with the L3 (inside layer23)
-
-
-=== RSLms ===
-
-RSLms is modeled after the GSM TS 08.58 Radio Subsystem Link protocol. Despite
-being designed for the network side, RSL seems a good match for the L2/L3
-interface inside a MS, too.
-
-At least the RLL (Radio Link Layer) part of RSL is 100% as applicable to the MS
-side as it is for the ntwork side.
-
-==== Lower interface (L2 to RSLms) ====
-
-Layer2 calls rslms_sendmsg() with a msgb that has the msgb->l2h pointing to a
-RSL header (struct abis_rsl_common_hdr).
-
-==== Upper interface (L3 to RSLms) ====
-
-Layer3 calls rslms_recvmsg() with a msgb that has the msgb->l2h pointing to a
-RSL header (struct abis_rsl_common_hdr).
-
-There are utility functions like rslms_tx_rll_req() and rslms_tx_rsll_req_l3()
-for creating msgb's with the apropriate RSL/RLL headers.
-
-
-=== LAPDm ===
-
-LAPDm is the GSM TS 04.06 protocol
-
-The lower interface (to L1) is using L1CTL
-
-The upper interface (to L3) is using RSLms
diff --git a/Src/osmoconbb/src/host/layer23/configure.ac b/Src/osmoconbb/src/host/layer23/configure.ac
deleted file mode 100644
index b50868a..0000000
--- a/Src/osmoconbb/src/host/layer23/configure.ac
+++ /dev/null
@@ -1,38 +0,0 @@
-dnl Process this file with autoconf to produce a configure script
-AC_INIT
-
-AM_INIT_AUTOMAKE(layer23, 0.0.0)
-
-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
-PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore)
-PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty)
-PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm)
-PKG_CHECK_MODULES(LIBOSMOCODEC, libosmocodec)
-AC_CHECK_LIB(gps, gps_waiting, CFLAGS+=" -D_HAVE_GPSD" LDFLAGS+=" -lgps",,)
-
-dnl checks for header files
-AC_HEADER_STDC
-
-dnl Checks for typedefs, structures and compiler characteristics
-
-AC_OUTPUT(
- src/Makefile
- src/common/Makefile
- src/misc/Makefile
- src/mobile/Makefile
- include/Makefile
- include/osmocom/Makefile
- include/osmocom/bb/Makefile
- include/osmocom/bb/common/Makefile
- include/osmocom/bb/misc/Makefile
- include/osmocom/bb/mobile/Makefile
- Makefile)
diff --git a/Src/osmoconbb/src/host/layer23/include/Makefile.am b/Src/osmoconbb/src/host/layer23/include/Makefile.am
deleted file mode 100644
index 297ece9..0000000
--- a/Src/osmoconbb/src/host/layer23/include/Makefile.am
+++ /dev/null
@@ -1,2 +0,0 @@
-noinst_HEADERS = l1ctl_proto.h
-SUBDIRS = osmocom
diff --git a/Src/osmoconbb/src/host/layer23/include/l1ctl_proto.h b/Src/osmoconbb/src/host/layer23/include/l1ctl_proto.h
deleted file mode 120000
index f12ba71..0000000
--- a/Src/osmoconbb/src/host/layer23/include/l1ctl_proto.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../../include/l1ctl_proto.h \ No newline at end of file
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/Makefile.am b/Src/osmoconbb/src/host/layer23/include/osmocom/Makefile.am
deleted file mode 100644
index 5adf9df..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/Makefile.am
+++ /dev/null
@@ -1 +0,0 @@
-SUBDIRS = bb
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/Makefile.am b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/Makefile.am
deleted file mode 100644
index 58a5f7f..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/Makefile.am
+++ /dev/null
@@ -1 +0,0 @@
-SUBDIRS = common misc mobile
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/Makefile.am b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/Makefile.am
deleted file mode 100644
index 26e63cf..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/Makefile.am
+++ /dev/null
@@ -1,2 +0,0 @@
-noinst_HEADERS = l1ctl.h l1l2_interface.h l23_app.h lapdm.h logging.h \
- networks.h gps.h sysinfo.h osmocom_data.h
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/gps.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/gps.h
deleted file mode 100644
index 58c0c53..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/gps.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-enum {
- GPS_TYPE_UNDEF,
- GPS_TYPE_GPSD,
- GPS_TYPE_SERIAL
-};
-
-struct osmo_gps {
- /* GPS device */
- uint8_t enable;
- uint8_t gps_type;
-
-#ifdef _HAVE_GPSD
- char gpsd_host[32];
- char gpsd_port[6];
-#endif
-
- char device[32];
- uint32_t baud;
-
- /* current data */
- uint8_t valid; /* we have a fix */
- time_t gmt; /* GMT time when position was received */
- double latitude, longitude;
-};
-
-extern struct osmo_gps g;
-
-int osmo_gps_open(void);
-void osmo_gps_close(void);
-void osmo_gps_init(void);
-
-
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/l1ctl.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/l1ctl.h
deleted file mode 100644
index 5ebea96..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/l1ctl.h
+++ /dev/null
@@ -1,76 +0,0 @@
-#ifndef osmocom_l1ctl_h
-#define osmocom_l1ctl_h
-
-#include <osmocom/core/msgb.h>
-#include <osmocom/bb/common/osmocom_data.h>
-
-struct osmocom_ms;
-
-/* Receive incoming data from L1 using L1CTL format */
-int l1ctl_recv(struct osmocom_ms *ms, struct msgb *msg);
-
-/* Transmit L1CTL_DATA_REQ */
-int l1ctl_tx_data_req(struct osmocom_ms *ms, struct msgb *msg, uint8_t chan_nr,
- uint8_t link_id);
-
-/* Transmit L1CTL_PARAM_REQ */
-int l1ctl_tx_param_req(struct osmocom_ms *ms, uint8_t ta, uint8_t tx_power);
-
-int l1ctl_tx_crypto_req(struct osmocom_ms *ms, uint8_t algo, uint8_t *key,
- uint8_t len);
-
-/* Transmit L1CTL_RACH_REQ */
-int l1ctl_tx_rach_req(struct osmocom_ms *ms, uint8_t ra, uint16_t offset,
- uint8_t combined);
-
-/* Transmit L1CTL_DM_EST_REQ */
-int l1ctl_tx_dm_est_req_h0(struct osmocom_ms *ms, uint16_t band_arfcn,
- uint8_t chan_nr, uint8_t tsc, uint8_t tch_mode, uint8_t audio_mode);
-int l1ctl_tx_dm_est_req_h1(struct osmocom_ms *ms, uint8_t maio, uint8_t hsn,
- uint16_t *ma, uint8_t ma_len, uint8_t chan_nr, uint8_t tsc,
- uint8_t tch_mode, uint8_t audio_mode);
-
-/* Transmit L1CTL_DM_FREQ_REQ */
-int l1ctl_tx_dm_freq_req_h0(struct osmocom_ms *ms, uint16_t band_arfcn,
- uint8_t tsc, uint16_t fn);
-int l1ctl_tx_dm_freq_req_h1(struct osmocom_ms *ms, uint8_t maio, uint8_t hsn,
- uint16_t *ma, uint8_t ma_len, uint8_t tsc, uint16_t fn);
-
-/* Transmit L1CTL_DM_REL_REQ */
-int l1ctl_tx_dm_rel_req(struct osmocom_ms *ms);
-
-/* Transmit FBSB_REQ */
-int l1ctl_tx_fbsb_req(struct osmocom_ms *ms, uint16_t arfcn,
- uint8_t flags, uint16_t timeout, uint8_t sync_info_idx,
- uint8_t ccch_mode);
-
-/* Transmit CCCH_MODE_REQ */
-int l1ctl_tx_ccch_mode_req(struct osmocom_ms *ms, uint8_t ccch_mode);
-
-/* Transmit TCH_MODE_REQ */
-int l1ctl_tx_tch_mode_req(struct osmocom_ms *ms, uint8_t tch_mode,
- uint8_t audio_mode);
-
-/* Transmit ECHO_REQ */
-int l1ctl_tx_echo_req(struct osmocom_ms *ms, unsigned int len);
-
-/* Transmit L1CTL_RESET_REQ */
-int l1ctl_tx_reset_req(struct osmocom_ms *ms, uint8_t type);
-
-/* Transmit L1CTL_PM_REQ */
-int l1ctl_tx_pm_req_range(struct osmocom_ms *ms, uint16_t arfcn_from,
- uint16_t arfcm_to);
-
-int l1ctl_tx_sim_req(struct osmocom_ms *ms, uint8_t *data, uint16_t length);
-
-/* Transmit L1CTL_VOICE_REQ */
-int l1ctl_tx_traffic_req(struct osmocom_ms *ms, struct msgb *msg,
- uint8_t chan_nr, uint8_t link_id);
-
-/* LAPDm wants to send a PH-* primitive to the physical layer (L1) */
-int l1ctl_ph_prim_cb(struct osmo_prim_hdr *oph, void *ctx);
-
-/* Transmit L1CTL_NEIGH_PM_REQ */
-int l1ctl_tx_neigh_pm_req(struct osmocom_ms *ms, int num, uint16_t *arfcn);
-
-#endif
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/l1l2_interface.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/l1l2_interface.h
deleted file mode 100644
index 41403d8..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/l1l2_interface.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _L1L2_INTERFACE_H
-#define _L1L2_INTERFACE_H
-
-int layer2_open(struct osmocom_ms *ms, const char *socket_path);
-int layer2_close(struct osmocom_ms *ms);
-int osmo_send_l1(struct osmocom_ms *ms, struct msgb *msg);
-
-#endif /* _L1L2_INTERFACE_H */
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/l23_app.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/l23_app.h
deleted file mode 100644
index e4c5d55..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/l23_app.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef _L23_APP_H
-#define _L23_APP_H
-
-struct option;
-
-/* Options supported by the l23 app */
-enum {
- L23_OPT_SAP = 1,
- L23_OPT_ARFCN = 2,
- L23_OPT_TAP = 4,
- L23_OPT_VTY = 8,
- L23_OPT_DBG = 16,
-};
-
-/* initialization, called once when starting the app, before entering
- * select loop */
-extern int l23_app_init(struct osmocom_ms *ms);
-extern int (*l23_app_work) (struct osmocom_ms *ms);
-extern int (*l23_app_exit) (struct osmocom_ms *ms);
-
-/* configuration options */
-struct l23_app_info {
- const char *copyright;
- const char *contribution;
-
- char *getopt_string;
- int (*cfg_supported)();
- int (*cfg_print_help)();
- int (*cfg_getopt_opt)(struct option **options);
- int (*cfg_handle_opt)(int c,const char *optarg);
-};
-
-extern struct l23_app_info *l23_app_info();
-
-#endif /* _L23_APP_H */
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/lapdm.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/lapdm.h
deleted file mode 100644
index 2e78aee..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/lapdm.h
+++ /dev/null
@@ -1,186 +0,0 @@
-#ifndef _OSMOCOM_LAPDM_H
-#define _OSMOCOM_LAPDM_H
-
-#include <stdint.h>
-
-#include <osmocom/core/timer.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/gsm/prim.h>
-
-/* primitive related sutff */
-
-enum osmo_ph_prim {
- PRIM_PH_DATA, /* PH-DATA */
- PRIM_PH_RACH, /* PH-RANDOM_ACCESS */
- PRIM_PH_CONN, /* PH-CONNECT */
- PRIM_PH_EMPTY_FRAME, /* PH-EMPTY_FRAME */
- PRIM_PH_RTS, /* PH-RTS */
-};
-
-/* for PH-RANDOM_ACCESS.req */
-struct ph_rach_req_param {
- uint8_t ra;
- uint8_t ta;
- uint8_t tx_power;
- uint8_t is_combined_ccch;
- uint16_t offset;
-};
-
-/* for PH-RANDOM_ACCESS.ind */
-struct ph_rach_ind_param {
- uint8_t ra;
- uint8_t acc_delay;
- uint32_t fn;
-};
-
-/* for PH-[UNIT]DATA.{req,ind} */
-struct ph_data_param {
- uint8_t link_id;
- uint8_t chan_nr;
-};
-
-struct ph_conn_ind_param {
- uint32_t fn;
-};
-
-struct osmo_phsap_prim {
- struct osmo_prim_hdr oph;
- union {
- struct ph_data_param data;
- struct ph_rach_req_param rach_req;
- struct ph_rach_ind_param rach_ind;
- struct ph_conn_ind_param conn_ind;
- } u;
-};
-
-enum lapdm_mode {
- LAPDM_MODE_MS,
- LAPDM_MODE_BTS,
-};
-
-enum lapdm_state {
- LAPDm_STATE_NULL = 0,
- LAPDm_STATE_IDLE,
- LAPDm_STATE_SABM_SENT,
- LAPDm_STATE_MF_EST,
- LAPDm_STATE_TIMER_RECOV,
- LAPDm_STATE_DISC_SENT,
-};
-
-struct lapdm_entity;
-
-struct lapdm_msg_ctx {
- struct lapdm_datalink *dl;
- int lapdm_fmt;
- uint8_t n201;
- uint8_t chan_nr;
- uint8_t link_id;
- uint8_t addr;
- uint8_t ctrl;
- uint8_t ta_ind;
- uint8_t tx_power_ind;
-};
-
-/* TS 04.06 / Section 3.5.2 */
-struct lapdm_datalink {
- uint8_t V_send; /* seq nr of next I frame to be transmitted */
- uint8_t V_ack; /* last frame ACKed by peer */
- uint8_t N_send; /* ? set to V_send at Tx time*/
- uint8_t V_recv; /* seq nr of next I frame expected to be received */
- uint8_t N_recv; /* expected send seq nr of the next received I frame */
- uint32_t state;
- int seq_err_cond; /* condition of sequence error */
- uint8_t own_busy, peer_busy;
- struct osmo_timer_list t200;
- uint8_t retrans_ctr;
- struct llist_head send_queue; /* frames from L3 */
- struct msgb *send_buffer; /* current frame transmitting */
- int send_out; /* how much was sent from send_buffer */
- uint8_t tx_hist[8][200]; /* tx history buffer */
- int tx_length[8]; /* length in history buffer */
- struct llist_head tx_queue; /* frames to L1 */
- struct lapdm_msg_ctx mctx; /* context of established connection */
- struct msgb *rcv_buffer; /* buffer to assemble the received message */
-
- struct lapdm_entity *entity;
-};
-
-enum lapdm_dl_sapi {
- DL_SAPI0 = 0,
- DL_SAPI3 = 1,
- _NR_DL_SAPI
-};
-
-typedef int (*lapdm_cb_t)(struct msgb *msg, struct lapdm_entity *le, void *ctx);
-
-struct lapdm_cr_ent {
- uint8_t cmd;
- uint8_t resp;
-};
-
-#define LAPDM_ENT_F_EMPTY_FRAME 0x0001
-#define LAPDM_ENT_F_POLLING_ONLY 0x0002
-
-/* register message handler for messages that are sent from L2->L3 */
-struct lapdm_entity {
- struct lapdm_datalink datalink[_NR_DL_SAPI];
- int last_tx_dequeue; /* last entity that was dequeued */
- int tx_pending; /* currently a pending frame not confirmed by L1 */
- enum lapdm_mode mode; /* are we in BTS mode or MS mode */
- unsigned int flags;
-
- struct {
- /* filled-in once we set the lapdm_mode above */
- struct lapdm_cr_ent loc2rem;
- struct lapdm_cr_ent rem2loc;
- } cr;
-
- void *l1_ctx; /* context for layer1 instance */
- void *l3_ctx; /* context for layer3 instance */
-
- osmo_prim_cb l1_prim_cb;
- lapdm_cb_t l3_cb; /* callback for sending stuff to L3 */
-
- struct lapdm_channel *lapdm_ch;
-};
-
-/* the two lapdm_entities that form a GSM logical channel (ACCH + DCCH) */
-struct lapdm_channel {
- struct llist_head list;
- char *name;
- struct lapdm_entity lapdm_acch;
- struct lapdm_entity lapdm_dcch;
-};
-
-const char *get_rsl_name(int value);
-extern const char *lapdm_state_names[];
-
-/* initialize a LAPDm entity */
-void lapdm_entity_init(struct lapdm_entity *le, enum lapdm_mode mode);
-void lapdm_channel_init(struct lapdm_channel *lc, enum lapdm_mode mode);
-
-/* deinitialize a LAPDm entity */
-void lapdm_entity_exit(struct lapdm_entity *le);
-void lapdm_channel_exit(struct lapdm_channel *lc);
-
-/* input into layer2 (from layer 1) */
-int lapdm_phsap_up(struct osmo_prim_hdr *oph, struct lapdm_entity *le);
-
-/* input into layer2 (from layer 3) */
-int lapdm_rslms_recvmsg(struct msgb *msg, struct lapdm_channel *lc);
-
-void lapdm_channel_set_l3(struct lapdm_channel *lc, lapdm_cb_t cb, void *ctx);
-void lapdm_channel_set_l1(struct lapdm_channel *lc, osmo_prim_cb cb, void *ctx);
-
-int lapdm_entity_set_mode(struct lapdm_entity *le, enum lapdm_mode mode);
-int lapdm_channel_set_mode(struct lapdm_channel *lc, enum lapdm_mode mode);
-
-void lapdm_entity_reset(struct lapdm_entity *le);
-void lapdm_channel_reset(struct lapdm_channel *lc);
-
-void lapdm_entity_set_flags(struct lapdm_entity *le, unsigned int flags);
-void lapdm_channel_set_flags(struct lapdm_channel *lc, unsigned int flags);
-
-int lapdm_phsap_dequeue_prim(struct lapdm_entity *le, struct osmo_phsap_prim *pp);
-
-#endif /* _OSMOCOM_LAPDM_H */
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/logging.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/logging.h
deleted file mode 100644
index 554b767..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/logging.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef _LOGGING_H
-#define _LOGGING_H
-
-#define DEBUG
-#include <osmocom/core/logging.h>
-
-enum {
- DRSL,
- DRR,
- DPLMN,
- DCS,
- DNB,
- DMM,
- DCC,
- DSMS,
- DMNCC,
- DMEAS,
- DPAG,
- DLAPDM,
- DL1C,
- DSAP,
- DSUM,
- DSIM,
- DGPS,
-};
-
-extern const struct log_info log_info;
-
-#endif /* _LOGGING_H */
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/networks.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/networks.h
deleted file mode 100644
index e681216..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/networks.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef _NETWORKS_H
-#define _NETWORKS_H
-
-#define GSM_INPUT_INVALID 0xffff
-
-struct gsm_networks {
- uint16_t mcc;
- int16_t mnc;
- const char *name;
-};
-
-int gsm_match_mcc(uint16_t mcc, char *imsi);
-int gsm_match_mnc(uint16_t mcc, uint8_t mnc, char *imsi);
-const char *gsm_print_mcc(uint16_t mcc);
-const char *gsm_print_mnc(uint16_t mcc);
-const char *gsm_get_mcc(uint16_t mcc);
-const char *gsm_get_mnc(uint16_t mcc, uint16_t mnc);
-const char *gsm_imsi_mcc(char *imsi);
-const char *gsm_imsi_mnc(char *imsi);
-const uint16_t gsm_input_mcc(char *string);
-const uint16_t gsm_input_mnc(char *string);
-
-#endif /* _NETWORKS_H */
-
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/osmocom_data.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/osmocom_data.h
deleted file mode 100644
index 6ad89cd..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/osmocom_data.h
+++ /dev/null
@@ -1,129 +0,0 @@
-#ifndef osmocom_data_h
-#define osmocom_data_h
-
-#include <osmocom/core/select.h>
-#include <osmocom/gsm/gsm_utils.h>
-#include <osmocom/core/write_queue.h>
-
-struct osmocom_ms;
-
- /* FIXME no 'mobile' specific stuff should be here */
-#include <osmocom/bb/mobile/support.h>
-#include <osmocom/bb/mobile/settings.h>
-#include <osmocom/bb/mobile/subscriber.h>
-#include <osmocom/bb/common/lapdm.h>
-#include <osmocom/bb/common/sap_interface.h>
-#include <osmocom/bb/mobile/gsm48_rr.h>
-#include <osmocom/bb/common/sysinfo.h>
-#include <osmocom/bb/mobile/gsm322.h>
-#include <osmocom/bb/mobile/gsm48_mm.h>
-#include <osmocom/bb/mobile/gsm48_cc.h>
-#include <osmocom/bb/common/sim.h>
-#include <osmocom/bb/common/l1ctl.h>
-
-struct osmosap_entity {
- osmosap_cb_t msg_handler;
-};
-
-struct osmol1_entity {
- int (*l1_traffic_ind)(struct osmocom_ms *ms, struct msgb *msg);
-};
-
-struct osmomncc_entity {
- int (*mncc_recv)(struct osmocom_ms *ms, int msg_type, void *arg);
- uint32_t ref;
-};
-
-
-/* RX measurement statistics */
-struct rx_meas_stat {
- uint32_t last_fn;
-
- /* cumulated values of current cell from SACCH dl */
- uint32_t frames;
- uint32_t snr;
- uint32_t berr;
- uint32_t rxlev;
-
- /* counters loss criterion */
- int16_t dsc, ds_fail;
- int16_t s, rl_fail;
-};
-
-/* One Mobilestation for osmocom */
-struct osmocom_ms {
- struct llist_head entity;
- char name[32];
- struct osmo_wqueue l2_wq, sap_wq;
- uint16_t test_arfcn;
- struct osmol1_entity l1_entity;
-
- uint8_t deleting, shutdown, started;
- struct gsm_support support;
- struct gsm_settings settings;
- struct gsm_subscriber subscr;
- struct gsm_sim sim;
- struct lapdm_channel lapdm_channel;
- struct osmosap_entity sap_entity;
- struct rx_meas_stat meas;
- struct gsm48_rrlayer rrlayer;
- struct gsm322_plmn plmn;
- struct gsm322_cellsel cellsel;
- struct gsm48_mmlayer mmlayer;
- struct gsm48_cclayer cclayer;
- struct osmomncc_entity mncc_entity;
- struct llist_head trans_list;
-};
-
-enum osmobb_sig_subsys {
- SS_L1CTL,
- SS_GLOBAL,
-};
-
-enum osmobb_l1ctl_sig {
- S_L1CTL_FBSB_ERR,
- S_L1CTL_FBSB_RESP,
- S_L1CTL_RESET,
- S_L1CTL_PM_RES,
- S_L1CTL_PM_DONE,
- S_L1CTL_CCCH_MODE_CONF,
- S_L1CTL_TCH_MODE_CONF,
- S_L1CTL_LOSS_IND,
- S_L1CTL_NEIGH_PM_IND,
-};
-
-enum osmobb_global_sig {
- S_GLOBAL_SHUTDOWN,
-};
-
-struct osmobb_fbsb_res {
- struct osmocom_ms *ms;
- int8_t snr;
- uint8_t bsic;
- uint16_t band_arfcn;
-};
-
-struct osmobb_meas_res {
- struct osmocom_ms *ms;
- uint16_t band_arfcn;
- uint8_t rx_lev;
-};
-
-struct osmobb_ccch_mode_conf {
- struct osmocom_ms *ms;
- uint8_t ccch_mode;
-};
-
-struct osmobb_tch_mode_conf {
- struct osmocom_ms *ms;
- uint8_t tch_mode;
- uint8_t audio_mode;
-};
-
-struct osmobb_neigh_pm_ind {
- struct osmocom_ms *ms;
- uint16_t band_arfcn;
- uint8_t rx_lev;
-};
-
-#endif
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/sap_interface.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/sap_interface.h
deleted file mode 100644
index f2f577a..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/sap_interface.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef _SAP_INTERFACE_H
-#define _SAP_INTERFACE_H
-
-typedef int (*osmosap_cb_t)(struct msgb *msg, struct osmocom_ms *ms);
-
-int sap_open(struct osmocom_ms *ms, const char *socket_path);
-int sap_close(struct osmocom_ms *ms);
-int osmosap_send(struct osmocom_ms *ms, struct msgb *msg);
-int osmosap_register_handler(struct osmocom_ms *ms, osmosap_cb_t cb);
-
-#endif /* _SAP_INTERFACE_H */
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/sim.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/sim.h
deleted file mode 100644
index a676b92..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/sim.h
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-
-/* 9.2 commands */
-#define GSM1111_CLASS_GSM 0xa0
-#define GSM1111_INST_SELECT 0xa4
-#define GSM1111_INST_STATUS 0xf2
-#define GSM1111_INST_READ_BINARY 0xb0
-#define GSM1111_INST_UPDATE_BINARY 0xd6
-#define GSM1111_INST_READ_RECORD 0xb2
-#define GSM1111_INST_UPDATE_RECORD 0xdc
-#define GSM1111_INST_SEEK 0xa2
-#define GSM1111_INST_INCREASE 0x32
-#define GSM1111_INST_VERIFY_CHV 0x20
-#define GSM1111_INST_CHANGE_CHV 0x24
-#define GSM1111_INST_DISABLE_CHV 0x26
-#define GSM1111_INST_ENABLE_CHV 0x28
-#define GSM1111_INST_UNBLOCK_CHV 0x2c
-#define GSM1111_INST_INVALIDATE 0x04
-#define GSM1111_INST_REHABLILITATE 0x44
-#define GSM1111_INST_RUN_GSM_ALGO 0x88
-#define GSM1111_INST_SLEEP 0xfa
-#define GSM1111_INST_GET_RESPONSE 0xc0
-#define GSM1111_INST_TERMINAL_PROFILE 0x10
-#define GSM1111_INST_ENVELOPE 0xc2
-#define GSM1111_INST_FETCH 0x12
-#define GSM1111_INST_TERMINAL_RESPONSE 0x14
-
-/* 9.3 access conditions */
-#define GSM1111_ACC_ALWAYS 0x0
-#define GSM1111_ACC_CHV1 0x1
-#define GSM1111_ACC_CHV2 0x2
-#define GSM1111_ACC_RFU 0x3
-#define GSM1111_ACC_NEW 0xf
-/* others are ADM */
-
-/* 9.3 type of file */
-#define GSM1111_TOF_RFU 0x00
-#define GSM1111_TOF_MF 0x01
-#define GSM1111_TOF_DF 0x02
-#define GSM1111_TOF_EF 0x04
-
-/* 9.3 struct of file */
-#define GSM1111_SOF_TRANSPARENT 0x00
-#define GSM1111_SOF_LINEAR 0x01
-#define GSM1111_SOF_CYCLIC 0x03
-
-/* 9.4 status */
-#define GSM1111_STAT_NORMAL 0x90
-#define GSM1111_STAT_PROACTIVE 0x91
-#define GSM1111_STAT_DL_ERROR 0x9e
-#define GSM1111_STAT_RESPONSE 0x9f
-#define GSM1111_STAT_RESPONSE_TOO 0x61
-#define GSM1111_STAT_APP_TK_BUSY 0x93
-#define GSM1111_STAT_MEM_PROBLEM 0x92
-#define GSM1111_STAT_REFERENCING 0x94
-#define GSM1111_STAT_SECURITY 0x98
-#define GSM1111_STAT_INCORR_P3 0x67
-#define GSM1111_STAT_INCORR_P1_P2 0x6b
-#define GSM1111_STAT_UKN_INST 0x6d
-#define GSM1111_STAT_WRONG_CLASS 0x6e
-#define GSM1111_STAT_TECH_PROBLEM 0x6f
-
-/* 9.4.4 Referencing management SW2 */
-#define GSM1111_REF_NO_EF 0x00
-#define GSM1111_REF_OUT_OF_RANGE 0x02
-#define GSM1111_REF_FILE_NOT_FOUND 0x04
-#define GSM1111_REF_FILE_INCONSI 0x08
-
-/* 9.4.5 Security management SW2 */
-#define GSM1111_SEC_NO_CHV 0x02
-#define GSM1111_SEC_NO_ACCESS 0x04
-#define GSM1111_SEC_CONTRA_CHV 0x08
-#define GSM1111_SEC_CONTRA_INVAL 0x10
-#define GSM1111_SEC_BLOCKED 0x40
-#define GSM1111_SEC_MAX_VALUE 0x50
-
-/* messages from application to sim client */
-enum {
- /* requests */
- SIM_JOB_READ_BINARY,
- SIM_JOB_UPDATE_BINARY,
- SIM_JOB_READ_RECORD,
- SIM_JOB_UPDATE_RECORD,
- SIM_JOB_SEEK_RECORD,
- SIM_JOB_INCREASE,
- SIM_JOB_INVALIDATE,
- SIM_JOB_REHABILITATE,
- SIM_JOB_RUN_GSM_ALGO,
- SIM_JOB_PIN1_UNLOCK,
- SIM_JOB_PIN1_CHANGE,
- SIM_JOB_PIN1_DISABLE,
- SIM_JOB_PIN1_ENABLE,
- SIM_JOB_PIN1_UNBLOCK,
- SIM_JOB_PIN2_UNLOCK,
- SIM_JOB_PIN2_CHANGE,
- SIM_JOB_PIN2_UNBLOCK,
-
- /* results */
- SIM_JOB_OK,
- SIM_JOB_ERROR,
-};
-
-/* messages from sim client to application */
-#define SIM_JOB_OK 0
-#define SIM_JOB_ERROR 1
-
-/* error causes */
-#define SIM_CAUSE_NO_SIM 0 /* no SIM present, if detectable */
-#define SIM_CAUSE_SIM_ERROR 1 /* any error while reading SIM */
-#define SIM_CAUSE_REQUEST_ERROR 2 /* error in request */
-#define SIM_CAUSE_PIN1_REQUIRED 3 /* CHV1 is required for access */
-#define SIM_CAUSE_PIN2_REQUIRED 4 /* CHV2 is required for access */
-#define SIM_CAUSE_PIN1_BLOCKED 5 /* CHV1 was entered too many times */
-#define SIM_CAUSE_PIN2_BLOCKED 6 /* CHV2 was entered too many times */
-#define SIM_CAUSE_PUC_BLOCKED 7 /* unblock entered too many times */
-
-/* job states */
-enum {
- SIM_JST_IDLE = 0,
- SIM_JST_SELECT_MFDF, /* SELECT sent */
- SIM_JST_SELECT_MFDF_RESP, /* GET RESPONSE sent */
- SIM_JST_SELECT_EF, /* SELECT sent */
- SIM_JST_SELECT_EF_RESP, /* GET RESPONSE sent */
- SIM_JST_WAIT_FILE, /* file command sent */
- SIM_JST_RUN_GSM_ALGO, /* wait for algorithm to process */
- SIM_JST_RUN_GSM_ALGO_RESP, /* wait for response */
- SIM_JST_PIN1_UNLOCK,
- SIM_JST_PIN1_CHANGE,
- SIM_JST_PIN1_DISABLE,
- SIM_JST_PIN1_ENABLE,
- SIM_JST_PIN1_UNBLOCK,
- SIM_JST_PIN2_UNLOCK,
- SIM_JST_PIN2_CHANGE,
- SIM_JST_PIN2_UNBLOCK,
-};
-
-#define MAX_SIM_PATH_LENGTH 6 + 1 /* one for the termination */
-
-struct gsm_sim_handler {
- struct llist_head entry;
-
- uint32_t handle;
- void (*cb)(struct osmocom_ms *ms, struct msgb *msg);
-};
-
-struct gsm_sim {
- struct llist_head handlers; /* gsm_sim_handler */
- struct llist_head jobs; /* messages */
- uint16_t path[MAX_SIM_PATH_LENGTH];
- uint16_t file;
-
- struct msgb *job_msg;
- uint32_t job_handle;
- int job_state;
-
- uint8_t reset;
- uint8_t chv1_remain, chv2_remain;
- uint8_t unblk1_remain, unblk2_remain;
-};
-
-struct sim_hdr {
- int handle;
- uint8_t job_type;
- uint16_t path[MAX_SIM_PATH_LENGTH];
- uint16_t file;
- uint8_t rec_no, rec_mode; /* in case of record */
- uint8_t seek_type_mode; /* in case of seek command */
-};
-
-#define SIM_ALLOC_SIZE 512
-#define SIM_ALLOC_HEADROOM 64
-
-struct msgb *gsm_sim_msgb_alloc(uint32_t handle, uint8_t job_type);
-uint32_t sim_open(struct osmocom_ms *ms,
- void (*cb)(struct osmocom_ms *ms, struct msgb *msg));
-void sim_close(struct osmocom_ms *ms, uint32_t handle);
-void sim_job(struct osmocom_ms *ms, struct msgb *msg);
-
-/* Section 9.2.1 (response to selecting DF or MF) */
-struct gsm1111_response_mfdf {
- uint16_t rfu1;
- uint16_t free_mem;
- uint16_t file_id;
- uint8_t tof;
- uint8_t rfu2[5];
- uint8_t length;
- uint8_t gsm_data[0];
-} __attribute__ ((packed));
-
-struct gsm1111_response_mfdf_gsm {
- uint8_t file_char;
- uint8_t num_df;
- uint8_t num_ef;
- uint8_t num_codes;
- uint8_t rfu1;
- uint8_t chv1_remain:4,
- rfu2:3,
- chv1_init:1;
- uint8_t unblk1_remain:4,
- rfu3:3,
- unblk1_init:1;
- uint8_t chv2_remain:4,
- rfu4:3,
- chv2_init:1;
- uint8_t unblk2_remain:4,
- rfu5:3,
- unblk2_init:1;
- uint8_t more_data[0];
-} __attribute__ ((packed));
-
-/* Section 9.2.1 (response to selecting EF) */
-struct gsm1111_response_ef {
- uint16_t rfu1;
- uint16_t file_size;
- uint16_t file_id;
- uint8_t tof;
- uint8_t inc_allowed;
- uint8_t acc_update:4,
- acc_read:4;
- uint8_t rfu2:4,
- acc_inc:4;
- uint8_t acc_inval:4,
- acc_reha:4;
- uint8_t not_inval:1,
- rfu3:1,
- ru_inval:1,
- rfu4:5;
- uint8_t length;
- uint8_t structure;
-} __attribute__ ((packed));
-
-/* Section 10.3.17 */
-struct gsm1111_ef_loci {
- uint32_t tmsi;
- struct gsm48_loc_area_id lai;
- uint8_t tmsi_time;
- uint8_t lupd_status;
-} __attribute__ ((packed));
-
-/* Section 10.5.1 */
-struct gsm1111_ef_adn {
- uint8_t len_bcd;
- uint8_t ton_npi;
- uint8_t number[10];
- uint8_t capa_conf;
- uint8_t ext_id;
-} __attribute__ ((packed));
-
-int sim_apdu_resp(struct osmocom_ms *ms, struct msgb *msg);
-int gsm_sim_init(struct osmocom_ms *ms);
-int gsm_sim_exit(struct osmocom_ms *ms);
-int gsm_sim_job_dequeue(struct osmocom_ms *ms);
-
-
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/sysinfo.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/sysinfo.h
deleted file mode 100644
index 5d3ed59..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/common/sysinfo.h
+++ /dev/null
@@ -1,158 +0,0 @@
-#ifndef _SYSINFO_H
-#define _SYSINFO_H
-
-#include <osmocom/gsm/gsm48_ie.h>
-
-/* collection of system information of the current cell */
-
-/* frequency mask flags of frequency type */
-#define FREQ_TYPE_SERV 0x01 /* frequency of the serving cell */
-#define FREQ_TYPE_HOPP 0x02 /* frequency used for channel hopping */
-#define FREQ_TYPE_NCELL 0x1c /* frequency of the neighbor cell */
-#define FREQ_TYPE_NCELL_2 0x04 /* sub channel of SI 2 */
-#define FREQ_TYPE_NCELL_2bis 0x08 /* sub channel of SI 2bis */
-#define FREQ_TYPE_NCELL_2ter 0x10 /* sub channel of SI 2ter */
-#define FREQ_TYPE_REP 0xe0 /* frequency to be reported */
-#define FREQ_TYPE_REP_5 0x20 /* sub channel of SI 5 */
-#define FREQ_TYPE_REP_5bis 0x40 /* sub channel of SI 5bis */
-#define FREQ_TYPE_REP_5ter 0x80 /* sub channel of SI 5ter */
-
-/* structure of all received system informations */
-struct gsm48_sysinfo {
- /* flags of available information */
- uint8_t si1, si2, si2bis, si2ter, si3,
- si4, si5, si5bis, si5ter, si6;
-
- /* memory maps to simply detect change in system info messages */
- uint8_t si1_msg[23];
- uint8_t si2_msg[23];
- uint8_t si2b_msg[23];
- uint8_t si2t_msg[23];
- uint8_t si3_msg[23];
- uint8_t si4_msg[23];
- uint8_t si5_msg[18];
- uint8_t si5b_msg[18];
- uint8_t si5t_msg[18];
- uint8_t si6_msg[18];
-
- struct gsm_sysinfo_freq freq[1024]; /* all frequencies */
- uint16_t hopping[64]; /* hopping arfcn */
- uint8_t hopp_len;
-
- /* serving cell */
- uint8_t bsic;
- uint16_t cell_id;
- uint16_t mcc, mnc, lac; /* LAI */
- uint8_t max_retrans; /* decoded */
- uint8_t tx_integer; /* decoded */
- uint8_t reest_denied; /* 1 = denied */
- uint8_t cell_barr; /* 1 = barred */
- uint16_t class_barr; /* bit 10 is emergency */
-
- /* si1 rest */
- uint8_t nch;
- uint8_t nch_position;
- uint8_t band_ind; /* set for DCS */
-
- /* si3 rest */
- uint8_t sp;
- uint8_t sp_cbq;
- uint8_t sp_cro;
- uint8_t sp_to;
- uint8_t sp_pt;
- uint8_t po;
- uint8_t po_value;
- uint8_t si2ter_ind;
- uint8_t ecsm;
- uint8_t sched;
- uint8_t sched_where;
- uint8_t gprs;
- uint8_t gprs_ra_colour;
- uint8_t gprs_si13_pos;
-
- /* cell selection */
- int8_t ms_txpwr_max_cch;
- int8_t cell_resel_hyst_db;
- int8_t rxlev_acc_min_db;
- uint8_t neci;
- uint8_t acs;
- /* bcch options */
- uint8_t bcch_radio_link_timeout;
- uint8_t bcch_dtx;
- uint8_t bcch_pwrc;
- /* sacch options */
- uint8_t sacch_radio_link_timeout;
- uint8_t sacch_dtx;
- uint8_t sacch_pwrc;
- /* control channel */
- uint8_t ccch_conf;
- uint8_t bs_ag_blks_res;
- uint8_t att_allowed;
- uint8_t pag_mf_periods;
- int32_t t3212; /* real value in seconds */
- /* channel description */
- uint8_t tsc;
- uint8_t h; /* using hopping */
- uint16_t arfcn;
- uint8_t maio;
- uint8_t hsn;
- uint8_t chan_nr; /* type, slot, sub slot */
-
- /* neighbor cell */
- uint8_t nb_ext_ind_si2;
- uint8_t nb_ba_ind_si2;
- uint8_t nb_ext_ind_si2bis;
- uint8_t nb_ba_ind_si2bis;
- uint8_t nb_multi_rep_si2ter; /* see GSM 05.08 8.4.3 */
- uint8_t nb_ba_ind_si2ter;
- uint8_t nb_ext_ind_si5;
- uint8_t nb_ba_ind_si5;
- uint8_t nb_ext_ind_si5bis;
- uint8_t nb_ba_ind_si5bis;
- uint8_t nb_multi_rep_si5ter;
- uint8_t nb_ba_ind_si5ter;
- uint8_t nb_ncc_permitted_si2;
- uint8_t nb_ncc_permitted_si6;
- uint8_t nb_max_retrans; /* decoded */
- uint8_t nb_tx_integer; /* decoded */
- uint8_t nb_reest_denied; /* 1 = denied */
- uint8_t nb_cell_barr; /* 1 = barred */
- uint16_t nb_class_barr; /* bit 10 is emergency */
-};
-
-char *gsm_print_arfcn(uint16_t arfcn);
-uint8_t gsm_refer_pcs(uint16_t arfcn, struct gsm48_sysinfo *s);
-int gsm48_sysinfo_dump(struct gsm48_sysinfo *s, uint16_t arfcn,
- void (*print)(void *, const char *, ...), void *priv,
- uint8_t *freq_map);
-int gsm48_decode_lai(struct gsm48_loc_area_id *lai, uint16_t *mcc,
- uint16_t *mnc, uint16_t *lac);
-int gsm48_decode_chan_h0(struct gsm48_chan_desc *cd, uint8_t *tsc,
- uint16_t *arfcn);
-int gsm48_decode_chan_h1(struct gsm48_chan_desc *cd, uint8_t *tsc,
- uint8_t *maio, uint8_t *hsn);
-int gsm48_decode_sysinfo1(struct gsm48_sysinfo *s,
- struct gsm48_system_information_type_1 *si, int len);
-int gsm48_decode_sysinfo2(struct gsm48_sysinfo *s,
- struct gsm48_system_information_type_2 *si, int len);
-int gsm48_decode_sysinfo2bis(struct gsm48_sysinfo *s,
- struct gsm48_system_information_type_2bis *si, int len);
-int gsm48_decode_sysinfo2ter(struct gsm48_sysinfo *s,
- struct gsm48_system_information_type_2ter *si, int len);
-int gsm48_decode_sysinfo3(struct gsm48_sysinfo *s,
- struct gsm48_system_information_type_3 *si, int len);
-int gsm48_decode_sysinfo4(struct gsm48_sysinfo *s,
- struct gsm48_system_information_type_4 *si, int len);
-int gsm48_decode_sysinfo5(struct gsm48_sysinfo *s,
- struct gsm48_system_information_type_5 *si, int len);
-int gsm48_decode_sysinfo5bis(struct gsm48_sysinfo *s,
- struct gsm48_system_information_type_5bis *si, int len);
-int gsm48_decode_sysinfo5ter(struct gsm48_sysinfo *s,
- struct gsm48_system_information_type_5ter *si, int len);
-int gsm48_decode_sysinfo6(struct gsm48_sysinfo *s,
- struct gsm48_system_information_type_6 *si, int len);
-int gsm48_decode_mobile_alloc(struct gsm_sysinfo_freq *freq,
- uint8_t *ma, uint8_t len, uint16_t *hopping, uint8_t *hopp_len,
- int si4);
-
-#endif /* _SYSINFO_H */
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/misc/Makefile.am b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/misc/Makefile.am
deleted file mode 100644
index 71c9d38..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/misc/Makefile.am
+++ /dev/null
@@ -1 +0,0 @@
-noinst_HEADERS = layer3.h rslms.h
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/misc/cell_log.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/misc/cell_log.h
deleted file mode 100644
index bce066e..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/misc/cell_log.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/* Cell Scanning code for OsmocomBB */
-
-/* (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-int scan_init(struct osmocom_ms *_ms);
-int scan_exit(void);
-
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/misc/layer3.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/misc/layer3.h
deleted file mode 100644
index bbf242d..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/misc/layer3.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef _OSMOCOM_L3_H
-#define _OSMOCOM_L3_H
-
-#include <osmocom/core/msgb.h>
-#include <osmocom/bb/common/osmocom_data.h>
-
-int gsm48_rx_ccch(struct msgb *msg, struct osmocom_ms *ms);
-int gsm48_rx_dcch(struct msgb *msg, struct osmocom_ms *ms);
-int gsm48_rx_bcch(struct msgb *msg, struct osmocom_ms *ms);
-
-/* Initialize layer3 for the MS, hook it to L2 */
-int layer3_init(struct osmocom_ms *ms);
-
-/* Reset the 'aplication' state */
-void layer3_app_reset(void);
-
-#endif
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/misc/rslms.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/misc/rslms.h
deleted file mode 100644
index 94fe99c..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/misc/rslms.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef _OSMOCOM_RSLMS_H
-#define _OSMOCOM_RSLMS_H
-
-#include <osmocom/core/msgb.h>
-#include <osmocom/bb/common/osmocom_data.h>
-
-/* From L3 into RSLMS (direction -> L2) */
-
-/* Send a 'simple' RLL request to L2 */
-int rslms_tx_rll_req(struct osmocom_ms *ms, uint8_t msg_type,
- uint8_t chan_nr, uint8_t link_id);
-
-/* Send a RLL request (including L3 info) to L2 */
-int rslms_tx_rll_req_l3(struct osmocom_ms *ms, uint8_t msg_type,
- uint8_t chan_nr, uint8_t link_id, struct msgb *msg);
-
-
-/* From L2 into RSLMS (direction -> L3) */
-
-/* input function that L2 calls when sending messages up to L3 */
-//int rslms_sendmsg(struct msgb *msg, struct osmocom_ms *ms);
-
-#endif /* _OSMOCOM_RSLMS_H */
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/Makefile.am b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/Makefile.am
deleted file mode 100644
index 951e4d1..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/Makefile.am
+++ /dev/null
@@ -1,2 +0,0 @@
-noinst_HEADERS = gsm322.h gsm48_cc.h gsm48_mm.h gsm48_rr.h mncc.h settings.h \
- subscriber.h support.h transaction.h vty.h
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/app_mobile.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/app_mobile.h
deleted file mode 100644
index 4010a68..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/app_mobile.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef APP_MOBILE_H
-#define APP_MOBILE_H
-
-char *config_dir;
-
-int l23_app_init(int (*mncc_recv)(struct osmocom_ms *ms, int, void *),
- const char *config_file, uint16_t vty_port);
-int l23_app_exit(void);
-int l23_app_work(int *quit);
-int mobile_delete(struct osmocom_ms *ms, int force);
-struct osmocom_ms *mobile_new(char *name);
-int mobile_init(struct osmocom_ms *ms);
-int mobile_exit(struct osmocom_ms *ms, int force);
-int mobile_work(struct osmocom_ms *ms);
-
-#endif
-
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/gsm322.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/gsm322.h
deleted file mode 100644
index f39e566..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/gsm322.h
+++ /dev/null
@@ -1,255 +0,0 @@
-#ifndef _GSM322_H
-#define _GSM322_H
-
-/* 4.3.1.1 List of states for PLMN slection process (automatic mode) */
-#define GSM322_A0_NULL 0
-#define GSM322_A1_TRYING_RPLMN 1
-#define GSM322_A2_ON_PLMN 2
-#define GSM322_A3_TRYING_PLMN 3
-#define GSM322_A4_WAIT_FOR_PLMN 4
-#define GSM322_A5_HPLMN_SEARCH 5
-#define GSM322_A6_NO_SIM 6
-
-/* 4.3.1.2 List of states for PLMN slection process (manual mode) */
-#define GSM322_M0_NULL 0
-#define GSM322_M1_TRYING_RPLMN 1
-#define GSM322_M2_ON_PLMN 2
-#define GSM322_M3_NOT_ON_PLMN 3
-#define GSM322_M4_TRYING_PLMN 4
-#define GSM322_M5_NO_SIM 5
-
-/* 4.3.2 List of states for cell selection process */
-#define GSM322_C0_NULL 0
-#define GSM322_C1_NORMAL_CELL_SEL 1
-#define GSM322_C2_STORED_CELL_SEL 2
-#define GSM322_C3_CAMPED_NORMALLY 3
-#define GSM322_C4_NORMAL_CELL_RESEL 4
-#define GSM322_C5_CHOOSE_CELL 5
-#define GSM322_C6_ANY_CELL_SEL 6
-#define GSM322_C7_CAMPED_ANY_CELL 7
-#define GSM322_C8_ANY_CELL_RESEL 8
-#define GSM322_C9_CHOOSE_ANY_CELL 9
-#define GSM322_CONNECTED_MODE_1 10
-#define GSM322_CONNECTED_MODE_2 11
-#define GSM322_PLMN_SEARCH 12
-#define GSM322_HPLMN_SEARCH 13
-#define GSM322_ANY_SEARCH 14
-
-/* GSM 03.22 events */
-#define GSM322_EVENT_SWITCH_ON 1
-#define GSM322_EVENT_SWITCH_OFF 2
-#define GSM322_EVENT_SIM_INSERT 3
-#define GSM322_EVENT_SIM_REMOVE 4
-#define GSM322_EVENT_REG_SUCCESS 5
-#define GSM322_EVENT_REG_FAILED 6
-#define GSM322_EVENT_ROAMING_NA 7
-#define GSM322_EVENT_INVALID_SIM 8
-#define GSM322_EVENT_NEW_PLMN 9
-#define GSM322_EVENT_ON_PLMN 10
-#define GSM322_EVENT_PLMN_SEARCH_START 11
-#define GSM322_EVENT_PLMN_SEARCH_END 12
-#define GSM322_EVENT_USER_RESEL 13
-#define GSM322_EVENT_PLMN_AVAIL 14
-#define GSM322_EVENT_CHOOSE_PLMN 15
-#define GSM322_EVENT_SEL_MANUAL 16
-#define GSM322_EVENT_SEL_AUTO 17
-#define GSM322_EVENT_CELL_FOUND 18
-#define GSM322_EVENT_NO_CELL_FOUND 19
-#define GSM322_EVENT_LEAVE_IDLE 20
-#define GSM322_EVENT_RET_IDLE 21
-#define GSM322_EVENT_CELL_RESEL 22
-#define GSM322_EVENT_SYSINFO 23
-#define GSM322_EVENT_HPLMN_SEARCH 24
-
-enum {
- PLMN_MODE_MANUAL,
- PLMN_MODE_AUTO
-};
-
-/* node for each PLMN */
-struct gsm322_plmn_list {
- struct llist_head entry;
- uint16_t mcc, mnc;
- int8_t rxlev; /* rx level in range format */
- uint8_t cause; /* cause value, if PLMN is not allowed */
-};
-
-/* node for each forbidden LA */
-struct gsm322_la_list {
- struct llist_head entry;
- uint16_t mcc, mnc, lac;
- uint8_t cause;
-};
-
-/* node for each BA-List */
-struct gsm322_ba_list {
- struct llist_head entry;
- uint16_t mcc, mnc;
- /* Band allocation for 1024+299 frequencies.
- * First bit of first index is frequency 0.
- */
- uint8_t freq[128+38];
-};
-
-#define GSM322_CS_FLAG_SUPPORT 0x01 /* frequency is supported by radio */
-#define GSM322_CS_FLAG_BA 0x02 /* frequency is part of the current ba */
-#define GSM322_CS_FLAG_POWER 0x04 /* frequency was power scanned */
-#define GSM322_CS_FLAG_SIGNAL 0x08 /* valid signal detected */
-#define GSM322_CS_FLAG_SYSINFO 0x10 /* complete sysinfo received */
-#define GSM322_CS_FLAG_BARRED 0x20 /* cell is barred */
-#define GSM322_CS_FLAG_FORBIDD 0x40 /* cell in list of forbidden LAs */
-#define GSM322_CS_FLAG_TEMP_AA 0x80 /* if temporary available and allowable */
-
-/* Cell selection list */
-struct gsm322_cs_list {
- uint8_t flags; /* see GSM322_CS_FLAG_* */
- int8_t rxlev; /* rx level range format */
- struct gsm48_sysinfo *sysinfo;
-};
-
-/* PLMN search process */
-struct gsm322_plmn {
- struct osmocom_ms *ms;
- int state; /* GSM322_Ax_* or GSM322_Mx_* */
-
- struct llist_head event_queue; /* event messages */
- struct llist_head sorted_plmn; /* list of sorted PLMN */
- struct llist_head forbidden_la; /* forbidden LAs */
-
- struct osmo_timer_list timer;
-
- int plmn_curr; /* current index in sorted_plmn */
- uint16_t mcc, mnc; /* current network selected */
-};
-
-/* state of CCCH activation */
-#define GSM322_CCCH_ST_IDLE 0 /* no connection */
-#define GSM322_CCCH_ST_INIT 1 /* initalized */
-#define GSM322_CCCH_ST_SYNC 2 /* got sync */
-#define GSM322_CCCH_ST_DATA 3 /* receiveing data */
-
-/* neighbour cell info list entry */
-struct gsm322_neighbour {
- struct llist_head entry;
- struct gsm322_cellsel *cs;
- uint16_t arfcn; /* ARFCN identity of that neighbour */
-
- uint8_t state; /* GSM322_NB_* */
- time_t created; /* when was this neighbour created */
- time_t when; /* when did we sync / read */
- int16_t rxlev_dbm; /* sum of received levels */
- uint8_t rxlev_count; /* number of received levels */
- int8_t rla_c_dbm; /* average of the reveive level */
- uint8_t c12_valid; /* both C1 and C2 are calculated */
- int16_t c1, c2, crh;
- uint8_t checked_for_resel;
- uint8_t suitable_allowable;
- uint8_t prio_low;
-};
-
-#define GSM322_NB_NEW 0 /* new NB instance */
-#define GSM322_NB_NOT_SUP 1 /* ARFCN not supported */
-#define GSM322_NB_RLA_C 2 /* valid measurement available */
-#define GSM322_NB_NO_SYNC 3 /* cannot sync to neighbour */
-#define GSM322_NB_NO_BCCH 4 /* sync */
-#define GSM322_NB_SYSINFO 5 /* sysinfo */
-
-struct gsm48_sysinfo;
-/* Cell selection process */
-struct gsm322_cellsel {
- struct osmocom_ms *ms;
- int state; /* GSM322_Cx_* */
-
- struct llist_head event_queue; /* event messages */
- struct llist_head ba_list; /* BCCH Allocation per PLMN */
- struct gsm322_cs_list list[1024+299];
- /* cell selection list per frequency. */
- /* scan and tune state */
- struct osmo_timer_list timer; /* cell selection timer */
- uint16_t mcc, mnc; /* current network to search for */
- uint8_t powerscan; /* currently scanning for power */
- uint8_t ccch_state; /* special state of current ccch */
- uint32_t scan_state; /* special state of current scan */
- uint16_t arfcn; /* current tuned idle mode arfcn */
- int arfci; /* list index of frequency above */
- uint8_t ccch_mode; /* curren CCCH_MODE_* */
- uint8_t sync_retries; /* number retries to sync */
- uint8_t sync_pending; /* to prevent double sync req. */
- struct gsm48_sysinfo *si; /* current sysinfo of tuned cell */
- uint8_t tuned; /* if a cell is selected */
- struct osmo_timer_list any_timer; /* restart search 'any cell' */
-
- /* serving cell */
- uint8_t selected; /* if a cell is selected */
- uint16_t sel_arfcn; /* current selected serving cell! */
- struct gsm48_sysinfo sel_si; /* copy of selected cell, will update */
- uint16_t sel_mcc, sel_mnc, sel_lac, sel_id;
-
- /* cell re-selection */
- struct llist_head nb_list; /* list of neighbour cells */
- uint16_t last_serving_arfcn; /* the ARFCN of last cell */
- uint8_t last_serving_valid; /* there is a last cell */
- struct gsm322_neighbour *neighbour; /* when selecting neighbour cell */
- time_t resel_when; /* timestamp of last re-selection */
- int8_t nb_meas_set;
- int16_t rxlev_dbm; /* sum of received levels */
- uint8_t rxlev_count; /* number of received levels */
- int8_t rla_c_dbm; /* average of received level */
- uint8_t c12_valid; /* both C1 and C2 values are
- calculated */
- int16_t c1, c2;
- uint8_t prio_low;
-};
-
-/* GSM 03.22 message */
-struct gsm322_msg {
- int msg_type;
- uint16_t mcc, mnc;
- uint8_t sysinfo; /* system information type */
- uint8_t same_cell; /* select same cell when RET_IDLE */
- uint8_t reject; /* location update reject cause */
- uint8_t limited; /* trigger search for limited serv. */
-};
-
-#define GSM322_ALLOC_SIZE sizeof(struct gsm322_msg)
-#define GSM322_ALLOC_HEADROOM 0
-
-uint16_t index2arfcn(int index);
-int arfcn2index(uint16_t arfcn);
-int gsm322_init(struct osmocom_ms *ms);
-int gsm322_exit(struct osmocom_ms *ms);
-struct msgb *gsm322_msgb_alloc(int msg_type);
-int gsm322_plmn_sendmsg(struct osmocom_ms *ms, struct msgb *msg);
-int gsm322_cs_sendmsg(struct osmocom_ms *ms, struct msgb *msg);
-int gsm322_c_event(struct osmocom_ms *ms, struct msgb *msg);
-int gsm322_plmn_dequeue(struct osmocom_ms *ms);
-int gsm322_cs_dequeue(struct osmocom_ms *ms);
-int gsm322_add_forbidden_la(struct osmocom_ms *ms, uint16_t mcc,
- uint16_t mnc, uint16_t lac, uint8_t cause);
-int gsm322_del_forbidden_la(struct osmocom_ms *ms, uint16_t mcc,
- uint16_t mnc, uint16_t lac);
-int gsm322_is_forbidden_la(struct osmocom_ms *ms, uint16_t mcc, uint16_t mnc,
- uint16_t lac);
-int gsm322_dump_sorted_plmn(struct osmocom_ms *ms);
-int gsm322_dump_cs_list(struct gsm322_cellsel *cs, uint8_t flags,
- void (*print)(void *, const char *, ...), void *priv);
-int gsm322_dump_forbidden_la(struct osmocom_ms *ms,
- void (*print)(void *, const char *, ...), void *priv);
-int gsm322_dump_ba_list(struct gsm322_cellsel *cs, uint16_t mcc, uint16_t mnc,
- void (*print)(void *, const char *, ...), void *priv);
-int gsm322_dump_nb_list(struct gsm322_cellsel *cs,
- void (*print)(void *, const char *, ...), void *priv);
-void start_cs_timer(struct gsm322_cellsel *cs, int sec, int micro);
-void start_loss_timer(struct gsm322_cellsel *cs, int sec, int micro);
-const char *get_a_state_name(int value);
-const char *get_m_state_name(int value);
-const char *get_cs_state_name(int value);
-int gsm322_l1_signal(unsigned int subsys, unsigned int signal,
- void *handler_data, void *signal_data);
-
-int gsm322_meas(struct osmocom_ms *ms, uint8_t rx_lev);
-
-char *gsm_print_rxlev(uint8_t rxlev);
-
-
-#endif /* _GSM322_H */
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/gsm48_cc.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/gsm48_cc.h
deleted file mode 100644
index 8cdd1c4..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/gsm48_cc.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef _GSM48_CC_H
-#define _GSM48_CC_H
-
-struct gsm48_cclayer {
- struct osmocom_ms *ms;
-
- struct llist_head mncc_upqueue;
-};
-
-int gsm48_cc_init(struct osmocom_ms *ms);
-int gsm48_cc_exit(struct osmocom_ms *ms);
-int gsm48_rcv_cc(struct osmocom_ms *ms, struct msgb *msg);
-int mncc_dequeue(struct osmocom_ms *ms);
-int mncc_send(struct osmocom_ms *ms, int msg_type, void *arg);
-
-#endif /* _GSM48_CC_H */
-
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h
deleted file mode 100644
index afdcf02..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/gsm48_mm.h
+++ /dev/null
@@ -1,230 +0,0 @@
-#ifndef _GSM48_MM_H
-#define _GSM48_MM_H
-
-/* GSM 04.07 9.2.2 */
-#define GSM48_MMXX_MASK 0xf00
-#define GSM48_MMCC_CLASS 0x100
-#define GSM48_MMSS_CLASS 0x200
-#define GSM48_MMSMS_CLASS 0x300
-#define GSM48_MMCC_EST_REQ 0x110
-#define GSM48_MMCC_EST_IND 0x112
-#define GSM48_MMCC_EST_CNF 0x111
-#define GSM48_MMCC_REL_REQ 0x120
-#define GSM48_MMCC_REL_IND 0x122
-#define GSM48_MMCC_DATA_REQ 0x130
-#define GSM48_MMCC_DATA_IND 0x132
-#define GSM48_MMCC_UNIT_DATA_REQ 0x140
-#define GSM48_MMCC_UNIT_DATA_IND 0x142
-#define GSM48_MMCC_SYNC_IND 0x152
-#define GSM48_MMCC_REEST_REQ 0x160
-#define GSM48_MMCC_REEST_CNF 0x161
-#define GSM48_MMCC_ERR_IND 0x172
-#define GSM48_MMCC_PROMPT_IND 0x182
-#define GSM48_MMCC_PROMPT_REJ 0x184
-#define GSM48_MMSS_EST_REQ 0x210
-#define GSM48_MMSS_EST_IND 0x212
-#define GSM48_MMSS_EST_CNF 0x211
-#define GSM48_MMSS_REL_REQ 0x220
-#define GSM48_MMSS_REL_IND 0x222
-#define GSM48_MMSS_DATA_REQ 0x230
-#define GSM48_MMSS_DATA_IND 0x232
-#define GSM48_MMSS_UNIT_DATA_REQ 0x240
-#define GSM48_MMSS_UNIT_DATA_IND 0x242
-#define GSM48_MMSS_REEST_REQ 0x260
-#define GSM48_MMSS_REEST_CNF 0x261
-#define GSM48_MMSS_ERR_IND 0x272
-#define GSM48_MMSS_PROMPT_IND 0x282
-#define GSM48_MMSS_PROMPT_REJ 0x284
-#define GSM48_MMSMS_EST_REQ 0x310
-#define GSM48_MMSMS_EST_IND 0x312
-#define GSM48_MMSMS_EST_CNF 0x311
-#define GSM48_MMSMS_REL_REQ 0x320
-#define GSM48_MMSMS_REL_IND 0x322
-#define GSM48_MMSMS_DATA_REQ 0x330
-#define GSM48_MMSMS_DATA_IND 0x332
-#define GSM48_MMSMS_UNIT_DATA_REQ 0x340
-#define GSM48_MMSMS_UNIT_DATA_IND 0x342
-#define GSM48_MMSMS_REEST_REQ 0x360
-#define GSM48_MMSMS_REEST_CNF 0x361
-#define GSM48_MMSMS_ERR_IND 0x372
-#define GSM48_MMSMS_PROMPT_IND 0x382
-#define GSM48_MMSMS_PROMPT_REJ 0x384
-
-#define MMXX_ALLOC_SIZE 256
-#define MMXX_ALLOC_HEADROOM 64
-
-/* MMxx-SAP header */
-struct gsm48_mmxx_hdr {
- int msg_type; /* MMxx_* primitive */
- uint32_t ref; /* reference to transaction */
- uint32_t transaction_id; /* transaction identifier */
- uint8_t emergency; /* emergency type of call */
- uint8_t cause; /* cause used for release */
-};
-
-/* GSM 6.1.2 */
-#define GSM48_MMR_REG_REQ 0x01
-#define GSM48_MMR_REG_CNF 0x02
-#define GSM48_MMR_NREG_REQ 0x03
-#define GSM48_MMR_NREG_IND 0x04
-
-/* MMR-SAP header */
-struct gsm48_mmr {
- int msg_type;
-
- uint8_t cause;
-};
-
-/* GSM 04.07 9.2.1 */
-#define GSM48_MMXX_ST_IDLE 0
-#define GSM48_MMXX_ST_CONN_PEND 1
-#define GSM48_MMXX_ST_DEDICATED 2
-#define GSM48_MMXX_ST_CONN_SUSP 3
-#define GSM48_MMXX_ST_REESTPEND 4
-
-/* GSM 04.08 4.1.2.1 */
-#define GSM48_MM_ST_NULL 0
-#define GSM48_MM_ST_LOC_UPD_INIT 3
-#define GSM48_MM_ST_WAIT_OUT_MM_CONN 5
-#define GSM48_MM_ST_MM_CONN_ACTIVE 6
-#define GSM48_MM_ST_IMSI_DETACH_INIT 7
-#define GSM48_MM_ST_PROCESS_CM_SERV_P 8
-#define GSM48_MM_ST_WAIT_NETWORK_CMD 9
-#define GSM48_MM_ST_LOC_UPD_REJ 10
-#define GSM48_MM_ST_WAIT_RR_CONN_LUPD 13
-#define GSM48_MM_ST_WAIT_RR_CONN_MM_CON 14
-#define GSM48_MM_ST_WAIT_RR_CONN_IMSI_D 15
-#define GSM48_MM_ST_WAIT_REEST 17
-#define GSM48_MM_ST_WAIT_RR_ACTIVE 18
-#define GSM48_MM_ST_MM_IDLE 19
-#define GSM48_MM_ST_WAIT_ADD_OUT_MM_CON 20
-#define GSM48_MM_ST_MM_CONN_ACTIVE_VGCS 21
-#define GSM48_MM_ST_WAIT_RR_CONN_VGCS 22
-#define GSM48_MM_ST_LOC_UPD_PEND 23
-#define GSM48_MM_ST_IMSI_DETACH_PEND 24
-#define GSM48_MM_ST_RR_CONN_RELEASE_NA 25
-
-/* GSM 04.08 4.1.2.1 */
-#define GSM48_MM_SST_NORMAL_SERVICE 1
-#define GSM48_MM_SST_ATTEMPT_UPDATE 2
-#define GSM48_MM_SST_LIMITED_SERVICE 3
-#define GSM48_MM_SST_NO_IMSI 4
-#define GSM48_MM_SST_NO_CELL_AVAIL 5
-#define GSM48_MM_SST_LOC_UPD_NEEDED 6
-#define GSM48_MM_SST_PLMN_SEARCH 7
-#define GSM48_MM_SST_PLMN_SEARCH_NORMAL 8
-#define GSM48_MM_SST_RX_VGCS_NORMAL 9
-#define GSM48_MM_SST_RX_VGCS_LIMITED 10
-
-/* MM events */
-#define GSM48_MM_EVENT_CELL_SELECTED 1
-#define GSM48_MM_EVENT_NO_CELL_FOUND 2
-#define GSM48_MM_EVENT_TIMEOUT_T3210 3
-#define GSM48_MM_EVENT_TIMEOUT_T3211 4
-#define GSM48_MM_EVENT_TIMEOUT_T3212 5
-#define GSM48_MM_EVENT_TIMEOUT_T3213 6
-#define GSM48_MM_EVENT_TIMEOUT_T3220 7
-#define GSM48_MM_EVENT_TIMEOUT_T3230 8
-#define GSM48_MM_EVENT_TIMEOUT_T3240 9
-#define GSM48_MM_EVENT_IMSI_DETACH 10
-#define GSM48_MM_EVENT_POWER_OFF 11
-#define GSM48_MM_EVENT_PAGING 12
-#define GSM48_MM_EVENT_AUTH_RESPONSE 13
-#define GSM48_MM_EVENT_SYSINFO 14
-#define GSM48_MM_EVENT_USER_PLMN_SEL 15
-#define GSM48_MM_EVENT_LOST_COVERAGE 16
-
-/* message for MM events */
-struct gsm48_mm_event {
- uint32_t msg_type;
-
- uint8_t sres[4];
-};
-
-/* GSM 04.08 MM timers */
-#define GSM_T3210_MS 20, 0
-#define GSM_T3211_MS 15, 0
-/* T3212 is given by SYSTEM INFORMATION */
-#define GSM_T3213_MS 4, 0
-#define GSM_T3220_MS 5, 0
-#define GSM_T3230_MS 15, 0
-#define GSM_T3240_MS 10, 0
-#define GSM_T3241_MS 300, 0
-
-/* MM sublayer instance */
-struct gsm48_mmlayer {
- struct osmocom_ms *ms;
- int state;
- int substate;
-
- /* queue for RR-SAP, MMxx-SAP, MMR-SAP, events message upwards */
- struct llist_head rr_upqueue;
- struct llist_head mmxx_upqueue;
- struct llist_head mmr_downqueue;
- struct llist_head event_queue;
-
- /* timers */
- struct osmo_timer_list t3210, t3211, t3212, t3213;
- struct osmo_timer_list t3220, t3230, t3240;
- int t3212_value;
- int start_t3211; /* remember to start timer */
-
- /* list of MM connections */
- struct llist_head mm_conn;
-
- /* network name */
- char name_short[32];
- char name_long[32];
-
- /* location update */
- uint8_t lupd_pending; /* current pending loc. upd. */
- uint8_t lupd_type; /* current coded type */
- uint8_t lupd_attempt; /* attempt counter */
- uint8_t lupd_ra_failure;/* random access failed */
- uint8_t lupd_rej_cause; /* cause of last reject */
- uint8_t lupd_periodic; /* periodic update pending */
- uint8_t lupd_retry; /* pending T3211/T3213 to */
- uint16_t lupd_mcc, lupd_mnc, lupd_lac;
-
- /* imsi detach */
- uint8_t delay_detach; /* do detach when possible */
-
- /* other */
- uint8_t est_cause; /* cause of establishment msg */
- int mr_substate; /* rem most recent substate */
- uint8_t power_off_idle; /* waits for IDLE before po */
-};
-
-/* MM connection entry */
-struct gsm48_mm_conn {
- struct llist_head list;
- struct gsm48_mmlayer *mm;
-
- /* ref and type form a unique tupple */
- uint32_t ref; /* reference to trans */
- uint8_t protocol;
- uint8_t transaction_id;
-
- int state;
-};
-
-uint8_t gsm48_current_pwr_lev(struct gsm_settings *set, uint16_t arfcn);
-int gsm48_mm_init(struct osmocom_ms *ms);
-int gsm48_mm_exit(struct osmocom_ms *ms);
-struct msgb *gsm48_mmr_msgb_alloc(int msg_type);
-struct msgb *gsm48_mmevent_msgb_alloc(int msg_type);
-int gsm48_mmevent_msg(struct osmocom_ms *ms, struct msgb *msg);
-int gsm48_mmr_downmsg(struct osmocom_ms *ms, struct msgb *msg);
-int gsm48_rr_dequeue(struct osmocom_ms *ms);
-int gsm48_mmxx_dequeue(struct osmocom_ms *ms);
-int gsm48_mmr_dequeue(struct osmocom_ms *ms);
-int gsm48_mmevent_dequeue(struct osmocom_ms *ms);
-int gsm48_mmxx_downmsg(struct osmocom_ms *ms, struct msgb *msg);
-struct msgb *gsm48_mmxx_msgb_alloc(int msg_type, uint32_t ref,
- uint8_t transaction_id);
-const char *get_mmr_name(int value);
-const char *get_mmxx_name(int value);
-extern const char *gsm48_mm_state_names[];
-extern const char *gsm48_mm_substate_names[];
-
-#endif /* _GSM48_MM_H */
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h
deleted file mode 100644
index 1af09f4..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/gsm48_rr.h
+++ /dev/null
@@ -1,203 +0,0 @@
-#ifndef _GSM48_RR_H
-#define _GSM48_RR_H
-
-#include <osmocom/gsm/protocol/gsm_04_08.h>
-
-#define GSM_TA_CM 55385
-
-/* GSM 04.07 9.1.2 */
-#define GSM48_RR_EST_REQ 0x10
-#define GSM48_RR_EST_IND 0x12
-#define GSM48_RR_EST_CNF 0x11
-#define GSM48_RR_REL_IND 0x22
-#define GSM48_RR_SYNC_IND 0x32
-#define GSM48_RR_DATA_REQ 0x40
-#define GSM48_RR_DATA_IND 0x42
-#define GSM48_RR_UNIT_DATA_IND 0x52
-#define GSM48_RR_ABORT_REQ 0x60
-#define GSM48_RR_ABORT_IND 0x62
-#define GSM48_RR_ACT_REQ 0x70
-
-#define RR_EST_CAUSE_EMERGENCY 1
-#define RR_EST_CAUSE_REESTAB_TCH_F 2
-#define RR_EST_CAUSE_REESTAB_TCH_H 3
-#define RR_EST_CAUSE_REESTAB_2_TCH_H 4
-#define RR_EST_CAUSE_ANS_PAG_ANY 5
-#define RR_EST_CAUSE_ANS_PAG_SDCCH 6
-#define RR_EST_CAUSE_ANS_PAG_TCH_F 7
-#define RR_EST_CAUSE_ANS_PAG_TCH_ANY 8
-#define RR_EST_CAUSE_ORIG_TCHF 9
-#define RR_EST_CAUSE_LOC_UPD 12
-#define RR_EST_CAUSE_OTHER_SDCCH 13
-
-#define RR_REL_CAUSE_UNDEFINED 0
-#define RR_REL_CAUSE_NORMAL 1
-#define RR_REL_CAUSE_NOT_AUTHORIZED 2
-#define RR_REL_CAUSE_RA_FAILURE 3
-#define RR_REL_CAUSE_T3122 4
-#define RR_REL_CAUSE_TRY_LATER 5
-#define RR_REL_CAUSE_EMERGENCY_ONLY 6
-#define RR_REL_CAUSE_LOST_SIGNAL 7
-#define RR_REL_CAUSE_LINK_FAILURE 8
-
-#define RR_SYNC_CAUSE_CIPHERING 1
-
-#define L3_ALLOC_SIZE 256
-#define L3_ALLOC_HEADROOM 64
-
-#define RSL_ALLOC_SIZE 256
-#define RSL_ALLOC_HEADROOM 64
-
-#define RR_ALLOC_SIZE 256
-#define RR_ALLOC_HEADROOM 64
-
-/* GSM 04.08 RR-SAP header */
-struct gsm48_rr_hdr {
- uint32_t msg_type; /* RR-* primitive */
- uint8_t cause;
-};
-
-/* GSM 04.07 9.1.1 */
-#define GSM48_RR_ST_IDLE 0
-#define GSM48_RR_ST_CONN_PEND 1
-#define GSM48_RR_ST_DEDICATED 2
-#define GSM48_RR_ST_REL_PEND 3
-
-/* modify state */
-#define GSM48_RR_MOD_NONE 0
-#define GSM48_RR_MOD_IMM_ASS 1
-#define GSM48_RR_MOD_ASSIGN 2
-#define GSM48_RR_MOD_HANDO 3
-#define GSM48_RR_MOD_ASSIGN_RESUME 4
-#define GSM48_RR_MOD_HANDO_RESUME 5
-
-/* channel description */
-struct gsm48_rr_cd {
- uint8_t tsc;
- uint8_t h; /* using hopping */
- uint16_t arfcn; /* dedicated mode */
- uint8_t maio;
- uint8_t hsn;
- uint8_t chan_nr; /* type, slot, sub slot */
- uint8_t link_id;
- uint8_t ind_tx_power; /* last indicated power */
- uint8_t ind_ta; /* last indicated ta */
- uint8_t mob_alloc_lv[9]; /* len + up to 64 bits */
- uint8_t freq_list_lv[131]; /* len + 130 octets */
- uint8_t freq_seq_lv[10]; /* len + 9 octets */
- uint8_t cell_desc_lv[17]; /* len + 16 octets */
- uint8_t start; /* start time available */
- struct gsm_time start_tm; /* start time */
- uint8_t mode; /* mode of channel */
- uint8_t cipher; /* ciphering of channel */
-};
-
-struct gsm48_cr_hist {
- uint8_t valid;
- struct gsm48_req_ref ref;
-};
-
-/* neighbor cell measurements */
-struct gsm48_rr_meas {
- /* note: must be sorted by arfcn 1..1023,0 according to SI5* */
- uint8_t nc_num; /* number of measured cells (32 max) */
- int8_t nc_rxlev[32]; /* -128 = no value */
- uint8_t nc_bsic[32];
- uint16_t nc_arfcn[32];
-};
-
-/* RR sublayer instance */
-struct gsm48_rrlayer {
- struct osmocom_ms *ms;
- int state;
-
- /* queue for RSL-SAP message upwards */
- struct llist_head rsl_upqueue;
-
- /* queue for messages while RR connection is built up */
- struct llist_head downqueue;
-
- /* timers */
- struct osmo_timer_list t_starting; /* starting time for chan. access */
- struct osmo_timer_list t_rel_wait; /* wait for L2 to transmit UA */
- struct osmo_timer_list t3110;
- struct osmo_timer_list t3122;
- struct osmo_timer_list t3124;
- struct osmo_timer_list t3126;
- int t3126_value;
-#ifndef TODO
- struct osmo_timer_list temp_rach_ti; /* temporary timer */
-#endif
-
- /* states if RR-EST-REQ was used */
- uint8_t rr_est_req;
- struct msgb *rr_est_msg;
- uint8_t est_cause; /* cause used for establishment */
-
- /* channel request states */
- uint8_t wait_assign; /* waiting for assignment state */
- uint8_t n_chan_req; /* number left, incl. current */
- uint8_t chan_req_val; /* current request value */
- uint8_t chan_req_mask; /* mask of random bits */
-
- /* state of dedicated mdoe */
- uint8_t dm_est;
-
- /* cr_hist */
- uint8_t cr_ra; /* stores requested ra until confirmed */
- struct gsm48_cr_hist cr_hist[3];
-
- /* V(SD) sequence numbers */
- uint16_t v_sd; /* 16 PD 1-bit sequence numbers packed */
-
- /* current channel descriptions */
- struct gsm48_rr_cd cd_now;
-
- /* current cipering */
- uint8_t cipher_on;
- uint8_t cipher_type; /* 10.5.2.9 */
-
- /* special states when assigning channel */
- uint8_t modify_state;
- uint8_t hando_sync_ind, hando_rot, hando_nci, hando_act;
- struct gsm48_rr_cd cd_last; /* store last cd in case of failure */
- struct gsm48_rr_cd cd_before; /* before start time */
- struct gsm48_rr_cd cd_after; /* after start time */
-
- /* BA range */
- uint8_t ba_ranges;
- uint32_t ba_range[16];
-
- /* measurements */
- struct osmo_timer_list t_meas;
- struct gsm48_rr_meas meas;
- uint8_t monitor;
-
- /* audio flow */
- uint8_t audio_mode;
-};
-
-const char *get_rr_name(int value);
-extern int gsm48_rr_init(struct osmocom_ms *ms);
-extern int gsm48_rr_exit(struct osmocom_ms *ms);
-int gsm48_rsl_dequeue(struct osmocom_ms *ms);
-int gsm48_rr_downmsg(struct osmocom_ms *ms, struct msgb *msg);
-struct msgb *gsm48_l3_msgb_alloc(void);
-struct msgb *gsm48_rr_msgb_alloc(int msg_type);
-int gsm48_decode_lai(struct gsm48_loc_area_id *lai, uint16_t *mcc,
- uint16_t *mnc, uint16_t *lac);
-int gsm48_encode_lai(struct gsm48_loc_area_id *lai, uint16_t mcc,
- uint16_t mnc, uint16_t lac);
-int gsm48_rr_enc_cm2(struct osmocom_ms *ms, struct gsm48_classmark2 *cm,
- uint16_t arfcn);
-int gsm48_rr_tx_rand_acc(struct osmocom_ms *ms, struct msgb *msg);
-int gsm48_rr_los(struct osmocom_ms *ms);
-int gsm48_rr_rach_conf(struct osmocom_ms *ms, uint32_t fn);
-extern const char *gsm48_rr_state_names[];
-int gsm48_rr_start_monitor(struct osmocom_ms *ms);
-int gsm48_rr_stop_monitor(struct osmocom_ms *ms);
-int gsm48_rr_alter_delay(struct osmocom_ms *ms);
-int gsm48_rr_tx_voice(struct osmocom_ms *ms, struct msgb *msg);
-int gsm48_rr_audio_mode(struct osmocom_ms *ms, uint8_t mode);
-
-#endif /* _GSM48_RR_H */
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/mncc.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/mncc.h
deleted file mode 100644
index a2b48cf..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/mncc.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/* GSM Mobile Radio Interface Layer 3 messages on the A-bis interface
- * 3GPP TS 04.08 version 7.21.0 Release 1998 / ETSI TS 100 940 V7.21.0 */
-
-/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
- * (C) 2008, 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef _MNCC_H
-#define _MNCC_H
-
-#include <osmocom/core/linuxlist.h>
-#include <osmocom/gsm/mncc.h>
-
-struct gsm_call {
- struct llist_head entry;
-
- struct osmocom_ms *ms;
-
- uint32_t callref;
-
- uint8_t init; /* call initiated, no response yet */
- uint8_t hold; /* call on hold */
- uint8_t ring; /* call ringing/knocking */
-
- struct osmo_timer_list dtmf_timer;
- uint8_t dtmf_state;
- uint8_t dtmf_index;
- char dtmf[32]; /* dtmf sequence */
-};
-
-#define DTMF_ST_IDLE 0 /* no DTMF active */
-#define DTMF_ST_START 1 /* DTMF started, waiting for resp. */
-#define DTMF_ST_MARK 2 /* wait tone duration */
-#define DTMF_ST_STOP 3 /* DTMF stopped, waiting for resp. */
-#define DTMF_ST_SPACE 4 /* wait space between tones */
-
-#define MNCC_SETUP_REQ 0x0101
-#define MNCC_SETUP_IND 0x0102
-#define MNCC_SETUP_RSP 0x0103
-#define MNCC_SETUP_CNF 0x0104
-#define MNCC_SETUP_COMPL_REQ 0x0105
-#define MNCC_SETUP_COMPL_IND 0x0106
-/* MNCC_REJ_* is perfomed via MNCC_REL_* */
-#define MNCC_CALL_CONF_IND 0x0107
-#define MNCC_CALL_PROC_REQ 0x0108
-#define MNCC_PROGRESS_REQ 0x0109
-#define MNCC_ALERT_REQ 0x010a
-#define MNCC_ALERT_IND 0x010b
-#define MNCC_NOTIFY_REQ 0x010c
-#define MNCC_NOTIFY_IND 0x010d
-#define MNCC_DISC_REQ 0x010e
-#define MNCC_DISC_IND 0x010f
-#define MNCC_REL_REQ 0x0110
-#define MNCC_REL_IND 0x0111
-#define MNCC_REL_CNF 0x0112
-#define MNCC_FACILITY_REQ 0x0113
-#define MNCC_FACILITY_IND 0x0114
-#define MNCC_START_DTMF_IND 0x0115
-#define MNCC_START_DTMF_RSP 0x0116
-#define MNCC_START_DTMF_REJ 0x0117
-#define MNCC_STOP_DTMF_IND 0x0118
-#define MNCC_STOP_DTMF_RSP 0x0119
-#define MNCC_MODIFY_REQ 0x011a
-#define MNCC_MODIFY_IND 0x011b
-#define MNCC_MODIFY_RSP 0x011c
-#define MNCC_MODIFY_CNF 0x011d
-#define MNCC_MODIFY_REJ 0x011e
-#define MNCC_HOLD_IND 0x011f
-#define MNCC_HOLD_CNF 0x0120
-#define MNCC_HOLD_REJ 0x0121
-#define MNCC_RETRIEVE_IND 0x0122
-#define MNCC_RETRIEVE_CNF 0x0123
-#define MNCC_RETRIEVE_REJ 0x0124
-#define MNCC_USERINFO_REQ 0x0125
-#define MNCC_USERINFO_IND 0x0126
-#define MNCC_REJ_REQ 0x0127
-#define MNCC_REJ_IND 0x0128
-#define MNCC_PROGRESS_IND 0x0129
-#define MNCC_CALL_PROC_IND 0x012a
-#define MNCC_CALL_CONF_REQ 0x012b
-#define MNCC_START_DTMF_REQ 0x012c
-#define MNCC_STOP_DTMF_REQ 0x012d
-#define MNCC_HOLD_REQ 0x012e
-#define MNCC_RETRIEVE_REQ 0x012f
-
-#define MNCC_BRIDGE 0x0200
-#define MNCC_FRAME_RECV 0x0201
-#define MNCC_FRAME_DROP 0x0202
-#define MNCC_LCHAN_MODIFY 0x0203
-
-#define GSM_TCHF_FRAME 0x0300
-#define GSM_TCHF_FRAME_EFR 0x0301
-
-#define MS_NEW 0x0400
-#define MS_DELETE 0x0401
-
-#define GSM_MAX_FACILITY 128
-#define GSM_MAX_SSVERSION 128
-#define GSM_MAX_USERUSER 128
-
-#define MNCC_F_BEARER_CAP 0x0001
-#define MNCC_F_CALLED 0x0002
-#define MNCC_F_CALLING 0x0004
-#define MNCC_F_REDIRECTING 0x0008
-#define MNCC_F_CONNECTED 0x0010
-#define MNCC_F_CAUSE 0x0020
-#define MNCC_F_USERUSER 0x0040
-#define MNCC_F_PROGRESS 0x0080
-#define MNCC_F_EMERGENCY 0x0100
-#define MNCC_F_FACILITY 0x0200
-#define MNCC_F_SSVERSION 0x0400
-#define MNCC_F_CCCAP 0x0800
-#define MNCC_F_KEYPAD 0x1000
-#define MNCC_F_SIGNAL 0x2000
-
-struct gsm_mncc {
- /* context based information */
- u_int32_t msg_type;
- u_int32_t callref;
-
- /* which fields are present */
- u_int32_t fields;
-
- /* data derived informations (MNCC_F_ based) */
- struct gsm_mncc_bearer_cap bearer_cap;
- struct gsm_mncc_number called;
- struct gsm_mncc_number calling;
- struct gsm_mncc_number redirecting;
- struct gsm_mncc_number connected;
- struct gsm_mncc_cause cause;
- struct gsm_mncc_progress progress;
- struct gsm_mncc_useruser useruser;
- struct gsm_mncc_facility facility;
- struct gsm_mncc_cccap cccap;
- struct gsm_mncc_ssversion ssversion;
- struct {
- int sup;
- int inv;
- } clir;
- int signal;
-
- /* data derived information, not MNCC_F based */
- int keypad;
- int more;
- int notify; /* 0..127 */
- int emergency;
- char imsi[16];
-
- unsigned char lchan_mode;
-};
-
-struct gsm_data_frame {
- u_int32_t msg_type;
- u_int32_t callref;
- unsigned char data[0];
-};
-
-const char *get_mncc_name(int value);
-int mncc_recv(struct osmocom_ms *ms, int msg_type, void *arg);
-void mncc_set_cause(struct gsm_mncc *data, int loc, int val);
-
-#endif
-
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/settings.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/settings.h
deleted file mode 100644
index cd1b800..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/settings.h
+++ /dev/null
@@ -1,120 +0,0 @@
-#ifndef _settings_h
-#define _settings_h
-
-/* type of test SIM key */
-enum {
- GSM_SIM_KEY_XOR = 0,
- GSM_SIM_KEY_COMP128
-};
-
-struct gsm_settings {
- char layer2_socket_path[128];
- char sap_socket_path[128];
-
- /* IMEI */
- char imei[16];
- char imeisv[17];
- char imei_random;
-
- /* network search */
- int plmn_mode; /* PLMN_MODE_* */
-
- /* SIM */
- int sim_type; /* selects card on power on */
- char emergency_imsi[16];
-
- /* test card simulator settings */
- char test_imsi[16];
- uint32_t test_tmsi;
- uint8_t test_ki_type;
- uint8_t test_ki[16]; /* 128 bit max */
- uint8_t test_barr;
- uint8_t test_rplmn_valid;
- uint16_t test_rplmn_mcc, test_rplmn_mnc;
- uint16_t test_lac;
- uint8_t test_always; /* ...search hplmn... */
-
- /* call related settings */
- uint8_t cw; /* set if call-waiting is allowed */
- uint8_t auto_answer;
- uint8_t clip, clir;
- uint8_t half, half_prefer;
-
- /* changing default behavior */
- uint8_t alter_tx_power;
- uint8_t alter_tx_power_value;
- int8_t alter_delay;
- uint8_t stick;
- uint16_t stick_arfcn;
- uint8_t skip_max_per_band;
- uint8_t no_lupd;
- uint8_t no_neighbour;
-
- /* supported by configuration */
- uint8_t cc_dtmf;
- uint8_t sms_ptp;
- uint8_t a5_1;
- uint8_t a5_2;
- uint8_t a5_3;
- uint8_t a5_4;
- uint8_t a5_5;
- uint8_t a5_6;
- uint8_t a5_7;
- uint8_t p_gsm;
- uint8_t e_gsm;
- uint8_t r_gsm;
- uint8_t dcs;
- uint8_t gsm_850;
- uint8_t pcs;
- uint8_t gsm_480;
- uint8_t gsm_450;
- uint8_t class_900;
- uint8_t class_dcs;
- uint8_t class_850;
- uint8_t class_pcs;
- uint8_t class_400;
- uint8_t freq_map[128+38];
- uint8_t full_v1;
- uint8_t full_v2;
- uint8_t full_v3;
- uint8_t half_v1;
- uint8_t half_v3;
- uint8_t ch_cap; /* channel capability */
- int8_t min_rxlev_db; /* min DB to access */
-
- /* radio */
- uint16_t dsc_max;
-
- /* dialing */
- struct llist_head abbrev;
-
- /* EDGE / UMTS / CDMA */
- uint8_t edge_ms_sup;
- uint8_t edge_psk_sup;
- uint8_t edge_psk_uplink;
- uint8_t class_900_edge;
- uint8_t class_dcs_pcs_edge;
- uint8_t umts_fdd;
- uint8_t umts_tdd;
- uint8_t cdma_2000;
- uint8_t dtm;
- uint8_t class_dtm;
- uint8_t dtm_mac;
- uint8_t dtm_egprs;
-};
-
-struct gsm_settings_abbrev {
- struct llist_head list;
- char abbrev[4];
- char number[32];
- char name[32];
-};
-
-int gsm_settings_arfcn(struct osmocom_ms *ms);
-int gsm_settings_init(struct osmocom_ms *ms);
-int gsm_settings_exit(struct osmocom_ms *ms);
-char *gsm_check_imei(const char *imei, const char *sv);
-int gsm_random_imei(struct gsm_settings *set);
-
-#endif /* _settings_h */
-
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/subscriber.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/subscriber.h
deleted file mode 100644
index cc0cfac..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/subscriber.h
+++ /dev/null
@@ -1,107 +0,0 @@
-#ifndef _SUBSCRIBER_H
-#define _SUBSCRIBER_H
-
-/* GSM 04.08 4.1.2.2 SIM update status */
-#define GSM_SIM_U0_NULL 0
-#define GSM_SIM_U1_UPDATED 1
-#define GSM_SIM_U2_NOT_UPDATED 2
-#define GSM_SIM_U3_ROAMING_NA 3
-
-struct gsm_sub_plmn_list {
- struct llist_head entry;
- uint16_t mcc, mnc;
-};
-
-struct gsm_sub_plmn_na {
- struct llist_head entry;
- uint16_t mcc, mnc;
- uint8_t cause;
-};
-
-#define GSM_IMSI_LENGTH 16
-
-enum {
- GSM_SIM_TYPE_NONE = 0,
- GSM_SIM_TYPE_READER,
- GSM_SIM_TYPE_TEST
-};
-
-struct gsm_subscriber {
- struct osmocom_ms *ms;
-
- /* status */
- uint8_t sim_type; /* type of sim */
- uint8_t sim_valid; /* sim inserted and valid */
- uint8_t ustate; /* update status */
- uint8_t imsi_attached; /* attached state */
-
- /* IMSI & co */
- char imsi[GSM_IMSI_LENGTH];
- char msisdn[31]; /* may include access codes */
- char iccid[21]; /* 20 + termination */
-
- /* TMSI / LAI */
- uint32_t tmsi; /* invalid tmsi: 0xffffffff */
- uint16_t mcc, mnc, lac; /* invalid lac: 0x0000 */
-
-
- /* key */
- uint8_t key_seq; /* ciphering key sequence number */
- uint8_t key[8]; /* 64 bit */
-
- /* other */
- struct llist_head plmn_list; /* PLMN Selector field */
- struct llist_head plmn_na; /* not allowed PLMNs */
- uint8_t t6m_hplmn; /* timer for hplmn search */
-
- /* special things */
- uint8_t always_search_hplmn;
- /* search hplmn in other countries also (for test cards) */
- uint8_t any_timeout;
- /* timer to restart 'any cell selection' */
- char sim_name[31]; /* name to load/save sim */
- char sim_spn[17]; /* name of service privider */
-
- /* PLMN last registered */
- uint8_t plmn_valid;
- uint16_t plmn_mcc, plmn_mnc;
-
- /* our access */
- uint8_t acc_barr; /* if we may access, if cell barred */
- uint16_t acc_class; /* bitmask of what we may access */
-
- /* talk to SIM */
- uint8_t sim_state;
- uint8_t sim_pin_required; /* state: wait for PIN */
- uint8_t sim_file_index;
- uint32_t sim_handle_query;
- uint32_t sim_handle_update;
- uint32_t sim_handle_key;
-};
-
-int gsm_subscr_init(struct osmocom_ms *ms);
-int gsm_subscr_exit(struct osmocom_ms *ms);
-int gsm_subscr_testcard(struct osmocom_ms *ms, uint16_t mcc, uint16_t mnc,
- uint16_t lac, uint32_t tmsi);
-int gsm_subscr_simcard(struct osmocom_ms *ms);
-void gsm_subscr_sim_pin(struct osmocom_ms *ms, char *pin1, char *pin2,
- int8_t mode);
-int gsm_subscr_write_loci(struct osmocom_ms *ms);
-int gsm_subscr_generate_kc(struct osmocom_ms *ms, uint8_t key_seq,
- uint8_t *rand, uint8_t no_sim);
-int gsm_subscr_remove(struct osmocom_ms *ms);
-void new_sim_ustate(struct gsm_subscriber *subscr, int state);
-int gsm_subscr_del_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc,
- uint16_t mnc);
-int gsm_subscr_add_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc,
- uint16_t mnc, uint8_t cause);
-int gsm_subscr_is_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc,
- uint16_t mnc);
-int gsm_subscr_dump_forbidden_plmn(struct osmocom_ms *ms,
- void (*print)(void *, const char *, ...), void *priv);
-void gsm_subscr_dump(struct gsm_subscriber *subscr,
- void (*print)(void *, const char *, ...), void *priv);
-char *gsm_check_imsi(const char *imsi);
-
-#endif /* _SUBSCRIBER_H */
-
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/support.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/support.h
deleted file mode 100644
index 035e10a..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/support.h
+++ /dev/null
@@ -1,122 +0,0 @@
-#ifndef _SUPPORT_H
-#define _SUPPORT_H
-
-#define GSM_CIPHER_A5_1 0
-#define GSM_CIPHER_A5_2 1
-#define GSM_CIPHER_A5_3 2
-#define GSM_CIPHER_A5_4 3
-#define GSM_CIPHER_A5_5 4
-#define GSM_CIPHER_A5_6 5
-#define GSM_CIPHER_A5_7 6
-#define GSM_CIPHER_RESERVED 7
-
-#define GSM_CAP_SDCCH 0
-#define GSM_CAP_SDCCH_TCHF 1
-#define GSM_CAP_SDCCH_TCHF_TCHH 2
-
-struct gsm_support {
- struct osmocom_ms *ms;
-
- /* controlled early classmark sending */
- uint8_t es_ind;
- /* revision level */
- uint8_t rev_lev;
- /* support of VGCS */
- uint8_t vgcs;
- /* support of VBS */
- uint8_t vbs;
- /* support of SMS */
- uint8_t sms_ptp;
- /* screening indicator */
- uint8_t ss_ind;
- /* pseudo synchronised capability */
- uint8_t ps_cap;
- /* CM service prompt */
- uint8_t cmsp;
- /* solsa support */
- uint8_t solsa;
- /* location service support */
- uint8_t lcsva;
- /* codec supprot */
- uint8_t a5_1;
- uint8_t a5_2;
- uint8_t a5_3;
- uint8_t a5_4;
- uint8_t a5_5;
- uint8_t a5_6;
- uint8_t a5_7;
- /* radio support */
- uint8_t p_gsm;
- uint8_t e_gsm;
- uint8_t r_gsm;
- uint8_t dcs;
- uint8_t gsm_850;
- uint8_t pcs;
- uint8_t gsm_480;
- uint8_t gsm_450;
- uint8_t class_900;
- uint8_t class_dcs;
- uint8_t class_850;
- uint8_t class_pcs;
- uint8_t class_400;
- /* multi slot support */
- uint8_t ms_sup;
- /* ucs2 treatment */
- uint8_t ucs2_treat;
- /* support extended measurements */
- uint8_t ext_meas;
- /* support switched measurement capability */
- uint8_t meas_cap;
- uint8_t sms_val;
- uint8_t sm_val;
- /* positioning method capability */
- uint8_t loc_serv;
- uint8_t e_otd_ass;
- uint8_t e_otd_based;
- uint8_t gps_ass;
- uint8_t gps_based;
- uint8_t gps_conv;
-
- /* radio */
- uint8_t ch_cap; /* channel capability */
- int8_t min_rxlev_db;
- uint8_t scan_to;
- uint8_t sync_to;
- uint16_t dsc_max; /* maximum dl signal failure counter */
-
- /* codecs */
- uint8_t full_v1;
- uint8_t full_v2;
- uint8_t full_v3;
- uint8_t half_v1;
- uint8_t half_v3;
-
- /* EDGE / UMTS / CDMA */
- uint8_t edge_ms_sup;
- uint8_t edge_psk_sup;
- uint8_t edge_psk_uplink;
- uint8_t class_900_edge;
- uint8_t class_dcs_pcs_edge;
- uint8_t umts_fdd;
- uint8_t umts_tdd;
- uint8_t cdma_2000;
- uint8_t dtm;
- uint8_t class_dtm;
- uint8_t dtm_mac;
- uint8_t dtm_egprs;
-};
-
-struct gsm_support_scan_max {
- uint16_t start;
- uint16_t end;
- uint16_t max;
- uint16_t temp;
-};
-extern struct gsm_support_scan_max gsm_sup_smax[];
-
-void gsm_support_init(struct osmocom_ms *ms);
-void gsm_support_dump(struct osmocom_ms *ms,
- void (*print)(void *, const char *, ...), void *priv);
-
-#endif /* _SUPPORT_H */
-
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/transaction.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/transaction.h
deleted file mode 100644
index aa62f46..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/transaction.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef _TRANSACT_H
-#define _TRANSACT_H
-
-#include <osmocom/core/linuxlist.h>
-
-/* One transaction */
-struct gsm_trans {
- /* Entry in list of all transactions */
- struct llist_head entry;
-
- /* The protocol within which we live */
- uint8_t protocol;
-
- /* The current transaction ID */
- uint8_t transaction_id;
-
- /* To whom we belong */
- struct osmocom_ms *ms;
-
- /* reference from MNCC or other application */
- uint32_t callref;
-
- /* if traffic channel receive was requested */
- int tch_recv;
-
- union {
- struct {
-
- /* current call state */
- int state;
-
- /* most recent progress indicator */
- uint8_t prog_ind;
-
- /* current timer and message queue */
- int Tcurrent; /* current CC timer */
- int T308_second; /* used to send release again */
- struct osmo_timer_list timer;
- struct gsm_mncc msg; /* stores setup/disconnect/release message */
- } cc;
-#if 0
- struct {
- uint8_t link_id; /* RSL Link ID to be used for this trans */
- int is_mt; /* is this a MO (0) or MT (1) transfer */
- enum gsm411_cp_state cp_state;
- struct osmo_timer_list cp_timer;
-
- enum gsm411_rp_state rp_state;
-
- struct gsm_sms *sms;
- } sms;
-#endif
- };
-};
-
-
-
-struct gsm_trans *trans_find_by_id(struct osmocom_ms *ms,
- uint8_t proto, uint8_t trans_id);
-struct gsm_trans *trans_find_by_callref(struct osmocom_ms *ms,
- uint32_t callref);
-
-struct gsm_trans *trans_alloc(struct osmocom_ms *ms,
- uint8_t protocol, uint8_t trans_id,
- uint32_t callref);
-void trans_free(struct gsm_trans *trans);
-
-int trans_assign_trans_id(struct osmocom_ms *ms,
- uint8_t protocol, uint8_t ti_flag);
-
-#endif
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/voice.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/voice.h
deleted file mode 100644
index a052418..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/voice.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef _voice_h
-#define _voice_h
-
-int gsm_voice_init(struct osmocom_ms *ms);
-int gsm_send_voice(struct osmocom_ms *ms, struct gsm_data_frame *data);
-
-#endif /* _voice_h */
diff --git a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/vty.h b/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/vty.h
deleted file mode 100644
index 1f1341b..0000000
--- a/Src/osmoconbb/src/host/layer23/include/osmocom/bb/mobile/vty.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef OSMOCOM_VTY_H
-#define OSMOCOM_VTY_H
-
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/vty/vty.h>
-#include <osmocom/vty/buffer.h>
-#include <osmocom/vty/command.h>
-
-enum ms_vty_node {
- MS_NODE = _LAST_OSMOVTY_NODE + 1,
- TESTSIM_NODE,
- SUPPORT_NODE,
-};
-
-enum node_type ms_vty_go_parent(struct vty *vty);
-int ms_vty_init(void);
-extern void vty_notify(struct osmocom_ms *ms, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
-
-#endif
-
diff --git a/Src/osmoconbb/src/host/layer23/src/Makefile.am b/Src/osmoconbb/src/host/layer23/src/Makefile.am
deleted file mode 100644
index 58a5f7f..0000000
--- a/Src/osmoconbb/src/host/layer23/src/Makefile.am
+++ /dev/null
@@ -1 +0,0 @@
-SUBDIRS = common misc mobile
diff --git a/Src/osmoconbb/src/host/layer23/src/common/Makefile.am b/Src/osmoconbb/src/host/layer23/src/common/Makefile.am
deleted file mode 100644
index aca2eb4..0000000
--- a/Src/osmoconbb/src/host/layer23/src/common/Makefile.am
+++ /dev/null
@@ -1,6 +0,0 @@
-INCLUDES = $(all_includes) -I$(top_srcdir)/include
-AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS)
-
-noinst_LIBRARIES = liblayer23.a
-liblayer23_a_SOURCES = l1ctl.c l1l2_interface.c sap_interface.c lapdm.c \
- logging.c networks.c sim.c sysinfo.c gps.c l1ctl_lapdm_glue.c
diff --git a/Src/osmoconbb/src/host/layer23/src/common/gps.c b/Src/osmoconbb/src/host/layer23/src/common/gps.c
deleted file mode 100644
index 38aae2c..0000000
--- a/Src/osmoconbb/src/host/layer23/src/common/gps.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdio.h>
-#include <sys/file.h>
-#include <termios.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <time.h>
-#include <stdbool.h>
-
-#ifdef _HAVE_GPSD
-#include <gps.h>
-#endif
-
-#include <osmocom/core/utils.h>
-
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/gps.h>
-
-struct osmo_gps g = {
- 0,
- GPS_TYPE_UNDEF,
-#ifdef _HAVE_GPSD
- "localhost",
- "2947",
-#endif
- "/dev/ttyACM0",
- 0,
- 0,
- 0,
- 0,0
-};
-
-static struct osmo_fd gps_bfd;
-
-#ifdef _HAVE_GPSD
-
-static struct gps_data_t* gdata;
-
-int osmo_gpsd_cb(struct osmo_fd *bfd, unsigned int what)
-{
- struct tm *tm;
- unsigned diff = 0;
-
- g.valid = 0;
-
- /* gps is offline */
- if (gdata->online)
- goto gps_not_ready;
-
- /* gps has no data */
- if (gps_waiting(gdata))
- goto gps_not_ready;
-
- /* polling returned an error */
- if (gps_poll(gdata))
- goto gps_not_ready;
-
- /* data are valid */
- if (gdata->set & LATLON_SET) {
- g.valid = 1;
- g.gmt = gdata->fix.time;
- tm = localtime(&g.gmt);
- diff = time(NULL) - g.gmt;
- g.latitude = gdata->fix.latitude;
- g.longitude = gdata->fix.longitude;
-
- LOGP(DGPS, LOGL_INFO, " time=%02d:%02d:%02d %04d-%02d-%02d, "
- "diff-to-host=%d, latitude=%do%.4f, longitude=%do%.4f\n",
- tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_year + 1900,
- tm->tm_mday, tm->tm_mon + 1, diff,
- (int)g.latitude,
- (g.latitude - ((int)g.latitude)) * 60.0,
- (int)g.longitude,
- (g.longitude - ((int)g.longitude)) * 60.0);
- }
-
- return 0;
-
-gps_not_ready:
- LOGP(DGPS, LOGL_DEBUG, "gps is offline");
- return -1;
-}
-
-int osmo_gpsd_open(void)
-{
- LOGP(DGPS, LOGL_INFO, "Connecting to gpsd at '%s:%s'\n", g.gpsd_host, g.gpsd_port);
-
- gps_bfd.data = NULL;
- gps_bfd.when = BSC_FD_READ;
- gps_bfd.cb = osmo_gpsd_cb;
-
- gdata = gps_open(g.gpsd_host, g.gpsd_port);
- if (gdata == NULL) {
- LOGP(DGPS, LOGL_ERROR, "Can't connect to gpsd\n");
- return -1;
- }
- gps_bfd.fd = gdata->gps_fd;
- if (gps_bfd.fd < 0)
- return gps_bfd.fd;
-
- if (gps_stream(gdata, WATCH_ENABLE, NULL) == -1) {
- LOGP(DGPS, LOGL_ERROR, "Error in gps_stream()\n");
- return -1;
- }
-
- osmo_fd_register(&gps_bfd);
-
- return 0;
-}
-
-void osmo_gpsd_close(void)
-{
- if (gps_bfd.fd <= 0)
- return;
-
- LOGP(DGPS, LOGL_INFO, "Disconnecting from gpsd\n");
-
- osmo_fd_unregister(&gps_bfd);
-
- gps_close(gdata);
- gps_bfd.fd = -1; /* -1 or 0 indicates: 'close' */
-}
-
-#endif
-
-static struct termios gps_termios, gps_old_termios;
-
-static int osmo_serialgps_line(char *line)
-{
- time_t gps_now, host_now;
- struct tm *tm;
- int32_t diff;
- double latitude, longitude;
-
- if (!!strncmp(line, "$GPGLL", 6))
- return 0;
- line += 7;
- if (strlen(line) < 37)
- return 0;
- line[37] = '\0';
- /* ddmm.mmmm,N,dddmm.mmmm,E,hhmmss.mmm,A */
-
- /* valid position */
- if (line[36] != 'A') {
- LOGP(DGPS, LOGL_INFO, "%s (invalid)\n", line);
- g.valid = 0;
- return 0;
- }
- g.valid = 1;
-
- /* time stamp */
- gps_now = line[30] - '0';
- gps_now += (line[29] - '0') * 10;
- gps_now += (line[28] - '0') * 60;
- gps_now += (line[27] - '0') * 600;
- gps_now += (line[26] - '0') * 3600;
- gps_now += (line[25] - '0') * 36000;
- time(&host_now);
- /* calculate the number of seconds the host differs from GPS */
- diff = host_now % 86400 - gps_now;
- if (diff < 0)
- diff += 86400;
- if (diff >= 43200)
- diff -= 86400;
- /* apply the "date" part to the GPS time */
- gps_now = host_now - diff;
- g.gmt = gps_now;
- tm = localtime(&gps_now);
-
- /* position */
- latitude = (double)(line[0] - '0') * 10.0;
- latitude += (double)(line[1] - '0');
- latitude += (double)(line[2] - '0') / 6.0;
- latitude += (double)(line[3] - '0') / 60.0;
- latitude += (double)(line[5] - '0') / 600.0;
- latitude += (double)(line[6] - '0') / 6000.0;
- latitude += (double)(line[7] - '0') / 60000.0;
- latitude += (double)(line[8] - '0') / 600000.0;
- if (line[10] == 'S')
- latitude = 0.0 - latitude;
- g.latitude = latitude;
- longitude = (double)(line[12] - '0') * 100.0;
- longitude += (double)(line[13] - '0') * 10.0;
- longitude += (double)(line[14] - '0');
- longitude += (double)(line[15] - '0') / 6.0;
- longitude += (double)(line[16] - '0') / 60.0;
- longitude += (double)(line[18] - '0') / 600.0;
- longitude += (double)(line[19] - '0') / 6000.0;
- longitude += (double)(line[20] - '0') / 60000.0;
- longitude += (double)(line[21] - '0') / 600000.0;
- if (line[23] == 'W')
- longitude = 360.0 - longitude;
- g.longitude = longitude;
-
- LOGP(DGPS, LOGL_DEBUG, "%s\n", line);
- LOGP(DGPS, LOGL_INFO, " time=%02d:%02d:%02d %04d-%02d-%02d, "
- "diff-to-host=%d, latitude=%do%.4f, longitude=%do%.4f\n",
- tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_year + 1900,
- tm->tm_mday, tm->tm_mon + 1, diff,
- (int)g.latitude,
- (g.latitude - ((int)g.latitude)) * 60.0,
- (int)g.longitude,
- (g.longitude - ((int)g.longitude)) * 60.0);
- return 0;
-}
-
-static int nmea_checksum(char *line)
-{
- uint8_t checksum = 0;
-
- while (*line) {
- if (*line == '$') {
- line++;
- continue;
- }
- if (*line == '*')
- break;
- checksum ^= *line++;
- }
- return (strtoul(line+1, NULL, 16) == checksum);
-}
-
-int osmo_serialgps_cb(struct osmo_fd *bfd, unsigned int what)
-{
- char buff[128];
- static char line[128];
- static int lpos = 0;
- int i = 0, len;
-
- len = read(bfd->fd, buff, sizeof(buff));
- if (len <= 0) {
- fprintf(stderr, "error reading GPS device (errno=%d)\n", errno);
- return len;
- }
- while(i < len) {
- if (buff[i] == 13) {
- i++;
- continue;
- }
- if (buff[i] == 10) {
- line[lpos] = '\0';
- lpos = 0;
- i++;
- if (!nmea_checksum(line))
- fprintf(stderr, "NMEA checksum error\n");
- else
- osmo_serialgps_line(line);
- continue;
- }
- line[lpos++] = buff[i++];
- if (lpos == sizeof(line))
- lpos--;
- }
-
- return 0;
-}
-
-int osmo_serialgps_open(void)
-{
- int baud = 0;
-
- if (gps_bfd.fd > 0)
- return 0;
-
- LOGP(DGPS, LOGL_INFO, "Open GPS device '%s'\n", g.device);
-
- gps_bfd.data = NULL;
- gps_bfd.when = BSC_FD_READ;
- gps_bfd.cb = osmo_serialgps_cb;
- gps_bfd.fd = open(g.device, O_RDONLY);
- if (gps_bfd.fd < 0)
- return gps_bfd.fd;
-
- switch (g.baud) {
- case 4800:
- baud = B4800; break;
- case 9600:
- baud = B9600; break;
- case 19200:
- baud = B19200; break;
- case 38400:
- baud = B38400; break;
- case 57600:
- baud = B57600; break;
- case 115200:
- baud = B115200; break;
- }
-
- if (isatty(gps_bfd.fd))
- {
- /* get termios */
- tcgetattr(gps_bfd.fd, &gps_old_termios);
- tcgetattr(gps_bfd.fd, &gps_termios);
- /* set baud */
- if (baud) {
- gps_termios.c_cflag |= baud;
- cfsetispeed(&gps_termios, baud);
- cfsetospeed(&gps_termios, baud);
- }
- if (tcsetattr(gps_bfd.fd, TCSANOW, &gps_termios))
- printf("Failed to set termios for GPS\n");
- }
-
- osmo_fd_register(&gps_bfd);
-
- return 0;
-}
-
-void osmo_serialgps_close(void)
-{
- if (gps_bfd.fd <= 0)
- return;
-
- LOGP(DGPS, LOGL_INFO, "Close GPS device\n");
-
- osmo_fd_unregister(&gps_bfd);
-
- if (isatty(gps_bfd.fd))
- tcsetattr(gps_bfd.fd, TCSANOW, &gps_old_termios);
-
- close(gps_bfd.fd);
- gps_bfd.fd = -1; /* -1 or 0 indicates: 'close' */
-}
-
-void osmo_gps_init(void)
-{
- memset(&gps_bfd, 0, sizeof(gps_bfd));
-}
-
-int osmo_gps_open(void)
-{
- switch (g.gps_type) {
-#ifdef _HAVE_GPSD
- case GPS_TYPE_GPSD:
- return osmo_gpsd_open();
-#endif
- case GPS_TYPE_SERIAL:
- return osmo_serialgps_open();
-
- default:
- return 0;
- }
-}
-
-void osmo_gps_close(void)
-{
- switch (g.gps_type) {
-#ifdef _HAVE_GPSD
- case GPS_TYPE_GPSD:
- return osmo_gpsd_close();
-#endif
- case GPS_TYPE_SERIAL:
- return osmo_serialgps_close();
-
- default:
- return;
- }
-}
-
diff --git a/Src/osmoconbb/src/host/layer23/src/common/l1ctl.c b/Src/osmoconbb/src/host/layer23/src/common/l1ctl.c
deleted file mode 100644
index e3ab4c9..0000000
--- a/Src/osmoconbb/src/host/layer23/src/common/l1ctl.c
+++ /dev/null
@@ -1,965 +0,0 @@
-/* Layer1 control code, talking L1CTL protocol with L1 on the phone */
-
-/* (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2010 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-
-#include <arpa/inet.h>
-
-#include <l1ctl_proto.h>
-
-#include <osmocom/core/signal.h>
-#include <osmocom/core/logging.h>
-#include <osmocom/core/timer.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/gsm/tlv.h>
-#include <osmocom/gsm/gsm_utils.h>
-#include <osmocom/core/gsmtap_util.h>
-#include <osmocom/gsm/protocol/gsm_04_08.h>
-#include <osmocom/gsm/protocol/gsm_08_58.h>
-#include <osmocom/gsm/rsl.h>
-
-#include <osmocom/bb/common/l1ctl.h>
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/l1l2_interface.h>
-#include <osmocom/bb/common/lapdm.h>
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/codec/codec.h>
-
-extern struct gsmtap_inst *gsmtap_inst;
-
-static struct msgb *osmo_l1_alloc(uint8_t msg_type)
-{
- struct l1ctl_hdr *l1h;
- struct msgb *msg = msgb_alloc_headroom(256, 4, "osmo_l1");
-
- if (!msg) {
- LOGP(DL1C, LOGL_ERROR, "Failed to allocate memory.\n");
- return NULL;
- }
-
- msg->l1h = msgb_put(msg, sizeof(*l1h));
- l1h = (struct l1ctl_hdr *) msg->l1h;
- l1h->msg_type = msg_type;
-
- return msg;
-}
-
-
-static inline int msb_get_bit(uint8_t *buf, int bn)
-{
- int pos_byte = bn >> 3;
- int pos_bit = 7 - (bn & 7);
-
- return (buf[pos_byte] >> pos_bit) & 1;
-}
-
-static inline void msb_set_bit(uint8_t *buf, int bn, int bit)
-{
- int pos_byte = bn >> 3;
- int pos_bit = 7 - (bn & 7);
-
- buf[pos_byte] |= (bit << pos_bit);
-}
-
-
-static int osmo_make_band_arfcn(struct osmocom_ms *ms, uint16_t arfcn)
-{
- /* TODO: Include the band */
- return arfcn;
-}
-
-static int rx_l1_fbsb_conf(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct l1ctl_info_dl *dl;
- struct l1ctl_fbsb_conf *sb;
- struct gsm_time tm;
- struct osmobb_fbsb_res fr;
-
- if (msgb_l3len(msg) < sizeof(*dl) + sizeof(*sb)) {
- LOGP(DL1C, LOGL_ERROR, "FBSB RESP: MSG too short %u\n",
- msgb_l3len(msg));
- return -1;
- }
-
- dl = (struct l1ctl_info_dl *) msg->l1h;
- sb = (struct l1ctl_fbsb_conf *) dl->payload;
-
- LOGP(DL1C, LOGL_INFO, "snr=%04x, arfcn=%u result=%u\n", dl->snr,
- ntohs(dl->band_arfcn), sb->result);
-
- if (sb->result != 0) {
- LOGP(DL1C, LOGL_ERROR, "FBSB RESP: result=%u\n", sb->result);
- fr.ms = ms;
- fr.band_arfcn = ntohs(dl->band_arfcn);
- osmo_signal_dispatch(SS_L1CTL, S_L1CTL_FBSB_ERR, &fr);
- return 0;
- }
-
- gsm_fn2gsmtime(&tm, ntohl(dl->frame_nr));
- DEBUGP(DL1C, "SCH: SNR: %u TDMA: (%.4u/%.2u/%.2u) bsic: %d\n",
- dl->snr, tm.t1, tm.t2, tm.t3, sb->bsic);
- fr.ms = ms;
- fr.snr = dl->snr;
- fr.bsic = sb->bsic;
- fr.band_arfcn = ntohs(dl->band_arfcn);
- osmo_signal_dispatch(SS_L1CTL, S_L1CTL_FBSB_RESP, &fr);
-
- return 0;
-}
-
-static int rx_l1_rach_conf(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct lapdm_entity *le = &ms->lapdm_channel.lapdm_dcch;
- struct osmo_phsap_prim pp;
- struct l1ctl_info_dl *dl;
-
- if (msgb_l2len(msg) < sizeof(*dl)) {
- LOGP(DL1C, LOGL_ERROR, "RACH CONF: MSG too short %u\n",
- msgb_l3len(msg));
- msgb_free(msg);
- return -1;
- }
-
- dl = (struct l1ctl_info_dl *) msg->l1h;
-
- osmo_prim_init(&pp.oph, SAP_GSM_PH, PRIM_PH_RACH,
- PRIM_OP_CONFIRM, msg);
- pp.u.rach_ind.fn = ntohl(dl->frame_nr);
-
- return lapdm_phsap_up(&pp.oph, le);
-}
-
-/* Receive L1CTL_DATA_IND (Data Indication from L1) */
-static int rx_ph_data_ind(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct osmo_phsap_prim pp;
- struct l1ctl_info_dl *dl;
- struct l1ctl_data_ind *ccch;
- struct lapdm_entity *le;
- struct rx_meas_stat *meas = &ms->meas;
- uint8_t chan_type, chan_ts, chan_ss;
- uint8_t gsmtap_chan_type;
- struct gsm_time tm;
-
- if (msgb_l3len(msg) < sizeof(*ccch)) {
- LOGP(DL1C, LOGL_ERROR, "MSG too short Data Ind: %u\n",
- msgb_l3len(msg));
- msgb_free(msg);
- return -1;
- }
-
- dl = (struct l1ctl_info_dl *) msg->l1h;
- msg->l2h = dl->payload;
- ccch = (struct l1ctl_data_ind *) msg->l2h;
-
- gsm_fn2gsmtime(&tm, ntohl(dl->frame_nr));
- rsl_dec_chan_nr(dl->chan_nr, &chan_type, &chan_ss, &chan_ts);
- DEBUGP(DL1C, "%s (%.4u/%.2u/%.2u) %d dBm: %s\n",
- rsl_chan_nr_str(dl->chan_nr), tm.t1, tm.t2, tm.t3,
- (int)dl->rx_level-110,
- osmo_hexdump(ccch->data, sizeof(ccch->data)));
-
- meas->last_fn = ntohl(dl->frame_nr);
- meas->frames++;
- meas->snr += dl->snr;
- meas->berr += dl->num_biterr;
- meas->rxlev += dl->rx_level;
-
- /* counting loss criteria */
- if (!(dl->link_id & 0x40)) {
- switch (chan_type) {
- case RSL_CHAN_PCH_AGCH:
- if (!meas->ds_fail)
- break;
- if (dl->fire_crc >= 2)
- meas->dsc -= 4;
- else
- meas->dsc += 1;
- if (meas->dsc > meas->ds_fail)
- meas->dsc = meas->ds_fail;
- if (meas->dsc < meas->ds_fail)
- printf("LOSS counter for CCCH %d\n", meas->dsc);
- if (meas->dsc > 0)
- break;
- meas->ds_fail = 0;
- osmo_signal_dispatch(SS_L1CTL, S_L1CTL_LOSS_IND, ms);
- break;
- }
- } else {
- switch (chan_type) {
- case RSL_CHAN_Bm_ACCHs:
- case RSL_CHAN_Lm_ACCHs:
- case RSL_CHAN_SDCCH4_ACCH:
- case RSL_CHAN_SDCCH8_ACCH:
- if (!meas->rl_fail)
- break;
- if (dl->fire_crc >= 2)
- meas->s -= 1;
- else
- meas->s += 2;
- if (meas->s > meas->rl_fail)
- meas->s = meas->rl_fail;
- if (meas->s < meas->rl_fail)
- printf("LOSS counter for ACCH %d\n", meas->s);
- if (meas->s > 0)
- break;
- meas->rl_fail = 0;
- osmo_signal_dispatch(SS_L1CTL, S_L1CTL_LOSS_IND, ms);
- break;
- }
- }
-
- if (dl->fire_crc >= 2) {
-printf("Dropping frame with %u bit errors\n", dl->num_biterr);
- LOGP(DL1C, LOGL_NOTICE, "Dropping frame with %u bit errors\n",
- dl->num_biterr);
- msgb_free(msg);
- return 0;
- }
-
- /* send CCCH data via GSMTAP */
- gsmtap_chan_type = chantype_rsl2gsmtap(chan_type, dl->link_id);
- gsmtap_send(gsmtap_inst, ntohs(dl->band_arfcn), chan_ts,
- gsmtap_chan_type, chan_ss, tm.fn, dl->rx_level-110,
- dl->snr, ccch->data, sizeof(ccch->data));
-
- /* determine LAPDm entity based on SACCH or not */
- if (dl->link_id & 0x40)
- le = &ms->lapdm_channel.lapdm_acch;
- else
- le = &ms->lapdm_channel.lapdm_dcch;
-
- /* pull the L1 header from the msgb */
- msgb_pull(msg, msg->l2h - (msg->l1h-sizeof(struct l1ctl_hdr)));
- msg->l1h = NULL;
-
- osmo_prim_init(&pp.oph, SAP_GSM_PH, PRIM_PH_DATA,
- PRIM_OP_INDICATION, msg);
- pp.u.data.chan_nr = dl->chan_nr;
- pp.u.data.link_id = dl->link_id;
-
- /* send it up into LAPDm */
- return lapdm_phsap_up(&pp.oph, le);
-}
-
-/* Receive L1CTL_DATA_CONF (Data Confirm from L1) */
-static int rx_ph_data_conf(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct osmo_phsap_prim pp;
- struct l1ctl_info_dl *dl = (struct l1ctl_info_dl *) msg->l1h;
- struct lapdm_entity *le;
-
- osmo_prim_init(&pp.oph, SAP_GSM_PH, PRIM_PH_RTS,
- PRIM_OP_INDICATION, msg);
-
- /* determine LAPDm entity based on SACCH or not */
- if (dl->link_id & 0x40)
- le = &ms->lapdm_channel.lapdm_acch;
- else
- le = &ms->lapdm_channel.lapdm_dcch;
-
- /* send it up into LAPDm */
- return lapdm_phsap_up(&pp.oph, le);
-}
-
-/* Transmit L1CTL_DATA_REQ */
-int l1ctl_tx_data_req(struct osmocom_ms *ms, struct msgb *msg,
- uint8_t chan_nr, uint8_t link_id)
-{
- struct l1ctl_hdr *l1h;
- struct l1ctl_info_ul *l1i_ul;
- uint8_t chan_type, chan_ts, chan_ss;
- uint8_t gsmtap_chan_type;
-
- DEBUGP(DL1C, "(%s)\n", osmo_hexdump(msg->l2h, msgb_l2len(msg)));
-
- if (msgb_l2len(msg) > 23) {
- LOGP(DL1C, LOGL_ERROR, "L1 cannot handle message length "
- "> 23 (%u)\n", msgb_l2len(msg));
- msgb_free(msg);
- return -EINVAL;
- } else if (msgb_l2len(msg) < 23)
- LOGP(DL1C, LOGL_ERROR, "L1 message length < 23 (%u) "
- "doesn't seem right!\n", msgb_l2len(msg));
-
- /* send copy via GSMTAP */
- rsl_dec_chan_nr(chan_nr, &chan_type, &chan_ss, &chan_ts);
- gsmtap_chan_type = chantype_rsl2gsmtap(chan_type, link_id);
- gsmtap_send(gsmtap_inst, 0|0x4000, chan_ts, gsmtap_chan_type,
- chan_ss, 0, 127, 255, msg->l2h, msgb_l2len(msg));
-
- /* prepend uplink info header */
- l1i_ul = (struct l1ctl_info_ul *) msgb_push(msg, sizeof(*l1i_ul));
-
- l1i_ul->chan_nr = chan_nr;
- l1i_ul->link_id = link_id;
-
- /* prepend l1 header */
- msg->l1h = msgb_push(msg, sizeof(*l1h));
- l1h = (struct l1ctl_hdr *) msg->l1h;
- l1h->msg_type = L1CTL_DATA_REQ;
-
- return osmo_send_l1(ms, msg);
-}
-
-/* Transmit FBSB_REQ */
-int l1ctl_tx_fbsb_req(struct osmocom_ms *ms, uint16_t arfcn,
- uint8_t flags, uint16_t timeout, uint8_t sync_info_idx,
- uint8_t ccch_mode)
-{
- struct msgb *msg;
- struct l1ctl_fbsb_req *req;
-
- LOGP(DL1C, LOGL_INFO, "Sync Req\n");
-
- msg = osmo_l1_alloc(L1CTL_FBSB_REQ);
- if (!msg)
- return -1;
-
- req = (struct l1ctl_fbsb_req *) msgb_put(msg, sizeof(*req));
- req->band_arfcn = htons(osmo_make_band_arfcn(ms, arfcn));
- req->timeout = htons(timeout);
- /* Threshold when to consider FB_MODE1: 4kHz - 1kHz */
- req->freq_err_thresh1 = htons(11000 - 1000);
- /* Threshold when to consider SCH: 1kHz - 200Hz */
- req->freq_err_thresh2 = htons(1000 - 200);
- /* not used yet! */
- req->num_freqerr_avg = 3;
- req->flags = flags;
- req->sync_info_idx = sync_info_idx;
- req->ccch_mode = ccch_mode;
-
- return osmo_send_l1(ms, msg);
-}
-
-/* Transmit L1CTL_CCCH_MODE_REQ */
-int l1ctl_tx_ccch_mode_req(struct osmocom_ms *ms, uint8_t ccch_mode)
-{
- struct msgb *msg;
- struct l1ctl_ccch_mode_req *req;
-
- LOGP(DL1C, LOGL_INFO, "CCCH Mode Req\n");
-
- msg = osmo_l1_alloc(L1CTL_CCCH_MODE_REQ);
- if (!msg)
- return -1;
-
- req = (struct l1ctl_ccch_mode_req *) msgb_put(msg, sizeof(*req));
- req->ccch_mode = ccch_mode;
-
- return osmo_send_l1(ms, msg);
-}
-
-/* Transmit L1CTL_TCH_MODE_REQ */
-int l1ctl_tx_tch_mode_req(struct osmocom_ms *ms, uint8_t tch_mode,
- uint8_t audio_mode)
-{
- struct msgb *msg;
- struct l1ctl_tch_mode_req *req;
-
- LOGP(DL1C, LOGL_INFO, "TCH Mode Req\n");
-
- msg = osmo_l1_alloc(L1CTL_TCH_MODE_REQ);
- if (!msg)
- return -1;
-
- req = (struct l1ctl_tch_mode_req *) msgb_put(msg, sizeof(*req));
- req->tch_mode = tch_mode;
- req->audio_mode = audio_mode;
-
- return osmo_send_l1(ms, msg);
-}
-
-/* Transmit L1CTL_PARAM_REQ */
-int l1ctl_tx_param_req(struct osmocom_ms *ms, uint8_t ta, uint8_t tx_power)
-{
- struct msgb *msg;
- struct l1ctl_info_ul *ul;
- struct l1ctl_par_req *req;
-
- msg = osmo_l1_alloc(L1CTL_PARAM_REQ);
- if (!msg)
- return -1;
-
- DEBUGP(DL1C, "PARAM Req. ta=%d, tx_power=%d\n", ta, tx_power);
- ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul));
- req = (struct l1ctl_par_req *) msgb_put(msg, sizeof(*req));
- req->tx_power = tx_power;
- req->ta = ta;
-
- return osmo_send_l1(ms, msg);
-}
-
-/* Transmit L1CTL_CRYPTO_REQ */
-int l1ctl_tx_crypto_req(struct osmocom_ms *ms, uint8_t algo, uint8_t *key,
- uint8_t len)
-{
- struct msgb *msg;
- struct l1ctl_info_ul *ul;
- struct l1ctl_crypto_req *req;
-
- msg = osmo_l1_alloc(L1CTL_CRYPTO_REQ);
- if (!msg)
- return -1;
-
- DEBUGP(DL1C, "CRYPTO Req. algo=%d, len=%d\n", algo, len);
- ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul));
- req = (struct l1ctl_crypto_req *) msgb_put(msg, sizeof(*req) + len);
- req->algo = algo;
- if (len)
- memcpy(req->key, key, len);
-
- return osmo_send_l1(ms, msg);
-}
-
-/* Transmit L1CTL_RACH_REQ */
-int l1ctl_tx_rach_req(struct osmocom_ms *ms, uint8_t ra, uint16_t offset,
- uint8_t combined)
-{
- struct msgb *msg;
- struct l1ctl_info_ul *ul;
- struct l1ctl_rach_req *req;
-
- msg = osmo_l1_alloc(L1CTL_RACH_REQ);
- if (!msg)
- return -1;
-
- DEBUGP(DL1C, "RACH Req. offset=%d combined=%d\n", offset, combined);
- ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul));
- req = (struct l1ctl_rach_req *) msgb_put(msg, sizeof(*req));
- req->ra = ra;
- req->offset = htons(offset);
- req->combined = combined;
-
- return osmo_send_l1(ms, msg);
-}
-
-/* Transmit L1CTL_DM_EST_REQ */
-int l1ctl_tx_dm_est_req_h0(struct osmocom_ms *ms, uint16_t band_arfcn,
- uint8_t chan_nr, uint8_t tsc, uint8_t tch_mode,
- uint8_t audio_mode)
-{
- struct msgb *msg;
- struct l1ctl_info_ul *ul;
- struct l1ctl_dm_est_req *req;
-
- msg = osmo_l1_alloc(L1CTL_DM_EST_REQ);
- if (!msg)
- return -1;
-
- LOGP(DL1C, LOGL_INFO, "Tx Dedic.Mode Est Req (arfcn=%u, "
- "chan_nr=0x%02x)\n", band_arfcn, chan_nr);
-
- ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul));
- ul->chan_nr = chan_nr;
- ul->link_id = 0;
-
- req = (struct l1ctl_dm_est_req *) msgb_put(msg, sizeof(*req));
- req->tsc = tsc;
- req->h = 0;
- req->h0.band_arfcn = htons(band_arfcn);
- req->tch_mode = tch_mode;
- req->audio_mode = audio_mode;
-
- return osmo_send_l1(ms, msg);
-}
-
-int l1ctl_tx_dm_est_req_h1(struct osmocom_ms *ms, uint8_t maio, uint8_t hsn,
- uint16_t *ma, uint8_t ma_len,
- uint8_t chan_nr, uint8_t tsc, uint8_t tch_mode,
- uint8_t audio_mode)
-{
- struct msgb *msg;
- struct l1ctl_info_ul *ul;
- struct l1ctl_dm_est_req *req;
- int i;
-
- msg = osmo_l1_alloc(L1CTL_DM_EST_REQ);
- if (!msg)
- return -1;
-
- LOGP(DL1C, LOGL_INFO, "Tx Dedic.Mode Est Req (maio=%u, hsn=%u, "
- "chan_nr=0x%02x)\n", maio, hsn, chan_nr);
-
- ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul));
- ul->chan_nr = chan_nr;
- ul->link_id = 0;
-
- req = (struct l1ctl_dm_est_req *) msgb_put(msg, sizeof(*req));
- req->tsc = tsc;
- req->h = 1;
- req->h1.maio = maio;
- req->h1.hsn = hsn;
- req->h1.n = ma_len;
- for (i = 0; i < ma_len; i++)
- req->h1.ma[i] = htons(ma[i]);
- req->tch_mode = tch_mode;
- req->audio_mode = audio_mode;
-
- return osmo_send_l1(ms, msg);
-}
-
-/* Transmit L1CTL_DM_FREQ_REQ */
-int l1ctl_tx_dm_freq_req_h0(struct osmocom_ms *ms, uint16_t band_arfcn,
- uint8_t tsc, uint16_t fn)
-{
- struct msgb *msg;
- struct l1ctl_info_ul *ul;
- struct l1ctl_dm_freq_req *req;
-
- msg = osmo_l1_alloc(L1CTL_DM_FREQ_REQ);
- if (!msg)
- return -1;
-
- LOGP(DL1C, LOGL_INFO, "Tx Dedic.Mode Freq Req (arfcn=%u, fn=%d)\n",
- band_arfcn, fn);
-
- ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul));
- ul->chan_nr = 0;
- ul->link_id = 0;
-
- req = (struct l1ctl_dm_freq_req *) msgb_put(msg, sizeof(*req));
- req->fn = htons(fn);
- req->tsc = tsc;
- req->h = 0;
- req->h0.band_arfcn = htons(band_arfcn);
-
- return osmo_send_l1(ms, msg);
-}
-
-int l1ctl_tx_dm_freq_req_h1(struct osmocom_ms *ms, uint8_t maio, uint8_t hsn,
- uint16_t *ma, uint8_t ma_len,
- uint8_t tsc, uint16_t fn)
-{
- struct msgb *msg;
- struct l1ctl_info_ul *ul;
- struct l1ctl_dm_freq_req *req;
- int i;
-
- msg = osmo_l1_alloc(L1CTL_DM_FREQ_REQ);
- if (!msg)
- return -1;
-
- LOGP(DL1C, LOGL_INFO, "Tx Dedic.Mode Freq Req (maio=%u, hsn=%u, "
- "fn=%d)\n", maio, hsn, fn);
-
- ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul));
- ul->chan_nr = 0;
- ul->link_id = 0;
-
- req = (struct l1ctl_dm_freq_req *) msgb_put(msg, sizeof(*req));
- req->fn = htons(fn);
- req->tsc = tsc;
- req->h = 1;
- req->h1.maio = maio;
- req->h1.hsn = hsn;
- req->h1.n = ma_len;
- for (i = 0; i < ma_len; i++)
- req->h1.ma[i] = htons(ma[i]);
-
- return osmo_send_l1(ms, msg);
-}
-
-/* Transmit L1CTL_DM_REL_REQ */
-int l1ctl_tx_dm_rel_req(struct osmocom_ms *ms)
-{
- struct msgb *msg;
- struct l1ctl_info_ul *ul;
-
- msg = osmo_l1_alloc(L1CTL_DM_REL_REQ);
- if (!msg)
- return -1;
-
- LOGP(DL1C, LOGL_INFO, "Tx Dedic.Mode Rel Req\n");
-
- ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul));
-
- return osmo_send_l1(ms, msg);
-}
-
-int l1ctl_tx_echo_req(struct osmocom_ms *ms, unsigned int len)
-{
- struct msgb *msg;
- uint8_t *data;
- unsigned int i;
-
- msg = osmo_l1_alloc(L1CTL_ECHO_REQ);
- if (!msg)
- return -1;
-
- data = msgb_put(msg, len);
- for (i = 0; i < len; i++)
- data[i] = i % 8;
-
- return osmo_send_l1(ms, msg);
-}
-
-int l1ctl_tx_sim_req(struct osmocom_ms *ms, uint8_t *data, uint16_t length)
-{
- struct msgb *msg;
- uint8_t *dat;
-
- msg = osmo_l1_alloc(L1CTL_SIM_REQ);
- if (!msg)
- return -1;
-
- dat = msgb_put(msg, length);
- memcpy(dat, data, length);
-
- return osmo_send_l1(ms, msg);
-}
-
-/* just forward the SIM response to the SIM handler */
-static int rx_l1_sim_conf(struct osmocom_ms *ms, struct msgb *msg)
-{
- uint16_t len = msg->len - sizeof(struct l1ctl_hdr);
- uint8_t *data = msg->data + sizeof(struct l1ctl_hdr);
-
- LOGP(DL1C, LOGL_INFO, "SIM %s\n", osmo_hexdump(data, len));
-
- /* pull the L1 header from the msgb */
- msgb_pull(msg, sizeof(struct l1ctl_hdr));
- msg->l1h = NULL;
-
- sim_apdu_resp(ms, msg);
-
- return 0;
-}
-
-/* Transmit L1CTL_PM_REQ */
-int l1ctl_tx_pm_req_range(struct osmocom_ms *ms, uint16_t arfcn_from,
- uint16_t arfcn_to)
-{
- struct msgb *msg;
- struct l1ctl_pm_req *pm;
-
- msg = osmo_l1_alloc(L1CTL_PM_REQ);
- if (!msg)
- return -1;
-
- LOGP(DL1C, LOGL_INFO, "Tx PM Req (%u-%u)\n", arfcn_from, arfcn_to);
- pm = (struct l1ctl_pm_req *) msgb_put(msg, sizeof(*pm));
- pm->type = 1;
- pm->range.band_arfcn_from = htons(arfcn_from);
- pm->range.band_arfcn_to = htons(arfcn_to);
-
- return osmo_send_l1(ms, msg);
-}
-
-/* Transmit L1CTL_RESET_REQ */
-int l1ctl_tx_reset_req(struct osmocom_ms *ms, uint8_t type)
-{
- struct msgb *msg;
- struct l1ctl_reset *res;
-
- msg = osmo_l1_alloc(L1CTL_RESET_REQ);
- if (!msg)
- return -1;
-
- LOGP(DL1C, LOGL_INFO, "Tx Reset Req (%u)\n", type);
- res = (struct l1ctl_reset *) msgb_put(msg, sizeof(*res));
- res->type = type;
-
- return osmo_send_l1(ms, msg);
-}
-
-/* Receive L1CTL_RESET_IND */
-static int rx_l1_reset(struct osmocom_ms *ms)
-{
- LOGP(DL1C, LOGL_INFO, "Layer1 Reset indication\n");
- osmo_signal_dispatch(SS_L1CTL, S_L1CTL_RESET, ms);
-
- return 0;
-}
-
-/* Receive L1CTL_PM_CONF */
-static int rx_l1_pm_conf(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct l1ctl_pm_conf *pmr;
-
- for (pmr = (struct l1ctl_pm_conf *) msg->l1h;
- (uint8_t *) pmr < msg->tail; pmr++) {
- struct osmobb_meas_res mr;
- DEBUGP(DL1C, "PM MEAS: ARFCN: %4u RxLev: %3d %3d\n",
- ntohs(pmr->band_arfcn), pmr->pm[0], pmr->pm[1]);
- mr.band_arfcn = ntohs(pmr->band_arfcn);
- mr.rx_lev = pmr->pm[0];
- mr.ms = ms;
- osmo_signal_dispatch(SS_L1CTL, S_L1CTL_PM_RES, &mr);
- }
- return 0;
-}
-
-/* Receive L1CTL_CCCH_MODE_CONF */
-static int rx_l1_ccch_mode_conf(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct osmobb_ccch_mode_conf mc;
- struct l1ctl_ccch_mode_conf *conf;
-
- if (msgb_l3len(msg) < sizeof(*conf)) {
- LOGP(DL1C, LOGL_ERROR, "CCCH MODE CONF: MSG too short %u\n",
- msgb_l3len(msg));
- return -1;
- }
-
- conf = (struct l1ctl_ccch_mode_conf *) msg->l1h;
-
- LOGP(DL1C, LOGL_INFO, "CCCH MODE CONF: mode=%u\n", conf->ccch_mode);
-
- mc.ccch_mode = conf->ccch_mode;
- mc.ms = ms;
- osmo_signal_dispatch(SS_L1CTL, S_L1CTL_CCCH_MODE_CONF, &mc);
-
- return 0;
-}
-
-/* Receive L1CTL_TCH_MODE_CONF */
-static int rx_l1_tch_mode_conf(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct osmobb_tch_mode_conf mc;
- struct l1ctl_tch_mode_conf *conf;
-
- if (msgb_l3len(msg) < sizeof(*conf)) {
- LOGP(DL1C, LOGL_ERROR, "TCH MODE CONF: MSG too short %u\n",
- msgb_l3len(msg));
- return -1;
- }
-
- conf = (struct l1ctl_tch_mode_conf *) msg->l1h;
-
- LOGP(DL1C, LOGL_INFO, "TCH MODE CONF: mode=%u\n", conf->tch_mode);
-
- mc.tch_mode = conf->tch_mode;
- mc.audio_mode = conf->audio_mode;
- mc.ms = ms;
- osmo_signal_dispatch(SS_L1CTL, S_L1CTL_TCH_MODE_CONF, &mc);
-
- return 0;
-}
-
-/* Receive L1CTL_TRAFFIC_IND (Traffic Indication from L1) */
-static int rx_l1_traffic_ind(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct l1ctl_info_dl *dl;
- struct l1ctl_traffic_ind *ti;
- uint8_t fr[33];
- int i, di, si;
-
- /* Header handling */
- dl = (struct l1ctl_info_dl *) msg->l1h;
- msg->l2h = dl->payload;
- ti = (struct l1ctl_traffic_ind *) msg->l2h;
-
- memset(fr, 0x00, 33);
- fr[0] = 0xd0;
- for (i = 0; i < 260; i++) {
- di = gsm610_bitorder[i];
- si = (i > 181) ? i + 4 : i;
- msb_set_bit(fr, 4 + di, msb_get_bit(ti->data, si));
- }
- memcpy(ti->data, fr, 33);
-
- DEBUGP(DL1C, "TRAFFIC IND (%s)\n", osmo_hexdump(ti->data, 33));
-
- /* distribute or drop */
- if (ms->l1_entity.l1_traffic_ind) {
- /* pull the L1 header from the msgb */
- msgb_pull(msg, msg->l2h - (msg->l1h-sizeof(struct l1ctl_hdr)));
- msg->l1h = NULL;
-
- return ms->l1_entity.l1_traffic_ind(ms, msg);
- }
-
- msgb_free(msg);
- return 0;
-}
-
-/* Transmit L1CTL_TRAFFIC_REQ (Traffic Request to L1) */
-int l1ctl_tx_traffic_req(struct osmocom_ms *ms, struct msgb *msg,
- uint8_t chan_nr, uint8_t link_id)
-{
- struct l1ctl_hdr *l1h;
- struct l1ctl_info_ul *l1i_ul;
- struct l1ctl_traffic_req *tr;
- uint8_t fr[33];
- int i, di, si;
-
- /* Header handling */
- tr = (struct l1ctl_traffic_req *) msg->l2h;
-
- DEBUGP(DL1C, "TRAFFIC REQ (%s)\n",
- osmo_hexdump(msg->l2h, msgb_l2len(msg)));
-
- if (msgb_l2len(msg) != 33) {
- LOGP(DL1C, LOGL_ERROR, "Traffic Request has incorrect length "
- "(%u != 33)\n", msgb_l2len(msg));
- msgb_free(msg);
- return -EINVAL;
- }
-
- if ((tr->data[0] >> 4) != 0xd) {
- LOGP(DL1C, LOGL_ERROR, "Traffic Request has incorrect magic "
- "(%u != 0xd)\n", tr->data[0] >> 4);
- msgb_free(msg);
- return -EINVAL;
- }
-
- memset(fr, 0x00, 33);
- for (i = 0; i < 260; i++) {
- si = gsm610_bitorder[i];
- di = (i > 181) ? i + 4 : i;
- msb_set_bit(fr, di, msb_get_bit(tr->data, 4 + si));
- }
- memcpy(tr->data, fr, 33);
-// printf("TX %s\n", osmo_hexdump(tr->data, 33));
-
- /* prepend uplink info header */
- l1i_ul = (struct l1ctl_info_ul *) msgb_push(msg, sizeof(*l1i_ul));
-
- l1i_ul->chan_nr = chan_nr;
- l1i_ul->link_id = link_id;
-
- /* prepend l1 header */
- msg->l1h = msgb_push(msg, sizeof(*l1h));
- l1h = (struct l1ctl_hdr *) msg->l1h;
- l1h->msg_type = L1CTL_TRAFFIC_REQ;
-
- return osmo_send_l1(ms, msg);
-}
-
-/* Transmit L1CTL_NEIGH_PM_REQ */
-int l1ctl_tx_neigh_pm_req(struct osmocom_ms *ms, int num, uint16_t *arfcn)
-{
- struct msgb *msg;
- struct l1ctl_neigh_pm_req *pm_req;
- int i;
-
- msg = osmo_l1_alloc(L1CTL_NEIGH_PM_REQ);
- if (!msg)
- return -1;
-
- LOGP(DL1C, LOGL_INFO, "Tx NEIGH PM Req (num %u)\n", num);
- pm_req = (struct l1ctl_neigh_pm_req *) msgb_put(msg, sizeof(*pm_req));
- pm_req->n = num;
- for (i = 0; i < num; i++)
- pm_req->band_arfcn[i] = htons(*arfcn++);
-
- return osmo_send_l1(ms, msg);
-}
-
-/* Receive L1CTL_NEIGH_PM_IND */
-static int rx_l1_neigh_pm_ind(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct l1ctl_neigh_pm_ind *pm_ind;
-
- for (pm_ind = (struct l1ctl_neigh_pm_ind *) msg->l1h;
- (uint8_t *) pm_ind < msg->tail; pm_ind++) {
- struct osmobb_neigh_pm_ind mi;
- DEBUGP(DL1C, "NEIGH_PM IND: ARFCN: %4u RxLev: %3d %3d\n",
- ntohs(pm_ind->band_arfcn), pm_ind->pm[0],
- pm_ind->pm[1]);
- mi.band_arfcn = ntohs(pm_ind->band_arfcn);
- mi.rx_lev = pm_ind->pm[0];
- mi.ms = ms;
- osmo_signal_dispatch(SS_L1CTL, S_L1CTL_NEIGH_PM_IND, &mi);
- }
- return 0;
-}
-
-/* Receive incoming data from L1 using L1CTL format */
-int l1ctl_recv(struct osmocom_ms *ms, struct msgb *msg)
-{
- int rc = 0;
- struct l1ctl_hdr *l1h;
- struct l1ctl_info_dl *dl;
-
- if (msgb_l2len(msg) < sizeof(*dl)) {
- LOGP(DL1C, LOGL_ERROR, "Short Layer2 message: %u\n",
- msgb_l2len(msg));
- msgb_free(msg);
- return -1;
- }
-
- l1h = (struct l1ctl_hdr *) msg->l1h;
-
- /* move the l1 header pointer to point _BEHIND_ l1ctl_hdr,
- as the l1ctl header is of no interest to subsequent code */
- msg->l1h = l1h->data;
-
- switch (l1h->msg_type) {
- case L1CTL_FBSB_CONF:
- rc = rx_l1_fbsb_conf(ms, msg);
- msgb_free(msg);
- break;
- case L1CTL_DATA_IND:
- rc = rx_ph_data_ind(ms, msg);
- break;
- case L1CTL_DATA_CONF:
- rc = rx_ph_data_conf(ms, msg);
- break;
- case L1CTL_RESET_IND:
- case L1CTL_RESET_CONF:
- rc = rx_l1_reset(ms);
- msgb_free(msg);
- break;
- case L1CTL_PM_CONF:
- rc = rx_l1_pm_conf(ms, msg);
- if (l1h->flags & L1CTL_F_DONE)
- osmo_signal_dispatch(SS_L1CTL, S_L1CTL_PM_DONE, ms);
- msgb_free(msg);
- break;
- case L1CTL_RACH_CONF:
- rc = rx_l1_rach_conf(ms, msg);
- break;
- case L1CTL_CCCH_MODE_CONF:
- rc = rx_l1_ccch_mode_conf(ms, msg);
- msgb_free(msg);
- break;
- case L1CTL_TCH_MODE_CONF:
- rc = rx_l1_tch_mode_conf(ms, msg);
- msgb_free(msg);
- break;
- case L1CTL_SIM_CONF:
- rc = rx_l1_sim_conf(ms, msg);
- break;
- case L1CTL_NEIGH_PM_IND:
- rc = rx_l1_neigh_pm_ind(ms, msg);
- msgb_free(msg);
- break;
- case L1CTL_TRAFFIC_IND:
- rc = rx_l1_traffic_ind(ms, msg);
- break;
- case L1CTL_TRAFFIC_CONF:
- msgb_free(msg);
- break;
- default:
- LOGP(DL1C, LOGL_ERROR, "Unknown MSG: %u\n", l1h->msg_type);
- msgb_free(msg);
- break;
- }
-
- return rc;
-}
diff --git a/Src/osmoconbb/src/host/layer23/src/common/l1ctl_lapdm_glue.c b/Src/osmoconbb/src/host/layer23/src/common/l1ctl_lapdm_glue.c
deleted file mode 100644
index db071a3..0000000
--- a/Src/osmoconbb/src/host/layer23/src/common/l1ctl_lapdm_glue.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Glue code between L1CTL and LAPDm */
-
-/* (C) 2011 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdint.h>
-
-#include <l1ctl_proto.h>
-
-#include <osmocom/gsm/prim.h>
-
-#include <osmocom/bb/common/l1ctl.h>
-#include <osmocom/bb/common/lapdm.h>
-
-/* LAPDm wants to send a PH-* primitive to the physical layer (L1) */
-int l1ctl_ph_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
-{
- struct osmocom_ms *ms = ctx;
- struct osmo_phsap_prim *pp = (struct osmo_phsap_prim *) oph;
- int rc = 0;
-
- if (oph->sap != SAP_GSM_PH)
- return -ENODEV;
-
- if (oph->operation != PRIM_OP_REQUEST)
- return -EINVAL;
-
- switch (oph->primitive) {
- case PRIM_PH_DATA:
- rc = l1ctl_tx_data_req(ms, oph->msg, pp->u.data.chan_nr,
- pp->u.data.link_id);
- break;
- case PRIM_PH_RACH:
- l1ctl_tx_param_req(ms, pp->u.rach_req.ta,
- pp->u.rach_req.tx_power);
- rc = l1ctl_tx_rach_req(ms, pp->u.rach_req.ra,
- pp->u.rach_req.offset,
- pp->u.rach_req.is_combined_ccch);
- break;
- default:
- rc = -EINVAL;
- }
-
- return rc;
-}
diff --git a/Src/osmoconbb/src/host/layer23/src/common/l1l2_interface.c b/Src/osmoconbb/src/host/layer23/src/common/l1l2_interface.c
deleted file mode 100644
index abaa64f..0000000
--- a/Src/osmoconbb/src/host/layer23/src/common/l1l2_interface.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/* Layer 1 socket interface of layer2/3 stack */
-
-/* (C) 2010 by Holger Hans Peter Freyther
- * (C) 2010 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/l1ctl.h>
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/l1l2_interface.h>
-
-#include <osmocom/core/utils.h>
-
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#include <arpa/inet.h>
-
-#define _GNU_SOURCE
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-
-#define GSM_L2_LENGTH 256
-#define GSM_L2_HEADROOM 32
-
-static int layer2_read(struct osmo_fd *fd)
-{
- struct msgb *msg;
- u_int16_t len;
- int rc;
-
- msg = msgb_alloc_headroom(GSM_L2_LENGTH+GSM_L2_HEADROOM, GSM_L2_HEADROOM, "Layer2");
- if (!msg) {
- LOGP(DL1C, LOGL_ERROR, "Failed to allocate msg.\n");
- return -ENOMEM;
- }
-
- rc = read(fd->fd, &len, sizeof(len));
- if (rc < sizeof(len)) {
- fprintf(stderr, "Layer2 socket failed\n");
- msgb_free(msg);
- if (rc >= 0)
- rc = -EIO;
- layer2_close((struct osmocom_ms *) fd->data);
- return rc;
- }
-
- len = ntohs(len);
- if (len > GSM_L2_LENGTH) {
- LOGP(DL1C, LOGL_ERROR, "Length is too big: %u\n", len);
- msgb_free(msg);
- return -EINVAL;
- }
-
-
- msg->l1h = msgb_put(msg, len);
- rc = read(fd->fd, msg->l1h, msgb_l1len(msg));
- if (rc != msgb_l1len(msg)) {
- LOGP(DL1C, LOGL_ERROR, "Can not read data: len=%d rc=%d "
- "errno=%d\n", len, rc, errno);
- msgb_free(msg);
- return rc;
- }
-
- l1ctl_recv((struct osmocom_ms *) fd->data, msg);
-
- return 0;
-}
-
-static int layer2_write(struct osmo_fd *fd, struct msgb *msg)
-{
- int rc;
-
- if (fd->fd <= 0)
- return -EINVAL;
-
- rc = write(fd->fd, msg->data, msg->len);
- if (rc != msg->len) {
- LOGP(DL1C, LOGL_ERROR, "Failed to write data: rc: %d\n", rc);
- return rc;
- }
-
- return 0;
-}
-
-int layer2_open(struct osmocom_ms *ms, const char *socket_path)
-{
- int rc;
- struct sockaddr_un local;
-
- ms->l2_wq.bfd.fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (ms->l2_wq.bfd.fd < 0) {
- fprintf(stderr, "Failed to create unix domain socket.\n");
- return ms->l2_wq.bfd.fd;
- }
-
- local.sun_family = AF_UNIX;
- strncpy(local.sun_path, socket_path, sizeof(local.sun_path));
- local.sun_path[sizeof(local.sun_path) - 1] = '\0';
-
- rc = connect(ms->l2_wq.bfd.fd, (struct sockaddr *) &local,
- sizeof(local));
- if (rc < 0) {
- fprintf(stderr, "Failed to connect to '%s': %s\n", local.sun_path,
- strerror(errno));
- close(ms->l2_wq.bfd.fd);
- return rc;
- }
-
- osmo_wqueue_init(&ms->l2_wq, 100);
- ms->l2_wq.bfd.data = ms;
- ms->l2_wq.bfd.when = BSC_FD_READ;
- ms->l2_wq.read_cb = layer2_read;
- ms->l2_wq.write_cb = layer2_write;
-
- rc = osmo_fd_register(&ms->l2_wq.bfd);
- if (rc != 0) {
- fprintf(stderr, "Failed to register fd.\n");
- close(ms->l2_wq.bfd.fd);
- return rc;
- }
-
- return 0;
-}
-
-int layer2_close(struct osmocom_ms *ms)
-{
- if (ms->l2_wq.bfd.fd <= 0)
- return -EINVAL;
-
- close(ms->l2_wq.bfd.fd);
- ms->l2_wq.bfd.fd = -1;
- osmo_fd_unregister(&ms->l2_wq.bfd);
-
- return 0;
-}
-
-int osmo_send_l1(struct osmocom_ms *ms, struct msgb *msg)
-{
- uint16_t *len;
-
- DEBUGP(DL1C, "Sending: '%s'\n", osmo_hexdump(msg->data, msg->len));
-
- if (msg->l1h != msg->data)
- LOGP(DL1C, LOGL_ERROR, "Message L1 header != Message Data\n");
-
- /* prepend 16bit length before sending */
- len = (uint16_t *) msgb_push(msg, sizeof(*len));
- *len = htons(msg->len - sizeof(*len));
-
- if (osmo_wqueue_enqueue(&ms->l2_wq, msg) != 0) {
- LOGP(DL1C, LOGL_ERROR, "Failed to enqueue msg.\n");
- msgb_free(msg);
- return -1;
- }
-
- return 0;
-}
-
-
diff --git a/Src/osmoconbb/src/host/layer23/src/common/lapdm.c b/Src/osmoconbb/src/host/layer23/src/common/lapdm.c
deleted file mode 100644
index 1fbebe6..0000000
--- a/Src/osmoconbb/src/host/layer23/src/common/lapdm.c
+++ /dev/null
@@ -1,2510 +0,0 @@
-/* GSM LAPDm (TS 04.06) implementation */
-
-/* (C) 2010-2011 by Harald Welte <laforge@gnumonks.org>
- * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-/* Notes on Buffering: rcv_buffer, tx_queue, tx_hist, send_buffer, send_queue
- *
- * RX data is stored in the rcv_buffer (pointer). If the message is complete, it
- * is removed from rcv_buffer pointer and forwarded to L3. If the RX data is
- * received while there is an incomplete rcv_buffer, it is appended to it.
- *
- * TX data is stored in the send_queue first. When transmitting a frame,
- * the first message in the send_queue is moved to the send_buffer. There it
- * resides until all fragments are acknowledged. Fragments to be sent by I
- * frames are stored in the tx_hist buffer for resend, if required. Also the
- * current fragment is copied into the tx_queue. There it resides until it is
- * forwarded to layer 1.
- *
- * In case we have SAPI 0, we only have a window size of 1, so the unack-
- * nowledged message resides always in the send_buffer. In case of a suspend,
- * it can be written back to the first position of the send_queue.
- *
- * The layer 1 normally sends a PH-READY-TO-SEND. But because we use
- * asynchronous transfer between layer 1 and layer 2 (serial link), we must
- * send a frame before layer 1 reaches the right timeslot to send it. So we
- * move the tx_queue to layer 1 when there is not already a pending frame, and
- * wait until acknowledge after the frame has been sent. If we receive an
- * acknowledge, we can send the next frame from the buffer, if any.
- *
- * The moving of tx_queue to layer 1 may also trigger T200, if desired. Also it
- * will trigger next I frame, if possible.
- *
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-#include <arpa/inet.h>
-
-#include <osmocom/core/logging.h>
-#include <osmocom/core/timer.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/gsm/tlv.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/gsm/rsl.h>
-#include <osmocom/gsm/prim.h>
-#include <osmocom/gsm/gsm_utils.h>
-#include <osmocom/gsm/protocol/gsm_04_08.h>
-#include <osmocom/gsm/protocol/gsm_08_58.h>
-
-#include <osmocom/bb/common/lapdm.h>
-#include <osmocom/bb/common/logging.h>
-
-/* TS 04.06 Figure 4 / Section 3.2 */
-#define LAPDm_LPD_NORMAL 0
-#define LAPDm_LPD_SMSCB 1
-#define LAPDm_SAPI_NORMAL 0
-#define LAPDm_SAPI_SMS 3
-#define LAPDm_ADDR(lpd, sapi, cr) ((((lpd) & 0x3) << 5) | (((sapi) & 0x7) << 2) | (((cr) & 0x1) << 1) | 0x1)
-
-#define LAPDm_ADDR_SAPI(addr) (((addr) >> 2) & 0x7)
-#define LAPDm_ADDR_CR(addr) (((addr) >> 1) & 0x1)
-#define LAPDm_ADDR_EA(addr) ((addr) & 0x1)
-
-/* TS 04.06 Table 3 / Section 3.4.3 */
-#define LAPDm_CTRL_I(nr, ns, p) ((((nr) & 0x7) << 5) | (((p) & 0x1) << 4) | (((ns) & 0x7) << 1))
-#define LAPDm_CTRL_S(nr, s, p) ((((nr) & 0x7) << 5) | (((p) & 0x1) << 4) | (((s) & 0x3) << 2) | 0x1)
-#define LAPDm_CTRL_U(u, p) ((((u) & 0x1c) << (5-2)) | (((p) & 0x1) << 4) | (((u) & 0x3) << 2) | 0x3)
-
-#define LAPDm_CTRL_is_I(ctrl) (((ctrl) & 0x1) == 0)
-#define LAPDm_CTRL_is_S(ctrl) (((ctrl) & 0x3) == 1)
-#define LAPDm_CTRL_is_U(ctrl) (((ctrl) & 0x3) == 3)
-
-#define LAPDm_CTRL_U_BITS(ctrl) ((((ctrl) & 0xC) >> 2) | ((ctrl) & 0xE0) >> 3)
-#define LAPDm_CTRL_PF_BIT(ctrl) (((ctrl) >> 4) & 0x1)
-
-#define LAPDm_CTRL_S_BITS(ctrl) (((ctrl) & 0xC) >> 2)
-
-#define LAPDm_CTRL_I_Ns(ctrl) (((ctrl) & 0xE) >> 1)
-#define LAPDm_CTRL_Nr(ctrl) (((ctrl) & 0xE0) >> 5)
-
-/* TS 04.06 Table 4 / Section 3.8.1 */
-#define LAPDm_U_SABM 0x7
-#define LAPDm_U_DM 0x3
-#define LAPDm_U_UI 0x0
-#define LAPDm_U_DISC 0x8
-#define LAPDm_U_UA 0xC
-
-#define LAPDm_S_RR 0x0
-#define LAPDm_S_RNR 0x1
-#define LAPDm_S_REJ 0x2
-
-#define LAPDm_LEN(len) ((len << 2) | 0x1)
-#define LAPDm_MORE 0x2
-
-/* TS 04.06 Section 5.8.3 */
-#define N201_AB_SACCH 18
-#define N201_AB_SDCCH 20
-#define N201_AB_FACCH 20
-#define N201_Bbis 23
-#define N201_Bter_SACCH 21
-#define N201_Bter_SDCCH 23
-#define N201_Bter_FACCH 23
-#define N201_B4 19
-
-/* 5.8.2.1 N200 during establish and release */
-#define N200_EST_REL 5
-/* 5.8.2.1 N200 during timer recovery state */
-#define N200_TR_SACCH 5
-#define N200_TR_SDCCH 23
-#define N200_TR_FACCH_FR 34
-#define N200_TR_EFACCH_FR 48
-#define N200_TR_FACCH_HR 29
-/* FIXME: this depends on chan type */
-#define N200 N200_TR_SACCH
-
-#define CR_MS2BS_CMD 0
-#define CR_MS2BS_RESP 1
-#define CR_BS2MS_CMD 1
-#define CR_BS2MS_RESP 0
-
-/* Set T200 to 1 Second (OpenBTS uses 900ms) */
-#define T200 1, 0
-
-/* k value for each SAPI */
-static uint8_t k_sapi[] = {1, 1, 1, 1, 1, 1, 1, 1};
-
-enum lapdm_format {
- LAPDm_FMT_A,
- LAPDm_FMT_B,
- LAPDm_FMT_Bbis,
- LAPDm_FMT_Bter,
- LAPDm_FMT_B4,
-};
-
-static void lapdm_t200_cb(void *data);
-static int rslms_send_i(struct lapdm_msg_ctx *mctx, int line);
-
-/* UTILITY FUNCTIONS */
-
-static inline uint8_t inc_mod8(uint8_t x)
-{
- return (x + 1) & 7;
-}
-
-static inline uint8_t add_mod8(uint8_t x, uint8_t y)
-{
- return (x + y) & 7;
-}
-
-static inline uint8_t sub_mod8(uint8_t x, uint8_t y)
-{
- return (x - y) & 7; /* handle negative results correctly */
-}
-
-static void lapdm_dl_init(struct lapdm_datalink *dl,
- struct lapdm_entity *entity)
-{
- memset(dl, 0, sizeof(*dl));
- INIT_LLIST_HEAD(&dl->send_queue);
- INIT_LLIST_HEAD(&dl->tx_queue);
- dl->state = LAPDm_STATE_IDLE;
- dl->t200.data = dl;
- dl->t200.cb = &lapdm_t200_cb;
- dl->entity = entity;
-}
-
-void lapdm_entity_init(struct lapdm_entity *le, enum lapdm_mode mode)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(le->datalink); i++)
- lapdm_dl_init(&le->datalink[i], le);
-
- lapdm_entity_set_mode(le, mode);
-}
-
-void lapdm_channel_init(struct lapdm_channel *lc, enum lapdm_mode mode)
-{
- lapdm_entity_init(&lc->lapdm_acch, mode);
- lapdm_entity_init(&lc->lapdm_dcch, mode);
-}
-
-
-static void lapdm_dl_flush_send(struct lapdm_datalink *dl)
-{
- struct msgb *msg;
-
- /* Flush send-queue */
- while ((msg = msgb_dequeue(&dl->send_queue)))
- msgb_free(msg);
-
- /* Clear send-buffer */
- if (dl->send_buffer) {
- msgb_free(dl->send_buffer);
- dl->send_buffer = NULL;
- }
-}
-
-static void lapdm_dl_flush_tx(struct lapdm_datalink *dl)
-{
- struct msgb *msg;
- unsigned int i;
-
- while ((msg = msgb_dequeue(&dl->tx_queue)))
- msgb_free(msg);
- for (i = 0; i < 8; i++)
- dl->tx_length[i] = 0;
-}
-
-void lapdm_entity_exit(struct lapdm_entity *le)
-{
- unsigned int i;
- struct lapdm_datalink *dl;
-
- for (i = 0; i < ARRAY_SIZE(le->datalink); i++) {
- dl = &le->datalink[i];
- lapdm_dl_flush_tx(dl);
- lapdm_dl_flush_send(dl);
- if (dl->rcv_buffer)
- msgb_free(dl->rcv_buffer);
- }
-}
-
-void lapdm_channel_exit(struct lapdm_channel *lc)
-{
- lapdm_entity_exit(&lc->lapdm_acch);
- lapdm_entity_exit(&lc->lapdm_dcch);
-}
-
-static void lapdm_dl_newstate(struct lapdm_datalink *dl, uint32_t state)
-{
- LOGP(DLAPDM, LOGL_INFO, "new state %s -> %s\n",
- lapdm_state_names[dl->state], lapdm_state_names[state]);
-
- dl->state = state;
-}
-
-static struct lapdm_datalink *datalink_for_sapi(struct lapdm_entity *le, uint8_t sapi)
-{
- switch (sapi) {
- case LAPDm_SAPI_NORMAL:
- return &le->datalink[0];
- case LAPDm_SAPI_SMS:
- return &le->datalink[1];
- default:
- return NULL;
- }
-}
-
-/* remove the L2 header from a MSGB */
-static inline unsigned char *msgb_pull_l2h(struct msgb *msg)
-{
- unsigned char *ret = msgb_pull(msg, msg->l3h - msg->l2h);
- msg->l2h = NULL;
- return ret;
-}
-
-/* Append padding (if required) */
-static void lapdm_pad_msgb(struct msgb *msg, uint8_t n201)
-{
- int pad_len = n201 - msgb_l2len(msg);
- uint8_t *data;
-
- if (pad_len < 0) {
- LOGP(DLAPDM, LOGL_ERROR,
- "cannot pad message that is already too big!\n");
- return;
- }
-
- data = msgb_put(msg, pad_len);
- memset(data, 0x2B, pad_len);
-}
-
-/* input function that L2 calls when sending messages up to L3 */
-static int rslms_sendmsg(struct msgb *msg, struct lapdm_entity *le)
-{
- if (!le->l3_cb) {
- msgb_free(msg);
- return -EIO;
- }
-
- /* call the layer2 message handler that is registered */
- return le->l3_cb(msg, le, le->l3_ctx);
-}
-
-/* write a frame into the tx queue */
-static int tx_ph_data_enqueue(struct lapdm_datalink *dl, struct msgb *msg,
- uint8_t chan_nr, uint8_t link_id, uint8_t n201)
-{
- struct lapdm_entity *le = dl->entity;
- struct osmo_phsap_prim pp;
-
- /* if there is a pending message, queue it */
- if (le->tx_pending || le->flags & LAPDM_ENT_F_POLLING_ONLY) {
- *msgb_push(msg, 1) = n201;
- *msgb_push(msg, 1) = link_id;
- *msgb_push(msg, 1) = chan_nr;
- msgb_enqueue(&dl->tx_queue, msg);
- return -EBUSY;
- }
-
- osmo_prim_init(&pp.oph, SAP_GSM_PH, PRIM_PH_DATA,
- PRIM_OP_REQUEST, msg);
- pp.u.data.chan_nr = chan_nr;
- pp.u.data.link_id = link_id;
-
- /* send the frame now */
- le->tx_pending = 0; /* disabled flow control */
- lapdm_pad_msgb(msg, n201);
-
- return le->l1_prim_cb(&pp.oph, le->l1_ctx);
-}
-
-static struct msgb *tx_dequeue_msgb(struct lapdm_entity *le)
-{
- struct lapdm_datalink *dl;
- int last = le->last_tx_dequeue;
- int i = last, n = ARRAY_SIZE(le->datalink);
- struct msgb *msg = NULL;
-
- /* round-robin dequeue */
- do {
- /* next */
- i = (i + 1) % n;
- dl = &le->datalink[i];
- if ((msg = msgb_dequeue(&dl->tx_queue)))
- break;
- } while (i != last);
-
- if (msg) {
- /* Set last dequeue position */
- le->last_tx_dequeue = i;
- }
-
- return msg;
-}
-
-/* dequeue a msg that's pending transmission via L1 and wrap it into
- * a osmo_phsap_prim */
-int lapdm_phsap_dequeue_prim(struct lapdm_entity *le, struct osmo_phsap_prim *pp)
-{
- struct msgb *msg;
- uint8_t n201;
-
- msg = tx_dequeue_msgb(le);
- if (!msg)
- return -ENODEV;
-
- /* if we have a message, send PH-DATA.req */
- osmo_prim_init(&pp->oph, SAP_GSM_PH, PRIM_PH_DATA,
- PRIM_OP_REQUEST, msg);
-
- /* Pull chan_nr and link_id */
- pp->u.data.chan_nr = *msg->data;
- msgb_pull(msg, 1);
- pp->u.data.link_id = *msg->data;
- msgb_pull(msg, 1);
- n201 = *msg->data;
- msgb_pull(msg, 1);
-
- /* Pad the frame, we can transmit now */
- lapdm_pad_msgb(msg, n201);
-
- return 0;
-}
-
-/* get next frame from the tx queue. because the ms has multiple datalinks,
- * each datalink's queue is read round-robin.
- */
-static int l2_ph_data_conf(struct msgb *msg, struct lapdm_entity *le)
-{
- struct osmo_phsap_prim pp;
-
- /* we may send again */
- le->tx_pending = 0;
-
- /* free confirm message */
- if (msg)
- msgb_free(msg);
-
- if (lapdm_phsap_dequeue_prim(le, &pp) < 0) {
- /* no message in all queues */
-
- /* If user didn't request PH-EMPTY_FRAME.req, abort */
- if (!(le->flags & LAPDM_ENT_F_EMPTY_FRAME))
- return 0;
-
- /* otherwise, send PH-EMPTY_FRAME.req */
- osmo_prim_init(&pp.oph, SAP_GSM_PH,
- PRIM_PH_EMPTY_FRAME,
- PRIM_OP_REQUEST, NULL);
- } else {
- le->tx_pending = 1;
- }
-
- return le->l1_prim_cb(&pp.oph, le->l1_ctx);
-}
-
-/* Create RSLms various RSLms messages */
-static int send_rslms_rll_l3(uint8_t msg_type, struct lapdm_msg_ctx *mctx,
- struct msgb *msg)
-{
- /* Add the RSL + RLL header */
- rsl_rll_push_l3(msg, msg_type, mctx->chan_nr, mctx->link_id, 1);
-
- /* send off the RSLms message to L3 */
- return rslms_sendmsg(msg, mctx->dl->entity);
-}
-
-/* Take a B4 format message from L1 and create RSLms UNIT DATA IND */
-static int send_rslms_rll_l3_ui(struct lapdm_msg_ctx *mctx, struct msgb *msg)
-{
- uint8_t l3_len = msg->tail - (uint8_t *)msgb_l3(msg);
- struct abis_rsl_rll_hdr *rllh;
-
- /* Add the RSL + RLL header */
- msgb_tv16_push(msg, RSL_IE_L3_INFO, l3_len);
- msgb_push(msg, 2 + 2);
- rsl_rll_push_hdr(msg, RSL_MT_UNIT_DATA_IND, mctx->chan_nr,
- mctx->link_id, 1);
- rllh = (struct abis_rsl_rll_hdr *)msgb_l2(msg);
-
- rllh->data[0] = RSL_IE_TIMING_ADVANCE;
- rllh->data[1] = mctx->ta_ind;
-
- rllh->data[2] = RSL_IE_MS_POWER;
- rllh->data[3] = mctx->tx_power_ind;
-
- return rslms_sendmsg(msg, mctx->dl->entity);
-}
-
-static int send_rll_simple(uint8_t msg_type, struct lapdm_msg_ctx *mctx)
-{
- struct msgb *msg;
-
- msg = rsl_rll_simple(msg_type, mctx->chan_nr, mctx->link_id, 1);
-
- /* send off the RSLms message to L3 */
- return rslms_sendmsg(msg, mctx->dl->entity);
-}
-
-static int rsl_rll_error(uint8_t cause, struct lapdm_msg_ctx *mctx)
-{
- struct msgb *msg;
-
- LOGP(DLAPDM, LOGL_NOTICE, "sending MDL-ERROR-IND %d\n", cause);
- msg = rsl_rll_simple(RSL_MT_ERROR_IND, mctx->chan_nr, mctx->link_id, 1);
- msg->l2h = msgb_put(msg, sizeof(struct abis_rsl_rll_hdr));
- msgb_tlv_put(msg, RSL_IE_RLM_CAUSE, 1, &cause);
- return rslms_sendmsg(msg, mctx->dl->entity);
-}
-
-static int check_length_ind(struct lapdm_msg_ctx *mctx, uint8_t length_ind)
-{
- if (!(length_ind & 0x01)) {
- /* G.4.1 If the EL bit is set to "0", an MDL-ERROR-INDICATION
- * primitive with cause "frame not implemented" is sent to the
- * mobile management entity. */
- LOGP(DLAPDM, LOGL_NOTICE,
- "we don't support multi-octet length\n");
- rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, mctx);
- return -EINVAL;
- }
- return 0;
-}
-
-static int lapdm_send_resend(struct lapdm_datalink *dl)
-{
- struct msgb *msg = msgb_alloc_headroom(23+10, 10, "LAPDm resend");
- int length;
-
- /* Resend SABM/DISC from tx_hist */
- length = dl->tx_length[0];
- msg->l2h = msgb_put(msg, length);
- memcpy(msg->l2h, dl->tx_hist[dl->V_send], length);
-
- return tx_ph_data_enqueue(dl, msg, dl->mctx.chan_nr, dl->mctx.link_id,
- dl->mctx.n201);
-}
-
-static int lapdm_send_ua(struct lapdm_msg_ctx *mctx, uint8_t len, uint8_t *data)
-{
- uint8_t sapi = mctx->link_id & 7;
- uint8_t f_bit = LAPDm_CTRL_PF_BIT(mctx->ctrl);
- struct msgb *msg = msgb_alloc_headroom(23+10, 10, "LAPDm UA");
- struct lapdm_entity *le = mctx->dl->entity;
-
- msg->l2h = msgb_put(msg, 3 + len);
- msg->l2h[0] = LAPDm_ADDR(LAPDm_LPD_NORMAL, sapi, le->cr.loc2rem.resp);
- msg->l2h[1] = LAPDm_CTRL_U(LAPDm_U_UA, f_bit);
- msg->l2h[2] = LAPDm_LEN(len);
- if (len)
- memcpy(msg->l2h + 3, data, len);
-
- return tx_ph_data_enqueue(mctx->dl, msg, mctx->chan_nr, mctx->link_id,
- mctx->n201);
-}
-
-static int lapdm_send_dm(struct lapdm_msg_ctx *mctx)
-{
- uint8_t sapi = mctx->link_id & 7;
- uint8_t f_bit = LAPDm_CTRL_PF_BIT(mctx->ctrl);
- struct msgb *msg = msgb_alloc_headroom(23+10, 10, "LAPDm DM");
- struct lapdm_entity *le = mctx->dl->entity;
-
- msg->l2h = msgb_put(msg, 3);
- msg->l2h[0] = LAPDm_ADDR(LAPDm_LPD_NORMAL, sapi, le->cr.loc2rem.resp);
- msg->l2h[1] = LAPDm_CTRL_U(LAPDm_U_DM, f_bit);
- msg->l2h[2] = 0;
-
- return tx_ph_data_enqueue(mctx->dl, msg, mctx->chan_nr, mctx->link_id,
- mctx->n201);
-}
-
-static int lapdm_send_rr(struct lapdm_msg_ctx *mctx, uint8_t f_bit)
-{
- uint8_t sapi = mctx->link_id & 7;
- struct msgb *msg = msgb_alloc_headroom(23+10, 10, "LAPDm RR");
- struct lapdm_entity *le = mctx->dl->entity;
-
- msg->l2h = msgb_put(msg, 3);
- msg->l2h[0] = LAPDm_ADDR(LAPDm_LPD_NORMAL, sapi, le->cr.loc2rem.resp);
- msg->l2h[1] = LAPDm_CTRL_S(mctx->dl->V_recv, LAPDm_S_RR, f_bit);
- msg->l2h[2] = LAPDm_LEN(0);
-
- return tx_ph_data_enqueue(mctx->dl, msg, mctx->chan_nr, mctx->link_id,
- mctx->n201);
-}
-
-static int lapdm_send_rnr(struct lapdm_msg_ctx *mctx, uint8_t f_bit)
-{
- uint8_t sapi = mctx->link_id & 7;
- struct msgb *msg = msgb_alloc_headroom(23+10, 10, "LAPDm RNR");
- struct lapdm_entity *le = mctx->dl->entity;
-
- msg->l2h = msgb_put(msg, 3);
- msg->l2h[0] = LAPDm_ADDR(LAPDm_LPD_NORMAL, sapi, le->cr.loc2rem.resp);
- msg->l2h[1] = LAPDm_CTRL_S(mctx->dl->V_recv, LAPDm_S_RNR, f_bit);
- msg->l2h[2] = LAPDm_LEN(0);
-
- return tx_ph_data_enqueue(mctx->dl, msg, mctx->chan_nr, mctx->link_id,
- mctx->n201);
-}
-
-static int lapdm_send_rej(struct lapdm_msg_ctx *mctx, uint8_t f_bit)
-{
- uint8_t sapi = mctx->link_id & 7;
- struct msgb *msg = msgb_alloc_headroom(23+10, 10, "LAPDm REJ");
- struct lapdm_entity *le = mctx->dl->entity;
-
- msg->l2h = msgb_put(msg, 3);
- msg->l2h[0] = LAPDm_ADDR(LAPDm_LPD_NORMAL, sapi, le->cr.loc2rem.resp);
- msg->l2h[1] = LAPDm_CTRL_S(mctx->dl->V_recv, LAPDm_S_REJ, f_bit);
- msg->l2h[2] = LAPDm_LEN(0);
-
- return tx_ph_data_enqueue(mctx->dl, msg, mctx->chan_nr, mctx->link_id,
- mctx->n201);
-}
-
-/* Timer callback on T200 expiry */
-static void lapdm_t200_cb(void *data)
-{
- struct lapdm_datalink *dl = data;
-
- LOGP(DLAPDM, LOGL_INFO, "lapdm_t200_cb(%p) state=%u\n", dl, dl->state);
-
- switch (dl->state) {
- case LAPDm_STATE_SABM_SENT:
- /* 5.4.1.3 */
- if (dl->retrans_ctr + 1 >= N200_EST_REL + 1) {
- /* send RELEASE INDICATION to L3 */
- send_rll_simple(RSL_MT_REL_IND, &dl->mctx);
- /* send MDL ERROR INIDCATION to L3 */
- rsl_rll_error(RLL_CAUSE_T200_EXPIRED, &dl->mctx);
- /* flush tx buffers */
- lapdm_dl_flush_tx(dl);
- /* go back to idle state */
- lapdm_dl_newstate(dl, LAPDm_STATE_IDLE);
- /* NOTE: we must not change any other states or buffers
- * and queues, since we may reconnect after handover
- * failure. the buffered messages is replaced there */
- break;
- }
- /* retransmit SABM command */
- lapdm_send_resend(dl);
- /* increment re-transmission counter */
- dl->retrans_ctr++;
- /* restart T200 (PH-READY-TO-SEND) */
- osmo_timer_schedule(&dl->t200, T200);
- break;
- case LAPDm_STATE_DISC_SENT:
- /* 5.4.4.3 */
- if (dl->retrans_ctr + 1 >= N200_EST_REL + 1) {
- /* send RELEASE INDICATION to L3 */
- send_rll_simple(RSL_MT_REL_CONF, &dl->mctx);
- /* send MDL ERROR INIDCATION to L3 */
- rsl_rll_error(RLL_CAUSE_T200_EXPIRED, &dl->mctx);
- /* flush buffers */
- lapdm_dl_flush_tx(dl);
- lapdm_dl_flush_send(dl);
- /* go back to idle state */
- lapdm_dl_newstate(dl, LAPDm_STATE_IDLE);
- /* NOTE: we must not change any other states or buffers
- * and queues, since we may reconnect after handover
- * failure. the buffered messages is replaced there */
- break;
- }
- /* retransmit DISC command */
- lapdm_send_resend(dl);
- /* increment re-transmission counter */
- dl->retrans_ctr++;
- /* restart T200 (PH-READY-TO-SEND) */
- osmo_timer_schedule(&dl->t200, T200);
- break;
- case LAPDm_STATE_MF_EST:
- /* 5.5.7 */
- dl->retrans_ctr = 0;
- lapdm_dl_newstate(dl, LAPDm_STATE_TIMER_RECOV);
- /* fall through */
- case LAPDm_STATE_TIMER_RECOV:
- dl->retrans_ctr++;
- if (dl->retrans_ctr < N200) {
- /* retransmit I frame (V_s-1) with P=1, if any */
- if (dl->tx_length[sub_mod8(dl->V_send, 1)]) {
- struct msgb *msg;
- int length;
-
- LOGP(DLAPDM, LOGL_INFO, "retransmit last frame "
- "V(S)=%d\n", sub_mod8(dl->V_send, 1));
- /* Create I frame (segment) from tx_hist */
- length = dl->tx_length[sub_mod8(dl->V_send, 1)];
- msg = msgb_alloc_headroom(23+10, 10, "LAPDm I");
- msg->l2h = msgb_put(msg, length);
- memcpy(msg->l2h,
- dl->tx_hist[sub_mod8(dl->V_send, 1)],
- length);
- msg->l2h[1] = LAPDm_CTRL_I(dl->V_recv,
- sub_mod8(dl->V_send, 1), 1); /* P=1 */
- tx_ph_data_enqueue(dl, msg, dl->mctx.chan_nr,
- dl->mctx.link_id, dl->mctx.n201);
- } else {
- /* OR send appropriate supervision frame with P=1 */
- if (!dl->own_busy && !dl->seq_err_cond) {
- lapdm_send_rr(&dl->mctx, 1);
- /* NOTE: In case of sequence error
- * condition, the REJ frame has been
- * transmitted when entering the
- * condition, so it has not be done
- * here
- */
- } else if (dl->own_busy) {
- lapdm_send_rnr(&dl->mctx, 1);
- } else {
- LOGP(DLAPDM, LOGL_INFO, "unhandled, "
- "pls. fix\n");
- }
- }
- /* restart T200 (PH-READY-TO-SEND) */
- osmo_timer_schedule(&dl->t200, T200);
- } else {
- /* send MDL ERROR INIDCATION to L3 */
- rsl_rll_error(RLL_CAUSE_T200_EXPIRED, &dl->mctx);
- }
- break;
- default:
- LOGP(DLAPDM, LOGL_INFO, "T200 expired in unexpected "
- "dl->state %u\n", dl->state);
- }
-}
-
-/* 5.5.3.1: Common function to acknowlege frames up to the given N(R) value */
-static void lapdm_acknowledge(struct lapdm_msg_ctx *mctx)
-{
- struct lapdm_datalink *dl = mctx->dl;
- uint8_t nr = LAPDm_CTRL_Nr(mctx->ctrl);
- int s = 0, rej = 0, t200_reset = 0;
- int i;
-
- /* supervisory frame ? */
- if (LAPDm_CTRL_is_S(mctx->ctrl))
- s = 1;
- /* REJ frame ? */
- if (s && LAPDm_CTRL_S_BITS(mctx->ctrl) == LAPDm_S_REJ)
- rej = 1;
-
- /* Flush all transmit buffers of acknowledged frames */
- for (i = dl->V_ack; i != nr; i = inc_mod8(i)) {
- if (dl->tx_length[i]) {
- dl->tx_length[i] = 0;
- LOGP(DLAPDM, LOGL_INFO, "ack frame %d\n", i);
- }
- }
-
- if (dl->state != LAPDm_STATE_TIMER_RECOV) {
- /* When not in the timer recovery condition, the data
- * link layer entity shall reset the timer T200 on
- * receipt of a valid I frame with N(R) higher than V(A),
- * or an REJ with an N(R) equal to V(A). */
- if ((!rej && nr != dl->V_ack)
- || (rej && nr == dl->V_ack)) {
- LOGP(DLAPDM, LOGL_INFO, "reset t200\n");
- t200_reset = 1;
- osmo_timer_del(&dl->t200);
- /* 5.5.3.1 Note 1 + 2 imply timer recovery cond. */
- }
- /* 5.7.4: N(R) sequence error
- * N(R) is called valid, if and only if
- * (N(R)-V(A)) mod 8 <= (V(S)-V(A)) mod 8.
- */
- if (sub_mod8(nr, dl->V_ack) > sub_mod8(dl->V_send, dl->V_ack)) {
- LOGP(DLAPDM, LOGL_NOTICE, "N(R) sequence error\n");
- rsl_rll_error(RLL_CAUSE_SEQ_ERR, mctx);
- }
- }
-
- /* V(A) shall be set to the value of N(R) */
- dl->V_ack = nr;
-
- /* If T200 has been reset by the receipt of an I, RR or RNR frame,
- * and if there are outstanding I frames, restart T200 */
- if (t200_reset && !rej) {
- if (dl->tx_length[dl->V_send - 1]) {
- LOGP(DLAPDM, LOGL_INFO, "start T200, due to unacked I "
- "frame(s)\n");
- osmo_timer_schedule(&dl->t200, T200);
- }
- }
-}
-
-/* L1 -> L2 */
-
-/* Receive a LAPDm U (Unnumbered) message from L1 */
-static int lapdm_rx_u(struct msgb *msg, struct lapdm_msg_ctx *mctx)
-{
- struct lapdm_datalink *dl = mctx->dl;
- struct lapdm_entity *le = dl->entity;
- uint8_t length;
- int rc;
- int rsl_msg;
-
- switch (LAPDm_CTRL_U_BITS(mctx->ctrl)) {
- case LAPDm_U_SABM:
- rsl_msg = RSL_MT_EST_IND;
-
- LOGP(DLAPDM, LOGL_INFO, "SABM received\n");
- /* 5.7.1 */
- dl->seq_err_cond = 0;
- /* G.2.2 Wrong value of the C/R bit */
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.resp) {
- LOGP(DLAPDM, LOGL_NOTICE, "SABM response error\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, mctx);
- return -EINVAL;
- }
-
- length = msg->l2h[2] >> 2;
- /* G.4.5 If SABM is received with L>N201 or with M bit
- * set, AN MDL-ERROR-INDICATION is sent to MM.
- */
- if ((msg->l2h[2] & LAPDm_MORE) || length + 3 > mctx->n201) {
- LOGP(DLAPDM, LOGL_NOTICE, "SABM too large error\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_UFRM_INC_PARAM, mctx);
- return -EIO;
- }
-
- /* Must be Format B */
- rc = check_length_ind(mctx, msg->l2h[2]);
- if (rc < 0) {
- msgb_free(msg);
- return rc;
- }
- switch (dl->state) {
- case LAPDm_STATE_IDLE:
- /* Set chan_nr and link_id for established connection */
- memset(&dl->mctx, 0, sizeof(dl->mctx));
- dl->mctx.dl = dl;
- dl->mctx.chan_nr = mctx->chan_nr;
- dl->mctx.link_id = mctx->link_id;
- dl->mctx.n201 = mctx->n201;
- break;
- case LAPDm_STATE_MF_EST:
- if (length == 0) {
- rsl_msg = RSL_MT_EST_CONF;
- break;
- }
- LOGP(DLAPDM, LOGL_INFO, "SABM command, multiple "
- "frame established state\n");
- /* check for contention resoultion */
- if (dl->tx_hist[0][2] >> 2) {
- LOGP(DLAPDM, LOGL_NOTICE, "SABM not allowed "
- "during contention resolution\n");
- rsl_rll_error(RLL_CAUSE_SABM_INFO_NOTALL, mctx);
- }
- msgb_free(msg);
- return 0;
- case LAPDm_STATE_DISC_SENT:
- /* 5.4.6.2 send DM with F=P */
- lapdm_send_dm(mctx);
- /* reset Timer T200 */
- osmo_timer_del(&dl->t200);
- msgb_free(msg);
- return send_rll_simple(RSL_MT_REL_CONF, mctx);
- default:
- lapdm_send_ua(mctx, length, msg->l2h + 3);
- msgb_free(msg);
- return 0;
- }
- /* send UA response */
- lapdm_send_ua(mctx, length, msg->l2h + 3);
- /* set Vs, Vr and Va to 0 */
- dl->V_send = dl->V_recv = dl->V_ack = 0;
- /* clear tx_hist */
- dl->tx_length[0] = 0;
- /* enter multiple-frame-established state */
- lapdm_dl_newstate(dl, LAPDm_STATE_MF_EST);
- /* send notification to L3 */
- if (length == 0) {
- /* 5.4.1.2 Normal establishment procedures */
- rc = send_rll_simple(rsl_msg, mctx);
- msgb_free(msg);
- } else {
- /* 5.4.1.4 Contention resolution establishment */
- msg->l3h = msg->l2h + 3;
- msgb_pull_l2h(msg);
- rc = send_rslms_rll_l3(rsl_msg, mctx, msg);
- }
- break;
- case LAPDm_U_DM:
- LOGP(DLAPDM, LOGL_INFO, "DM received\n");
- /* G.2.2 Wrong value of the C/R bit */
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.cmd) {
- LOGP(DLAPDM, LOGL_NOTICE, "DM command error\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, mctx);
- return -EINVAL;
- }
- if (!LAPDm_CTRL_PF_BIT(mctx->ctrl)) {
- /* 5.4.1.2 DM responses with the F bit set to "0"
- * shall be ignored.
- */
- msgb_free(msg);
- return 0;
- }
- switch (dl->state) {
- case LAPDm_STATE_SABM_SENT:
- break;
- case LAPDm_STATE_MF_EST:
- if (LAPDm_CTRL_PF_BIT(mctx->ctrl) == 1) {
- LOGP(DLAPDM, LOGL_INFO, "unsolicited DM "
- "response\n");
- rsl_rll_error(RLL_CAUSE_UNSOL_DM_RESP, mctx);
- } else {
- LOGP(DLAPDM, LOGL_INFO, "unsolicited DM "
- "response, multiple frame established "
- "state\n");
- rsl_rll_error(RLL_CAUSE_UNSOL_DM_RESP_MF, mctx);
- }
- msgb_free(msg);
- return 0;
- case LAPDm_STATE_TIMER_RECOV:
- /* DM is normal in case PF = 1 */
- if (LAPDm_CTRL_PF_BIT(mctx->ctrl) == 0) {
- LOGP(DLAPDM, LOGL_INFO, "unsolicited DM "
- "response, multiple frame established "
- "state\n");
- rsl_rll_error(RLL_CAUSE_UNSOL_DM_RESP_MF, mctx);
- msgb_free(msg);
- return 0;
- }
- break;
- case LAPDm_STATE_DISC_SENT:
- /* reset Timer T200 */
- osmo_timer_del(&dl->t200);
- /* go to idle state */
- lapdm_dl_newstate(dl, LAPDm_STATE_IDLE);
- rc = send_rll_simple(RSL_MT_REL_CONF, mctx);
- msgb_free(msg);
- return 0;
- case LAPDm_STATE_IDLE:
- /* 5.4.5 all other frame types shall be discarded */
- default:
- LOGP(DLAPDM, LOGL_INFO, "unsolicited DM response! "
- "(discarding)\n");
- msgb_free(msg);
- return 0;
- }
- /* reset T200 */
- osmo_timer_del(&dl->t200);
- rc = send_rll_simple(RSL_MT_REL_IND, mctx);
- msgb_free(msg);
- break;
- case LAPDm_U_UI:
- LOGP(DLAPDM, LOGL_INFO, "UI received\n");
- /* G.2.2 Wrong value of the C/R bit */
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.resp) {
- LOGP(DLAPDM, LOGL_NOTICE, "UI indicates response "
- "error\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, mctx);
- return -EINVAL;
- }
-
- length = msg->l2h[2] >> 2;
- /* FIXME: G.4.5 If UI is received with L>N201 or with M bit
- * set, AN MDL-ERROR-INDICATION is sent to MM.
- */
-
- if (mctx->lapdm_fmt == LAPDm_FMT_B4) {
- length = N201_B4;
- msg->l3h = msg->l2h + 2;
- } else {
- rc = check_length_ind(mctx, msg->l2h[2]);
- if (rc < 0) {
- msgb_free(msg);
- return rc;
- }
- length = msg->l2h[2] >> 2;
- msg->l3h = msg->l2h + 3;
- }
- /* do some length checks */
- if (length == 0) {
- /* 5.3.3 UI frames received with the length indicator
- * set to "0" shall be ignored
- */
- LOGP(DLAPDM, LOGL_INFO, "length=0 (discarding)\n");
- msgb_free(msg);
- return 0;
- }
- switch (LAPDm_ADDR_SAPI(mctx->addr)) {
- case LAPDm_SAPI_NORMAL:
- case LAPDm_SAPI_SMS:
- break;
- default:
- /* 5.3.3 UI frames with invalid SAPI values shall be
- * discarded
- */
- LOGP(DLAPDM, LOGL_INFO, "sapi=%u (discarding)\n",
- LAPDm_ADDR_SAPI(mctx->addr));
- msgb_free(msg);
- return 0;
- }
- msgb_pull_l2h(msg);
- rc = send_rslms_rll_l3_ui(mctx, msg);
- break;
- case LAPDm_U_DISC:
- rsl_msg = RSL_MT_REL_IND;
-
- LOGP(DLAPDM, LOGL_INFO, "DISC received\n");
- /* flush buffers */
- lapdm_dl_flush_tx(dl);
- lapdm_dl_flush_send(dl);
- /* 5.7.1 */
- dl->seq_err_cond = 0;
- /* G.2.2 Wrong value of the C/R bit */
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.resp) {
- LOGP(DLAPDM, LOGL_NOTICE, "DISC response error\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, mctx);
- return -EINVAL;
- }
- length = msg->l2h[2] >> 2;
- if (length > 0 || msg->l2h[2] & 0x02) {
- /* G.4.4 If a DISC or DM frame is received with L>0 or
- * with the M bit set to "1", an MDL-ERROR-INDICATION
- * primitive with cause "U frame with incorrect
- * parameters" is sent to the mobile management entity.
- */
- LOGP(DLAPDM, LOGL_NOTICE,
- "U frame iwth incorrect parameters ");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_UFRM_INC_PARAM, mctx);
- return -EIO;
- }
- switch (dl->state) {
- case LAPDm_STATE_IDLE:
- LOGP(DLAPDM, LOGL_INFO, "DISC in idle state\n");
- /* send DM with F=P */
- msgb_free(msg);
- return lapdm_send_dm(mctx);
- case LAPDm_STATE_SABM_SENT:
- LOGP(DLAPDM, LOGL_INFO, "DISC in SABM state\n");
- /* 5.4.6.2 send DM with F=P */
- lapdm_send_dm(mctx);
- /* reset Timer T200 */
- osmo_timer_del(&dl->t200);
- msgb_free(msg);
- return send_rll_simple(RSL_MT_REL_IND, mctx);
- case LAPDm_STATE_MF_EST:
- case LAPDm_STATE_TIMER_RECOV:
- LOGP(DLAPDM, LOGL_INFO, "DISC in est state\n");
- break;
- case LAPDm_STATE_DISC_SENT:
- LOGP(DLAPDM, LOGL_INFO, "DISC in disc state\n");
- rsl_msg = RSL_MT_REL_CONF;
- break;
- default:
- lapdm_send_ua(mctx, length, msg->l2h + 3);
- msgb_free(msg);
- return 0;
- }
- /* send UA response */
- lapdm_send_ua(mctx, length, msg->l2h + 3);
- /* reset Timer T200 */
- osmo_timer_del(&dl->t200);
- /* enter idle state */
- lapdm_dl_newstate(dl, LAPDm_STATE_IDLE);
- /* send notification to L3 */
- rc = send_rll_simple(rsl_msg, mctx);
- msgb_free(msg);
- break;
- case LAPDm_U_UA:
- LOGP(DLAPDM, LOGL_INFO, "UA received\n");
- /* G.2.2 Wrong value of the C/R bit */
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.cmd) {
- LOGP(DLAPDM, LOGL_NOTICE, "UA indicates command "
- "error\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, mctx);
- return -EINVAL;
- }
-
- length = msg->l2h[2] >> 2;
- /* G.4.5 If UA is received with L>N201 or with M bit
- * set, AN MDL-ERROR-INDICATION is sent to MM.
- */
- if ((msg->l2h[2] & LAPDm_MORE) || length + 3 > mctx->n201) {
- LOGP(DLAPDM, LOGL_NOTICE, "UA too large error\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_UFRM_INC_PARAM, mctx);
- return -EIO;
- }
-
- if (!LAPDm_CTRL_PF_BIT(mctx->ctrl)) {
- /* 5.4.1.2 A UA response with the F bit set to "0"
- * shall be ignored.
- */
- LOGP(DLAPDM, LOGL_INFO, "F=0 (discarding)\n");
- msgb_free(msg);
- return 0;
- }
- switch (dl->state) {
- case LAPDm_STATE_SABM_SENT:
- break;
- case LAPDm_STATE_MF_EST:
- case LAPDm_STATE_TIMER_RECOV:
- LOGP(DLAPDM, LOGL_INFO, "unsolicited UA response! "
- "(discarding)\n");
- rsl_rll_error(RLL_CAUSE_UNSOL_UA_RESP, mctx);
- msgb_free(msg);
- return 0;
- case LAPDm_STATE_DISC_SENT:
- LOGP(DLAPDM, LOGL_INFO, "UA in disconnect state\n");
- /* reset Timer T200 */
- osmo_timer_del(&dl->t200);
- /* go to idle state */
- lapdm_dl_newstate(dl, LAPDm_STATE_IDLE);
- rc = send_rll_simple(RSL_MT_REL_CONF, mctx);
- msgb_free(msg);
- return 0;
- case LAPDm_STATE_IDLE:
- /* 5.4.5 all other frame types shall be discarded */
- default:
- LOGP(DLAPDM, LOGL_INFO, "unsolicited UA response! "
- "(discarding)\n");
- msgb_free(msg);
- return 0;
- }
- LOGP(DLAPDM, LOGL_INFO, "UA in SABM state\n");
- /* reset Timer T200 */
- osmo_timer_del(&dl->t200);
- /* compare UA with SABME if contention resolution is applied */
- if (dl->tx_hist[0][2] >> 2) {
- rc = check_length_ind(mctx, msg->l2h[2]);
- if (rc < 0) {
- rc = send_rll_simple(RSL_MT_REL_IND, mctx);
- msgb_free(msg);
- /* go to idle state */
- lapdm_dl_newstate(dl, LAPDm_STATE_IDLE);
- return 0;
- }
- length = msg->l2h[2] >> 2;
- if (length != (dl->tx_hist[0][2] >> 2)
- || !!memcmp(dl->tx_hist[0] + 3, msg->l2h + 3,
- length)) {
- LOGP(DLAPDM, LOGL_INFO, "**** UA response "
- "mismatches ****\n");
- rc = send_rll_simple(RSL_MT_REL_IND, mctx);
- msgb_free(msg);
- /* go to idle state */
- lapdm_dl_newstate(dl, LAPDm_STATE_IDLE);
- return 0;
- }
- }
- /* set Vs, Vr and Va to 0 */
- dl->V_send = dl->V_recv = dl->V_ack = 0;
- /* clear tx_hist */
- dl->tx_length[0] = 0;
- /* enter multiple-frame-established state */
- lapdm_dl_newstate(dl, LAPDm_STATE_MF_EST);
- /* send outstanding frames, if any (resume / reconnect) */
- rslms_send_i(mctx, __LINE__);
- /* send notification to L3 */
- rc = send_rll_simple(RSL_MT_EST_CONF, mctx);
- msgb_free(msg);
- break;
- default:
- /* G.3.1 */
- LOGP(DLAPDM, LOGL_NOTICE, "Unnumbered frame not allowed.\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, mctx);
- return -EINVAL;
- }
- return rc;
-}
-
-/* Receive a LAPDm S (Supervisory) message from L1 */
-static int lapdm_rx_s(struct msgb *msg, struct lapdm_msg_ctx *mctx)
-{
- struct lapdm_datalink *dl = mctx->dl;
- struct lapdm_entity *le = dl->entity;
- uint8_t length;
-
- length = msg->l2h[2] >> 2;
- if (length > 0 || msg->l2h[2] & 0x02) {
- /* G.4.3 If a supervisory frame is received with L>0 or
- * with the M bit set to "1", an MDL-ERROR-INDICATION
- * primitive with cause "S frame with incorrect
- * parameters" is sent to the mobile management entity. */
- LOGP(DLAPDM, LOGL_NOTICE,
- "S frame with incorrect parameters\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_SFRM_INC_PARAM, mctx);
- return -EIO;
- }
-
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.resp
- && LAPDm_CTRL_PF_BIT(mctx->ctrl)
- && dl->state != LAPDm_STATE_TIMER_RECOV) {
- /* 5.4.2.2: Inidcate error on supervisory reponse F=1 */
- LOGP(DLAPDM, LOGL_NOTICE, "S frame response with F=1 error\n");
- rsl_rll_error(RLL_CAUSE_UNSOL_SPRV_RESP, mctx);
- }
-
- switch (dl->state) {
- case LAPDm_STATE_IDLE:
- /* if P=1, respond DM with F=1 (5.2.2) */
- /* 5.4.5 all other frame types shall be discarded */
- if (LAPDm_CTRL_PF_BIT(mctx->ctrl))
- lapdm_send_dm(mctx); /* F=P */
- /* fall though */
- case LAPDm_STATE_SABM_SENT:
- case LAPDm_STATE_DISC_SENT:
- LOGP(DLAPDM, LOGL_NOTICE, "S frame ignored in this state\n");
- msgb_free(msg);
- return 0;
- }
- switch (LAPDm_CTRL_S_BITS(mctx->ctrl)) {
- case LAPDm_S_RR:
- LOGP(DLAPDM, LOGL_INFO, "RR received\n");
- /* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
- lapdm_acknowledge(mctx);
-
- /* 5.5.3.2 */
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.cmd
- && LAPDm_CTRL_PF_BIT(mctx->ctrl)) {
- if (!dl->own_busy && !dl->seq_err_cond) {
- LOGP(DLAPDM, LOGL_NOTICE, "RR frame command "
- "with polling bit set and we are not "
- "busy, so we reply with RR frame\n");
- lapdm_send_rr(mctx, 1);
- /* NOTE: In case of sequence error condition,
- * the REJ frame has been transmitted when
- * entering the condition, so it has not be
- * done here
- */
- } else if (dl->own_busy) {
- LOGP(DLAPDM, LOGL_NOTICE, "RR frame command "
- "with polling bit set and we are busy, "
- "so we reply with RR frame\n");
- lapdm_send_rnr(mctx, 1);
- }
- } else if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.resp
- && LAPDm_CTRL_PF_BIT(mctx->ctrl)
- && dl->state == LAPDm_STATE_TIMER_RECOV) {
- LOGP(DLAPDM, LOGL_INFO, "RR response with F==1, "
- "and we are in timer recovery state, so "
- "we leave that state\n");
- /* V(S) to the N(R) in the RR frame */
- dl->V_send = LAPDm_CTRL_Nr(mctx->ctrl);
- /* reset Timer T200 */
- osmo_timer_del(&dl->t200);
- /* 5.5.7 Clear timer recovery condition */
- lapdm_dl_newstate(dl, LAPDm_STATE_MF_EST);
- }
- /* Send message, if possible due to acknowledged data */
- rslms_send_i(mctx, __LINE__);
-
- break;
- case LAPDm_S_RNR:
- LOGP(DLAPDM, LOGL_INFO, "RNR received\n");
- /* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
- lapdm_acknowledge(mctx);
-
- /* 5.5.5 */
- /* Set peer receiver busy condition */
- dl->peer_busy = 1;
-
- if (LAPDm_CTRL_PF_BIT(mctx->ctrl)) {
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.cmd) {
- if (!dl->own_busy) {
- LOGP(DLAPDM, LOGL_INFO, "RNR poll "
- "command and we are not busy, "
- "so we reply with RR final "
- "response\n");
- /* Send RR with F=1 */
- lapdm_send_rr(mctx, 1);
- } else {
- LOGP(DLAPDM, LOGL_INFO, "RNR poll "
- "command and we are busy, so "
- "we reply with RNR final "
- "response\n");
- /* Send RNR with F=1 */
- lapdm_send_rnr(mctx, 1);
- }
- } else if (dl->state == LAPDm_STATE_TIMER_RECOV) {
- LOGP(DLAPDM, LOGL_INFO, "RNR poll response "
- "and we in timer recovery state, so "
- "we leave that state\n");
- /* 5.5.7 Clear timer recovery condition */
- lapdm_dl_newstate(dl, LAPDm_STATE_MF_EST);
- /* V(S) to the N(R) in the RNR frame */
- dl->V_send = LAPDm_CTRL_Nr(mctx->ctrl);
- }
- } else
- LOGP(DLAPDM, LOGL_INFO, "RNR not polling/final state "
- "received\n");
-
- /* Send message, if possible due to acknowledged data */
- rslms_send_i(mctx, __LINE__);
-
- break;
- case LAPDm_S_REJ:
- LOGP(DLAPDM, LOGL_INFO, "REJ received\n");
- /* 5.5.3.1: Acknowlege all tx frames up the the N(R)-1 */
- lapdm_acknowledge(mctx);
-
- /* 5.5.4.1 */
- if (dl->state != LAPDm_STATE_TIMER_RECOV) {
- /* Clear an existing peer receiver busy condition */
- dl->peer_busy = 0;
- /* V(S) and V(A) to the N(R) in the REJ frame */
- dl->V_send = dl->V_ack = LAPDm_CTRL_Nr(mctx->ctrl);
- /* reset Timer T200 */
- osmo_timer_del(&dl->t200);
- /* 5.5.3.2 */
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.cmd
- && LAPDm_CTRL_PF_BIT(mctx->ctrl)) {
- if (!dl->own_busy && !dl->seq_err_cond) {
- LOGP(DLAPDM, LOGL_INFO, "REJ poll "
- "command not in timer recovery "
- "state and not in own busy "
- "condition received, so we "
- "respond with RR final "
- "response\n");
- lapdm_send_rr(mctx, 1);
- /* NOTE: In case of sequence error
- * condition, the REJ frame has been
- * transmitted when entering the
- * condition, so it has not be done
- * here
- */
- } else if (dl->own_busy) {
- LOGP(DLAPDM, LOGL_INFO, "REJ poll "
- "command not in timer recovery "
- "state and in own busy "
- "condition received, so we "
- "respond with RNR final "
- "response\n");
- lapdm_send_rnr(mctx, 1);
- }
- } else
- LOGP(DLAPDM, LOGL_INFO, "REJ response or not "
- "polling command not in timer recovery "
- "state received\n");
- /* send MDL ERROR INIDCATION to L3 */
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.resp
- && LAPDm_CTRL_PF_BIT(mctx->ctrl)) {
- rsl_rll_error(RLL_CAUSE_UNSOL_SPRV_RESP, mctx);
- }
-
- } else if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.resp
- && LAPDm_CTRL_PF_BIT(mctx->ctrl)) {
- LOGP(DLAPDM, LOGL_INFO, "REJ poll response in timer "
- "recovery state received\n");
- /* Clear an existing peer receiver busy condition */
- dl->peer_busy = 0;
- /* 5.5.7 Clear timer recovery condition */
- lapdm_dl_newstate(dl, LAPDm_STATE_MF_EST);
- /* V(S) and V(A) to the N(R) in the REJ frame */
- dl->V_send = dl->V_ack = LAPDm_CTRL_Nr(mctx->ctrl);
- /* reset Timer T200 */
- osmo_timer_del(&dl->t200);
- } else {
- /* Clear an existing peer receiver busy condition */
- dl->peer_busy = 0;
- /* V(S) and V(A) to the N(R) in the REJ frame */
- dl->V_send = dl->V_ack = LAPDm_CTRL_Nr(mctx->ctrl);
- /* 5.5.3.2 */
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.cmd
- && LAPDm_CTRL_PF_BIT(mctx->ctrl)) {
- if (!dl->own_busy && !dl->seq_err_cond) {
- LOGP(DLAPDM, LOGL_INFO, "REJ poll "
- "command in timer recovery "
- "state and not in own busy "
- "condition received, so we "
- "respond with RR final "
- "response\n");
- lapdm_send_rr(mctx, 1);
- /* NOTE: In case of sequence error
- * condition, the REJ frame has been
- * transmitted when entering the
- * condition, so it has not be done
- * here
- */
- } else if (dl->own_busy) {
- LOGP(DLAPDM, LOGL_INFO, "REJ poll "
- "command in timer recovery "
- "state and in own busy "
- "condition received, so we "
- "respond with RNR final "
- "response\n");
- lapdm_send_rnr(mctx, 1);
- }
- } else
- LOGP(DLAPDM, LOGL_INFO, "REJ response or not "
- "polling command in timer recovery "
- "state received\n");
- }
-
- /* FIXME: 5.5.4.2 2) */
-
- /* Send message, if possible due to acknowledged data */
- rslms_send_i(mctx, __LINE__);
-
- break;
- default:
- /* G.3.1 */
- LOGP(DLAPDM, LOGL_NOTICE, "Supervisory frame not allowed.\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, mctx);
- return -EINVAL;
- }
- msgb_free(msg);
- return 0;
-}
-
-/* Receive a LAPDm I (Information) message from L1 */
-static int lapdm_rx_i(struct msgb *msg, struct lapdm_msg_ctx *mctx)
-{
- struct lapdm_datalink *dl = mctx->dl;
- struct lapdm_entity *le = dl->entity;
- //uint8_t nr = LAPDm_CTRL_Nr(mctx->ctrl);
- uint8_t ns = LAPDm_CTRL_I_Ns(mctx->ctrl);
- uint8_t length;
- int rc;
-
- LOGP(DLAPDM, LOGL_NOTICE, "I received\n");
-
- /* G.2.2 Wrong value of the C/R bit */
- if (LAPDm_ADDR_CR(mctx->addr) == le->cr.rem2loc.resp) {
- LOGP(DLAPDM, LOGL_NOTICE, "I frame response not allowed\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, mctx);
- return -EINVAL;
- }
-
- length = msg->l2h[2] >> 2;
- if (length == 0 || length + 3 > mctx->n201) {
- /* G.4.2 If the length indicator of an I frame is set
- * to a numerical value L>N201 or L=0, an MDL-ERROR-INDICATION
- * primitive with cause "I frame with incorrect length"
- * is sent to the mobile management entity. */
- LOGP(DLAPDM, LOGL_NOTICE, "I frame length not allowed\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_IFRM_INC_LEN, mctx);
- return -EIO;
- }
-
- /* G.4.2 If the numerical value of L is L<N201 and the M
- * bit is set to "1", then an MDL-ERROR-INDICATION primitive with
- * cause "I frame with incorrect use of M bit" is sent to the
- * mobile management entity. */
- if ((msg->l2h[2] & LAPDm_MORE) && length + 3 < mctx->n201) {
- LOGP(DLAPDM, LOGL_NOTICE, "I frame with M bit too short\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_IFRM_INC_MBITS, mctx);
- return -EIO;
- }
-
- switch (dl->state) {
- case LAPDm_STATE_IDLE:
- /* if P=1, respond DM with F=1 (5.2.2) */
- /* 5.4.5 all other frame types shall be discarded */
- if (LAPDm_CTRL_PF_BIT(mctx->ctrl))
- lapdm_send_dm(mctx); /* F=P */
- /* fall though */
- case LAPDm_STATE_SABM_SENT:
- case LAPDm_STATE_DISC_SENT:
- LOGP(DLAPDM, LOGL_NOTICE, "I frame ignored in this state\n");
- msgb_free(msg);
- return 0;
- }
-
- /* 5.7.1: N(s) sequence error */
- if (ns != dl->V_recv) {
- LOGP(DLAPDM, LOGL_NOTICE, "N(S) sequence error: N(S)=%u, "
- "V(R)=%u\n", ns, dl->V_recv);
- /* discard data */
- msgb_free(msg);
- if (!dl->seq_err_cond) {
- /* FIXME: help me understand what exactly todo here
- dl->seq_err_cond = 1;
- */
- lapdm_send_rej(mctx, LAPDm_CTRL_PF_BIT(mctx->ctrl));
- } else {
- }
- return -EIO;
- }
- dl->seq_err_cond = 0;
-
- /* Increment receiver state */
- dl->V_recv = inc_mod8(dl->V_recv);
- LOGP(DLAPDM, LOGL_NOTICE, "incrementing V(R) to %u\n", dl->V_recv);
-
- /* 5.5.3.1: Acknowlege all transmitted frames up the the N(R)-1 */
- lapdm_acknowledge(mctx); /* V(A) is also set here */
-
- /* Only if we are not in own receiver busy condition */
- if (!dl->own_busy) {
- /* if the frame carries a complete segment */
- if (!(msg->l2h[2] & LAPDm_MORE)
- && !dl->rcv_buffer) {
- LOGP(DLAPDM, LOGL_INFO, "message in single I frame\n");
- /* send a DATA INDICATION to L3 */
- msg->l3h = msg->l2h + 3;
- msgb_pull_l2h(msg);
- msg->len = length;
- msg->tail = msg->data + length;
- rc = send_rslms_rll_l3(RSL_MT_DATA_IND, mctx, msg);
- } else {
- /* create rcv_buffer */
- if (!dl->rcv_buffer) {
- LOGP(DLAPDM, LOGL_INFO, "message in multiple I "
- "frames (first message)\n");
- dl->rcv_buffer = msgb_alloc_headroom(200+56, 56,
- "LAPDm RX");
- dl->rcv_buffer->l3h = dl->rcv_buffer->data;
- }
- /* concat. rcv_buffer */
- if (msgb_l3len(dl->rcv_buffer) + length > 200) {
- LOGP(DLAPDM, LOGL_NOTICE, "Received frame "
- "overflow!\n");
- } else {
- memcpy(msgb_put(dl->rcv_buffer, length),
- msg->l2h + 3, length);
- }
- /* if the last segment was received */
- if (!(msg->l2h[2] & LAPDm_MORE)) {
- LOGP(DLAPDM, LOGL_INFO, "message in multiple I "
- "frames (last message)\n");
- rc = send_rslms_rll_l3(RSL_MT_DATA_IND, mctx,
- dl->rcv_buffer);
- dl->rcv_buffer = NULL;
- } else
- LOGP(DLAPDM, LOGL_INFO, "message in multiple I "
- "frames (next message)\n");
- msgb_free(msg);
-
- }
- } else
- LOGP(DLAPDM, LOGL_INFO, "I frame ignored during own receiver "
- "busy condition\n");
-
- /* Check for P bit */
- if (LAPDm_CTRL_PF_BIT(mctx->ctrl)) {
- /* 5.5.2.1 */
- /* check if we are not in own receiver busy */
- if (!dl->own_busy) {
- LOGP(DLAPDM, LOGL_INFO, "we are not busy, send RR\n");
- /* Send RR with F=1 */
- rc = lapdm_send_rr(mctx, 1);
- } else {
- LOGP(DLAPDM, LOGL_INFO, "we are busy, send RNR\n");
- /* Send RNR with F=1 */
- rc = lapdm_send_rnr(mctx, 1);
- }
- } else {
- /* 5.5.2.2 */
- /* check if we are not in own receiver busy */
- if (!dl->own_busy) {
- /* NOTE: V(R) is already set above */
- rc = rslms_send_i(mctx, __LINE__);
- if (rc) {
- LOGP(DLAPDM, LOGL_INFO, "we are not busy and "
- "have no pending data, send RR\n");
- /* Send RR with F=0 */
- return lapdm_send_rr(mctx, 0);
- }
- /* all I or one RR is sent, we are done */
- return 0;
- } else {
- LOGP(DLAPDM, LOGL_INFO, "we are busy, send RNR\n");
- /* Send RNR with F=0 */
- rc = lapdm_send_rnr(mctx, 0);
- }
- }
-
- /* Send message, if possible due to acknowledged data */
- rslms_send_i(mctx, __LINE__);
-
- return rc;
-}
-
-/* Receive a LAPDm message from L1 */
-static int lapdm_ph_data_ind(struct msgb *msg, struct lapdm_msg_ctx *mctx)
-{
- int rc;
-
- /* G.2.3 EA bit set to "0" is not allowed in GSM */
- if (!LAPDm_ADDR_EA(mctx->addr)) {
- LOGP(DLAPDM, LOGL_NOTICE, "EA bit 0 is not allowed in GSM\n");
- msgb_free(msg);
- rsl_rll_error(RLL_CAUSE_FRM_UNIMPL, mctx);
- return -EINVAL;
- }
-
- if (LAPDm_CTRL_is_U(mctx->ctrl))
- rc = lapdm_rx_u(msg, mctx);
- else if (LAPDm_CTRL_is_S(mctx->ctrl))
- rc = lapdm_rx_s(msg, mctx);
- else if (LAPDm_CTRL_is_I(mctx->ctrl))
- rc = lapdm_rx_i(msg, mctx);
- else {
- LOGP(DLAPDM, LOGL_NOTICE, "unknown LAPDm format\n");
- msgb_free(msg);
- rc = -EINVAL;
- }
- return rc;
-}
-
-/* input into layer2 (from layer 1) */
-static int l2_ph_data_ind(struct msgb *msg, struct lapdm_entity *le, uint8_t chan_nr, uint8_t link_id)
-{
- uint8_t cbits = chan_nr >> 3;
- uint8_t sapi = link_id & 7;
- struct lapdm_msg_ctx mctx;
- int rc = 0;
-
- /* when we reach here, we have a msgb with l2h pointing to the raw
- * 23byte mac block. The l1h has already been purged. */
-
- mctx.dl = datalink_for_sapi(le, sapi);
- mctx.chan_nr = chan_nr;
- mctx.link_id = link_id;
- mctx.addr = mctx.ctrl = 0;
-
- /* G.2.1 No action schall be taken on frames containing an unallocated
- * SAPI.
- */
- if (!mctx.dl) {
- LOGP(DLAPDM, LOGL_NOTICE, "Received frame for unsupported "
- "SAPI %d!\n", sapi);
- return -EINVAL;
- msgb_free(msg);
- return -EIO;
- }
-
- /* check for L1 chan_nr/link_id and determine LAPDm hdr format */
- if (cbits == 0x10 || cbits == 0x12) {
- /* Format Bbis is used on BCCH and CCCH(PCH, NCH and AGCH) */
- mctx.lapdm_fmt = LAPDm_FMT_Bbis;
- mctx.n201 = N201_Bbis;
- } else {
- if (mctx.link_id & 0x40) {
- /* It was received from network on SACCH, thus
- * lapdm_fmt must be B4 */
- mctx.lapdm_fmt = LAPDm_FMT_B4;
- mctx.n201 = N201_B4;
- LOGP(DLAPDM, LOGL_INFO, "fmt=B4\n");
- /* SACCH frames have a two-byte L1 header that
- * OsmocomBB L1 doesn't strip */
- mctx.tx_power_ind = msg->l2h[0] & 0x1f;
- mctx.ta_ind = msg->l2h[1];
- msgb_pull(msg, 2);
- msg->l2h += 2;
- } else {
- mctx.lapdm_fmt = LAPDm_FMT_B;
- LOGP(DLAPDM, LOGL_INFO, "fmt=B\n");
- mctx.n201 = 23; // FIXME: select correct size by chan.
- }
- }
-
- switch (mctx.lapdm_fmt) {
- case LAPDm_FMT_A:
- case LAPDm_FMT_B:
- case LAPDm_FMT_B4:
- mctx.addr = msg->l2h[0];
- if (!(mctx.addr & 0x01)) {
- LOGP(DLAPDM, LOGL_ERROR, "we don't support "
- "multibyte addresses (discarding)\n");
- msgb_free(msg);
- return -EINVAL;
- }
- mctx.ctrl = msg->l2h[1];
- /* obtain SAPI from address field */
- mctx.link_id |= LAPDm_ADDR_SAPI(mctx.addr);
- rc = lapdm_ph_data_ind(msg, &mctx);
- break;
- case LAPDm_FMT_Bter:
- /* FIXME */
- msgb_free(msg);
- break;
- case LAPDm_FMT_Bbis:
- /* directly pass up to layer3 */
- LOGP(DLAPDM, LOGL_INFO, "fmt=Bbis UI\n");
- msg->l3h = msg->l2h;
- msgb_pull_l2h(msg);
- rc = send_rslms_rll_l3(RSL_MT_UNIT_DATA_IND, &mctx, msg);
- break;
- default:
- msgb_free(msg);
- }
-
- return rc;
-}
-
-/* input into layer2 (from layer 1) */
-static int l2_ph_rach_ind(struct lapdm_entity *le, uint8_t ra, uint32_t fn, uint8_t acc_delay)
-{
- struct abis_rsl_cchan_hdr *ch;
- struct gsm48_req_ref req_ref;
- struct gsm_time gt;
- struct msgb *msg = msgb_alloc_headroom(512, 64, "RSL CHAN RQD");
-
- msg->l2h = msgb_push(msg, sizeof(*ch));
- ch = (struct abis_rsl_cchan_hdr *)msg->l2h;
- rsl_init_cchan_hdr(ch, RSL_MT_CHAN_RQD);
- ch->chan_nr = RSL_CHAN_RACH;
-
- /* generate a RSL CHANNEL REQUIRED message */
- gsm_fn2gsmtime(&gt, fn);
- req_ref.ra = ra;
- req_ref.t1 = gt.t1; /* FIXME: modulo? */
- req_ref.t2 = gt.t2;
- req_ref.t3_low = gt.t3 & 7;
- req_ref.t3_high = gt.t3 >> 3;
-
- msgb_tv_fixed_put(msg, RSL_IE_REQ_REFERENCE, 3, (uint8_t *) &req_ref);
- msgb_tv_put(msg, RSL_IE_ACCESS_DELAY, acc_delay);
-
- return rslms_sendmsg(msg, le);
-}
-
-static int l2_ph_chan_conf(struct msgb *msg, struct lapdm_entity *le, uint32_t frame_nr);
-
-int lapdm_phsap_up(struct osmo_prim_hdr *oph, struct lapdm_entity *le)
-{
- struct osmo_phsap_prim *pp = (struct osmo_phsap_prim *) oph;
- int rc = 0;
-
- if (oph->sap != SAP_GSM_PH) {
- LOGP(DLAPDM, LOGL_ERROR, "primitive for unknown SAP %u\n",
- oph->sap);
- return -ENODEV;
- }
-
- switch (oph->primitive) {
- case PRIM_PH_DATA:
- if (oph->operation != PRIM_OP_INDICATION) {
- LOGP(DLAPDM, LOGL_ERROR, "PH_DATA is not INDICATION %u\n",
- oph->operation);
- return -ENODEV;
- }
- rc = l2_ph_data_ind(oph->msg, le, pp->u.data.chan_nr,
- pp->u.data.link_id);
- break;
- case PRIM_PH_RTS:
- if (oph->operation != PRIM_OP_INDICATION) {
- LOGP(DLAPDM, LOGL_ERROR, "PH_RTS is not INDICATION %u\n",
- oph->operation);
- return -ENODEV;
- }
- rc = l2_ph_data_conf(oph->msg, le);
- break;
- case PRIM_PH_RACH:
- switch (oph->operation) {
- case PRIM_OP_INDICATION:
- rc = l2_ph_rach_ind(le, pp->u.rach_ind.ra, pp->u.rach_ind.fn,
- pp->u.rach_ind.acc_delay);
- break;
- case PRIM_OP_CONFIRM:
- rc = l2_ph_chan_conf(oph->msg, le, pp->u.rach_ind.fn);
- break;
- default:
- return -EIO;
- }
- break;
- }
-
- return rc;
-}
-
-
-/* L3 -> L2 / RSLMS -> LAPDm */
-
-/* L3 requests establishment of data link */
-static int rslms_rx_rll_est_req(struct msgb *msg, struct lapdm_datalink *dl)
-{
- struct lapdm_entity *le = dl->entity;
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- uint8_t chan_nr = rllh->chan_nr;
- uint8_t link_id = rllh->link_id;
- uint8_t sapi = rllh->link_id & 7;
- struct tlv_parsed tv;
- uint8_t length;
- uint8_t n201 = 23; //FIXME
-
- /* Set chan_nr and link_id for established connection */
- memset(&dl->mctx, 0, sizeof(dl->mctx));
- dl->mctx.dl = dl;
- dl->mctx.n201 = n201;
- dl->mctx.chan_nr = chan_nr;
- dl->mctx.link_id = link_id;
-
- rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh));
- if (TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) {
- msg->l3h = TLVP_VAL(&tv, RSL_IE_L3_INFO);
- /* contention resolution establishment procedure */
- if (sapi != 0) {
- /* According to clause 6, the contention resolution
- * procedure is only permitted with SAPI value 0 */
- LOGP(DLAPDM, LOGL_ERROR, "SAPI != 0 but contention"
- "resolution (discarding)\n");
- msgb_free(msg);
- return send_rll_simple(RSL_MT_REL_IND, &dl->mctx);
- }
- /* transmit a SABM command with the P bit set to "1". The SABM
- * command shall contain the layer 3 message unit */
- length = TLVP_LEN(&tv, RSL_IE_L3_INFO);
- LOGP(DLAPDM, LOGL_INFO, "perform establishment with content "
- "(SABM)\n");
- } else {
- /* normal establishment procedure */
- length = 0;
- LOGP(DLAPDM, LOGL_INFO, "perform normal establishm. (SABM)\n");
- }
-
- /* check if the layer3 message length exceeds N201 */
- if (length + 3 > 21) { /* FIXME: do we know the channel N201? */
- LOGP(DLAPDM, LOGL_ERROR, "frame too large: %d > N201(%d) "
- "(discarding)\n", length + 3, 21);
- msgb_free(msg);
- return send_rll_simple(RSL_MT_REL_IND, &dl->mctx);
- }
-
- /* Flush send-queue */
- /* Clear send-buffer */
- lapdm_dl_flush_send(dl);
-
- /* Discard partly received L3 message */
- if (dl->rcv_buffer) {
- msgb_free(dl->rcv_buffer);
- dl->rcv_buffer = NULL;
- }
-
- /* Remove RLL header from msgb */
- msgb_pull_l2h(msg);
-
- /* Push LAPDm header on msgb */
- msg->l2h = msgb_push(msg, 3);
- msg->l2h[0] = LAPDm_ADDR(LAPDm_LPD_NORMAL, sapi, le->cr.loc2rem.cmd);
- msg->l2h[1] = LAPDm_CTRL_U(LAPDm_U_SABM, 1);
- msg->l2h[2] = LAPDm_LEN(length);
- /* Transmit-buffer carries exactly one segment */
- memcpy(dl->tx_hist[0], msg->l2h, 3 + length);
- dl->tx_length[0] = 3 + length;
- /* set Vs to 0, because it is used as index when resending SABM */
- dl->V_send = 0;
-
- /* Set states */
- dl->own_busy = dl->peer_busy = 0;
- dl->retrans_ctr = 0;
- lapdm_dl_newstate(dl, LAPDm_STATE_SABM_SENT);
-
- /* Tramsmit and start T200 */
- osmo_timer_schedule(&dl->t200, T200);
- return tx_ph_data_enqueue(dl, msg, chan_nr, link_id, n201);
-}
-
-/* L3 requests transfer of unnumbered information */
-static int rslms_rx_rll_udata_req(struct msgb *msg, struct lapdm_datalink *dl)
-{
- struct lapdm_entity *le = dl->entity;
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- uint8_t chan_nr = rllh->chan_nr;
- uint8_t link_id = rllh->link_id;
- uint8_t sapi = link_id & 7;
- struct tlv_parsed tv;
- int length;
- uint8_t n201 = 23; //FIXME
- uint8_t ta = 0, tx_power = 0;
-
- /* check if the layer3 message length exceeds N201 */
-
- rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh));
-
- if (TLVP_PRESENT(&tv, RSL_IE_TIMING_ADVANCE)) {
- ta = *TLVP_VAL(&tv, RSL_IE_TIMING_ADVANCE);
- }
- if (TLVP_PRESENT(&tv, RSL_IE_MS_POWER)) {
- tx_power = *TLVP_VAL(&tv, RSL_IE_MS_POWER);
- }
- if (!TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) {
- LOGP(DLAPDM, LOGL_ERROR, "unit data request without message "
- "error\n");
- msgb_free(msg);
- return -EINVAL;
- }
- msg->l3h = TLVP_VAL(&tv, RSL_IE_L3_INFO);
- length = TLVP_LEN(&tv, RSL_IE_L3_INFO);
- /* check if the layer3 message length exceeds N201 */
- if (length + 5 > 23) { /* FIXME: do we know the channel N201? */
- LOGP(DLAPDM, LOGL_ERROR, "frame too large: %d > N201(%d) "
- "(discarding)\n", length + 5, 23);
- msgb_free(msg);
- return -EIO;
- }
-
- LOGP(DLAPDM, LOGL_INFO, "sending unit data (tx_power=%d, ta=%d)\n",
- tx_power, ta);
-
- /* Remove RLL header from msgb */
- msgb_pull_l2h(msg);
-
- /* Push L1 + LAPDm header on msgb */
- msg->l2h = msgb_push(msg, 2 + 3);
- msg->l2h[0] = tx_power;
- msg->l2h[1] = ta;
- msg->l2h[2] = LAPDm_ADDR(LAPDm_LPD_NORMAL, sapi, le->cr.loc2rem.cmd);
- msg->l2h[3] = LAPDm_CTRL_U(LAPDm_U_UI, 0);
- msg->l2h[4] = LAPDm_LEN(length);
- // FIXME: short L2 header support
-
- /* Tramsmit */
- return tx_ph_data_enqueue(dl, msg, chan_nr, link_id, n201);
-}
-
-/* L3 requests transfer of acknowledged information */
-static int rslms_rx_rll_data_req(struct msgb *msg, struct lapdm_datalink *dl)
-{
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- struct tlv_parsed tv;
-
- rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh));
- if (!TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) {
- LOGP(DLAPDM, LOGL_ERROR, "data request without message "
- "error\n");
- msgb_free(msg);
- return -EINVAL;
- }
- msg->l3h = TLVP_VAL(&tv, RSL_IE_L3_INFO);
-
- LOGP(DLAPDM, LOGL_INFO, "writing message to send-queue\n");
-
- /* Remove the RSL/RLL header */
- msgb_pull_l2h(msg);
-
- /* Write data into the send queue */
- msgb_enqueue(&dl->send_queue, msg);
-
- /* Send message, if possible */
- rslms_send_i(&dl->mctx, __LINE__);
- return 0;
-}
-
-/* Send next I frame from queued/buffered data */
-static int rslms_send_i(struct lapdm_msg_ctx *mctx, int line)
-{
- struct lapdm_datalink *dl = mctx->dl;
- struct lapdm_entity *le = dl->entity;
- uint8_t chan_nr = mctx->chan_nr;
- uint8_t link_id = mctx->link_id;
- uint8_t sapi = link_id & 7;
- int k = k_sapi[sapi];
- struct msgb *msg;
- int length, left;
- int rc = - 1; /* we sent nothing */
-
- LOGP(DLAPDM, LOGL_INFO, "%s() called from line %d\n", __func__, line);
-
- next_frame:
-
- if (dl->peer_busy) {
- LOGP(DLAPDM, LOGL_INFO, "peer busy, not sending\n");
- return rc;
- }
-
- if (dl->state == LAPDm_STATE_TIMER_RECOV) {
- LOGP(DLAPDM, LOGL_INFO, "timer recovery, not sending\n");
- return rc;
- }
-
- /* If the send state variable V(S) is equal to V(A) plus k
- * (where k is the maximum number of outstanding I frames - see
- * subclause 5.8.4), the data link layer entity shall not transmit any
- * new I frames, but shall retransmit an I frame as a result
- * of the error recovery procedures as described in subclauses 5.5.4 and
- * 5.5.7. */
- if (dl->V_send == add_mod8(dl->V_ack, k)) {
- LOGP(DLAPDM, LOGL_INFO, "k frames outstanding, not sending "
- "more (k=%u V(S)=%u V(A)=%u)\n", k, dl->V_send,
- dl->V_ack);
- return rc;
- }
-
- /* if we have no tx_hist yet, we create it */
- if (!dl->tx_length[dl->V_send]) {
- /* Get next message into send-buffer, if any */
- if (!dl->send_buffer) {
- next_message:
- dl->send_out = 0;
- dl->send_buffer = msgb_dequeue(&dl->send_queue);
- /* No more data to be sent */
- if (!dl->send_buffer)
- return rc;
- LOGP(DLAPDM, LOGL_INFO, "get message from "
- "send-queue\n");
- }
-
- /* How much is left in the send-buffer? */
- left = msgb_l3len(dl->send_buffer) - dl->send_out;
- /* Segment, if data exceeds N201 */
- length = left;
- if (length > mctx->n201 - 3)
- length = mctx->n201 - 3;
- LOGP(DLAPDM, LOGL_INFO, "msg-len %d sent %d left %d N201 %d "
- "length %d first byte %02x\n",
- msgb_l3len(dl->send_buffer), dl->send_out, left,
- mctx->n201, length, dl->send_buffer->l3h[0]);
- /* If message in send-buffer is completely sent */
- if (left == 0) {
- msgb_free(dl->send_buffer);
- dl->send_buffer = NULL;
- goto next_message;
- }
-
- LOGP(DLAPDM, LOGL_INFO, "send I frame %sV(S)=%d\n",
- (left > length) ? "segment " : "", dl->V_send);
-
- /* Create I frame (segment) and transmit-buffer content */
- msg = msgb_alloc_headroom(23+10, 10, "LAPDm I");
- msg->l2h = msgb_put(msg, 3 + length);
- msg->l2h[0] = LAPDm_ADDR(LAPDm_LPD_NORMAL, sapi, le->cr.loc2rem.cmd);
- msg->l2h[1] = LAPDm_CTRL_I(dl->V_recv, dl->V_send, 0);
- msg->l2h[2] = LAPDm_LEN(length);
- if (left > length)
- msg->l2h[2] |= LAPDm_MORE;
- memcpy(msg->l2h + 3, dl->send_buffer->l3h + dl->send_out,
- length);
- memcpy(dl->tx_hist[dl->V_send], msg->l2h, 3 + length);
- dl->tx_length[dl->V_send] = 3 + length;
- /* Add length to track how much is already in the tx buffer */
- dl->send_out += length;
- } else {
- LOGP(DLAPDM, LOGL_INFO, "resend I frame from tx buffer "
- "V(S)=%d\n", dl->V_send);
-
- /* Create I frame (segment) from tx_hist */
- length = dl->tx_length[dl->V_send];
- msg = msgb_alloc_headroom(23+10, 10, "LAPDm I");
- msg->l2h = msgb_put(msg, length);
- memcpy(msg->l2h, dl->tx_hist[dl->V_send], length);
- msg->l2h[1] = LAPDm_CTRL_I(dl->V_recv, dl->V_send, 0);
- }
-
- /* The value of the send state variable V(S) shall be incremented by 1
- * at the end of the transmission of the I frame */
- dl->V_send = inc_mod8(dl->V_send);
-
- /* If timer T200 is not running at the time right before transmitting a
- * frame, when the PH-READY-TO-SEND primitive is received from the
- * physical layer., it shall be set. */
- if (!osmo_timer_pending(&dl->t200))
- osmo_timer_schedule(&dl->t200, T200);
-
- tx_ph_data_enqueue(dl, msg, chan_nr, link_id, mctx->n201);
-
- rc = 0; /* we sent something */
- goto next_frame;
-}
-
-/* L3 requests suspension of data link */
-static int rslms_rx_rll_susp_req(struct msgb *msg, struct lapdm_datalink *dl)
-{
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- uint8_t sapi = rllh->link_id & 7;
-
- if (sapi != 0) {
- LOGP(DLAPDM, LOGL_ERROR, "SAPI != 0 while suspending\n");
- msgb_free(msg);
- return -EINVAL;
- }
-
- LOGP(DLAPDM, LOGL_INFO, "perform suspension\n");
-
- /* put back the send-buffer to the send-queue (first position) */
- if (dl->send_buffer) {
- LOGP(DLAPDM, LOGL_INFO, "put frame in sendbuffer back to "
- "queue\n");
- llist_add(&dl->send_buffer->list, &dl->send_queue);
- dl->send_buffer = NULL;
- } else
- LOGP(DLAPDM, LOGL_INFO, "no frame in sendbuffer\n");
-
- /* Clear transmit buffer, but keep send buffer */
- lapdm_dl_flush_tx(dl);
-
- msgb_free(msg);
-
- return send_rll_simple(RSL_MT_SUSP_CONF, &dl->mctx);
-}
-
-/* L3 requests resume of data link */
-static int rslms_rx_rll_res_req(struct msgb *msg, struct lapdm_datalink *dl)
-{
- struct lapdm_entity *le = dl->entity;
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- uint8_t chan_nr = rllh->chan_nr;
- uint8_t link_id = rllh->link_id;
- uint8_t sapi = rllh->link_id & 7;
- struct tlv_parsed tv;
- uint8_t length;
- uint8_t n201 = 23; //FIXME
-
- /* Set chan_nr and link_id for established connection */
- memset(&dl->mctx, 0, sizeof(dl->mctx));
- dl->mctx.dl = dl;
- dl->mctx.n201 = n201;
- dl->mctx.chan_nr = chan_nr;
- dl->mctx.link_id = link_id;
-
- rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh));
- if (!TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) {
- LOGP(DLAPDM, LOGL_ERROR, "resume without message error\n");
- msgb_free(msg);
- return send_rll_simple(RSL_MT_REL_IND, &dl->mctx);
- }
- length = TLVP_LEN(&tv, RSL_IE_L3_INFO);
-
- LOGP(DLAPDM, LOGL_INFO, "perform re-establishment (SABM) length=%d\n",
- length);
-
- /* Replace message in the send-buffer (reconnect) */
- if (dl->send_buffer)
- msgb_free(dl->send_buffer);
- dl->send_out = 0;
- if (length) {
- /* Remove the RSL/RLL header */
- msgb_pull_l2h(msg);
- /* Write data into the send buffer, to be sent first */
- dl->send_buffer = msg;
- }
-
- /* Discard partly received L3 message */
- if (dl->rcv_buffer) {
- msgb_free(dl->rcv_buffer);
- dl->rcv_buffer = NULL;
- }
-
- /* Create new msgb (old one is now free) */
- msg = msgb_alloc_headroom(23+10, 10, "LAPDm SABM");
- msg->l2h = msgb_put(msg, 3);
- msg->l2h[0] = LAPDm_ADDR(LAPDm_LPD_NORMAL, sapi, le->cr.loc2rem.cmd);
- msg->l2h[1] = LAPDm_CTRL_U(LAPDm_U_SABM, 1);
- msg->l2h[2] = LAPDm_LEN(0);
- /* Transmit-buffer carries exactly one segment */
- memcpy(dl->tx_hist[0], msg->l2h, 3);
- dl->tx_length[0] = 3;
- /* set Vs to 0, because it is used as index when resending SABM */
- dl->V_send = 0;
-
- /* Set states */
- dl->own_busy = dl->peer_busy = 0;
- dl->retrans_ctr = 0;
- lapdm_dl_newstate(dl, LAPDm_STATE_SABM_SENT);
-
- /* Tramsmit and start T200 */
- osmo_timer_schedule(&dl->t200, T200);
- return tx_ph_data_enqueue(dl, msg, chan_nr, link_id, n201);
-}
-
-/* L3 requests release of data link */
-static int rslms_rx_rll_rel_req(struct msgb *msg, struct lapdm_datalink *dl)
-{
- struct lapdm_entity *le = dl->entity;
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- uint8_t chan_nr = rllh->chan_nr;
- uint8_t link_id = rllh->link_id;
- uint8_t sapi = rllh->link_id & 7;
- uint8_t mode = 0;
-
- /* get release mode */
- if (rllh->data[0] == RSL_IE_RELEASE_MODE)
- mode = rllh->data[1] & 1;
-
- /* local release */
- if (mode) {
- LOGP(DLAPDM, LOGL_INFO, "perform local release\n");
- msgb_free(msg);
- /* reset Timer T200 */
- osmo_timer_del(&dl->t200);
- /* enter idle state */
- lapdm_dl_newstate(dl, LAPDm_STATE_IDLE);
- /* flush buffers */
- lapdm_dl_flush_tx(dl);
- lapdm_dl_flush_send(dl);
- /* send notification to L3 */
- return send_rll_simple(RSL_MT_REL_CONF, &dl->mctx);
- }
-
- /* in case we are already disconnecting */
- if (dl->state == LAPDm_STATE_DISC_SENT)
- return -EBUSY;
-
- LOGP(DLAPDM, LOGL_INFO, "perform normal release (DISC)\n");
-
- /* Pull rllh */
- msgb_pull(msg, msg->tail - msg->l2h);
-
- /* Push LAPDm header on msgb */
- msg->l2h = msgb_push(msg, 3);
- msg->l2h[0] = LAPDm_ADDR(LAPDm_LPD_NORMAL, sapi, le->cr.loc2rem.cmd);
- msg->l2h[1] = LAPDm_CTRL_U(LAPDm_U_DISC, 1);
- msg->l2h[2] = LAPDm_LEN(0);
- /* Transmit-buffer carries exactly one segment */
- memcpy(dl->tx_hist[0], msg->l2h, 3);
- dl->tx_length[0] = 3;
-
- /* Set states */
- dl->own_busy = dl->peer_busy = 0;
- dl->retrans_ctr = 0;
- lapdm_dl_newstate(dl, LAPDm_STATE_DISC_SENT);
-
- /* Tramsmit and start T200 */
- osmo_timer_schedule(&dl->t200, T200);
- return tx_ph_data_enqueue(dl, msg, chan_nr, link_id, dl->mctx.n201);
-}
-
-/* L3 requests release in idle state */
-static int rslms_rx_rll_rel_req_idle(struct msgb *msg, struct lapdm_datalink *dl)
-{
- msgb_free(msg);
-
- /* send notification to L3 */
- return send_rll_simple(RSL_MT_REL_CONF, &dl->mctx);
-}
-
-/* L3 requests channel in idle state */
-static int rslms_rx_chan_rqd(struct lapdm_channel *lc, struct msgb *msg)
-{
- struct abis_rsl_cchan_hdr *cch = msgb_l2(msg);
- void *l1ctx = lc->lapdm_dcch.l1_ctx;
- struct osmo_phsap_prim pp;
-
- osmo_prim_init(&pp.oph, SAP_GSM_PH, PRIM_PH_RACH,
- PRIM_OP_REQUEST, NULL);
-
- if (msgb_l2len(msg) < sizeof(*cch) + 4 + 2 + 2) {
- LOGP(DRSL, LOGL_ERROR, "Message too short for CHAN RQD!\n");
- return -EINVAL;
- }
- if (cch->data[0] != RSL_IE_REQ_REFERENCE) {
- LOGP(DRSL, LOGL_ERROR, "Missing REQ REFERENCE IE\n");
- return -EINVAL;
- }
- pp.u.rach_req.ra = cch->data[1];
- pp.u.rach_req.offset = ((cch->data[2] & 0x7f) << 8) | cch->data[3];
- pp.u.rach_req.is_combined_ccch = cch->data[2] >> 7;
-
- if (cch->data[4] != RSL_IE_ACCESS_DELAY) {
- LOGP(DRSL, LOGL_ERROR, "Missing ACCESS_DELAY IE\n");
- return -EINVAL;
- }
- /* TA = 0 - delay */
- pp.u.rach_req.ta = 0 - cch->data[5];
-
- if (cch->data[6] != RSL_IE_MS_POWER) {
- LOGP(DRSL, LOGL_ERROR, "Missing MS POWER IE\n");
- return -EINVAL;
- }
- pp.u.rach_req.tx_power = cch->data[7];
-
- msgb_free(msg);
-
- return lc->lapdm_dcch.l1_prim_cb(&pp.oph, l1ctx);
-}
-
-/* L1 confirms channel request */
-static int l2_ph_chan_conf(struct msgb *msg, struct lapdm_entity *le, uint32_t frame_nr)
-{
- struct abis_rsl_cchan_hdr *ch;
- struct gsm_time tm;
- struct gsm48_req_ref *ref;
-
- gsm_fn2gsmtime(&tm, frame_nr);
-
- msgb_pull_l2h(msg);
- msg->l2h = msgb_push(msg, sizeof(*ch) + sizeof(*ref));
- ch = (struct abis_rsl_cchan_hdr *)msg->l2h;
- rsl_init_cchan_hdr(ch, RSL_MT_CHAN_CONF);
- ch->chan_nr = RSL_CHAN_RACH;
- ch->data[0] = RSL_IE_REQ_REFERENCE;
- ref = (struct gsm48_req_ref *) (ch->data + 1);
- ref->t1 = tm.t1;
- ref->t2 = tm.t2;
- ref->t3_low = tm.t3 & 0x7;
- ref->t3_high = tm.t3 >> 3;
-
- return rslms_sendmsg(msg, le);
-}
-
-const char *lapdm_state_names[] = {
- "LAPDm_STATE_NULL",
- "LAPDm_STATE_IDLE",
- "LAPDm_STATE_SABM_SENT",
- "LAPDm_STATE_MF_EST",
- "LAPDm_STATE_TIMER_RECOV",
- "LAPDm_STATE_DISC_SENT",
-};
-
-/* statefull handling for RSLms RLL messages from L3 */
-static struct l2downstate {
- uint32_t states;
- int type;
- int (*rout) (struct msgb *msg, struct lapdm_datalink *dl);
-} l2downstatelist[] = {
- /* create and send UI command */
- {ALL_STATES,
- RSL_MT_UNIT_DATA_REQ, rslms_rx_rll_udata_req},
-
- /* create and send SABM command */
- {SBIT(LAPDm_STATE_IDLE),
- RSL_MT_EST_REQ, rslms_rx_rll_est_req},
-
- /* create and send I command */
- {SBIT(LAPDm_STATE_MF_EST) |
- SBIT(LAPDm_STATE_TIMER_RECOV),
- RSL_MT_DATA_REQ, rslms_rx_rll_data_req},
-
- /* suspend datalink */
- {SBIT(LAPDm_STATE_MF_EST) |
- SBIT(LAPDm_STATE_TIMER_RECOV),
- RSL_MT_SUSP_REQ, rslms_rx_rll_susp_req},
-
- /* create and send SABM command (resume) */
- {SBIT(LAPDm_STATE_MF_EST) |
- SBIT(LAPDm_STATE_TIMER_RECOV),
- RSL_MT_RES_REQ, rslms_rx_rll_res_req},
-
- /* create and send SABM command (reconnect) */
- {SBIT(LAPDm_STATE_IDLE) |
- SBIT(LAPDm_STATE_MF_EST) |
- SBIT(LAPDm_STATE_TIMER_RECOV),
- RSL_MT_RECON_REQ, rslms_rx_rll_res_req},
-
- /* create and send DISC command */
- {SBIT(LAPDm_STATE_SABM_SENT) |
- SBIT(LAPDm_STATE_MF_EST) |
- SBIT(LAPDm_STATE_TIMER_RECOV) |
- SBIT(LAPDm_STATE_DISC_SENT),
- RSL_MT_REL_REQ, rslms_rx_rll_rel_req},
-
- /* release in idle state */
- {SBIT(LAPDm_STATE_IDLE),
- RSL_MT_REL_REQ, rslms_rx_rll_rel_req_idle},
-};
-
-#define L2DOWNSLLEN \
- (sizeof(l2downstatelist) / sizeof(struct l2downstate))
-
-/* incoming RSLms RLL message from L3 */
-static int rslms_rx_rll(struct msgb *msg, struct lapdm_channel *lc)
-{
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- int msg_type = rllh->c.msg_type;
- uint8_t sapi = rllh->link_id & 7;
- struct lapdm_entity *le;
- struct lapdm_datalink *dl;
- int i, supported = 0;
- int rc = 0;
-
- if (msgb_l2len(msg) < sizeof(*rllh)) {
- LOGP(DRSL, LOGL_ERROR, "Message too short for RLL hdr!\n");
- return -EINVAL;
- }
-
- if (rllh->link_id & 0x40)
- le = &lc->lapdm_acch;
- else
- le = &lc->lapdm_dcch;
-
- /* G.2.1 No action schall be taken on frames containing an unallocated
- * SAPI.
- */
- dl = datalink_for_sapi(le, sapi);
- if (!dl) {
- LOGP(DRSL, LOGL_ERROR, "No instance for SAPI %d!\n", sapi);
- return -EINVAL;
- }
-
- LOGP(DRSL, LOGL_INFO, "(%p) RLL Message '%s' received in state %s\n",
- lc->name, rsl_msg_name(msg_type), lapdm_state_names[dl->state]);
-
- /* find function for current state and message */
- for (i = 0; i < L2DOWNSLLEN; i++) {
- if (msg_type == l2downstatelist[i].type)
- supported = 1;
- if ((msg_type == l2downstatelist[i].type)
- && ((1 << dl->state) & l2downstatelist[i].states))
- break;
- }
- if (!supported) {
- LOGP(DRSL, LOGL_NOTICE, "Message unsupported.\n");
- msgb_free(msg);
- return 0;
- }
- if (i == L2DOWNSLLEN) {
- LOGP(DRSL, LOGL_NOTICE, "Message unhandled at this state.\n");
- msgb_free(msg);
- return 0;
- }
-
- rc = l2downstatelist[i].rout(msg, dl);
-
- return rc;
-}
-
-/* incoming RSLms COMMON CHANNEL message from L3 */
-static int rslms_rx_com_chan(struct msgb *msg, struct lapdm_channel *lc)
-{
- struct abis_rsl_cchan_hdr *cch = msgb_l2(msg);
- int msg_type = cch->c.msg_type;
- int rc = 0;
-
- if (msgb_l2len(msg) < sizeof(*cch)) {
- LOGP(DRSL, LOGL_ERROR, "Message too short for COM CHAN hdr!\n");
- return -EINVAL;
- }
-
- switch (msg_type) {
- case RSL_MT_CHAN_RQD:
- /* create and send RACH request */
- rc = rslms_rx_chan_rqd(lc, msg);
- break;
- default:
- LOGP(DRSL, LOGL_NOTICE, "Unknown COMMON CHANNEL msg %d!\n",
- msg_type);
- msgb_free(msg);
- return 0;
- }
-
- return rc;
-}
-
-/* input into layer2 (from layer 3) */
-int lapdm_rslms_recvmsg(struct msgb *msg, struct lapdm_channel *lc)
-{
- struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
- int rc = 0;
-
- if (msgb_l2len(msg) < sizeof(*rslh)) {
- LOGP(DRSL, LOGL_ERROR, "Message too short RSL hdr!\n");
- return -EINVAL;
- }
-
- switch (rslh->msg_discr & 0xfe) {
- case ABIS_RSL_MDISC_RLL:
- rc = rslms_rx_rll(msg, lc);
- break;
- case ABIS_RSL_MDISC_COM_CHAN:
- rc = rslms_rx_com_chan(msg, lc);
- break;
- default:
- LOGP(DRSL, LOGL_ERROR, "unknown RSLms message "
- "discriminator 0x%02x", rslh->msg_discr);
- msgb_free(msg);
- return -EINVAL;
- }
-
- return rc;
-}
-
-int lapdm_entity_set_mode(struct lapdm_entity *le, enum lapdm_mode mode)
-{
- switch (mode) {
- case LAPDM_MODE_MS:
- le->cr.loc2rem.cmd = CR_MS2BS_CMD;
- le->cr.loc2rem.resp = CR_MS2BS_RESP;
- le->cr.rem2loc.cmd = CR_BS2MS_CMD;
- le->cr.rem2loc.resp = CR_BS2MS_RESP;
- break;
- case LAPDM_MODE_BTS:
- le->cr.loc2rem.cmd = CR_BS2MS_CMD;
- le->cr.loc2rem.resp = CR_BS2MS_RESP;
- le->cr.rem2loc.cmd = CR_MS2BS_CMD;
- le->cr.rem2loc.resp = CR_MS2BS_RESP;
- break;
- default:
- return -EINVAL;
- }
-
- le->mode = mode;
-
- return 0;
-}
-
-int lapdm_channel_set_mode(struct lapdm_channel *lc, enum lapdm_mode mode)
-{
- int rc;
-
- rc = lapdm_entity_set_mode(&lc->lapdm_dcch, mode);
- if (rc < 0)
- return rc;
-
- return lapdm_entity_set_mode(&lc->lapdm_acch, mode);
-}
-
-void lapdm_channel_set_l1(struct lapdm_channel *lc, osmo_prim_cb cb, void *ctx)
-{
- lc->lapdm_dcch.l1_prim_cb = cb;
- lc->lapdm_acch.l1_prim_cb = cb;
- lc->lapdm_dcch.l1_ctx = ctx;
- lc->lapdm_acch.l1_ctx = ctx;
-}
-
-void lapdm_channel_set_l3(struct lapdm_channel *lc, lapdm_cb_t cb, void *ctx)
-{
- lc->lapdm_dcch.l3_cb = cb;
- lc->lapdm_acch.l3_cb = cb;
- lc->lapdm_dcch.l3_ctx = ctx;
- lc->lapdm_acch.l3_ctx = ctx;
-}
-
-void lapdm_entity_reset(struct lapdm_entity *le)
-{
- struct lapdm_datalink *dl;
- int i;
-
- for (i = 0; i < ARRAY_SIZE(le->datalink); i++) {
- dl = &le->datalink[i];
- if (dl->state == LAPDm_STATE_IDLE)
- continue;
- LOGP(DLAPDM, LOGL_INFO, "Resetting LAPDm instance\n");
- /* reset Timer T200 */
- osmo_timer_del(&dl->t200);
- /* enter idle state */
- dl->state = LAPDm_STATE_IDLE;
- /* flush buffer */
- lapdm_dl_flush_tx(dl);
- lapdm_dl_flush_send(dl);
- }
-}
-
-void lapdm_channel_reset(struct lapdm_channel *lc)
-{
- lapdm_entity_reset(&lc->lapdm_dcch);
- lapdm_entity_reset(&lc->lapdm_acch);
-}
-
-void lapdm_entity_set_flags(struct lapdm_entity *le, unsigned int flags)
-{
- le->flags = flags;
-}
-
-void lapdm_channel_set_flags(struct lapdm_channel *lc, unsigned int flags)
-{
- lapdm_entity_set_flags(&lc->lapdm_dcch, flags);
- lapdm_entity_set_flags(&lc->lapdm_acch, flags);
-}
diff --git a/Src/osmoconbb/src/host/layer23/src/common/logging.c b/Src/osmoconbb/src/host/layer23/src/common/logging.c
deleted file mode 100644
index 82ce914..0000000
--- a/Src/osmoconbb/src/host/layer23/src/common/logging.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/* Logging/Debug support of the layer2/3 stack */
-
-/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-
-#include <osmocom/core/utils.h>
-#include <osmocom/core/logging.h>
-#include <osmocom/bb/common/logging.h>
-
-static const struct log_info_cat default_categories[] = {
- [DRSL] = {
- .name = "DRSL",
- .description = "Radio Signalling Link (MS)",
- .color = "\033[1;35m",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
- [DCS] = {
- .name = "DCS",
- .description = "Cell selection",
- .color = "\033[34m",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DNB] = {
- .name = "DNB",
- .description = "Neighbour cell measurement",
- .color = "\033[0;31m",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
- [DPLMN] = {
- .name = "DPLMN",
- .description = "PLMN selection",
- .color = "\033[32m",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DRR] = {
- .name = "DRR",
- .description = "Radio Resource",
- .color = "\033[1;34m",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DMM] = {
- .name = "DMM",
- .description = "Mobility Management",
- .color = "\033[1;32m",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DCC] = {
- .name = "DCC",
- .description = "Call Control",
- .color = "\033[1;33m",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DSMS] = {
- .name = "DSMS",
- .description = "Short Message Service",
- .color = "\033[1;37m",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DMNCC] = {
- .name = "DMNCC",
- .description = "Mobile Network Call Control",
- .color = "\033[1;37m",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DMEAS] = {
- .name = "DMEAS",
- .description = "MEasurement Reporting",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DPAG] = {
- .name = "DPAG",
- .description = "Paging",
- .color = "\033[33m",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DLAPDM] = {
- .name = "DLAPDM",
- .description = "LAPDm Layer2",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
- [DL1C] = {
- .name = "DL1C",
- .description = "Layer 1 Control",
- .color = "\033[1;31m",
- .enabled = 1, .loglevel = LOGL_NOTICE,
- },
- [DSAP] = {
- .name = "DSAP",
- .description = "SAP Control",
- .color = "\033[1;31m",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DSUM] = {
- .name = "DSUM",
- .description = "Summary of Process",
- .color = "\033[1;37m",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DSIM] = {
- .name = "DSIM",
- .description = "SIM client",
- .color = "\033[0;35m",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
- [DGPS] = {
- .name = "DGPS",
- .description = "GPS",
- .color = "\033[1;35m",
- .enabled = 1, .loglevel = LOGL_DEBUG,
- },
-};
-
-const struct log_info log_info = {
- .filter_fn = NULL,
- .cat = default_categories,
- .num_cat = ARRAY_SIZE(default_categories),
-};
-
diff --git a/Src/osmoconbb/src/host/layer23/src/common/main.c b/Src/osmoconbb/src/host/layer23/src/common/main.c
deleted file mode 100644
index 751f95e..0000000
--- a/Src/osmoconbb/src/host/layer23/src/common/main.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/* Main method of the layer2/3 stack */
-
-/* (C) 2010 by Holger Hans Peter Freyther
- * (C) 2010 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/l1ctl.h>
-#include <osmocom/bb/common/l1l2_interface.h>
-#include <osmocom/bb/common/sap_interface.h>
-#include <osmocom/bb/misc/layer3.h>
-#include <osmocom/bb/common/lapdm.h>
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/l23_app.h>
-
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/select.h>
-#include <osmocom/core/linuxlist.h>
-#include <osmocom/core/gsmtap_util.h>
-#include <osmocom/core/gsmtap.h>
-#include <osmocom/core/utils.h>
-
-#include <arpa/inet.h>
-
-#define _GNU_SOURCE
-#include <getopt.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-
-struct log_target *stderr_target;
-
-void *l23_ctx = NULL;
-
-static char *layer2_socket_path = "/tmp/osmocom_l2";
-static char *sap_socket_path = "/tmp/osmocom_sap";
-struct llist_head ms_list;
-static struct osmocom_ms *ms = NULL;
-static char *gsmtap_ip = NULL;
-
-unsigned short vty_port = 4247;
-int (*l23_app_work) (struct osmocom_ms *ms) = NULL;
-int (*l23_app_exit) (struct osmocom_ms *ms) = NULL;
-int quit = 0;
-struct gsmtap_inst *gsmtap_inst;
-
-const char *openbsc_copyright =
- "%s"
- "%s\n"
- "License GPLv2+: GNU GPL version 2 or later "
- "<http://gnu.org/licenses/gpl.html>\n"
- "This is free software: you are free to change and redistribute it.\n"
- "There is NO WARRANTY, to the extent permitted by law.\n\n";
-
-static void print_usage(const char *app)
-{
- printf("Usage: %s\n", app);
-}
-
-static void print_help()
-{
- int options = 0xff;
- struct l23_app_info *app = l23_app_info();
-
- if (app && app->cfg_supported != 0)
- options = app->cfg_supported();
-
- printf(" Some help...\n");
- printf(" -h --help this text\n");
- printf(" -s --socket /tmp/osmocom_l2. Path to the unix "
- "domain socket (l2)\n");
-
- if (options & L23_OPT_SAP)
- printf(" -S --sap /tmp/osmocom_sap. Path to the "
- "unix domain socket (BTSAP)\n");
-
- if (options & L23_OPT_ARFCN)
- printf(" -a --arfcn NR The ARFCN to be used for layer2.\n");
-
- if (options & L23_OPT_TAP)
- printf(" -i --gsmtap-ip The destination IP used for GSMTAP.\n");
-
- if (options & L23_OPT_VTY)
- printf(" -v --vty-port The VTY port number to telnet "
- "to. (default %u)\n", vty_port);
-
- if (options & L23_OPT_DBG)
- printf(" -d --debug Change debug flags.\n");
-
- if (app && app->cfg_print_help)
- app->cfg_print_help();
-}
-
-static void build_config(char **opt, struct option **option)
-{
- struct l23_app_info *app;
- struct option *app_opp = NULL;
- int app_len = 0, len;
-
- static struct option long_options[] = {
- {"help", 0, 0, 'h'},
- {"socket", 1, 0, 's'},
- {"sap", 1, 0, 'S'},
- {"arfcn", 1, 0, 'a'},
- {"gsmtap-ip", 1, 0, 'i'},
- {"vty-port", 1, 0, 'v'},
- {"debug", 1, 0, 'd'},
- };
-
-
- app = l23_app_info();
- *opt = talloc_asprintf(l23_ctx, "hs:S:a:i:v:d:%s",
- app && app->getopt_string ? app->getopt_string : "");
-
- len = ARRAY_SIZE(long_options);
- if (app && app->cfg_getopt_opt)
- app_len = app->cfg_getopt_opt(&app_opp);
-
- *option = talloc_zero_array(l23_ctx, struct option, len + app_len + 1);
- memcpy(*option, long_options, sizeof(long_options));
- memcpy(*option + len, app_opp, app_len * sizeof(struct option));
-}
-
-static void handle_options(int argc, char **argv)
-{
- struct l23_app_info *app = l23_app_info();
- struct option *long_options;
- char *opt;
-
- build_config(&opt, &long_options);
-
- while (1) {
- int option_index = 0, c;
-
- c = getopt_long(argc, argv, opt,
- long_options, &option_index);
- if (c == -1)
- break;
-
- switch (c) {
- case 'h':
- print_usage(argv[0]);
- print_help();
- exit(0);
- break;
- case 's':
- layer2_socket_path = talloc_strdup(l23_ctx, optarg);
- break;
- case 'S':
- sap_socket_path = talloc_strdup(l23_ctx, optarg);
- break;
- case 'a':
- ms->test_arfcn = atoi(optarg);
- break;
- case 'i':
- gsmtap_ip = optarg;
- break;
- case 'v':
- vty_port = atoi(optarg);
- break;
- case 'd':
- log_parse_category_mask(stderr_target, optarg);
- break;
- default:
- if (app && app->cfg_handle_opt)
- app->cfg_handle_opt(c, optarg);
- break;
- }
- }
-
- talloc_free(opt);
- talloc_free(long_options);
-}
-
-void sighandler(int sigset)
-{
- int rc = 0;
-
- if (sigset == SIGHUP || sigset == SIGPIPE)
- return;
-
- fprintf(stderr, "Signal %d recevied.\n", sigset);
- if (l23_app_exit)
- rc = l23_app_exit(ms);
-
- if (rc != -EBUSY)
- exit (0);
-}
-
-static void print_copyright()
-{
- struct l23_app_info *app;
- app = l23_app_info();
- printf(openbsc_copyright,
- app && app->copyright ? app->copyright : "",
- app && app->contribution ? app->contribution : "");
-}
-
-int main(int argc, char **argv)
-{
- int rc;
-
- INIT_LLIST_HEAD(&ms_list);
- log_init(&log_info, NULL);
- stderr_target = log_target_create_stderr();
- log_add_target(stderr_target);
- log_set_all_filter(stderr_target, 1);
-
- l23_ctx = talloc_named_const(NULL, 1, "layer2 context");
-
- ms = talloc_zero(l23_ctx, struct osmocom_ms);
- if (!ms) {
- fprintf(stderr, "Failed to allocate MS\n");
- exit(1);
- }
-
- print_copyright();
-
- llist_add_tail(&ms->entity, &ms_list);
-
- sprintf(ms->name, "1");
-
- ms->test_arfcn = 871;
-
- handle_options(argc, argv);
-
- rc = layer2_open(ms, layer2_socket_path);
- if (rc < 0) {
- fprintf(stderr, "Failed during layer2_open()\n");
- exit(1);
- }
-
- rc = sap_open(ms, sap_socket_path);
- if (rc < 0)
- fprintf(stderr, "Failed during sap_open(), no SIM reader\n");
-
- ms->lapdm_channel.lapdm_dcch.l1_ctx = ms;
- ms->lapdm_channel.lapdm_dcch.l3_ctx = ms;
- ms->lapdm_channel.lapdm_acch.l1_ctx = ms;
- ms->lapdm_channel.lapdm_acch.l3_ctx = ms;
- lapdm_channel_init(&ms->lapdm_channel, LAPDM_MODE_MS);
- lapdm_channel_set_l1(&ms->lapdm_channel, l1ctl_ph_prim_cb, ms);
-
- rc = l23_app_init(ms);
- if (rc < 0)
- exit(1);
-
- if (gsmtap_ip) {
- gsmtap_inst = gsmtap_source_init(gsmtap_ip, GSMTAP_UDP_PORT, 1);
- if (!gsmtap_inst) {
- fprintf(stderr, "Failed during gsmtap_init()\n");
- exit(1);
- }
- gsmtap_source_add_sink(gsmtap_inst);
- }
-
- signal(SIGINT, sighandler);
- signal(SIGHUP, sighandler);
- signal(SIGTERM, sighandler);
- signal(SIGPIPE, sighandler);
-
- while (!quit) {
- if (l23_app_work)
- l23_app_work(ms);
- osmo_select_main(0);
- }
-
- return 0;
-}
diff --git a/Src/osmoconbb/src/host/layer23/src/common/networks.c b/Src/osmoconbb/src/host/layer23/src/common/networks.c
deleted file mode 100644
index 63221f0..0000000
--- a/Src/osmoconbb/src/host/layer23/src/common/networks.c
+++ /dev/null
@@ -1,1986 +0,0 @@
-#include <string.h>
-#include <stdint.h>
-#include <stdio.h>
-
-#include <osmocom/bb/common/networks.h>
-
-/* list of networks */
-
-struct gsm_networks gsm_networks[] = {
- { 0x001, -1, "Test" },
- { 0x001, 0x01f, "Test" },
- { 0x412, -1, "Afghanistan" },
- { 0x412, 0x01f, "AWCC" },
- { 0x412, 0x20f, "Roshan" },
- { 0x412, 0x30f, "New1" },
- { 0x412, 0x40f, "Areeba" },
- { 0x412, 0x50f, "Etisalat" }, /* ? */
- { 0x412, 0x88f, "Afghan Telecom" },
- { 0x276, -1, "Albania" },
- { 0x276, 0x01f, "AMC" },
- { 0x276, 0x02f, "Vodafone" },
- { 0x276, 0x03f, "Eagle Mobile" },
- { 0x276, 0x04f, "Mobile 4 AL" },
- { 0x603, -1, "Algeria" },
- { 0x603, 0x01f, "Algerie Telecom" },
- { 0x603, 0x02f, "Orascom Telecom Algerie" },
- { 0x603, 0x03f, "Nedjma" }, /* ? */
- { 0x213, -1, "Andorra" },
- { 0x213, 0x03f, "Mobiland" },
- { 0x631, -1, "Angola" },
- { 0x631, 0x02f, "UNITEL" },
- { 0x365, -1, "Anguilla" },
- { 0x365, 0x010, "Weblinks Limited" },
- { 0x365, 0x840, "Cable & Wireless" }, /* ? */
- { 0x344, -1, "Antigua and Barbuda" },
- { 0x344, 0x030, "APUA PCS" },
- { 0x338, 0x050, "Digicel" }, /* ? */
- { 0x344, 0x920, "Cable & Wireless (Antigua)" },
- { 0x344, 0x930, "AT&T Wireless (Antigua)" },
- { 0x722, -1, "Argentina" },
- { 0x722, 0x010, "Companie de Radiocomunicatciones Moviles S.A." },
- { 0x722, 0x020, "Nextel Argentina srl" },
- { 0x722, 0x070, "Telefonica Communicationes Personales S.A." },
- { 0x722, 0x310, "CTI PCS S.A" },
- { 0x722, 0x320, "Compania de Telefonos del Interior Norte S.A." },
- { 0x722, 0x330, "Companie de Telefonos del Interior S.A." },
- { 0x722, 0x340, "Personal" }, /* ? */
- { 0x722, 0x341, "Telecom Personal S.A." },
- { 0x722, 0x350, "Hutchinson (PORT HABLE)" }, /* ? */
- { 0x283, -1, "Armenia" },
- { 0x283, 0x01f, "Beeline" },
- { 0x283, 0x05f, "VivaCell-MTS" },
- { 0x283, 0x10f, "Orange" },
- { 0x363, -1, "Aruba" },
- { 0x363, 0x01f, "SETAR" },
- { 0x363, 0x02f, "Digicel" }, /* ? */
- { 0x505, -1, "Australia" },
- { 0x505, 0x01f, "Telstra" },
- { 0x505, 0x02f, "Optus" },
- { 0x505, 0x03f, "Vodafone" },
- { 0x505, 0x04f, "Department of Defence" },
- { 0x505, 0x05f, "Ozitel" },
- { 0x505, 0x06f, "Hutchison 3G"},
- { 0x505, 0x07f, "Vodafone" },
- { 0x505, 0x08f, "One.Tel" },
- { 0x505, 0x09f, "Airnet" },
- { 0x505, 0x10f, "Norfolk Telecom" },
- { 0x505, 0x11f, "Telstra" },
- { 0x505, 0x12f, "3" },
- { 0x505, 0x13f, "Railcorp" },
- { 0x505, 0x14f, "AAPT" },
- { 0x505, 0x15f, "3GIS" },
- { 0x505, 0x16f, "Victorian Rail Track" },
- { 0x505, 0x17f, "Vivid Wireless Pty Ltd" },
- { 0x505, 0x18f, "Pactel International Pty Ltd" },
- { 0x505, 0x19f, "Lycamobile Pty Ltd" },
- { 0x505, 0x21f, "SOUL" }, /* ? */
- { 0x505, 0x24f, "Advanced Communications Technologies Pty. Ltd." },
- { 0x505, 0x38f, "Crazy John's" }, /* ? */
- { 0x505, 0x71f, "Telstra" },
- { 0x505, 0x72f, "Telstra" },
- { 0x505, 0x88f, "Localstar Holding Pty. Ltd." },
- { 0x505, 0x90f, "Optus" },
- { 0x505, 0x99f, "One.Tel" },
- { 0x232, -1, "Austria" },
- { 0x232, 0x01f, "A1" },
- { 0x232, 0x02f, "A1" },
- { 0x232, 0x03f, "T-Mobile" },
- { 0x232, 0x04f, "T-Mobile" },
- { 0x232, 0x05f, "Orange" },
- { 0x232, 0x06f, "Orange" },
- { 0x232, 0x07f, "T-Mobile (tele.ring)" },
- { 0x232, 0x09f, "Mobilkom Austria" },
- { 0x232, 0x10f, "Hutchison 3G Austria" },
- { 0x232, 0x11f, "Mobilkom Austria" },
- { 0x232, 0x12f, "Orange Austria" },
- { 0x232, 0x14f, "Hutchison 3G Austria" },
- { 0x232, 0x15f, "Barablu Mobile Austria" },
- { 0x232, 0x16f, "3" }, /* ? */
- { 0x232, 0x91f, "OBB - Infrastruktur Bau AG" },
- { 0x400, -1, "Azerbaijan" },
- { 0x400, 0x01f, "Azercell" },
- { 0x400, 0x02f, "Bakcell" },
- { 0x400, 0x03f, "Catel JV" },
- { 0x400, 0x04f, "Azerphone LLC" },
- { 0x364, -1, "Bahamas" },
- { 0x364, 0x390, "BaTelCo" },
- { 0x426, -1, "Bahrain" },
- { 0x426, 0x01f, "BHR Mobile Plus" },
- { 0x426, 0x02f, "zain BH" }, /* ? */
- { 0x426, 0x04f, "VIVA" }, /* ? */
- { 0x470, -1, "Bangladesh" },
- { 0x470, 0x01f, "Grameenphone" },
- { 0x470, 0x02f, "Aktel" },
- { 0x470, 0x03f, "Mobile 2000" },
- { 0x470, 0x04f, "TeleTalk" }, /* ? */
- { 0x470, 0x05f, "Citycell" }, /* ? */
- { 0x470, 0x06f, "Warid" }, /* ? */
- { 0x470, 0x07f, "WTBL" }, /* ? */
- { 0x342, -1, "Barbados" },
- { 0x342, 0x600, "Cable & Wireless (Barbados) Ltd." },
- { 0x342, 0x750, "Digicel" }, /* ? */
- { 0x342, 0x820, "Sunbeach Communications" },
- { 0x257, -1, "Belarus" },
- { 0x257, 0x01f, "MCD Velcom" },
- { 0x257, 0x02f, "MTS" },
- { 0x257, 0x04f, "life:)" }, /* ? */
- { 0x257, 0x03f, "DIALLOG" }, /* ? */
- { 0x206, -1, "Belgium" },
- { 0x206, 0x01f, "Proximus" },
- { 0x206, 0x02f, "SNCB GSM-R" }, /* ? */
- { 0x206, 0x10f, "Mobistar" },
- { 0x206, 0x20f, "BASE" },
- { 0x702, -1, "Belize" },
- { 0x702, 0x67f, "Belize Telemedia" },
- { 0x702, 0x68f, "International Telecommunications Ltd." },
- { 0x702, 0x00f, "Smart" }, /* ? */
- { 0x616, -1, "Benin" },
- { 0x616, 0x01f, "Libercom" },
- { 0x616, 0x02f, "Telecel" },
- { 0x616, 0x03f, "Spacetel Benin" },
- { 0x616, 0x04f, "BBCOM" }, /* ? */
- { 0x616, 0x05f, "Glo" }, /* ? */
- { 0x350, -1, "Bermuda" },
- { 0x350, 0x01f, "Digicel Bermuda" }, /* ? */
- { 0x350, 0x02f, "Mobility" }, /* ? */
- { 0x338, 0x050, "Digicel Bermuda" }, /* ? */
- { 0x310, 0x00f, "Cellular One" }, /* ? */
- { 0x402, -1, "Bhutan" },
- { 0x402, 0x11f, "Bhutan Telecom Ltd" },
- { 0x402, 0x77f, "B-Mobile" },
- { 0x736, -1, "Bolivia" },
- { 0x736, 0x01f, "Nuevatel" },
- { 0x736, 0x02f, "Entel" },
- { 0x736, 0x03f, "Telecel" },
- { 0x218, -1, "Bosnia and Herzegovina" },
- { 0x218, 0x03f, "HT-ERONET" },
- { 0x218, 0x05f, "MOBI'S" },
- { 0x218, 0x90f, "GSMBIH" },
- { 0x652, -1, "Botswana" },
- { 0x652, 0x01f, "Mascom" },
- { 0x652, 0x02f, "Orange" },
- { 0x652, 0x04f, "BTC Mobile" },
- { 0x724, -1, "Brazil" },
- { 0x724, 0x00f, "Telet" },
- { 0x724, 0x01f, "CRT Cellular" },
- { 0x724, 0x02f, "TIM" },
- { 0x724, 0x03f, "TIM" },
- { 0x724, 0x04f, "TIM" },
- { 0x724, 0x05f, "Claro" },
- { 0x724, 0x06f, "Vivo" },
- { 0x724, 0x07f, "CTBC Celular" },
- { 0x724, 0x08f, "TIM" },
- { 0x724, 0x10f, "Vivo" },
- { 0x724, 0x11f, "Vivo" },
- { 0x724, 0x15f, "Sercomtel" },
- { 0x724, 0x16f, "Oi / Brasil Telecom" },
- { 0x724, 0x23f, "Vivo" },
- { 0x724, 0x24f, "Oi / Amazonia Celular" },
- { 0x724, 0x31f, "Oi" },
- { 0x724, 0x32f, "CTBC Celular" },
- { 0x724, 0x33f, "CTBC Celular" },
- { 0x724, 0x34f, "CTBC Celular" },
- { 0x724, 0x35f, "TIM" },
- { 0x724, 0x37f, "aeiou" },
- { 0x724, 0x39f, "TIM" },
- { 0x724, 0x41f, "TIM" },
- { 0x724, 0x43f, "TIM" },
- { 0x724, 0x45f, "TIM" },
- { 0x724, 0x47f, "TIM" },
- { 0x724, 0x48f, "TIM" },
- { 0x724, 0x51f, "TIM" },
- { 0x724, 0x53f, "TIM" },
- { 0x724, 0x55f, "TIM" },
- { 0x724, 0x57f, "TIM" },
- { 0x724, 0x59f, "TIM" },
- { 0x724, 0x00f, "Nextel" },
- { 0x348, -1, "British Virgin Islands" },
- { 0x348, 0x170, "Cable & Wireless" },
- { 0x348, 0x370, "BVI Cable TV Ltd" },
- { 0x348, 0x570, "CCT Boatphone" },
- { 0x348, 0x770, "Digicel (BVI) Ltd" },
- { 0x528, -1, "Brunei" },
- { 0x528, 0x01f, "Jabatan Telekom" }, /* ? */
- { 0x528, 0x02f, "B-Mobile" }, /* ? */
- { 0x528, 0x11f, "DSTCom" },
- { 0x284, -1, "Bulgaria" },
- { 0x284, 0x01f, "M-Tel" },
- { 0x284, 0x03f, "Vivacom" }, /* ? */
- { 0x284, 0x05f, "GLOBUL" },
- { 0x613, -1, "Burkina Faso" },
- { 0x613, 0x01f, "Onatel" }, /* ? */
- { 0x613, 0x02f, "Celtel / Zain" },
- { 0x613, 0x03f, "Telecel Faso" },
- { 0x642, -1, "Burundi" },
- { 0x642, 0x01f, "Econet / Spacetel" },
- { 0x642, 0x02f, "Africell" },
- { 0x642, 0x03f, "Onamob" },
- { 0x642, 0x07f, "Lacell" },
- { 0x642, 0x08f, "Hits" },
- { 0x642, 0x82f, "U.COM / Onatel" },
- { 0x456, -1, "Cambodia" },
- { 0x456, 0x01f, "Mobitel" },
- { 0x456, 0x02f, "hello" },
- { 0x456, 0x03f, "S Telecom" },
- { 0x456, 0x04f, "Cadcomms / qb" },
- { 0x456, 0x05f, "Star-Cell" },
- { 0x456, 0x06f, "Smart" },
- { 0x456, 0x08f, "Viettel" },
- { 0x456, 0x18f, "Mfone" },
-// { 0x456, ?, "Excell" }, /* ? */
- { 0x456, 0x09f, "Beeline" }, /* ? */
- { 0x456, 0x08f, "Metfone" }, /* ? */
- { 0x624, -1, "Cameroon" },
- { 0x624, 0x01f, "MTN Cameroon" },
- { 0x624, 0x02f, "Orange" },
- { 0x302, -1, "Canada" },
- { 0x302, 0x220, "Telus" },
- { 0x302, 0x221, "Telus" },
- { 0x302, 0x290, "Airtel Wireless" },
- { 0x302, 0x350, "FIRST" },
- { 0x302, 0x360, "MiKe" },
- { 0x302, 0x361, "Telus" },
- { 0x302, 0x370, "Fido" },
- { 0x302, 0x380, "DMTS" },
- { 0x302, 0x490, "WIND Mobile" },
- { 0x302, 0x500, "Videotron" },
- { 0x302, 0x510, "Videotron" },
- { 0x302, 0x610, "Bell" },
- { 0x302, 0x620, "ICE Wireless" },
- { 0x302, 0x640, "Bell" },
- { 0x302, 0x651, "Bell" },
- { 0x302, 0x652, "BC Tel Mobility (Telus)" },
- { 0x302, 0x653, "Telus" },
- { 0x302, 0x655, "MTS" },
- { 0x302, 0x656, "TBay" },
- { 0x302, 0x657, "Telus" },
- { 0x302, 0x680, "SaskTel" },
- { 0x302, 0x701, "MB Tel Mobility" },
- { 0x302, 0x702, "MT&T Mobility (Aliant)" },
- { 0x302, 0x703, "New Tel Mobility (Aliant)" },
- { 0x302, 0x710, "Globalstar" },
- { 0x302, 0x720, "Rogers Wireless" },
- { 0x302, 0x780, "SaskTel" },
- { 0x302, 0x880, "Bell / Telus" },
- { 0x625, -1, "Cape Verde" },
- { 0x625, 0x01f, "CVMOVEL" },
- { 0x625, 0x02f, "T+" },
- { 0x346, -1, "Cayman Islands" },
- { 0x346, 0x140, "Cable & Wireless" },
- { 0x338, 0x050, "Digicel" }, /* ? */
- { 0x623, -1, "Central African Republic" },
- { 0x623, 0x01f, "CTP" },
- { 0x623, 0x02f, "TC" },
- { 0x623, 0x03f, "Celca / Socatel / Orange" },
- { 0x623, 0x04f, "Nationlink" }, /* ? */
- { 0x622, -1, "Chad" },
- { 0x622, 0x01f, "Celtel / Zain" },
- { 0x622, 0x02f, "Tchad Mobile" },
- { 0x622, 0x03f, "TIGO - Millicom" }, /* ? */
- { 0x622, 0x02f, "TAWALI" }, /* ? */
- { 0x622, 0x04f, "Salam" }, /* ? */
- { 0x730, -1, "Chile" },
- { 0x730, 0x01f, "Entel" },
- { 0x730, 0x02f, "movistar" },
- { 0x730, 0x03f, "Smartcom / Claro" },
- { 0x730, 0x04f, "Centennial Cayman Corp / Nextel" },
- { 0x730, 0x05f, "Multikom S.A." },
- { 0x730, 0x06f, "Blue Two Chile S.A." },
- { 0x730, 0x07f, "Telefonica" },
- { 0x730, 0x10f, "Entel" },
- { 0x730, 0x99f, "WILL" }, /* ? */
- { 0x460, -1, "China" },
- { 0x460, 0x00f, "China Mobile" },
- { 0x460, 0x01f, "China Unicom" },
- { 0x460, 0x02f, "China Mobile" },
- { 0x460, 0x03f, "China Unicom CMDA" },
- { 0x460, 0x04f, "China Satellite Global Star Network" },
- { 0x460, 0x05f, "China Telecom" }, /* ? */
- { 0x460, 0x06f, "China Unicom" }, /* ? */
- { 0x460, 0x20f, "China TIETONG" }, /* ? */
- { 0x732, -1, "Colombia" },
- { 0x732, 0x001, "Colombia Telecomunicaciones S.A." },
- { 0x732, 0x002, "Edatel" },
- { 0x732, 0x020, "Emtelsa" },
- { 0x732, 0x099, "Emcali" },
- { 0x732, 0x101, "Comcel" },
- { 0x732, 0x102, "Bellsouth / movistar" },
- { 0x732, 0x103, "Colombia Movil / Tigo" },
- { 0x732, 0x111, "Colombia Movil / Tigo" },
- { 0x732, 0x123, "movistar" },
- { 0x732, 0x12f, "movistar" }, /* ? */
- { 0x732, 0x130, "Avantel" },
- { 0x654, -1, "Comoros" },
- { 0x654, 0x01f, "HURI - SNPT" },
- { 0x629, -1, "Republic of the Congo" },
- { 0x629, 0x01f, "Celtel / Zain" },
- { 0x629, 0x10f, "Libertis Telecom" },
-// { 0x629, ?, "Warid Telecom" },
- { 0x548, -1, "Cook Islands" },
- { 0x548, 0x01f, "Telecom Cook" },
- { 0x712, -1, "Costa Rica" },
- { 0x712, 0x01f, "ICE" },
- { 0x712, 0x02f, "ICE" }, /* ? */
- { 0x712, 0x03f, "ICE" }, /* ? */
- { 0x219, -1, "Croatia" },
- { 0x219, 0x01f, "T-Mobile" },
- { 0x219, 0x02f, "Tele2" },
- { 0x219, 0x10f, "VIPnet" },
- { 0x368, -1, "Cuba" },
- { 0x368, 0x01f, "ETECSA" },
- { 0x280, -1, "Cyprus" },
- { 0x280, 0x01f, "Cytamobile-Vodafone" },
- { 0x280, 0x10f, "Scanacom / MTN" },
- { 0x230, -1, "Czech Republic" },
- { 0x230, 0x01f, "T-Mobile" },
- { 0x230, 0x02f, "O2" },
- { 0x230, 0x03f, "Vodafone" },
- { 0x230, 0x04f, "Mobilkom / U:fon" },
- { 0x230, 0x98f, "SZDC s.o." },
- { 0x230, 0x99f, "Vodafone" },
- { 0x630, -1, "Democratic Republic of the Congo" },
- { 0x630, 0x01f, "Vodacom" },
- { 0x630, 0x02f, "Zain" }, /* ? */
- { 0x630, 0x04f, "Cellco" }, /* ? */
- { 0x630, 0x05f, "Supercell" },
- { 0x630, 0x86f, "CCT" },
- { 0x630, 0x89f, "SAIT Telecom" }, /* ? */
-// { 0x630, ?, "Africell" },
- { 0x238, -1, "Denmark" },
- { 0x238, 0x01f, "TDC" },
- { 0x238, 0x02f, "Sonofon / Telenor" },
- { 0x238, 0x03f, "MIGway A/S" },
- { 0x238, 0x05f, "ApS KBUS" },
- { 0x238, 0x06f, "Hi3G" },
- { 0x238, 0x07f, "Lycamobile / Barablu Mobile" },
- { 0x238, 0x09f, "Dansk Beredskabskommunikation A/S" }, /* ? */
- { 0x238, 0x10f, "TDC" },
- { 0x238, 0x11f, "Dansk Beredskabskommunikation A/S" }, /* ? */
- { 0x238, 0x12f, "Lycamobile Denmark Ltd" },
- { 0x238, 0x20f, "Telia" },
- { 0x238, 0x30f, "Telia" },
- { 0x238, 0x40f, "Ericsson Danmark A/S" }, /* ? */
- { 0x238, 0x77f, "Tele2 / Telenor" },
- { 0x638, -1, "Djibouti" },
- { 0x638, 0x01f, "Evatis" },
- { 0x366, -1, "Dominica" },
- { 0x366, 0x020, "Digicel" }, /* ? */
- { 0x366, 0x110, "Cable & Wireless" }, /* ? */
- { 0x370, -1, "Dominican Republic" },
- { 0x370, 0x01f, "Orange" },
- { 0x370, 0x02f, "Verizon / Claro" },
- { 0x370, 0x03f, "Tricom" },
- { 0x370, 0x04f, "CentennialDominicana / Viva" },
- { 0x514, -1, "East Timor" },
- { 0x514, 0x02f, "Timor Telecom" }, /* ? */
- { 0x740, -1, "Ecuador" },
- { 0x740, 0x00f, "Otecel / Bellsouth / Movistar" },
- { 0x740, 0x01f, "Porta GSM" },
- { 0x740, 0x02f, "Telecsa / Alegro" },
- { 0x602, -1, "Egypt" },
- { 0x602, 0x01f, "Mobinil" },
- { 0x602, 0x02f, "Vodafone" },
- { 0x602, 0x03f, "Etisalat" },
- { 0x706, -1, "El Salvador" },
- { 0x706, 0x01f, "CTE Telecom Personal" },
- { 0x706, 0x02f, "digicel" },
- { 0x706, 0x03f, "Telemovil EL Salvador" },
- { 0x706, 0x04f, "movistar" }, /* ? */
- { 0x706, 0x10f, "Claro" }, /* ? */
- { 0x627, -1, "Equatorial Guinea" },
- { 0x627, 0x01f, "Orange GQ" },
- { 0x627, 0x03f, "Hits GQ" },
- { 0x657, -1, "Eritrea" },
- { 0x657, 0x01f, "Eritel" }, /* ? */
- { 0x248, -1, "Estonia" },
- { 0x248, 0x01f, "EMT" },
- { 0x248, 0x02f, "RLE / Elisa" },
- { 0x248, 0x03f, "Tele 2" },
- { 0x248, 0x04f, "OY Top Connect" },
- { 0x248, 0x05f, "AS Bravocom Mobiil" },
- { 0x248, 0x06f, "Pro Group Holding / ViaTel" },
- { 0x248, 0x07f, "Televorgu AS" },
- { 0x248, 0x71f, "Siseministeerium" },
- { 0x636, -1, "Ethiopia" },
- { 0x636, 0x01f, "ETMTN" },
- { 0x750, -1, "Falkland Islands (Malvinas)" },
- { 0x750, 0x001, "Touch" },
- { 0x288, -1, "Faroe Islands" },
- { 0x288, 0x01f, "Faroese Telecom" },
- { 0x288, 0x02f, "Kall / Vodafone" },
- { 0x274, 0x02f, "P/F Kall" },
- { 0x542, -1, "Fiji" },
- { 0x542, 0x01f, "Vodafone" },
- { 0x542, 0x02f, "Digicel" },
- { 0x542, 0x03f, "Telecom Fiji" },
- { 0x244, -1, "Finland" },
- { 0x244, 0x03f, "DNA" }, /* ? */
- { 0x244, 0x04f, "Finnet" },
- { 0x244, 0x05f, "Elisa" },
- { 0x244, 0x07f, "Nokia" },
- { 0x244, 0x08f, "Unknown" },
- { 0x244, 0x09f, "Finnet Group" },
- { 0x244, 0x10f, "TDC Oy" },
- { 0x244, 0x12f, "Finnet Networks / DNA" },
- { 0x244, 0x14f, "AMT" },
- { 0x244, 0x16f, "Oy Finland Tele2" },
- { 0x244, 0x21f, "Saunalahti" },
- { 0x244, 0x29f, "Scnl Truphone" }, /* ? */
- { 0x244, 0x91f, "Sonera" },
- { 0x208, -1, "France" },
- { 0x208, 0x00f, "Orange" }, /* ? */
- { 0x208, 0x01f, "Orange" },
- { 0x208, 0x02f, "Orange" },
- { 0x208, 0x05f, "Globalstar Europe" },
- { 0x208, 0x06f, "Globalstar Europe" },
- { 0x208, 0x07f, "Globalstar Europe" },
- { 0x208, 0x10f, "SFR" },
- { 0x208, 0x11f, "SFR" },
- { 0x208, 0x13f, "SFR" }, /* ? */
- { 0x208, 0x20f, "Bouygues" },
- { 0x208, 0x21f, "Bouygues" },
- { 0x208, 0x22f, "Transatel Mobile" },
- { 0x208, 0x88f, "Bouygues" },
- { 0x628, -1, "Gabon" },
- { 0x628, 0x01f, "Libertis" },
- { 0x628, 0x02f, "Moov (Telecel) Gabon S.A." },
- { 0x628, 0x03f, "Celtel / Zain" },
- { 0x628, 0x04f, "USAN Gabon" },
- { 0x607, -1, "Gambia" },
- { 0x607, 0x01f, "Gamcel" },
- { 0x607, 0x02f, "Africel" },
- { 0x607, 0x03f, "Comium" },
- { 0x607, 0x04f, "QCell" }, /* ? */
- { 0x282, -1, "Georgia" },
- { 0x282, 0x01f, "Geocell" },
- { 0x282, 0x02f, "MagtiCom" },
- { 0x282, 0x03f, "Iberiatel" },
- { 0x282, 0x04f, "Beeline" },
- { 0x282, 0x05f, "Silknet JSC" },
- { 0x289, 0x67f, "Aquafon" }, /* ? */
- { 0x289, 0x88f, "A-Mobile" }, /* ? */
- { 0x262, -1, "Germany" },
- { 0x262, 0x01f, "T-Mobile" },
- { 0x262, 0x02f, "Vodafone" },
- { 0x262, 0x03f, "E-Plus" },
- { 0x262, 0x04f, "Vodafone" },
- { 0x262, 0x05f, "E-Plus" },
- { 0x262, 0x06f, "T-Mobile" },
- { 0x262, 0x07f, "O2" },
- { 0x262, 0x08f, "O2" },
- { 0x262, 0x09f, "Vodafone" },
- { 0x262, 0x10f, "DB Systel GSM-R" },
- { 0x262, 0x11f, "O2" },
- { 0x262, 0x12f, "Dolphin Telecom" },
- { 0x262, 0x13f, "Mobilcom Multimedia" },
- { 0x262, 0x14f, "Group 3G UMTS" },
- { 0x262, 0x15f, "Airdata" },
- { 0x262, 0x16f, "Vistream" }, /* ? */
- { 0x262, 0x42f, "OpenBSC" }, /* ? */
- { 0x262, 0x60f, "DB Telematik" },
- { 0x262, 0x76f, "Siemens AG" },
- { 0x262, 0x77f, "E-Plus" },
- { 0x262, 0x901, "Debitel" }, /* ? */
- { 0x620, -1, "Ghana" },
- { 0x620, 0x01f, "Spacefon / MTN" },
- { 0x620, 0x02f, "Ghana Telecom Mobile / Vodafone" },
- { 0x620, 0x03f, "Mobiltel / tiGO" },
- { 0x620, 0x04f, "Kasapa / Hutchison Telecom" },
- { 0x620, 0x06f, "Zain" }, /* ? */
- { 0x620, 0x10f, "Netafriques" }, /* ? */
- { 0x266, -1, "Gibraltar" },
- { 0x266, 0x01f, "GibTel" },
- { 0x266, 0x06f, "CTS Mobile" },
- { 0x266, 0x09f, "Cloud9 Mobile Communications" },
- { 0x202, -1, "Greece" },
- { 0x202, 0x01f, "Cosmote" },
- { 0x202, 0x05f, "Vodafone" },
- { 0x202, 0x09f, "Infoquest / Wind" },
- { 0x202, 0x10f, "Wind" },
- { 0x290, -1, "Greenland" },
- { 0x290, 0x01f, "TELE Greenland A/S" },
- { 0x352, -1, "Grenada" },
- { 0x352, 0x030, "Digicel" },
- { 0x352, 0x110, "Cable & Wireless" },
- { 0x340, -1, "Guadeloupe" },
- { 0x340, 0x01f, "Orange" },
- { 0x340, 0x02f, "Outremer" },
- { 0x340, 0x03f, "Telcell" },
- { 0x340, 0x08f, "MIO GSM" },
- { 0x340, 0x10f, "Guadeloupe Telephone Mobile" },
- { 0x340, 0x20f, "Digicel" },
- { 0x310, -1, "United States of America" },
- { 0x310, 0x010, "Verizon Wireless" },
- { 0x310, 0x012, "Verizon Wireless" },
- { 0x310, 0x013, "Verizon Wireless" },
- { 0x310, 0x016, "Cricket Communications" },
- { 0x310, 0x017, "North Sight Communications Inc." },
- { 0x310, 0x020, "Union Telephone Company" },
- { 0x310, 0x030, "Centennial Communications" },
- { 0x310, 0x035, "ETEX Communications dba ETEX Wireless" },
- { 0x310, 0x040, "MTA Communications dba MTA Wireless" },
- { 0x310, 0x050, "ACS Wireless Inc." },
- { 0x310, 0x060, "Consolidated Telecom" },
- { 0x310, 0x070, "Cingular Wireless" },
- { 0x310, 0x080, "Corr Wireless Communications LLC" },
- { 0x310, 0x090, "Cingular Wireless" },
- { 0x310, 0x100, "New Mexicu RSA 4 East Ltd. Partnership" },
- { 0x310, 0x110, "Pacific Telecom Inc." },
- { 0x310, 0x130, "Carolina West Wireless" },
- { 0x310, 0x140, "GTA Wireless LLC" },
- { 0x310, 0x150, "Cingular Wireless" },
- { 0x310, 0x160, "T-Mobile USA" },
- { 0x310, 0x170, "Cingular Wireless" },
- { 0x310, 0x180, "West Central Wireless" },
- { 0x310, 0x190, "Alaska Wireless Communications LLC" },
- { 0x310, 0x200, "T-Mobile USA" },
- { 0x310, 0x210, "T-Mobile USA" },
- { 0x310, 0x220, "T-Mobile USA" },
- { 0x310, 0x230, "T-Mobile USA" },
- { 0x310, 0x240, "T-Mobile USA" },
- { 0x310, 0x250, "T-Mobile USA" },
- { 0x310, 0x260, "T-Mobile USA" },
- { 0x310, 0x270, "T-Mobile USA" },
- { 0x310, 0x280, "Contennial Puerto Rio License Corp." },
- { 0x310, 0x290, "Nep Cellcorp Inc." },
- { 0x310, 0x300, "Blanca Telephone Company" },
- { 0x310, 0x310, "T-Mobile USA" },
- { 0x310, 0x320, "Simth Bagley Inc, dba Cellular One" },
- { 0x310, 0x340, "High Plains Midwest LLC, dba Wetlink Communications" },
- { 0x310, 0x350, "Mohave Cellular L.P." },
- { 0x310, 0x360, "Cellular Network Partnership dba Pioneer Cellular" },
- { 0x310, 0x370, "Guamcell Cellular and Paging" },
- { 0x310, 0x380, "New Cingular Wireless PCS, LLC" },
- { 0x310, 0x390, "TX-11 Acquisition LLC" },
- { 0x310, 0x400, "Wave Runner LLC" },
- { 0x310, 0x410, "Cingular Wireless" },
- { 0x310, 0x420, "Cincinnati Bell Wireless LLC" },
- { 0x310, 0x430, "Alaska Digital LLC" },
- { 0x310, 0x440, "Numerex Corp" },
- { 0x310, 0x450, "North East Cellular Inc" },
- { 0x310, 0x460, "TMP Corporation" },
- { 0x310, 0x470, "nTELOS Communications Inc" },
- { 0x310, 0x480, "Choice Phone LLC" },
- { 0x310, 0x490, "T-Mobile USA" },
- { 0x310, 0x500, "Public Service Cellular, Inc." },
- { 0x310, 0x520, "Transactions Network Services" },
- { 0x310, 0x530, "Iowa Wireless Services LLC" },
- { 0x310, 0x540, "Oklahoma Western Telephone Company" },
- { 0x310, 0x550, "Wireless Solutions International" },
- { 0x310, 0x560, "Cingular Wireless" },
- { 0x310, 0x570, "MTPCS LLC" },
- { 0x310, 0x580, "Inland Celluar Telephone Company" },
- { 0x310, 0x590, "Western Wireless Corporation" },
- { 0x310, 0x600, "New Cell Inc. dba Cellcom" },
- { 0x310, 0x610, "Elkhart Telephone Co. Inc. dba Epic Touch Co." },
- { 0x310, 0x620, "Coleman County Telecommunications Inc. (Trans Texas PCS)" },
- { 0x310, 0x640, "Airadigm Communications" },
- { 0x310, 0x650, "Jasper Wireless Inc." },
- { 0x310, 0x660, "T-Mobile USA" },
- { 0x310, 0x670, "AT&T Mobility Vanguard Services" },
- { 0x310, 0x680, "Cingular Wireless" },
- { 0x310, 0x690, "Keystane Wireless LLC" },
- { 0x310, 0x700, "Cross Valiant Cellular Partnership" },
- { 0x310, 0x710, "Arctic Slope Telephone Association Cooperative" },
- { 0x310, 0x720, "Wireless Solutions International Inc." },
- { 0x310, 0x730, "US Cellular" },
- { 0x310, 0x740, "Convey Communications Inc" },
- { 0x310, 0x750, "East Kentucky Network LLC dba Appalachian Wireless" },
- { 0x310, 0x760, "Lynch 3G Communcations Corporation" },
- { 0x310, 0x770, "Iowa Wireless Services LLC dba I Wireless" },
- { 0x310, 0x780, "Connect Net Inc" },
- { 0x310, 0x790, "PinPoint Communications Inc."},
- { 0x310, 0x800, "T-Mobile USA" },
- { 0x310, 0x810, "LCFR LLC" },
- { 0x310, 0x820, "South Canaan Cellular Communications Co. LP" },
- { 0x310, 0x830, "Caprock Cellular Ltd. Partnership" },
- { 0x310, 0x840, "Telecom North America Mobile Inc" },
- { 0x310, 0x850, "Aeris Communications Inc." },
- { 0x310, 0x860, "TX RSA 15B2, LP dba Five Star Wireless" },
- { 0x310, 0x870, "Kaplan Telephone Company, Inc" },
- { 0x310, 0x890, "Rural Cellular Corporation" },
- { 0x310, 0x900, "Cable & Communications Corporation dba Mid-Rivers Wireless" },
- { 0x310, 0x910, "Verizon Wireless" },
- { 0x310, 0x930, "Copper Valley Wireless" },
- { 0x310, 0x940, "Iris Wireless LLC" },
- { 0x310, 0x950, "Texas RSA 1 dba XIT Wireless" },
- { 0x310, 0x960, "UBET Wireless" },
- { 0x310, 0x970, "Globalstar USA" },
- { 0x310, 0x980, "Texas RSA 7B3 dba Peoples Wireless Services" },
- { 0x310, 0x99, "Worldcall Interconnect" },
-
- { 0x704, -1, "Guatemala" },
- { 0x704, 0x01f, "Claro" },
- { 0x704, 0x02f, "Comcel / Tigo" },
- { 0x704, 0x03f, "movistar" },
-// { 0x704, ?, "digicel" },
- { 0x234, -1, "Guernsey" },
- { 0x234, 0x55f, "Sure Mobile" },
- { 0x234, 0x50f, "Wave Telecom" },
- { 0x234, 0x03f, "Airtel Vodafone" },
- { 0x611, -1, "Guinea" },
- { 0x611, 0x01f, "Orange / Spacetel" },
- { 0x611, 0x02f, "Sotelgui / Lagui" },
- { 0x611, 0x03f, "Telecel Guinee" }, /* ? */
- { 0x611, 0x04f, "MTN" }, /* ? */
- { 0x611, 0x05f, "Cellcom Guinee" },
- { 0x632, -1, "Guinea-Bissau" },
- { 0x632, 0x01f, "Guinetel" },
- { 0x632, 0x02f, "Spacetel / Areeba" },
- { 0x632, 0x03f, "Orange" },
- { 0x738, -1, "Guyana" },
- { 0x738, 0x01f, "Digicel" },
- { 0x738, 0x02f, "GT&T Cellink Plus" }, /* ? */
- { 0x372, -1, "Haiti" },
- { 0x372, 0x01f, "Comcel / Voila" },
- { 0x338, 0x050, "Digicel" },
- { 0x338, 0x03f, "Rectel" },
- { 0x708, -1, "Honduras" },
- { 0x708, 0x01f, "Claro" },
- { 0x708, 0x02f, "Celtel / Tigo" },
- { 0x708, 0x30f, "Hondutel" }, /* ? */
- { 0x708, 0x40f, "DIGICEL" },
- { 0x454, -1, "Hong Kong" },
- { 0x454, 0x00f, "1O1O and One2Free" },
- { 0x454, 0x01f, "CITIC Telecom 1616" },
- { 0x454, 0x02f, "CSL Limited" },
- { 0x454, 0x03f, "3 (3G)" },
- { 0x454, 0x04f, "3 DualBand (2G)" },
- { 0x454, 0x05f, "3 CDMA" },
- { 0x454, 0x06f, "SmarTone-Vodafone" },
- { 0x454, 0x07f, "China Unicom (Hong Kong) Limited" },
- { 0x454, 0x08f, "Trident" },
- { 0x454, 0x09f, "China Motion Telecom" },
- { 0x454, 0x10f, "New World Mobility" },
- { 0x454, 0x11f, "China-Hongkong Telecom" },
- { 0x454, 0x12f, "CMCC HK" },
- { 0x454, 0x14f, "Hutchison Telecom" },
- { 0x454, 0x15f, "SmarTone Mobile Communications Limited" },
- { 0x454, 0x16f, "PCCW Mobile (2G)" },
- { 0x454, 0x17f, "SmarTone Mobile Communications Limited" },
- { 0x454, 0x18f, "CSL Limited" },
- { 0x454, 0x19f, "Sunday3G" },
- { 0x454, 0x19f, "PCCW Mobile (3G)" },
- { 0x454, 0x29f, "PCCW Mobile (CDMA)" },
- { 0x216, -1, "Hungary" },
- { 0x216, 0x01f, "Pannon GSM" },
- { 0x216, 0x30f, "Westel 900" },
- { 0x216, 0x70f, "Vodafone" },
- { 0x274, -1, "Iceland" },
- { 0x274, 0x01f, "Siminn" },
- { 0x274, 0x02f, "Vodafone" },
- { 0x274, 0x03f, "Vodafone" },
- { 0x274, 0x04f, "IMC Viking" },
- { 0x274, 0x06f, "N?ll n?u ehf" }, /* ? */
- { 0x274, 0x07f, "IceCell" },
- { 0x274, 0x08f, "On-waves" },
- { 0x274, 0x11f, "Nova" },
- /* FIXME: update the list from here below */
- { 0x404, -1, "India" },
- { 0x404, 0x01f, "Vodafone IN" },
- { 0x404, 0x02f, "AirTel" },
- { 0x404, 0x04f, "IDEA" },
- { 0x404, 0x05f, "Vodafone IN" },
- { 0x404, 0x07f, "IDEA" },
- { 0x404, 0x09f, "Reliance" },
- { 0x404, 0x10f, "AirTel" },
- { 0x404, 0x11f, "Vodafone IN" },
- { 0x404, 0x12f, "IDEA" },
- { 0x404, 0x13f, "Vodafone IN" },
- { 0x404, 0x14f, "IDEA" },
- { 0x404, 0x15f, "Vodafone IN" },
- { 0x404, 0x17f, "AIRCEL" },
- { 0x404, 0x19f, "IDEA" },
- { 0x404, 0x20f, "Vodafone IN" },
- { 0x404, 0x21f, "Loop Mobile" },
- { 0x404, 0x22f, "IDEA" },
- { 0x404, 0x24f, "IDEA" },
- { 0x404, 0x27f, "Vodafone IN" },
- { 0x404, 0x28f, "AIRCEL" },
- { 0x404, 0x29f, "AIRCEL" },
- { 0x404, 0x30f, "Vodafone IN" },
- { 0x404, 0x31f, "AirTel" },
- { 0x404, 0x34f, "CellOne" },
- { 0x404, 0x36f, "Reliance" },
- { 0x404, 0x37f, "Aircel" },
- { 0x404, 0x38f, "CellOne" },
- { 0x404, 0x41f, "Aircel" },
- { 0x404, 0x42f, "Aircel" },
- { 0x404, 0x44f, "IDEA" },
- { 0x404, 0x45f, "Airtel" },
- { 0x404, 0x51f, "CellOne" },
- { 0x404, 0x52f, "Reliance" },
- { 0x404, 0x53f, "CellOne" },
- { 0x404, 0x54f, "CellOne" },
- { 0x404, 0x55f, "CellOne" },
- { 0x404, 0x56f, "IDEA" },
- { 0x404, 0x57f, "CellOne" },
- { 0x404, 0x58f, "CellOne" },
- { 0x404, 0x59f, "CellOne" },
- { 0x404, 0x60f, "Vodafone IN" },
- { 0x404, 0x62f, "CellOne" },
- { 0x404, 0x64f, "CellOne" },
- { 0x404, 0x66f, "CellOne" },
- { 0x404, 0x67f, "Reliance GSM" },
- { 0x404, 0x68f, "DOLPHIN" },
- { 0x404, 0x69f, "DOLPHIN" },
- { 0x404, 0x72f, "CellOne" },
- { 0x404, 0x74f, "CellOne" },
- { 0x404, 0x76f, "CellOne" },
- { 0x404, 0x78f, "Idea Cellular Ltd" },
- { 0x404, 0x80f, "BSNL MOBILE" },
- { 0x404, 0x81f, "CellOne" },
- { 0x404, 0x82f, "Idea" },
- { 0x404, 0x83f, "Reliance Smart GSM" },
- { 0x404, 0x84f, "Vodafone IN" },
- { 0x404, 0x85f, "Reliance" },
- { 0x404, 0x86f, "Vodafone IN" },
- { 0x404, 0x90f, "AirTel" },
- { 0x404, 0x91f, "AIRCEL" },
- { 0x404, 0x92f, "AirTel" },
- { 0x404, 0x93f, "AirTel" },
- { 0x404, 0x96f, "AirTel" },
- { 0x405, 0x05f, "Reliance" },
- { 0x405, 0x10f, "Reliance" },
- { 0x405, 0x13f, "Reliance" },
- { 0x405, 0x025, "TATA DOCOMO" },
- { 0x405, 0x026, "TATA DOCOMO" },
- { 0x405, 0x027, "TATA DOCOMO" },
- { 0x405, 0x029, "TATA DOCOMO" },
- { 0x405, 0x030, "TATA DOCOMO" },
- { 0x405, 0x031, "TATA DOCOMO" },
- { 0x405, 0x032, "TATA DOCOMO" },
- { 0x405, 0x034, "TATA DOCOMO" },
- { 0x405, 0x035, "TATA DOCOMO" },
- { 0x405, 0x036, "TATA DOCOMO" },
- { 0x405, 0x037, "TATA DOCOMO" },
- { 0x405, 0x038, "TATA DOCOMO" },
- { 0x405, 0x039, "TATA DOCOMO" },
- { 0x405, 0x041, "TATA DOCOMO" },
- { 0x405, 0x042, "TATA DOCOMO" },
- { 0x405, 0x043, "TATA DOCOMO" },
- { 0x405, 0x044, "TATA DOCOMO" },
- { 0x405, 0x045, "TATA DOCOMO" },
- { 0x405, 0x046, "TATA DOCOMO" },
- { 0x405, 0x047, "TATA DOCOMO" },
- { 0x405, 0x51f, "AirTel" },
- { 0x405, 0x52f, "AirTel" },
- { 0x405, 0x54f, "AirTel" },
- { 0x405, 0x56f, "AirTel" },
- { 0x405, 0x66f, "Vodafone IN" },
- { 0x405, 0x70f, "IDEA" },
- { 0x405, 0x750, "Vodafone IN" },
- { 0x405, 0x751, "Vodafone IN" },
- { 0x405, 0x752, "Vodafone IN" },
- { 0x405, 0x753, "Vodafone IN" },
- { 0x405, 0x754, "Vodafone IN" },
- { 0x405, 0x755, "Vodafone IN" },
- { 0x405, 0x756, "Vodafone IN" },
- { 0x405, 0x799, "IDEA" },
- { 0x405, 0x800, "AIRCEL" },
- { 0x405, 0x801, "AIRCEL" },
- { 0x405, 0x802, "AIRCEL" },
- { 0x405, 0x803, "AIRCEL" },
- { 0x405, 0x804, "AIRCEL" },
- { 0x405, 0x805, "AIRCEL" },
- { 0x405, 0x806, "AIRCEL" },
- { 0x405, 0x807, "AIRCEL" },
- { 0x405, 0x808, "AIRCEL" },
- { 0x405, 0x809, "AIRCEL" },
- { 0x405, 0x810, "AIRCEL" },
- { 0x405, 0x811, "AIRCEL" },
- { 0x405, 0x812, "AIRCEL" },
- { 0x405, 0x819, "Uninor" },
- { 0x405, 0x818, "[Uninor]" },
- { 0x405, 0x820, "Uninor" },
- { 0x405, 0x821, "Uninor" },
- { 0x405, 0x822, "Uninor" },
- { 0x405, 0x880, "Uninor" },
- { 0x405, 0x824, "Videocon Datacom" },
- { 0x405, 0x834, "Videocon Datacom" },
- { 0x405, 0x844, "Uninor" },
- { 0x405, 0x845, "IDEA" },
- { 0x405, 0x848, "IDEA" },
- { 0x405, 0x850, "IDEA" },
- { 0x405, 0x855, "Loop Mobile" },
- { 0x405, 0x864, "Loop Mobile" },
- { 0x405, 0x865, "Loop Mobile" },
- { 0x405, 0x875, "Uninor" },
- { 0x405, 0x881, "S Tel" },
- { 0x405, 0x912, "Etisalat DB" },
- { 0x405, 0x913, "Etisalat DB" },
- { 0x405, 0x917, "Etisalat DB" },
- { 0x405, 0x929, "Uninor" },
- { 0x510, -1, "Indonesia" },
- { 0x510, 0x00f, "PSN" },
- { 0x510, 0x01f, "INDOSAT" },
- { 0x510, 0x03f, "StarOne" },
- { 0x510, 0x07f, "TelkomFlexi" },
- { 0x510, 0x08f, "AXIS" },
- { 0x510, 0x09f, "SMART" },
- { 0x510, 0x10f, "Telkomsel" },
- { 0x510, 0x11f, "XL" },
- { 0x510, 0x20f, "TELKOMMobile" },
- { 0x510, 0x21f, "IM3" },
- { 0x510, 0x27f, "Ceria" },
- { 0x510, 0x28f, "Fren/Hepi" },
- { 0x510, 0x89f, "3" },
- { 0x510, 0x99f, "Esia " },
- { 0x432, -1, "Iran" },
- { 0x432, 0x11f, "MCI" },
- { 0x432, 0x14f, "TKC" },
- { 0x432, 0x19f, "MTCE" },
- { 0x432, 0x32f, "Taliya" },
- { 0x432, 0x35f, "Irancell" },
- { 0x418, -1, "Iraq" },
- { 0x418, 0x20f, "Zain IQ" },
- { 0x418, 0x30f, "Zain IQ" },
- { 0x418, 0x05f, "Asia Cell" },
- { 0x418, 0x40f, "Korek" },
- { 0x418, 0x08f, "SanaTel" },
-// { 0x418, ?, "IRAQNA" },
- { 0x272, -1, "Ireland" },
- { 0x272, 0x01f, "Vodafone" },
- { 0x272, 0x02f, "O2" },
- { 0x272, 0x03f, "Meteor" },
- { 0x272, 0x04f, "Access Telecom" },
- { 0x272, 0x05f, "3" },
- { 0x272, 0x07f, "Eircom" },
- { 0x272, 0x09f, "Clever Communications" },
- { 0x234, -1, "Isle of Man" },
- { 0x234, 0x58f, "Pronto GSM" },
- { 0x425, -1, "Israel" },
- { 0x425, 0x01f, "Orange" },
- { 0x425, 0x02f, "Cellcom" },
- { 0x425, 0x03f, "Pelephone" },
- { 0x425, 0x77f, "Mirs" },
- { 0x222, -1, "Italy" },
- { 0x222, 0x01f, "TIM" },
- { 0x222, 0x02f, "Elsacom" },
- { 0x222, 0x10f, "Vodafone" },
- { 0x222, 0x30f, "RFI" },
- { 0x222, 0x77f, "IPSE 2000" },
- { 0x222, 0x88f, "Wind" },
- { 0x222, 0x98f, "Blu" },
- { 0x222, 0x99f, "3 Italia" },
- { 0x612, -1, "Ivory Coast" },
- { 0x612, 0x01f, "Cora de Comstar" },
- { 0x612, 0x02f, "Moov" },
- { 0x612, 0x03f, "Orange" },
- { 0x612, 0x04f, "KoZ" },
- { 0x612, 0x05f, "MTN" },
- { 0x612, 0x06f, "ORICEL" },
- { 0x338, -1, "Jamaica" },
- { 0x338, 0x020, "LIME (formerly known as Cable & Wireless)" },
- { 0x338, 0x050, "Digicel" },
- { 0x338, 0x070, "Claro" },
- { 0x338, 0x180, "LIME (formerly known as Cable & Wireless)" },
- { 0x440, -1, "Japan" },
- { 0x440, 0x00f, "eMobile" },
- { 0x440, 0x01f, "NTT docomo" },
- { 0x440, 0x02f, "NTT docomo" },
- { 0x440, 0x03f, "NTT docomo" },
- { 0x440, 0x04f, "SoftBank" },
- { 0x440, 0x06f, "SoftBank" },
- { 0x440, 0x07f, "KDDI" },
- { 0x440, 0x08f, "KDDI" },
- { 0x440, 0x09f, "NTT docomo" },
- { 0x440, 0x10f, "NTT docomo" },
- { 0x440, 0x11f, "NTT docomo" },
- { 0x440, 0x12f, "NTT docomo" },
- { 0x440, 0x13f, "NTT docomo" },
- { 0x440, 0x14f, "NTT docomo" },
- { 0x440, 0x15f, "NTT docomo" },
- { 0x440, 0x16f, "NTT docomo" },
- { 0x440, 0x17f, "NTT docomo" },
- { 0x440, 0x18f, "NTT docomo" },
- { 0x440, 0x19f, "NTT docomo" },
- { 0x440, 0x20f, "SoftBank" },
- { 0x440, 0x21f, "NTT docomo" },
- { 0x440, 0x22f, "NTT docomo" },
- { 0x440, 0x23f, "DoCoMo" },
- { 0x440, 0x24f, "DoCoMo" },
- { 0x440, 0x25f, "DoCoMo" },
- { 0x440, 0x26f, "DoCoMo" },
- { 0x440, 0x27f, "DoCoMo" },
- { 0x440, 0x28f, "DoCoMo" },
- { 0x440, 0x29f, "DoCoMo" },
- { 0x440, 0x30f, "DoCoMo" },
- { 0x440, 0x31f, "DoCoMo" },
- { 0x440, 0x32f, "DoCoMo" },
- { 0x440, 0x33f, "DoCoMo" },
- { 0x440, 0x34f, "DoCoMo" },
- { 0x440, 0x35f, "DoCoMo" },
- { 0x440, 0x36f, "DoCoMo" },
- { 0x440, 0x37f, "DoCoMo" },
- { 0x440, 0x38f, "DoCoMo" },
- { 0x440, 0x39f, "DoCoMo" },
- { 0x440, 0x40f, "SoftBank" },
- { 0x440, 0x41f, "SoftBank" },
- { 0x440, 0x42f, "SoftBank" },
- { 0x440, 0x43f, "SoftBank" },
- { 0x440, 0x44f, "SoftBank" },
- { 0x440, 0x45f, "SoftBank" },
- { 0x440, 0x46f, "SoftBank" },
- { 0x440, 0x47f, "SoftBank" },
- { 0x440, 0x48f, "SoftBank" },
- { 0x440, 0x49f, "DoCoMo" },
- { 0x440, 0x50f, "KDDI" },
- { 0x440, 0x51f, "KDDI" },
- { 0x440, 0x52f, "KDDI" },
- { 0x440, 0x53f, "KDDI" },
- { 0x440, 0x54f, "KDDI" },
- { 0x440, 0x55f, "KDDI" },
- { 0x440, 0x56f, "KDDI" },
- { 0x440, 0x58f, "DoCoMo" },
- { 0x440, 0x60f, "DoCoMo" },
- { 0x440, 0x61f, "DoCoMo" },
- { 0x440, 0x62f, "DoCoMo" },
- { 0x440, 0x63f, "DoCoMo" },
- { 0x440, 0x64f, "DoCoMo" },
- { 0x440, 0x65f, "DoCoMo" },
- { 0x440, 0x66f, "DoCoMo" },
- { 0x440, 0x67f, "DoCoMo" },
- { 0x440, 0x68f, "DoCoMo" },
- { 0x440, 0x69f, "DoCoMo" },
- { 0x440, 0x70f, "au" },
- { 0x440, 0x71f, "KDDI" },
- { 0x440, 0x72f, "KDDI" },
- { 0x440, 0x73f, "KDDI" },
- { 0x440, 0x74f, "KDDI" },
- { 0x440, 0x75f, "KDDI" },
- { 0x440, 0x76f, "KDDI" },
- { 0x440, 0x77f, "KDDI" },
- { 0x440, 0x78f, "Okinawa Cellular Telephone" },
- { 0x440, 0x79f, "KDDI" },
- { 0x440, 0x80f, "TU-KA" },
- { 0x440, 0x81f, "TU-KA" },
- { 0x440, 0x82f, "TU-KA" },
- { 0x440, 0x83f, "TU-KA" },
- { 0x440, 0x84f, "TU-KA" },
- { 0x440, 0x85f, "TU-KA" },
- { 0x440, 0x86f, "TU-KA" },
- { 0x440, 0x87f, "DoCoMo" },
- { 0x440, 0x88f, "KDDI" },
- { 0x440, 0x89f, "KDDI" },
- { 0x440, 0x90f, "SoftBank" },
- { 0x440, 0x92f, "SoftBank" },
- { 0x440, 0x93f, "SoftBank" },
- { 0x440, 0x94f, "SoftBank" },
- { 0x440, 0x95f, "SoftBank" },
- { 0x440, 0x96f, "SoftBank" },
- { 0x440, 0x97f, "SoftBank" },
- { 0x440, 0x98f, "SoftBank" },
- { 0x440, 0x99f, "DoCoMo" },
- { 0x234, -1, "Jersey" },
- { 0x234, 0x50f, "JT-Wave" },
- { 0x234, 0x55f, "Sure Mobile" },
- { 0x234, 0x03f, "Airtel Vodafone" },
- { 0x416, -1, "Jordan" },
- { 0x416, 0x01f, "zain JO" },
- { 0x416, 0x02f, "XPress Telecom" },
- { 0x416, 0x03f, "Umniah" },
- { 0x416, 0x77f, "Orange" },
- { 0x401, -1, "Kazakhstan" },
- { 0x401, 0x01f, "Beeline" },
- { 0x401, 0x02f, "Kcell" },
- { 0x401, 0x07f, "Dalacom" },
- { 0x401, 0x77f, "Mobile Telecom Service" },
- { 0x639, -1, "Kenya" },
- { 0x639, 0x02f, "Safaricom" },
- { 0x639, 0x03f, "Zain" },
- { 0x639, 0x07f, "Orange Kenya" },
- { 0x545, -1, "Kiribati" },
- { 0x545, 0x09f, "Kiribati Frigate" },
- { 0x467, -1, "North Korea" },
- { 0x467, 0x193, "SUN NET" },
- { 0x450, -1, "South Korea" },
- { 0x450, 0x02f, "KT" },
- { 0x450, 0x03f, "Power 017" },
- { 0x450, 0x04f, "KT" },
- { 0x450, 0x05f, "SKT" },
- { 0x450, 0x06f, "LGT" },
- { 0x450, 0x08f, "KT SHOW" },
- { 0x212, -1, "Kosovo" },
- { 0x212, 0x01f, "Vala" },
- { 0x293, 0x41f, "iPKO" },
- { 0x293, 0x41f, "D3 Mobile" },
- { 0x212, 0x01f, "Z Mobile" },
- { 0x419, -1, "Kuwait" },
- { 0x419, 0x02f, "zain KW" },
- { 0x419, 0x03f, "Wataniya" },
- { 0x419, 0x04f, "Viva" },
- { 0x437, -1, "Kyrgyzstan" },
- { 0x437, 0x01f, "Beeline" },
- { 0x437, 0x05f, "MegaCom" },
- { 0x437, 0x09f, "O!" },
- { 0x457, -1, "Laos" },
- { 0x457, 0x01f, "LaoTel" },
- { 0x457, 0x02f, "ETL" },
- { 0x457, 0x03f, "Unitel" },
- { 0x457, 0x08f, "Tigo" },
- { 0x247, -1, "Latvia" },
- { 0x247, 0x01f, "LMT" },
- { 0x247, 0x02f, "Tele2" },
- { 0x247, 0x03f, "TRIATEL" },
- { 0x247, 0x05f, "Bite" },
- { 0x247, 0x06f, "Rigatta" },
- { 0x247, 0x07f, "MTS" },
- { 0x247, 0x08f, "IZZI" },
- { 0x247, 0x09f, "Camel Mobile" },
- { 0x415, -1, "Lebanon" },
- { 0x415, 0x01f, "Alfa" },
- { 0x415, 0x03f, "MTC-Touch" },
- { 0x651, -1, "Lesotho" },
- { 0x651, 0x01f, "Vodacom" },
- { 0x651, 0x02f, "Econet Ezin-cel" },
- { 0x618, -1, "Liberia" },
- { 0x618, 0x01f, "Lonestar Cell" },
- { 0x618, 0x04f, "Comium" },
- { 0x618, 0x20f, "LIBTELCO" },
- { 0x606, -1, "Libya" },
- { 0x606, 0x00f, "Libyana" },
- { 0x606, 0x01f, "Madar" },
- { 0x295, -1, "Liechtenstein" },
- { 0x295, 0x01f, "Swisscom" },
- { 0x295, 0x02f, "Orange" },
- { 0x295, 0x05f, "FL1" },
- { 0x295, 0x77f, "Tele 2" },
- { 0x246, -1, "Lithuania" },
- { 0x246, 0x01f, "Omnitel" },
- { 0x246, 0x02f, "BITE" },
- { 0x246, 0x03f, "Tele 2" },
- { 0x270, -1, "Luxembourg" },
- { 0x270, 0x01f, "LuxGSM" },
- { 0x270, 0x77f, "Tango" },
- { 0x270, 0x99f, "Orange" },
- { 0x455, -1, "Macau" },
- { 0x455, 0x00f, "SmarTone" },
- { 0x455, 0x01f, "CTM" },
- { 0x455, 0x02f, "China Telecom" },
- { 0x455, 0x03f, "3" },
- { 0x455, 0x04f, "CTM" },
- { 0x455, 0x05f, "3" },
- { 0x294, -1, "Republic of Macedonia" },
- { 0x294, 0x01f, "T-Mobile MK" },
- { 0x294, 0x02f, "ONE" },
- { 0x294, 0x03f, "Vip MK" },
- { 0x646, -1, "Madagascar" },
- { 0x646, 0x01f, "Zain" },
- { 0x646, 0x02f, "Orange" },
- { 0x646, 0x03f, "Sacel" },
- { 0x646, 0x04f, "Telma" },
- { 0x650, -1, "Malawi" },
- { 0x650, 0x01f, "TNM" },
- { 0x650, 0x10f, "Zain" },
- { 0x502, -1, "Malaysia" },
- { 0x502, 0x12f, "Maxis" },
- { 0x502, 0x13f, "Celcom" },
- { 0x502, 0x16f, "DiGi" },
- { 0x502, 0x17f, "Maxis" },
- { 0x502, 0x18f, "U Mobile" },
- { 0x502, 0x19f, "Celcom" },
- { 0x472, -1, "Maldives" },
- { 0x472, 0x01f, "Dhiraagu" },
- { 0x472, 0x02f, "Wataniya" },
- { 0x610, -1, "Mali" },
- { 0x610, 0x01f, "Malitel" },
- { 0x610, 0x02f, "Orange" },
- { 0x278, -1, "Malta" },
- { 0x278, 0x01f, "Vodafone" },
- { 0x278, 0x21f, "GO" },
- { 0x278, 0x77f, "Melita" },
- { 0x000, -1, "Marshall Islands" },
-// { 0x000, ?, "?" },
- { 0x340, -1, "Martinique" },
- { 0x340, 0x01f, "Orange" },
- { 0x340, 0x02f, "Outremer" },
- { 0x340, 0x20f, "Digicel" },
- { 0x609, -1, "Mauritania" },
- { 0x609, 0x01f, "Mattel" },
- { 0x609, 0x10f, "Mauritel" },
- { 0x617, -1, "Mauritius" },
- { 0x617, 0x01f, "Orange" },
- { 0x617, 0x02f, "MTML" },
- { 0x617, 0x10f, "Emtel" },
- { 0x334, -1, "Mexico" },
- { 0x334, 0x01f, "Nextel" },
- { 0x334, 0x02f, "Telcel" },
- { 0x334, 0x03f, "movistar" },
- { 0x334, 0x04f, "Iusacell / Unefon" },
- { 0x550, -1, "Federated States of Micronesia" },
- { 0x550, 0x01f, "FSM Telecom" },
- { 0x259, -1, "Moldova" },
- { 0x259, 0x01f, "Orange" },
- { 0x259, 0x02f, "Moldcell" },
- { 0x259, 0x03f, "IDC" },
- { 0x259, 0x03f, "Unit?" },
- { 0x259, 0x04f, "Eventis" },
- { 0x259, 0x05f, "Unit?" },
- { 0x212, -1, "Monaco" },
- { 0x212, 0x01f, "Office des Telephones" },
- { 0x428, -1, "Mongolia" },
- { 0x428, 0x99f, "MobiCom" },
- { 0x428, 0x88f, "Unitel" },
- { 0x428, 0x91f, "Skytel" },
- { 0x428, 0x98f, "G.Mobile" },
- { 0x297, -1, "Montenegro" },
- { 0x297, 0x01f, "Telenor" },
- { 0x297, 0x02f, "T-Mobile" },
- { 0x297, 0x03f, "m:tel CG" },
- { 0x604, -1, "Morocco" },
- { 0x604, 0x00f, "Moditel" },
- { 0x604, 0x01f, "IAM" },
- { 0x604, 0x02f, "INWI" },
- { 0x605, 0x03f, "yassine" },
- { 0x643, -1, "Mozambique" },
- { 0x643, 0x01f, "mCel" },
- { 0x643, 0x04f, "Vodacom" },
- { 0x414, -1, "Myanmar" },
- { 0x414, 0x01f, "MPT" },
- { 0x649, -1, "Namibia" },
- { 0x649, 0x01f, "MTC" },
- { 0x649, 0x02f, "switch" },
- { 0x649, 0x03f, "Leo" },
- { 0x536, -1, "Nauru" },
- { 0x429, -1, "Nepal" },
- { 0x429, 0x01f, "Namaste / NT Mobile" },
- { 0x429, 0x02f, "Ncell" },
- { 0x429, 0x03f, "Sky/C-Phone" },
- { 0x204, -1, "Netherlands" },
- { 0x204, 0x01f, "OneFoon" },
- { 0x204, 0x02f, "Tele2" },
- { 0x204, 0x03f, "Blyk" },
- { 0x204, 0x04f, "Vodafone" },
- { 0x204, 0x05f, "Elephant Talk" },
- { 0x204, 0x06f, "Barablu Mobile" },
- { 0x204, 0x07f, "Teleena" },
- { 0x204, 0x08f, "KPN" },
- { 0x204, 0x09f, "Lycamobile" },
- { 0x204, 0x10f, "KPN" },
- { 0x204, 0x12f, "Telfort" },
- { 0x204, 0x14f, "6Gmobile" },
- { 0x204, 0x16f, "T-Mobile" },
- { 0x204, 0x18f, "Telfort" },
- { 0x204, 0x20f, "Orange Nederland" },
- { 0x204, 0x21f, "NS Railinfrabeheer B.V." },
- { 0x204, 0x67f, "RadioAccess" },
- { 0x204, 0x69f, "KPN Mobile" },
- { 0x362, -1, "Netherlands Antilles" },
- { 0x362, 0x51f, "Telcell" },
- { 0x362, 0x69f, "Digicel" },
- { 0x362, 0x91f, "UTS" },
- { 0x362, 0x00f, "East Caribbean Cellular" },
- { 0x362, 0x00f, "Antiliano Por N.V." },
- { 0x362, 0x95f, "MIO" },
- { 0x362, 0x94f, "Bay?s" },
- { 0x546, -1, "New Caledonia" },
- { 0x546, 0x01f, "Mobilis" },
- { 0x530, -1, "New Zealand" },
- { 0x530, 0x00f, "Telecom" },
- { 0x530, 0x01f, "Vodafone" },
- { 0x530, 0x02f, "Telecom" },
- { 0x530, 0x03f, "Woosh" },
- { 0x530, 0x04f, "TelstraClear" },
- { 0x530, 0x05f, "XT Mobile Network" },
- { 0x530, 0x12f, "360" },
- { 0x530, 0x24f, "2degrees" },
- { 0x710, -1, "Nicaragua" },
- { 0x710, 0x21f, "Claro" },
- { 0x710, 0x30f, "movistar" },
- { 0x710, 0x73f, "SERCOM" },
- { 0x614, -1, "Niger" },
- { 0x614, 0x01f, "SahelCom" },
- { 0x614, 0x02f, "Zain" },
- { 0x614, 0x03f, "Telecel" },
- { 0x614, 0x04f, "Orange" },
- { 0x621, -1, "Nigeria" },
- { 0x621, 0x20f, "Zain" },
- { 0x621, 0x30f, "MTN" },
- { 0x621, 0x40f, "M-Tel" },
- { 0x621, 0x50f, "Glo" },
- { 0x621, 0x60f, "Etisalat" },
- { 0x242, -1, "Norway" },
- { 0x242, 0x01f, "Telenor" },
- { 0x242, 0x02f, "NetCom" },
- { 0x242, 0x03f, "Teletopia" },
- { 0x242, 0x04f, "Tele2" },
- { 0x242, 0x05f, "Network Norway" },
- { 0x242, 0x06f, "Ice" },
- { 0x242, 0x07f, "Ventelo" },
- { 0x242, 0x08f, "TDC Mobil AS" },
- { 0x242, 0x09f, "Barablu Mobile Norway Ltd" },
- { 0x242, 0x20f, "Jernbaneverket AS" },
- { 0x422, -1, "Oman" },
- { 0x422, 0x02f, "Oman Mobile" },
- { 0x422, 0x03f, "Nawras" },
- { 0x410, -1, "Pakistan" },
- { 0x410, 0x01f, "Mobilink" },
- { 0x410, 0x03f, "Ufone" },
- { 0x410, 0x04f, "Zong" },
- { 0x410, 0x06f, "Telenor" },
- { 0x410, 0x07f, "Warid" },
- { 0x552, -1, "Palau" },
- { 0x552, 0x01f, "PNCC" },
- { 0x552, 0x80f, "Palau Mobile" },
- { 0x423, -1, "Palestinian Authority" },
- { 0x423, 0x05f, "Jawwal" },
- { 0x423, 0x06f, "Wataniya" },
- { 0x714, -1, "Panama" },
- { 0x714, 0x01f, "Cable & Wireless" },
- { 0x714, 0x02f, "movistar" },
- { 0x714, 0x04f, "Digicel" },
- { 0x714, 0x03f, "Claro" },
- { 0x537, -1, "Papua New Guinea" },
- { 0x537, 0x01f, "B-Mobile" },
- { 0x537, 0x03f, "Digicel" },
- { 0x744, -1, "Paraguay" },
- { 0x744, 0x01f, "VOX" },
- { 0x744, 0x02f, "Claro" },
- { 0x744, 0x04f, "Tigo" },
- { 0x744, 0x05f, "Personal" },
- { 0x716, -1, "Peru" },
- { 0x716, 0x06f, "movistar" },
- { 0x716, 0x10f, "Claro" },
- { 0x716, 0x17f, "NEXTEL" },
- { 0x515, -1, "Philippines" },
- { 0x515, 0x01f, "Islacom" },
- { 0x515, 0x02f, "Globe" },
- { 0x515, 0x03f, "Smart" },
- { 0x515, 0x05f, "Sun" },
- { 0x515, 0x11f, "PLDT via ACeS Philippines" },
- { 0x515, 0x18f, "Cure" },
- { 0x515, 0x88f, "Nextel" },
- { 0x260, -1, "Poland" },
- { 0x260, 0x01f, "Plus" },
- { 0x260, 0x02f, "Era" },
- { 0x260, 0x03f, "Orange" },
- { 0x260, 0x04f, "Netia S.A." },
- { 0x260, 0x05f, "Polska Telefonia Kom?rkowa Centertel Sp. z o.o." },
- { 0x260, 0x06f, "Play" },
- { 0x260, 0x07f, "Netia" },
- { 0x260, 0x08f, "E-Telko Sp. z o.o." },
- { 0x260, 0x09f, "Telekomunikacja Kolejowa Sp. z o.o." },
- { 0x260, 0x10f, "Sferia" },
- { 0x260, 0x11f, "Nordisk Polska" },
- { 0x260, 0x12f, "Cyfrowy Polsat" },
- { 0x260, 0x13f, "Sferia" },
- { 0x260, 0x14f, "Sferia" },
- { 0x260, 0x15f, "CenterNet" },
- { 0x260, 0x16f, "Mobyland" },
- { 0x260, 0x17f, "Aero2" },
- { 0x268, -1, "Portugal" },
- { 0x268, 0x01f, "Vodafone" },
- { 0x268, 0x03f, "Optimus" },
- { 0x268, 0x06f, "TMN" },
- { 0x268, 0x21f, "Zapp" },
- { 0x330, -1, "Puerto Rico" },
- { 0x330, 0x11f, "Claro" },
- { 0x427, -1, "Qatar" },
- { 0x427, 0x01f, "Qatarnet" },
- { 0x427, 0x02f, "Vodafone Qatar" },
- { 0x647, -1, "R&?union" },
- { 0x647, 0x00f, "Orange" },
- { 0x647, 0x02f, "Outremer" },
- { 0x647, 0x10f, "SFR Reunion" },
- { 0x226, -1, "Romania" },
- { 0x226, 0x01f, "Vodafone" },
- { 0x226, 0x02f, "Romtelecom" },
- { 0x226, 0x03f, "Cosmote" },
- { 0x226, 0x04f, "Cosmote" },
- { 0x226, 0x05f, "Digi.Mobil" },
- { 0x226, 0x06f, "Cosmote" },
- { 0x226, 0x10f, "Orange" },
- { 0x250, -1, "Russian Federation" },
- { 0x250, 0x01f, "MTS" },
- { 0x250, 0x02f, "MegaFon" },
- { 0x250, 0x03f, "NCC" },
- { 0x250, 0x04f, "Sibchallenge" },
- { 0x250, 0x05f, "ETK" },
- { 0x250, 0x06f, "Skylink" },
- { 0x250, 0x07f, "SMARTS" },
- { 0x250, 0x09f, "Skylink" },
- { 0x250, 0x10f, "DTC" },
- { 0x250, 0x11f, "Orensot" },
- { 0x250, 0x12f, "Baykalwestcom" },
- { 0x250, 0x12f, "Akos" },
- { 0x250, 0x13f, "KUGSM" },
- { 0x250, 0x15f, "SMARTS" },
- { 0x250, 0x16f, "NTC" },
- { 0x250, 0x17f, "Utel" },
- { 0x250, 0x19f, "INDIGO" },
- { 0x250, 0x20f, "Tele2" },
- { 0x250, 0x23f, "Mobicom - Novosibirsk" },
- { 0x250, 0x28f, "Beeline" },
- { 0x250, 0x35f, "MOTIV" },
- { 0x250, 0x38f, "Tambov GSM" },
- { 0x250, 0x39f, "Utel" },
- { 0x250, 0x44f, "Stavtelesot / North Caucasian GSM" },
- { 0x250, 0x92f, "Primtelefon" },
- { 0x250, 0x93f, "Telecom XXI" },
- { 0x250, 0x99f, "Beeline" },
-// { 0x250, ?, "SkyLink/MTS/the Moscow Cellular communication" },
- { 0x635, -1, "Rwanda" },
- { 0x635, 0x10f, "MTN" },
- { 0x635, 0x13f, "Tigo" },
- { 0x356, -1, "Saint Kitts and Nevis" },
- { 0x356, 0x050, "Digicel" },
- { 0x356, 0x110, "Cable & Wireless" },
- { 0x358, -1, "Saint Lucia" },
- { 0x358, 0x050, "Digicel" },
- { 0x358, 0x110, "Cable & Wireless" },
- { 0x308, -1, "Saint Pierre and Miquelon" },
- { 0x308, 0x01f, "Ameris" },
- { 0x360, -1, "Saint Vincent and the Grenadines" },
- { 0x360, 0x070, "Digicel" },
- { 0x360, 0x100, "Cingular Wireless" },
- { 0x360, 0x110, "Cable & Wireless" },
- { 0x549, -1, "Samoa" },
- { 0x549, 0x01f, "Digicel" },
- { 0x549, 0x27f, "SamoaTel" },
- { 0x292, -1, "San Marino" },
- { 0x292, 0x01f, "PRIMA" },
- { 0x626, -1, "Sao Tome and Principe" },
- { 0x626, 0x01f, "CSTmovel" },
- { 0x420, -1, "Saudi Arabia" },
- { 0x420, 0x01f, "Al Jawal" },
- { 0x420, 0x03f, "Mobily" },
- { 0x420, 0x07f, "EAE" },
- { 0x420, 0x04f, "Zain SA" },
- { 0x608, -1, "Senegal" },
- { 0x608, 0x01f, "Orange (telecommunications)" },
- { 0x608, 0x02f, "Tigo" },
- { 0x608, 0x03f, "Expresso" },
- { 0x220, -1, "Serbia" },
- { 0x220, 0x01f, "Telenor" },
- { 0x220, 0x03f, "mt:s" },
- { 0x220, 0x05f, "VIP" },
- { 0x633, -1, "Seychelles" },
- { 0x633, 0x01f, "Cable & Wireless" },
- { 0x633, 0x02f, "Mediatech International" },
- { 0x633, 0x10f, "Airtel" },
- { 0x619, -1, "Sierra Leone" },
- { 0x619, 0x01f, "Zain" },
- { 0x619, 0x02f, "Millicom" },
- { 0x619, 0x03f, "Datatel" },
- { 0x619, 0x04f, "Comium" },
- { 0x619, 0x05f, "Africell" },
- { 0x619, 0x25f, "Mobitel" },
-// { 0x619, ?, "LeoneCel" },
- { 0x525, -1, "Singapore" },
- { 0x525, 0x01f, "SingTel" },
- { 0x525, 0x02f, "SingTel-G18" },
- { 0x525, 0x03f, "M1" },
- { 0x525, 0x05f, "StarHub" },
- { 0x525, 0x12f, "Digital Trunked Radio Network" },
- { 0x231, -1, "Slovakia" },
- { 0x231, 0x01f, "Orange" },
- { 0x231, 0x02f, "T-Mobile" },
- { 0x231, 0x03f, "Unient Communications" },
- { 0x231, 0x04f, "T-Mobile" },
- { 0x231, 0x05f, "Mobile Entertainment Company" },
- { 0x231, 0x06f, "O2" },
- { 0x231, 0x99f, "?SR" },
- { 0x293, -1, "Slovenia" },
- { 0x293, 0x40f, "Si.mobil" },
- { 0x293, 0x41f, "Mobitel" },
- { 0x293, 0x64f, "T-2" },
- { 0x293, 0x70f, "Tu?mobil" },
- { 0x540, -1, "Solomon Islands" },
- { 0x637, -1, "Somalia" },
- { 0x637, 0x01f, "Telesom" },
- { 0x637, 0x04f, "Somafone" },
- { 0x637, 0x10f, "Nationlink" },
- { 0x637, 0x25f, "Hormuud" },
- { 0x637, 0x30f, "Golis" },
- { 0x637, 0x82f, "Telcom" },
- { 0x655, -1, "South Africa" },
- { 0x655, 0x01f, "Vodacom" },
- { 0x655, 0x06f, "Sentech" },
- { 0x655, 0x07f, "Cell C" },
- { 0x655, 0x10f, "MTN" },
- { 0x655, 0x11f, "SAPS Gauteng" },
- { 0x655, 0x13f, "Neotel" },
- { 0x655, 0x21f, "Cape Town Metropolitan Council" },
- { 0x655, 0x30f, "Bokamoso Consortium" },
- { 0x655, 0x31f, "Karabo Telecoms (Pty) Ltd." },
- { 0x655, 0x32f, "Ilizwi Telecommunications" },
- { 0x655, 0x33f, "Thinta Thinta Telecommunications" },
- { 0x655, 0x02f, "Telkom" },
- { 0x214, -1, "Spain" },
- { 0x214, 0x01f, "Vodafone" },
- { 0x214, 0x03f, "Orange" },
- { 0x214, 0x04f, "Yoigo" },
- { 0x214, 0x05f, "TME" },
- { 0x214, 0x06f, "Vodafone" },
- { 0x214, 0x07f, "movistar" },
- { 0x214, 0x08f, "Euskaltel" },
- { 0x214, 0x09f, "Orange" },
- { 0x214, 0x15f, "BT" },
- { 0x214, 0x16f, "TeleCable" },
- { 0x214, 0x17f, "M?bil R" },
- { 0x214, 0x18f, "ONO" },
- { 0x214, 0x19f, "Simyo" },
- { 0x214, 0x21f, "Jazztel" },
- { 0x214, 0x22f, "DigiMobil" },
- { 0x214, 0x23f, "Barablu" },
- { 0x413, -1, "Sri Lanka" },
- { 0x413, 0x01f, "Mobitel" },
- { 0x413, 0x02f, "Dialog" },
- { 0x413, 0x03f, "Etisalat" },
- { 0x413, 0x05f, "Airtel" },
- { 0x413, 0x08f, "Hutch" },
- { 0x413, 0x00f, "RTEC Mobile" },
- { 0x634, -1, "Sudan" },
- { 0x634, 0x01f, "Zain SD" },
- { 0x634, 0x02f, "MTN" },
- { 0x634, 0x05f, "Vivacell" },
- { 0x746, -1, "Suriname" },
- { 0x746, 0x05f, "Telesur" },
- { 0x653, -1, "Swaziland" },
- { 0x653, 0x10f, "Swazi MTN" },
- { 0x240, -1, "Sweden" },
- { 0x240, 0x01f, "Telia" },
- { 0x240, 0x02f, "3" },
- { 0x240, 0x03f, "Ice.net" },
- { 0x240, 0x04f, "3G Infrastructure Services" },
- { 0x240, 0x05f, "Sweden 3G" },
- { 0x240, 0x06f, "Telenor" },
- { 0x240, 0x07f, "Tele2" },
- { 0x240, 0x08f, "Telenor" },
- { 0x240, 0x09f, "djuice" },
- { 0x240, 0x10f, "Spring Mobil" },
- { 0x240, 0x11f, "Lindholmen Science Park" },
- { 0x240, 0x12f, "Barablu Mobile Scandinavia" },
- { 0x240, 0x13f, "Ventelo Sverige" },
- { 0x240, 0x14f, "TDC Mobil" },
- { 0x240, 0x15f, "Wireless Maingate Nordic" },
- { 0x240, 0x16f, "42IT" },
- { 0x240, 0x17f, "G?talandsn?tet" },
- { 0x240, 0x20f, "Wireless Maingate Message Services" },
- { 0x240, 0x21f, "MobiSir" },
- { 0x240, 0x25f, "DigiTelMobile" },
- { 0x228, -1, "Switzerland" },
- { 0x228, 0x01f, "Swisscom" },
- { 0x228, 0x02f, "Sunrise" },
- { 0x228, 0x03f, "Orange" },
- { 0x228, 0x05f, "Togewanet AG (Comfone)" },
- { 0x228, 0x06f, "SBB AG" },
- { 0x228, 0x07f, "IN&Phone" },
- { 0x228, 0x08f, "Tele2" },
- { 0x228, 0x50f, "3G Mobile AG" },
- { 0x228, 0x51f, "BebbiCell AG" },
- { 0x417, -1, "Syria" },
- { 0x417, 0x01f, "Syriatel" },
- { 0x417, 0x02f, "MTN" },
- { 0x466, -1, "Taiwan" },
- { 0x466, 0x01f, "FarEasTone" },
- { 0x466, 0x02f, "APTG" },
- { 0x466, 0x06f, "Tuntex" },
- { 0x466, 0x11f, "Chunghwa LDM" },
- { 0x466, 0x88f, "KG Telecom" },
- { 0x466, 0x89f, "VIBO" },
- { 0x466, 0x92f, "Chungwa" },
- { 0x466, 0x93f, "MobiTai" },
- { 0x466, 0x97f, "Taiwan Mobile" },
- { 0x466, 0x99f, "TransAsia" },
- { 0x436, -1, "Tajikistan" },
- { 0x436, 0x01f, "Tcell" },
- { 0x436, 0x02f, "Indigo" },
- { 0x436, 0x03f, "MLT" },
- { 0x436, 0x04f, "Babilon-M" },
- { 0x436, 0x05f, "Beeline" },
- { 0x640, -1, "Tanzania" },
- { 0x640, 0x06f, "SasaTel" },
- { 0x640, 0x02f, "tiGO" },
- { 0x640, 0x03f, "Zantel" },
- { 0x640, 0x04f, "Vodacom" },
- { 0x640, 0x05f, "Zain" },
- { 0x520, -1, "Thailand" },
- { 0x520, 0x00f, "Hutch" },
- { 0x520, 0x01f, "AIS" },
- { 0x520, 0x02f, "CAT CDMA" },
- { 0x520, 0x10f, "?" },
- { 0x520, 0x15f, "Thai Mobile" },
- { 0x520, 0x15f, "TOT 3G" },
- { 0x520, 0x18f, "dtac" },
- { 0x520, 0x23f, "AIS GSM 1800" },
- { 0x520, 0x99f, "True Move" },
- { 0x520, 0x00f, "WE PCT" },
- { 0x615, -1, "Togo" },
- { 0x615, 0x01f, "Togo Cell" },
- { 0x615, 0x03f, "Moov" },
- { 0x539, -1, "Tonga" },
- { 0x539, 0x01f, "Tonga Communications Corporation" },
- { 0x539, 0x43f, "Shoreline Communication" },
- { 0x539, 0x88f, "Digicel" },
- { 0x374, -1, "Trinidad and Tobago" },
- { 0x374, 0x12f, "bmobile" },
- { 0x374, 0x13f, "Digicel" },
- { 0x605, -1, "Tunisia" },
- { 0x605, 0x01f, "Orange" },
- { 0x605, 0x02f, "Tunicell" },
- { 0x605, 0x03f, "Tunisiana" },
- { 0x286, -1, "Turkey" },
- { 0x286, 0x01f, "Turkcell" },
- { 0x286, 0x02f, "Vodafone" },
- { 0x286, 0x03f, "Avea" },
- { 0x286, 0x04f, "Aycell" },
- { 0x438, -1, "Turkmenistan" },
- { 0x438, 0x01f, "MTS" },
- { 0x438, 0x02f, "TM-Cell" },
- { 0x376, -1, "Turks and Caicos Islands" },
- { 0x376, 0x350, "C&W" },
- { 0x376, 0x352, "Islandcom" },
- { 0x338, 0x05f, "Digicel" },
- { 0x553, -1, "Tuvalu" },
- { 0x553, 0x01f, "TTC" },
- { 0x641, -1, "Uganda" },
- { 0x641, 0x01f, "Zain" },
- { 0x641, 0x10f, "MTN" },
- { 0x641, 0x11f, "Uganda Telecom Ltd." },
- { 0x641, 0x22f, "Warid Telecom" },
- { 0x641, 0x14f, "Orange" },
- { 0x255, -1, "Ukraine" },
- { 0x255, 0x01f, "MTS" },
- { 0x255, 0x02f, "Beeline" },
- { 0x255, 0x03f, "Kyivstar" },
- { 0x255, 0x04f, "IT" },
- { 0x255, 0x05f, "Golden Telecom" },
- { 0x255, 0x06f, "life:)" },
- { 0x255, 0x07f, "Ukrtelecom" },
- { 0x255, 0x21f, "PEOPLEnet" },
- { 0x255, 0x23f, "CDMA Ukraine" },
- { 0x424, -1, "United Arab Emirates" },
- { 0x424, 0x02f, "Etisalat" },
- { 0x424, 0x03f, "du" },
- { 0x234, -1, "United Kingdom" },
- { 0x234, 0x00f, "BT" },
- { 0x234, 0x01f, "UK01" },
- { 0x234, 0x02f, "O2" },
- { 0x234, 0x03f, "Airtel-Vodafone" },
- { 0x234, 0x04f, "FMS Solutions Ltd" },
- { 0x234, 0x07f, "Cable and Wireless UK" },
- { 0x234, 0x08f, "OnePhone Ltd" },
- { 0x234, 0x10f, "O2" },
- { 0x234, 0x11f, "O2" },
- { 0x234, 0x12f, "Railtrack" },
- { 0x234, 0x14f, "Hay Systems Ltd" },
- { 0x234, 0x15f, "Vodafone" },
- { 0x234, 0x16f, "Opal Telecom Ltd" },
- { 0x234, 0x18f, "Cloud9" },
- { 0x234, 0x19f, "Teleware" },
- { 0x234, 0x20f, "3" },
- { 0x234, 0x22f, "RoutoMessaging" },
- { 0x234, 0x25f, "Truphone" },
- { 0x234, 0x30f, "T-Mobile" },
- { 0x234, 0x31f, "Virgin" },
- { 0x234, 0x32f, "Virgin" },
- { 0x234, 0x33f, "Orange" },
- { 0x234, 0x34f, "Orange" },
- { 0x234, 0x50f, "JT-Wave" },
- { 0x234, 0x55f, "Cable & Wireless Guernsey / Sure Mobile (Jersey)" },
- { 0x234, 0x58f, "Manx Telecom" },
- { 0x234, 0x75f, "Inquam" },
- { 0x234, 0x77f, "BT" },
- { 0x200, -1, "United States of America" },
- { 0x200, 0x053, "Virgin Mobile US" },
- { 0x200, 0x054, "Alltel US" },
- { 0x200, 0x066, "U.S. Cellular" },
- /* 0x310 taken from Annex to ITU Operational Bulletin No. 958 – 15.VI.2010 */
- { 0x310, 0x00f, "nTelos" },
- { 0x310, 0x000, "Mid-Tex Cellular" },
- { 0x310, 0x004, "Verizon" },
- { 0x310, 0x010, "MCI" },
- { 0x310, 0x012, "Verizon" },
- { 0x310, 0x013, "MobileTel" },
- { 0x310, 0x014, "Testing" },
- { 0x310, 0x016, "Cricket Communications" },
- { 0x310, 0x017, "North Sight Communications Inc." },
- { 0x310, 0x020, "Union Telephone Company" },
- { 0x310, 0x026, "T-Mobile" },
- { 0x310, 0x030, "Centennial" },
- { 0x310, 0x034, "Airpeak" },
- { 0x310, 0x038, "AT&T" },
- { 0x310, 0x040, "Concho" },
- { 0x310, 0x046, "SIMMETRY" },
- { 0x310, 0x060, "Consolidated Telcom" },
- { 0x310, 0x070, "Highland Cellular" },
- { 0x310, 0x080, "Corr" },
- { 0x310, 0x090, "AT&T" },
- { 0x310, 0x100, "Plateau Wireless" },
- { 0x310, 0x110, "PTI Pacifica" },
- { 0x310, 0x120, "Sprint" },
- { 0x310, 0x150, "AT&T" },
- { 0x310, 0x160, "T-Mobile" },
- { 0x310, 0x170, "T-Mobile" },
- { 0x310, 0x180, "West Central" },
- { 0x310, 0x190, "Dutch Harbor" },
- { 0x310, 0x200, "T-Mobile" },
- { 0x310, 0x210, "T-Mobile" },
- { 0x310, 0x220, "T-Mobile" },
- { 0x310, 0x230, "T-Mobile" },
- { 0x310, 0x240, "T-Mobile" },
- { 0x310, 0x250, "T-Mobile" },
- { 0x310, 0x260, "T-Mobile" },
- { 0x310, 0x270, "T-Mobile" },
- { 0x310, 0x280, "T-Mobile" },
- { 0x310, 0x290, "T-Mobile" },
- { 0x310, 0x300, "iSmart Mobile" },
- { 0x310, 0x310, "T-Mobile" },
- { 0x310, 0x311, "Farmers Wireless" },
- { 0x310, 0x320, "Cellular One" },
- { 0x310, 0x330, "T-Mobile" },
- { 0x310, 0x340, "Westlink" },
- { 0x310, 0x350, "Carolina Phone" },
- { 0x310, 0x380, "AT&T Mobility" },
- { 0x310, 0x390, "Cellular One of East Texas" },
- { 0x310, 0x400, "i CAN_GSM" },
- { 0x310, 0x410, "AT&T" },
- { 0x310, 0x420, "Cincinnati Bell" },
- { 0x310, 0x430, "Alaska Digitel" },
- { 0x310, 0x440, "Cellular One" },
- { 0x310, 0x450, "Viaero" },
- { 0x310, 0x460, "Simmetry" },
- { 0x310, 0x480, "Choice Phone" },
- { 0x310, 0x490, "T-Mobile" },
- { 0x310, 0x500, "Alltel" },
- { 0x310, 0x510, "Airtel" },
- { 0x310, 0x520, "VeriSign" },
- { 0x310, 0x530, "West Virginia Wireless" },
- { 0x310, 0x540, "Oklahoma Western" },
- { 0x310, 0x560, "AT&T" },
- { 0x310, 0x570, "Cellular One" },
- { 0x310, 0x580, "T-Mobile" },
- { 0x310, 0x590, "Alltel" },
- { 0x310, 0x610, "Epic Touch" },
- { 0x310, 0x620, "Coleman County Telecom" },
- { 0x310, 0x630, "AmeriLink PCS" },
- { 0x310, 0x640, "Airadigm" },
- { 0x310, 0x650, "Jasper" },
- { 0x310, 0x660, "T-Mobile" },
- { 0x310, 0x670, "Northstar" },
- { 0x310, 0x680, "AT&T" },
- { 0x310, 0x690, "Conestoga" },
- { 0x310, 0x730, "SeaMobile" },
- { 0x310, 0x740, "Convey" },
- { 0x310, 0x760, "Panhandle" },
- { 0x310, 0x770, "i wireless" },
- { 0x310, 0x780, "Airlink PCS" },
- { 0x310, 0x790, "PinPoint" },
- { 0x310, 0x800, "T-Mobile" },
- { 0x310, 0x830, "Caprock" },
- { 0x310, 0x850, "Aeris" },
- { 0x310, 0x870, "PACE" },
- { 0x310, 0x880, "Advantage" },
- { 0x310, 0x890, "Unicel" },
- { 0x310, 0x900, "Mid-Rivers Wireless" },
- { 0x310, 0x910, "First Cellular" },
- { 0x310, 0x940, "Iris Wireless LLC" },
- { 0x310, 0x950, "XIT Wireless" },
- { 0x310, 0x960, "Plateau Wireless" },
- { 0x310, 0x970, "Globalstar" },
- { 0x310, 0x980, "AT&T Mobility" },
- { 0x310, 0x990, "AT&T Mobility" },
- { 0x311, 0x000, "Mid-Tex Cellular" },
- { 0x311, 0x010, "Chariton Valley" },
- { 0x311, 0x020, "Missouri RSA 5 Partnership" },
- { 0x311, 0x030, "Indigo Wireless" },
- { 0x311, 0x040, "Commnet Wireless" },
- { 0x311, 0x050, "Wikes Cellular" },
- { 0x311, 0x060, "Farmers Cellular" },
- { 0x311, 0x070, "Easterbrooke" },
- { 0x311, 0x080, "Pine Cellular" },
- { 0x311, 0x090, "Long Lines Wireless" },
- { 0x311, 0x100, "High Plains Wireless" },
- { 0x311, 0x110, "High Plains Wireless" },
- { 0x311, 0x120, "Choice Phone" },
- { 0x311, 0x130, "Cell One Amarillo" },
- { 0x311, 0x140, "Sprocket" },
- { 0x311, 0x150, "Wilkes Cellular" },
- { 0x311, 0x160, "Endless Mountains Wireless" },
- { 0x311, 0x170, "PetroCom" },
- { 0x311, 0x180, "Cingular Wireless" },
- { 0x311, 0x190, "Cellular Properties" },
- { 0x311, 0x210, "Farmers Cellular" },
- { 0x316, 0x010, "Nextel" },
- { 0x316, 0x011, "Southern Communications Services" },
- { 0x748, -1, "Uruguay" },
- { 0x748, 0x00f, "Ancel" },
- { 0x748, 0x01f, "Ancel" },
- { 0x748, 0x07f, "Movistar" },
- { 0x748, 0x10f, "Claro" },
- { 0x434, -1, "Uzbekistan" },
- { 0x434, 0x01f, "Buztel" },
- { 0x434, 0x02f, "Uzmacom" },
- { 0x434, 0x04f, "Beeline" },
- { 0x434, 0x05f, "Ucell" },
- { 0x434, 0x06f, "Perfectum Mobile" },
- { 0x434, 0x07f, "MTS" },
- { 0x541, -1, "Vanuatu" },
- { 0x541, 0x01f, "SMILE" },
- { 0x225, -1, "Vatican" },
- { 0x734, -1, "Venezuela" },
- { 0x734, 0x01f, "Digitel" },
- { 0x734, 0x02f, "Digitel" },
- { 0x734, 0x03f, "Digitel" },
- { 0x734, 0x04f, "movistar" },
- { 0x734, 0x06f, "Movilnet" },
- { 0x452, -1, "Vietnam" },
- { 0x452, 0x01f, "MobiFone" },
- { 0x452, 0x02f, "Vinaphone" },
- { 0x452, 0x03f, "S-Fone" },
- { 0x452, 0x04f, "Viettel Mobile" },
- { 0x452, 0x05f, "Vietnamobile" },
- { 0x452, 0x06f, "E-Mobile" },
- { 0x452, 0x07f, "Beeline VN" },
- { 0x421, -1, "Yemen" },
- { 0x421, 0x01f, "SabaFon" },
- { 0x421, 0x02f, "MTN" },
- { 0x421, 0x03f, "Yemen Mobile" },
- { 0x421, 0x04f, "HiTS-UNITEL" },
- { 0x645, -1, "Zambia" },
- { 0x645, 0x01f, "Zain" },
- { 0x645, 0x02f, "MTN" },
- { 0x645, 0x03f, "ZAMTEL" },
- { 0x648, -1, "Zimbabwe" },
- { 0x648, 0x01f, "Net*One" },
- { 0x648, 0x03f, "Telecel" },
- { 0x648, 0x04f, "Econet" },
- { 0x901, -1, "International" },
- { 0x901, 0x01f, "ICO" },
- { 0x901, 0x02f, "Sense Communications International" },
- { 0x901, 0x03f, "Iridium" },
- { 0x901, 0x04f, "Globalstar" },
- { 0x901, 0x05f, "Thuraya RMSS Network" },
- { 0x901, 0x06f, "Thuraya Satellite Telecommunications Company" },
- { 0x901, 0x07f, "Ellipso" },
- { 0x901, 0x08f, "" },
- { 0x901, 0x09f, "Tele1 Europe" },
- { 0x901, 0x10f, "ACeS" },
- { 0x901, 0x11f, "Inmarsat" },
- { 0x901, 0x12f, "MCP" },
- { 0x901, 0x13f, "GSM.AQ" },
- { 0x901, 0x14f, "AeroMobile AS" },
- { 0x901, 0x15f, "OnAir Switzerland Sarl" },
- { 0x901, 0x16f, "Jasper Systems" },
- { 0x901, 0x17f, "Navitas" },
- { 0x901, 0x18f, "Cellular @Sea" },
- { 0x901, 0x19f, "Vodafone Malta Maritime" },
- { 0x901, 0x21f, "Seanet" },
- { 0x901, 0x24f, "iNum" },
- { 0x901, 0x29f, "Telenor" },
- { 0, 0, NULL }
-};
-
-/* GSM 03.22 Annex A */
-int gsm_match_mcc(uint16_t mcc, char *imsi)
-{
- uint16_t sim_mcc;
-
- sim_mcc = ((imsi[0] - '0') << 8)
- + ((imsi[1] - '0') << 4)
- + imsi[2] - '0';
-
- return (mcc == sim_mcc);
-}
-
-/* GSM 03.22 Annex A */
-int gsm_match_mnc(uint16_t mcc, uint8_t mnc, char *imsi)
-{
- uint16_t sim_mnc;
-
- /* 1. SIM-MCC = BCCH-MCC */
- if (!gsm_match_mcc(mcc, imsi))
- return 0;
-
- /* 2. 3rd digit of BCCH-MNC is not 0xf */
- if ((mnc & 0x00f) != 0x00f) {
- /* 3. 3 digit SIM-MNC = BCCH-MNC */
- sim_mnc = ((imsi[3] - '0') << 8)
- + ((imsi[4] - '0') << 4)
- + imsi[5] - '0';
-
- return (mnc == sim_mnc);
- }
-
- /* 4. BCCH-MCC in the range 310-316 */
- if (mcc >= 310 && mcc <= 316) {
- /* 5. 3rd diit of SIM-MNC is 0 */
- if (imsi[5] != 0)
- return 0;
- }
-
- /* 6. 1st 2 digits of SIM-MNC and BCCH-MNC match */
- sim_mnc = ((imsi[3] - '0') << 8)
- + ((imsi[4] - '0') << 4)
- + 0x00f;
-
- return (mnc == sim_mnc);
-}
-
-const char *gsm_print_mcc(uint16_t mcc)
-{
- static char string[5] = "000";
-
- snprintf(string, 4, "%03x", mcc);
- return string;
-}
-
-const char *gsm_print_mnc(uint16_t mnc)
-{
- static char string[7];
-
- /* invalid format: return hex value */
- if ((mnc & 0xf000)
- || (mnc & 0x0f00) > 0x0900
- || (mnc & 0x00f0) > 0x0090
- || ((mnc & 0x000f) > 0x0009 && (mnc & 0x000f) < 0x000f)) {
- snprintf(string, 6, "0x%03x", mnc);
- return string;
- }
-
- /* two digits */
- if ((mnc & 0x000f) == 0x000f) {
- snprintf(string, 6, "%02x", mnc >> 4);
- return string;
- }
-
- /* three digits */
- snprintf(string, 6, "%03x", mnc);
- return string;
-}
-
-const uint16_t gsm_input_mcc(char *string)
-{
- uint16_t mcc;
-
- if (strlen(string) != 3)
- return GSM_INPUT_INVALID;
- if (string[0] < '0' || string [0] > '9'
- || string[1] < '0' || string [1] > '9'
- || string[2] < '0' || string [2] > '9')
- return GSM_INPUT_INVALID;
-
- mcc = ((string[0] - '0') << 8)
- | ((string[1] - '0') << 4)
- | ((string[2] - '0'));
-
- if (mcc == 0x000)
- return GSM_INPUT_INVALID;
-
- return mcc;
-}
-
-const uint16_t gsm_input_mnc(char *string)
-{
- uint16_t mnc = 0;
-
- if (strlen(string) == 2) {
- if (string[0] < '0' || string [0] > '9'
- || string[1] < '0' || string [1] > '9')
- return GSM_INPUT_INVALID;
-
- mnc = ((string[0] - '0') << 8)
- | ((string[1] - '0') << 4)
- | 0x00f;
- } else
- if (strlen(string) == 3) {
- if (string[0] < '0' || string [0] > '9'
- || string[1] < '0' || string [1] > '9'
- || string[2] < '0' || string [2] > '9')
- return GSM_INPUT_INVALID;
-
- mnc = ((string[0] - '0') << 8)
- | ((string[1] - '0') << 4)
- | ((string[2] - '0'));
- }
-
- return mnc;
-}
-
-const char *gsm_get_mcc(uint16_t mcc)
-{
- int i;
-
- for (i = 0; gsm_networks[i].name; i++)
- if (gsm_networks[i].mnc < 0 && gsm_networks[i].mcc == mcc)
- return gsm_networks[i].name;
-
- return gsm_print_mcc(mcc);
-}
-
-const char *gsm_get_mnc(uint16_t mcc, uint16_t mnc)
-{
- int i;
-
- for (i = 0; gsm_networks[i].name; i++)
- if (gsm_networks[i].mcc == mcc && gsm_networks[i].mnc == mnc)
- return gsm_networks[i].name;
-
- return gsm_print_mnc(mnc);
-}
-
-/* get MCC from IMSI */
-const char *gsm_imsi_mcc(char *imsi)
-{
- int i, found = 0;
- uint16_t mcc;
-
- mcc = ((imsi[0] - '0') << 8)
- | ((imsi[1] - '0') << 4)
- | ((imsi[2] - '0'));
-
- for (i = 0; gsm_networks[i].name; i++) {
- if (gsm_networks[i].mcc == mcc) {
- found = 1;
- break;
- }
- }
- if (found == 0)
- return "Unknown";
-
- return gsm_networks[i].name;
-}
-
-/* get MNC from IMSI */
-const char *gsm_imsi_mnc(char *imsi)
-{
- int i, found = 0, position = 0;
- uint16_t mcc, mnc2, mnc3;
-
- mcc = ((imsi[0] - '0') << 8)
- | ((imsi[1] - '0') << 4)
- | ((imsi[2] - '0'));
- mnc2 = ((imsi[3] - '0') << 8)
- + ((imsi[4] - '0') << 4)
- + 0x00f;
- mnc3 = ((imsi[3] - '0') << 8)
- + ((imsi[4] - '0') << 4)
- + imsi[5] - '0';
-
- for (i = 0; gsm_networks[i].name; i++) {
- if (gsm_networks[i].mcc != mcc)
- continue;
- if ((gsm_networks[i].mnc & 0x00f) == 0x00f) {
- if (mnc2 == gsm_networks[i].mnc) {
- found++;
- position = i;
- }
- } else {
- if (mnc3 == gsm_networks[i].mnc) {
- found++;
- position = i;
- }
- }
- }
-
- if (found == 0)
- return "Unknown";
- if (found > 1)
- return "Ambiguous";
- return gsm_networks[position].name;
-}
-
-
diff --git a/Src/osmoconbb/src/host/layer23/src/common/sap_interface.c b/Src/osmoconbb/src/host/layer23/src/common/sap_interface.c
deleted file mode 100644
index fd5cdc3..0000000
--- a/Src/osmoconbb/src/host/layer23/src/common/sap_interface.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/* BTSAP socket interface of layer2/3 stack */
-
-/* (C) 2010 by Holger Hans Peter Freyther
- * (C) 2010 by Harald Welte <laforge@gnumonks.org>
- * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/sap_interface.h>
-
-#include <osmocom/core/utils.h>
-
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#include <arpa/inet.h>
-
-#define _GNU_SOURCE
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-
-#define GSM_SAP_LENGTH 300
-#define GSM_SAP_HEADROOM 32
-
-static int sap_read(struct osmo_fd *fd)
-{
- struct msgb *msg;
- u_int16_t len;
- int rc;
- struct osmocom_ms *ms = (struct osmocom_ms *) fd->data;
-
- msg = msgb_alloc_headroom(GSM_SAP_LENGTH+GSM_SAP_HEADROOM, GSM_SAP_HEADROOM, "Layer2");
- if (!msg) {
- LOGP(DSAP, LOGL_ERROR, "Failed to allocate msg.\n");
- return -ENOMEM;
- }
-
- rc = read(fd->fd, &len, sizeof(len));
- if (rc < sizeof(len)) {
- fprintf(stderr, "SAP socket failed\n");
- msgb_free(msg);
- if (rc >= 0)
- rc = -EIO;
- sap_close(ms);
- return rc;
- }
-
- len = ntohs(len);
- if (len > GSM_SAP_LENGTH) {
- LOGP(DSAP, LOGL_ERROR, "Length is too big: %u\n", len);
- msgb_free(msg);
- return -EINVAL;
- }
-
-
- msg->l1h = msgb_put(msg, len);
- rc = read(fd->fd, msg->l1h, msgb_l1len(msg));
- if (rc != msgb_l1len(msg)) {
- LOGP(DSAP, LOGL_ERROR, "Can not read data: len=%d rc=%d "
- "errno=%d\n", len, rc, errno);
- msgb_free(msg);
- return rc;
- }
-
- if (ms->sap_entity.msg_handler)
- ms->sap_entity.msg_handler(msg, ms);
-
- return 0;
-}
-
-static int sap_write(struct osmo_fd *fd, struct msgb *msg)
-{
- int rc;
-
- if (fd->fd <= 0)
- return -EINVAL;
-
- rc = write(fd->fd, msg->data, msg->len);
- if (rc != msg->len) {
- LOGP(DSAP, LOGL_ERROR, "Failed to write data: rc: %d\n", rc);
- return rc;
- }
-
- return 0;
-}
-
-int sap_open(struct osmocom_ms *ms, const char *socket_path)
-{
- int rc;
- struct sockaddr_un local;
-
- ms->sap_wq.bfd.fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (ms->sap_wq.bfd.fd < 0) {
- fprintf(stderr, "Failed to create unix domain socket.\n");
- return ms->sap_wq.bfd.fd;
- }
-
- local.sun_family = AF_UNIX;
- strncpy(local.sun_path, socket_path, sizeof(local.sun_path));
- local.sun_path[sizeof(local.sun_path) - 1] = '\0';
-
- rc = connect(ms->sap_wq.bfd.fd, (struct sockaddr *) &local,
- sizeof(local.sun_family) + strlen(local.sun_path));
- if (rc < 0) {
- fprintf(stderr, "Failed to connect to '%s'.\n", local.sun_path);
- close(ms->sap_wq.bfd.fd);
- return rc;
- }
-
- osmo_wqueue_init(&ms->sap_wq, 100);
- ms->sap_wq.bfd.data = ms;
- ms->sap_wq.bfd.when = BSC_FD_READ;
- ms->sap_wq.read_cb = sap_read;
- ms->sap_wq.write_cb = sap_write;
-
- rc = osmo_fd_register(&ms->sap_wq.bfd);
- if (rc != 0) {
- fprintf(stderr, "Failed to register fd.\n");
- return rc;
- }
-
- return 0;
-}
-
-int sap_close(struct osmocom_ms *ms)
-{
- if (ms->sap_wq.bfd.fd <= 0)
- return -EINVAL;
-
- close(ms->sap_wq.bfd.fd);
- ms->sap_wq.bfd.fd = -1;
- osmo_fd_unregister(&ms->sap_wq.bfd);
-
- return 0;
-}
-
-int osmosap_send(struct osmocom_ms *ms, struct msgb *msg)
-{
- uint16_t *len;
-
- if (ms->sap_wq.bfd.fd <= 0)
- return -EINVAL;
-
- DEBUGP(DSAP, "Sending: '%s'\n", osmo_hexdump(msg->data, msg->len));
-
- if (msg->l1h != msg->data)
- LOGP(DSAP, LOGL_ERROR, "Message SAP header != Message Data\n");
-
- /* prepend 16bit length before sending */
- len = (uint16_t *) msgb_push(msg, sizeof(*len));
- *len = htons(msg->len - sizeof(*len));
-
- if (osmo_wqueue_enqueue(&ms->sap_wq, msg) != 0) {
- LOGP(DSAP, LOGL_ERROR, "Failed to enqueue msg.\n");
- msgb_free(msg);
- return -1;
- }
-
- return 0;
-}
-
-/* register message handler for messages that are sent from L2->L3 */
-int osmosap_register_handler(struct osmocom_ms *ms, osmosap_cb_t cb)
-{
- ms->sap_entity.msg_handler = cb;
-
- return 0;
-}
-
diff --git a/Src/osmoconbb/src/host/layer23/src/common/sim.c b/Src/osmoconbb/src/host/layer23/src/common/sim.c
deleted file mode 100644
index 3aca693..0000000
--- a/Src/osmoconbb/src/host/layer23/src/common/sim.c
+++ /dev/null
@@ -1,1236 +0,0 @@
-/*
- * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdint.h>
-#include <errno.h>
-#include <arpa/inet.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/utils.h>
-
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/l1ctl.h>
-
-extern void *l23_ctx;
-static int sim_process_job(struct osmocom_ms *ms);
-
-/*
- * support
- */
-
-uint32_t new_handle = 1;
-
-static struct gsm1111_df_name {
- uint16_t file;
- const char *name;
-} gsm1111_df_name[] = {
- { 0x3f00, "MF" },
- { 0x7f20, "DFgsm" },
- { 0x7f10, "DFtelecom" },
- { 0x7f22, "DFis-41" },
- { 0x7f23, "DFfp-cts" },
- { 0x5f50, "DFgraphics" },
- { 0x5f30, "DFiridium" },
- { 0x5f31, "DFglobst" },
- { 0x5f32, "DFico" },
- { 0x5f33, "DFaces" },
- { 0x5f40, "DFeia/tia-553" },
- { 0x5f60, "DFcts" },
- { 0x5f70, "DFsolsa" },
- { 0x5f3c, "DFmexe" },
- { 0, NULL }
-};
-
-static const char *get_df_name(uint16_t fid)
-{
- int i;
- static char text[7];
-
- for (i = 0; gsm1111_df_name[i].file; i++)
- if (gsm1111_df_name[i].file == fid)
- break;
- if (gsm1111_df_name[i].file)
- return gsm1111_df_name[i].name;
-
- sprintf(text, "0x%04x", fid);
- return text;
-}
-
-static struct gsm_sim_handler *sim_get_handler(struct gsm_sim *sim,
- uint32_t handle)
-{
- struct gsm_sim_handler *handler;
-
- llist_for_each_entry(handler, &sim->handlers, entry)
- if (handler->handle == handle)
- return handler;
-
- return NULL;
-}
-
-/*
- * messages
- */
-
-static const struct value_string sim_job_names[] = {
- { SIM_JOB_READ_BINARY, "SIM_JOB_READ_BINARY" },
- { SIM_JOB_UPDATE_BINARY, "SIM_JOB_UPDATE_BINARY" },
- { SIM_JOB_READ_RECORD, "SIM_JOB_READ_RECORD" },
- { SIM_JOB_UPDATE_RECORD, "SIM_JOB_UPDATE_RECORD" },
- { SIM_JOB_SEEK_RECORD, "SIM_JOB_SEEK_RECORD" },
- { SIM_JOB_INCREASE, "SIM_JOB_INCREASE" },
- { SIM_JOB_INVALIDATE, "SIM_JOB_INVALIDATE" },
- { SIM_JOB_REHABILITATE, "SIM_JOB_REHABILITATE" },
- { SIM_JOB_RUN_GSM_ALGO, "SIM_JOB_RUN_GSM_ALGO" },
- { SIM_JOB_PIN1_UNLOCK, "SIM_JOB_PIN1_UNLOCK" },
- { SIM_JOB_PIN1_CHANGE, "SIM_JOB_PIN1_CHANGE" },
- { SIM_JOB_PIN1_DISABLE, "SIM_JOB_PIN1_DISABLE" },
- { SIM_JOB_PIN1_ENABLE, "SIM_JOB_PIN1_ENABLE" },
- { SIM_JOB_PIN1_UNBLOCK, "SIM_JOB_PIN1_UNBLOCK" },
- { SIM_JOB_PIN2_UNLOCK, "SIM_JOB_PIN2_UNLOCK" },
- { SIM_JOB_PIN2_CHANGE, "SIM_JOB_PIN2_CHANGE" },
- { SIM_JOB_PIN2_UNBLOCK, "SIM_JOB_PIN2_UNBLOCK" },
- { SIM_JOB_OK, "SIM_JOB_OK" },
- { SIM_JOB_ERROR, "SIM_JOB_ERROR" },
- { 0, NULL }
-};
-
-static const char *get_job_name(int value)
-{
- return get_value_string(sim_job_names, value);
-}
-
-/* allocate sim client message (upper layer) */
-struct msgb *gsm_sim_msgb_alloc(uint32_t handle, uint8_t job_type)
-{
- struct msgb *msg;
- struct sim_hdr *nsh;
-
- msg = msgb_alloc_headroom(SIM_ALLOC_SIZE+SIM_ALLOC_HEADROOM,
- SIM_ALLOC_HEADROOM, "SIM");
- if (!msg)
- return NULL;
-
- nsh = (struct sim_hdr *) msgb_put(msg, sizeof(*nsh));
- nsh->handle = handle;
- nsh->job_type = job_type;
-
- return msg;
-}
-
-/* reply to job, after it is done. reuse the msgb in the job */
-void gsm_sim_reply(struct osmocom_ms *ms, uint8_t result_type, uint8_t *result,
- uint16_t result_len)
-{
- struct gsm_sim *sim = &ms->sim;
- struct msgb *msg = sim->job_msg;
- struct sim_hdr *sh;
- uint8_t *payload;
- uint16_t payload_len;
- struct gsm_sim_handler *handler;
-
- LOGP(DSIM, LOGL_INFO, "sending result to callback function "
- "(type=%d)\n", result_type);
-
- /* if no handler, or no callback, just free the job */
- sh = (struct sim_hdr *)msg->data;
- handler = sim_get_handler(sim, sh->handle);
- if (!handler || !handler->cb) {
- LOGP(DSIM, LOGL_INFO, "no callback or no handler, "
- "dropping result\n");
- msgb_free(sim->job_msg);
- sim->job_msg = NULL;
- sim->job_state = SIM_JST_IDLE;
- return;
- }
-
- payload = msg->data + sizeof(*sh);
- payload_len = msg->len - sizeof(*sh);
-
- /* remove data */
- msg->tail -= payload_len;
- msg->len -= payload_len;
-
- /* add reply data */
- sh->job_type = result_type;
- if (result_len)
- memcpy(msgb_put(msg, result_len), result, result_len);
-
- /* callback */
- sim->job_state = SIM_JST_IDLE;
- sim->job_msg = NULL;
- handler->cb(ms, msg);
-}
-
-/* send APDU to card reader */
-static int sim_apdu_send(struct osmocom_ms *ms, uint8_t *data, uint16_t length)
-{
- LOGP(DSIM, LOGL_INFO, "sending APDU (class 0x%02x, ins 0x%02x)\n",
- data[0], data[1]);
- l1ctl_tx_sim_req(ms, data, length);
- return 0;
-}
-
-/* dequeue messages (RSL-SAP) */
-int gsm_sim_job_dequeue(struct osmocom_ms *ms)
-{
- struct gsm_sim *sim = &ms->sim;
- struct sim_hdr *sh;
- struct msgb *msg;
- struct gsm_sim_handler *handler;
-
- /* already have a job */
- if (sim->job_msg)
- return 0;
-
- /* get next job */
- while ((msg = msgb_dequeue(&sim->jobs))) {
- /* resolve handler */
- sh = (struct sim_hdr *) msg->data;
- LOGP(DSIM, LOGL_INFO, "got new job: %s (handle=%08x)\n",
- get_job_name(sh->job_type), sh->handle);
- handler = sim_get_handler(sim, sh->handle);
- if (!handler) {
- LOGP(DSIM, LOGL_INFO, "no handler, ignoring job\n");
- /* does not exist anymore */
- msgb_free(msg);
- continue;
- }
-
- /* init job */
- sim->job_state = SIM_JST_IDLE;
- sim->job_msg = msg;
- sim->job_handle = sh->handle;
-
- /* process current job, message is freed there */
- sim_process_job(ms);
- return 1; /* work done */
- }
-
- return 0;
-}
-
-
-/*
- * SIM commands
- */
-
-/* 9.2.1 */
-static int gsm1111_tx_select(struct osmocom_ms *ms, uint16_t fid)
-{
- uint8_t buffer[5 + 2];
-
- LOGP(DSIM, LOGL_INFO, "SELECT (file=0x%04x)\n", fid);
- buffer[0] = GSM1111_CLASS_GSM;
- buffer[1] = GSM1111_INST_SELECT;
- buffer[2] = 0x00;
- buffer[3] = 0x00;
- buffer[4] = 2;
- buffer[5] = fid >> 8;
- buffer[6] = fid;
-
- return sim_apdu_send(ms, buffer, 5 + 2);
-}
-
-#if 0
-/* 9.2.2 */
-static int gsm1111_tx_status(struct osmocom_ms *ms)
-{
- uint8_t buffer[5];
-
- LOGP(DSIM, LOGL_INFO, "STATUS\n");
- buffer[0] = GSM1111_CLASS_GSM;
- buffer[1] = GSM1111_INST_STATUS;
- buffer[2] = 0x00;
- buffer[3] = 0x00;
- buffer[4] = 0;
-
- return sim_apdu_send(ms, buffer, 5);
-}
-#endif
-
-/* 9.2.3 */
-static int gsm1111_tx_read_binary(struct osmocom_ms *ms, uint16_t offset,
- uint8_t length)
-{
- uint8_t buffer[5];
-
- LOGP(DSIM, LOGL_INFO, "READ BINARY (offset=%d len=%d)\n", offset,
- length);
- buffer[0] = GSM1111_CLASS_GSM;
- buffer[1] = GSM1111_INST_READ_BINARY;
- buffer[2] = offset >> 8;
- buffer[3] = offset;
- buffer[4] = length;
-
- return sim_apdu_send(ms, buffer, 5);
-}
-
-/* 9.2.4 */
-static int gsm1111_tx_update_binary(struct osmocom_ms *ms, uint16_t offset,
- uint8_t *data, uint8_t length)
-{
- uint8_t buffer[5 + length];
-
- LOGP(DSIM, LOGL_INFO, "UPDATE BINARY (offset=%d len=%d)\n", offset,
- length);
- buffer[0] = GSM1111_CLASS_GSM;
- buffer[1] = GSM1111_INST_UPDATE_BINARY;
- buffer[2] = offset >> 8;
- buffer[3] = offset;
- buffer[4] = length;
- memcpy(buffer + 5, data, length);
-
- return sim_apdu_send(ms, buffer, 5 + length);
-}
-
-/* 9.2.5 */
-static int gsm1111_tx_read_record(struct osmocom_ms *ms, uint8_t rec_no,
- uint8_t mode, uint8_t length)
-{
- uint8_t buffer[5];
-
- LOGP(DSIM, LOGL_INFO, "READ RECORD (rec_no=%d mode=%d len=%d)\n",
- rec_no, mode, length);
- buffer[0] = GSM1111_CLASS_GSM;
- buffer[1] = GSM1111_INST_READ_RECORD;
- buffer[2] = rec_no;
- buffer[3] = mode;
- buffer[4] = length;
-
- return sim_apdu_send(ms, buffer, 5);
-}
-
-/* 9.2.6 */
-static int gsm1111_tx_update_record(struct osmocom_ms *ms, uint8_t rec_no,
- uint8_t mode, uint8_t *data, uint8_t length)
-{
- uint8_t buffer[5 + length];
-
- LOGP(DSIM, LOGL_INFO, "UPDATE RECORD (rec_no=%d mode=%d len=%d)\n",
- rec_no, mode, length);
- buffer[0] = GSM1111_CLASS_GSM;
- buffer[1] = GSM1111_INST_UPDATE_RECORD;
- buffer[2] = rec_no;
- buffer[3] = mode;
- buffer[4] = length;
- memcpy(buffer + 5, data, length);
-
- return sim_apdu_send(ms, buffer, 5 + length);
-}
-
-/* 9.2.7 */
-static int gsm1111_tx_seek(struct osmocom_ms *ms, uint8_t type_mode,
- uint8_t *pattern, uint8_t length)
-{
- uint8_t buffer[5 + length];
- uint8_t type = type_mode >> 4;
- uint8_t mode = type_mode & 0x0f;
-
- LOGP(DSIM, LOGL_INFO, "SEEK (type=%d mode=%d len=%d)\n", type, mode,
- length);
- buffer[0] = GSM1111_CLASS_GSM;
- buffer[1] = GSM1111_INST_SEEK;
- buffer[2] = 0x00;
- buffer[3] = type_mode;
- buffer[4] = length;
- memcpy(buffer + 5, pattern, length);
-
- return sim_apdu_send(ms, buffer, 5 + length);
-}
-
-/* 9.2.8 */
-static int gsm1111_tx_increase(struct osmocom_ms *ms, uint32_t value)
-{
- uint8_t buffer[5 + 3];
-
- LOGP(DSIM, LOGL_INFO, "INCREASE (value=%d)\n", value);
- buffer[0] = GSM1111_CLASS_GSM;
- buffer[1] = GSM1111_INST_INCREASE;
- buffer[2] = 0x00;
- buffer[3] = 0x00;
- buffer[4] = 3;
- buffer[5] = value >> 16;
- buffer[6] = value >> 8;
- buffer[7] = value;
-
- return sim_apdu_send(ms, buffer, 5 + 3);
-}
-
-/* 9.2.9 */
-static int gsm1111_tx_verify_chv(struct osmocom_ms *ms, uint8_t chv_no,
- uint8_t *chv, uint8_t length)
-{
- uint8_t buffer[5 + 8];
- int i;
-
- LOGP(DSIM, LOGL_INFO, "VERIFY CHV (CHV%d)\n", chv_no);
- buffer[0] = GSM1111_CLASS_GSM;
- buffer[1] = GSM1111_INST_VERIFY_CHV;
- buffer[2] = 0x00;
- buffer[3] = chv_no;
- buffer[4] = 8;
- for (i = 0; i < 8; i++) {
- if (i < length)
- buffer[5 + i] = chv[i];
- else
- buffer[5 + i] = 0xff;
- }
-
- return sim_apdu_send(ms, buffer, 5 + 8);
-}
-
-/* 9.2.10 */
-static int gsm1111_tx_change_chv(struct osmocom_ms *ms, uint8_t chv_no,
- uint8_t *chv_old, uint8_t length_old, uint8_t *chv_new,
- uint8_t length_new)
-{
- uint8_t buffer[5 + 16];
- int i;
-
- LOGP(DSIM, LOGL_INFO, "CHANGE CHV (CHV%d)\n", chv_no);
- buffer[0] = GSM1111_CLASS_GSM;
- buffer[1] = GSM1111_INST_CHANGE_CHV;
- buffer[2] = 0x00;
- buffer[3] = chv_no;
- buffer[4] = 16;
- for (i = 0; i < 8; i++) {
- if (i < length_old)
- buffer[5 + i] = chv_old[i];
- else
- buffer[5 + i] = 0xff;
- if (i < length_new)
- buffer[13 + i] = chv_new[i];
- else
- buffer[13 + i] = 0xff;
- }
-
- return sim_apdu_send(ms, buffer, 5 + 16);
-}
-
-/* 9.2.11 */
-static int gsm1111_tx_disable_chv(struct osmocom_ms *ms, uint8_t *chv,
- uint8_t length)
-{
- uint8_t buffer[5 + 8];
- int i;
-
- LOGP(DSIM, LOGL_INFO, "DISABLE CHV (CHV1)\n");
- buffer[0] = GSM1111_CLASS_GSM;
- buffer[1] = GSM1111_INST_DISABLE_CHV;
- buffer[2] = 0x00;
- buffer[3] = 0x01;
- buffer[4] = 8;
- for (i = 0; i < 8; i++) {
- if (i < length)
- buffer[5 + i] = chv[i];
- else
- buffer[5 + i] = 0xff;
- }
-
- return sim_apdu_send(ms, buffer, 5 + 8);
-}
-
-/* 9.2.12 */
-static int gsm1111_tx_enable_chv(struct osmocom_ms *ms, uint8_t *chv,
- uint8_t length)
-{
- uint8_t buffer[5 + 8];
- int i;
-
- LOGP(DSIM, LOGL_INFO, "ENABLE CHV (CHV1)\n");
- buffer[0] = GSM1111_CLASS_GSM;
- buffer[1] = GSM1111_INST_ENABLE_CHV;
- buffer[2] = 0x00;
- buffer[3] = 0x01;
- buffer[4] = 8;
- for (i = 0; i < 8; i++) {
- if (i < length)
- buffer[5 + i] = chv[i];
- else
- buffer[5 + i] = 0xff;
- }
-
- return sim_apdu_send(ms, buffer, 5 + 8);
-}
-
-/* 9.2.13 */
-static int gsm1111_tx_unblock_chv(struct osmocom_ms *ms, uint8_t chv_no,
- uint8_t *chv_unblk, uint8_t length_unblk, uint8_t *chv_new,
- uint8_t length_new)
-{
- uint8_t buffer[5 + 16];
- int i;
-
- LOGP(DSIM, LOGL_INFO, "UNBLOCK CHV (CHV%d)\n", (chv_no == 2) ? 2 : 1);
- buffer[0] = GSM1111_CLASS_GSM;
- buffer[1] = GSM1111_INST_UNBLOCK_CHV;
- buffer[2] = 0x00;
- buffer[3] = (chv_no == 1) ? 0 : chv_no;
- buffer[4] = 16;
- for (i = 0; i < 8; i++) {
- if (i < length_unblk)
- buffer[5 + i] = chv_unblk[i];
- else
- buffer[5 + i] = 0xff;
- if (i < length_new)
- buffer[13 + i] = chv_new[i];
- else
- buffer[13 + i] = 0xff;
- }
-
- return sim_apdu_send(ms, buffer, 5 + 16);
-}
-
-/* 9.2.14 */
-static int gsm1111_tx_invalidate(struct osmocom_ms *ms)
-{
- uint8_t buffer[5];
-
- LOGP(DSIM, LOGL_INFO, "INVALIDATE\n");
- buffer[0] = GSM1111_CLASS_GSM;
- buffer[1] = GSM1111_INST_INVALIDATE;
- buffer[2] = 0x00;
- buffer[3] = 0x00;
- buffer[4] = 0;
-
- return sim_apdu_send(ms, buffer, 5);
-}
-
-/* 9.2.15 */
-static int gsm1111_tx_rehabilitate(struct osmocom_ms *ms)
-{
- uint8_t buffer[5];
-
- LOGP(DSIM, LOGL_INFO, "REHABILITATE\n");
- buffer[0] = GSM1111_CLASS_GSM;
- buffer[1] = GSM1111_INST_REHABLILITATE;
- buffer[2] = 0x00;
- buffer[3] = 0x00;
- buffer[4] = 0;
-
- return sim_apdu_send(ms, buffer, 5);
-}
-
-/* 9.2.16 */
-static int gsm1111_tx_run_gsm_algo(struct osmocom_ms *ms, uint8_t *rand)
-{
- uint8_t buffer[5 + 16];
-
- LOGP(DSIM, LOGL_INFO, "RUN GSM ALGORITHM\n");
- buffer[0] = GSM1111_CLASS_GSM;
- buffer[1] = GSM1111_INST_RUN_GSM_ALGO;
- buffer[2] = 0x00;
- buffer[3] = 0x00;
- buffer[4] = 16;
- memcpy(buffer + 5, rand, 16);
-
- return sim_apdu_send(ms, buffer, 5 + 16);
-}
-
-#if 0
-/* 9.2.17 */
-static int gsm1111_tx_sleep(struct osmocom_ms *ms)
-{
- uint8_t buffer[5];
-
- LOGP(DSIM, LOGL_INFO, "\n");
- buffer[0] = GSM1111_CLASS_GSM;
- buffer[1] = GSM1111_INST_SLEEP;
- buffer[2] = 0x00;
- buffer[3] = 0x00;
- buffer[4] = 0;
-
- return sim_apdu_send(ms, buffer, 5);
-}
-#endif
-
-/* 9.2.18 */
-static int gsm1111_tx_get_response(struct osmocom_ms *ms, uint8_t length)
-{
- uint8_t buffer[5];
-
- LOGP(DSIM, LOGL_INFO, "GET RESPONSE (len=%d)\n", length);
- buffer[0] = GSM1111_CLASS_GSM;
- buffer[1] = GSM1111_INST_GET_RESPONSE;
- buffer[2] = 0x00;
- buffer[3] = 0x00;
- buffer[4] = length;
-
- return sim_apdu_send(ms, buffer, 5);
-}
-
-#if 0
-/* 9.2.19 */
-static int gsm1111_tx_terminal_profile(struct osmocom_ms *ms, uint8_t *data,
- uint8_t length)
-{
- uint8_t buffer[5 + length];
-
- LOGP(DSIM, LOGL_INFO, "TERMINAL PROFILE (len=%d)\n", length);
- buffer[0] = GSM1111_CLASS_GSM;
- buffer[1] = GSM1111_INST_TERMINAL_PROFILE;
- buffer[2] = 0x00;
- buffer[3] = 0x00;
- buffer[4] = length;
- memcpy(buffer + 5, data, length);
-
- return sim_apdu_send(ms, buffer, 5 + length);
-}
-
-/* 9.2.20 */
-static int gsm1111_tx_envelope(struct osmocom_ms *ms, uint8_t *data,
- uint8_t length)
-{
- uint8_t buffer[5 + length];
-
- LOGP(DSIM, LOGL_INFO, "ENVELOPE (len=%d)\n", length);
- buffer[0] = GSM1111_CLASS_GSM;
- buffer[1] = GSM1111_INST_ENVELOPE;
- buffer[2] = 0x00;
- buffer[3] = 0x00;
- buffer[4] = length;
- memcpy(buffer + 5, data, length);
-
- return sim_apdu_send(ms, buffer, 5 + length);
-}
-
-/* 9.2.21 */
-static int gsm1111_tx_fetch(struct osmocom_ms *ms, uint8_t length)
-{
- uint8_t buffer[5];
-
- LOGP(DSIM, LOGL_INFO, "FETCH (len=%d)\n", length);
- buffer[0] = GSM1111_CLASS_GSM;
- buffer[1] = GSM1111_INST_FETCH;
- buffer[2] = 0x00;
- buffer[3] = 0x00;
- buffer[4] = length;
-
- return sim_apdu_send(ms, buffer, 5);
-}
-
-/* 9.2.22 */
-static int gsm1111_tx_terminal_response(struct osmocom_ms *ms, uint8_t *data,
- uint8_t length)
-{
- uint8_t buffer[5 + length];
-
- LOGP(DSIM, LOGL_INFO, "TERMINAL RESPONSE (len=%d)\n", length);
- buffer[0] = GSM1111_CLASS_GSM;
- buffer[1] = GSM1111_INST_TERMINAL_RESPONSE;
- buffer[2] = 0x00;
- buffer[3] = 0x00;
- buffer[4] = length;
- memcpy(buffer + 5, data, length);
-
- return sim_apdu_send(ms, buffer, 5 + length);
-}
-#endif
-
-/*
- * SIM state machine
- */
-
-/* process job */
-static int sim_process_job(struct osmocom_ms *ms)
-{
- struct gsm_sim *sim = &ms->sim;
- uint8_t *payload, *payload2;
- uint16_t payload_len, payload_len2;
- struct sim_hdr *sh;
- uint8_t cause;
- int i;
-
- /* no current */
- if (!sim->job_msg)
- return 0;
-
- sh = (struct sim_hdr *)sim->job_msg->data;
- payload = sim->job_msg->data + sizeof(*sh);
- payload_len = sim->job_msg->len - sizeof(*sh);
-
- /* do reset before sim reading */
- if (!sim->reset) {
- sim->reset = 1;
- // FIXME: send reset command to L1
- }
-
- /* navigate to right DF */
- switch (sh->job_type) {
- case SIM_JOB_READ_BINARY:
- case SIM_JOB_UPDATE_BINARY:
- case SIM_JOB_READ_RECORD:
- case SIM_JOB_UPDATE_RECORD:
- case SIM_JOB_SEEK_RECORD:
- case SIM_JOB_INCREASE:
- case SIM_JOB_INVALIDATE:
- case SIM_JOB_REHABILITATE:
- case SIM_JOB_RUN_GSM_ALGO:
- /* check MF / DF */
- i = 0;
- while (sh->path[i] && sim->path[i]) {
- if (sh->path[i] != sim->path[i])
- break;
- i++;
- }
- /* if path in message is shorter or if paths are different */
- if (sim->path[i]) {
- LOGP(DSIM, LOGL_INFO, "go MF\n");
- sim->job_state = SIM_JST_SELECT_MFDF;
- /* go MF */
- sim->path[0] = 0;
- return gsm1111_tx_select(ms, 0x3f00);
- }
- /* if path in message is longer */
- if (sh->path[i]) {
- LOGP(DSIM, LOGL_INFO, "requested path is longer, go "
- "child %s\n", get_df_name(sh->path[i]));
- sim->job_state = SIM_JST_SELECT_MFDF;
- /* select child */
- sim->path[i] = sh->path[i];
- sim->path[i + 1] = 0;
- return gsm1111_tx_select(ms, sh->path[i]);
- }
- /* if paths are equal, continue */
- }
-
- /* set state and trigger SIM process */
- switch (sh->job_type) {
- case SIM_JOB_READ_BINARY:
- case SIM_JOB_UPDATE_BINARY:
- case SIM_JOB_READ_RECORD:
- case SIM_JOB_UPDATE_RECORD:
- case SIM_JOB_SEEK_RECORD:
- case SIM_JOB_INCREASE:
- case SIM_JOB_INVALIDATE:
- case SIM_JOB_REHABILITATE:
- sim->job_state = SIM_JST_SELECT_EF;
- sim->file = sh->file;
- return gsm1111_tx_select(ms, sh->file);
- case SIM_JOB_RUN_GSM_ALGO:
- if (payload_len != 16) {
- LOGP(DSIM, LOGL_ERROR, "random not 16 bytes\n");
- break;
- }
- sim->job_state = SIM_JST_RUN_GSM_ALGO;
- return gsm1111_tx_run_gsm_algo(ms, payload);
- case SIM_JOB_PIN1_UNLOCK:
- payload_len = strlen((char *)payload);
- if (payload_len < 4 || payload_len > 8) {
- LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n");
- break;
- }
- sim->job_state = SIM_JST_PIN1_UNLOCK;
- return gsm1111_tx_verify_chv(ms, 0x01, payload, payload_len);
- case SIM_JOB_PIN2_UNLOCK:
- payload_len = strlen((char *)payload);
- if (payload_len < 4 || payload_len > 8) {
- LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n");
- break;
- }
- sim->job_state = SIM_JST_PIN2_UNLOCK;
- return gsm1111_tx_verify_chv(ms, 0x02, payload, payload_len);
- case SIM_JOB_PIN1_CHANGE:
- payload_len = strlen((char *)payload);
- payload2 = payload + payload_len + 1;
- payload_len2 = strlen((char *)payload2);
- if (payload_len < 4 || payload_len > 8) {
- LOGP(DSIM, LOGL_ERROR, "key1 not in range 4..8\n");
- break;
- }
- if (payload_len2 < 4 || payload_len2 > 8) {
- LOGP(DSIM, LOGL_ERROR, "key2 not in range 4..8\n");
- break;
- }
- sim->job_state = SIM_JST_PIN1_CHANGE;
- return gsm1111_tx_change_chv(ms, 0x01, payload, payload_len,
- payload2, payload_len2);
- case SIM_JOB_PIN2_CHANGE:
- payload_len = strlen((char *)payload);
- payload2 = payload + payload_len + 1;
- payload_len2 = strlen((char *)payload2);
- if (payload_len < 4 || payload_len > 8) {
- LOGP(DSIM, LOGL_ERROR, "key1 not in range 4..8\n");
- break;
- }
- if (payload_len2 < 4 || payload_len2 > 8) {
- LOGP(DSIM, LOGL_ERROR, "key2 not in range 4..8\n");
- break;
- }
- sim->job_state = SIM_JST_PIN2_CHANGE;
- return gsm1111_tx_change_chv(ms, 0x02, payload, payload_len,
- payload2, payload_len2);
- case SIM_JOB_PIN1_DISABLE:
- payload_len = strlen((char *)payload);
- if (payload_len < 4 || payload_len > 8) {
- LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n");
- break;
- }
- sim->job_state = SIM_JST_PIN1_DISABLE;
- return gsm1111_tx_disable_chv(ms, payload, payload_len);
- case SIM_JOB_PIN1_ENABLE:
- payload_len = strlen((char *)payload);
- if (payload_len < 4 || payload_len > 8) {
- LOGP(DSIM, LOGL_ERROR, "key not in range 4..8\n");
- break;
- }
- sim->job_state = SIM_JST_PIN1_ENABLE;
- return gsm1111_tx_enable_chv(ms, payload, payload_len);
- case SIM_JOB_PIN1_UNBLOCK:
- payload_len = strlen((char *)payload);
- payload2 = payload + payload_len + 1;
- payload_len2 = strlen((char *)payload2);
- if (payload_len != 8) {
- LOGP(DSIM, LOGL_ERROR, "key1 not 8 digits\n");
- break;
- }
- if (payload_len2 < 4 || payload_len2 > 8) {
- LOGP(DSIM, LOGL_ERROR, "key2 not in range 4..8\n");
- break;
- }
- sim->job_state = SIM_JST_PIN1_UNBLOCK;
- /* NOTE: CHV1 is coded 0x00 here */
- return gsm1111_tx_unblock_chv(ms, 0x00, payload, payload_len,
- payload2, payload_len2);
- case SIM_JOB_PIN2_UNBLOCK:
- payload_len = strlen((char *)payload);
- payload2 = payload + payload_len + 1;
- payload_len2 = strlen((char *)payload2);
- if (payload_len != 8) {
- LOGP(DSIM, LOGL_ERROR, "key1 not 8 digits\n");
- break;
- }
- if (payload_len2 < 4 || payload_len2 > 8) {
- LOGP(DSIM, LOGL_ERROR, "key2 not in range 4..8\n");
- break;
- }
- sim->job_state = SIM_JST_PIN2_UNBLOCK;
- return gsm1111_tx_unblock_chv(ms, 0x02, payload, payload_len,
- payload2, payload_len2);
- }
-
- LOGP(DSIM, LOGL_ERROR, "unknown job %x, please fix\n", sh->job_type);
- cause = SIM_CAUSE_REQUEST_ERROR;
- gsm_sim_reply(ms, SIM_JOB_ERROR, &cause, 1);
-
- return 0;
-}
-
-/* receive SIM response */
-int sim_apdu_resp(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm_sim *sim = &ms->sim;
- uint8_t *payload;
- uint16_t payload_len;
- uint8_t *data = msg->data;
- int length = msg->len, ef_len;
- uint8_t sw1, sw2;
- uint8_t cause;
- uint8_t pin_cause[2];
- struct sim_hdr *sh;
- struct gsm1111_response_ef *ef;
- struct gsm1111_response_mfdf *mfdf;
- struct gsm1111_response_mfdf_gsm *mfdf_gsm;
- int i;
-
- /* ignore, if current job already gone */
- if (!sim->job_msg) {
- LOGP(DSIM, LOGL_ERROR, "received APDU but no job, "
- "please fix!\n");
- msgb_free(msg);
- return 0;
- }
-
- sh = (struct sim_hdr *)sim->job_msg->data;
- payload = sim->job_msg->data + sizeof(*sh);
- payload_len = sim->job_msg->len - sizeof(*sh);
-
- /* process status */
- if (length < 2) {
- msgb_free(msg);
- return 0;
- }
- sw1 = data[length - 2];
- sw2 = data[length - 1];
- length -= 2;
- LOGP(DSIM, LOGL_INFO, "received APDU (len=%d sw1=0x%02x sw2=0x%02x)\n",
- length, sw1, sw2);
-
- switch (sw1) {
- case GSM1111_STAT_SECURITY:
- LOGP(DSIM, LOGL_NOTICE, "SIM Security\n");
- /* error */
- if (sw2 != GSM1111_SEC_NO_ACCESS && sw2 != GSM1111_SEC_BLOCKED)
- goto sim_error;
-
- /* select the right remaining counter an cause */
- // FIXME: read status to replace "*_remain"-counters
- switch (sim->job_state) {
- case SIM_JST_PIN1_UNBLOCK:
- if (sw2 == GSM1111_SEC_NO_ACCESS) {
- pin_cause[0] = SIM_CAUSE_PIN1_BLOCKED;
- pin_cause[1] = --sim->unblk1_remain;
- } else {
- pin_cause[0] = SIM_CAUSE_PUC_BLOCKED;
- pin_cause[1] = 0;
- }
- break;
- case SIM_JST_PIN2_UNLOCK:
- case SIM_JST_PIN2_CHANGE:
- if (sw2 == GSM1111_SEC_NO_ACCESS && sim->chv2_remain) {
- pin_cause[0] = SIM_CAUSE_PIN2_REQUIRED;
- pin_cause[1] = sim->chv2_remain--;
- } else {
- pin_cause[0] = SIM_CAUSE_PIN2_BLOCKED;
- pin_cause[1] = sim->unblk2_remain;
- }
- break;
- case SIM_JST_PIN2_UNBLOCK:
- if (sw2 == GSM1111_SEC_NO_ACCESS) {
- pin_cause[0] = SIM_CAUSE_PIN2_BLOCKED;
- pin_cause[1] = --sim->unblk2_remain;
- } else {
- pin_cause[0] = SIM_CAUSE_PUC_BLOCKED;
- pin_cause[1] = 0;
- }
- case SIM_JST_PIN1_UNLOCK:
- case SIM_JST_PIN1_CHANGE:
- case SIM_JST_PIN1_DISABLE:
- case SIM_JST_PIN1_ENABLE:
- default:
- if (sw2 == GSM1111_SEC_NO_ACCESS && sim->chv1_remain) {
- pin_cause[0] = SIM_CAUSE_PIN1_REQUIRED;
- pin_cause[1] = sim->chv1_remain--;
- } else {
- pin_cause[0] = SIM_CAUSE_PIN1_BLOCKED;
- pin_cause[1] = sim->unblk1_remain;
- }
- break;
- }
- gsm_sim_reply(ms, SIM_JOB_ERROR, pin_cause, 2);
- msgb_free(msg);
- return 0;
- case GSM1111_STAT_MEM_PROBLEM:
- if (sw2 >= 0x40) {
- LOGP(DSIM, LOGL_NOTICE, "memory of SIM failed\n");
- sim_error:
- cause = SIM_CAUSE_SIM_ERROR;
- gsm_sim_reply(ms, SIM_JOB_ERROR, &cause, 1);
- msgb_free(msg);
- return 0;
- }
- LOGP(DSIM, LOGL_NOTICE, "memory of SIM is bad (write took %d "
- "times to succeed)\n", sw2);
- /* fall through */
- case GSM1111_STAT_NORMAL:
- case GSM1111_STAT_PROACTIVE:
- case GSM1111_STAT_DL_ERROR:
- case GSM1111_STAT_RESPONSE:
- case GSM1111_STAT_RESPONSE_TOO:
- LOGP(DSIM, LOGL_INFO, "command successfull\n");
- break;
- default:
- LOGP(DSIM, LOGL_INFO, "command failed\n");
- request_error:
- cause = SIM_CAUSE_REQUEST_ERROR;
- gsm_sim_reply(ms, SIM_JOB_ERROR, &cause, 1);
- msgb_free(msg);
- return 0;
- }
-
-
- switch (sim->job_state) {
- /* step 1: after selecting MF / DF, request the response */
- case SIM_JST_SELECT_MFDF:
- /* not enough data */
- if (sw2 < 22) {
- LOGP(DSIM, LOGL_NOTICE, "expecting minimum 22 bytes\n");
- goto sim_error;
- }
- /* request response */
- sim->job_state = SIM_JST_SELECT_MFDF_RESP;
- gsm1111_tx_get_response(ms, sw2);
- msgb_free(msg);
- return 0;
- /* step 2: after getting response of selecting MF / DF, continue
- * to "process_job".
- */
- case SIM_JST_SELECT_MFDF_RESP:
- if (length < 22) {
- LOGP(DSIM, LOGL_NOTICE, "expecting minimum 22 bytes\n");
- goto sim_error;
- }
- mfdf = (struct gsm1111_response_mfdf *)data;
- mfdf_gsm = (struct gsm1111_response_mfdf_gsm *)(data + 13);
- sim->chv1_remain = mfdf_gsm->chv1_remain;
- sim->chv2_remain = mfdf_gsm->chv2_remain;
- sim->unblk1_remain = mfdf_gsm->unblk1_remain;
- sim->unblk2_remain = mfdf_gsm->unblk2_remain;
- /* if MF was selected */
- if (sim->path[0] == 0) {
- /* if MF was selected, but MF is not indicated */
- if (ntohs(mfdf->file_id) != 0x3f00) {
- LOGP(DSIM, LOGL_NOTICE, "Not MF\n");
- goto sim_error;
- }
- /* if MF was selected, but type is not indicated */
- if (mfdf->tof != GSM1111_TOF_MF) {
- LOGP(DSIM, LOGL_NOTICE, "MF %02x != %02x "
- "%04x\n", mfdf->tof, GSM1111_TOF_MF,
- sim->path[0]);
- goto sim_error;
- }
- /* now continue */
- msgb_free(msg);
- return sim_process_job(ms);
- }
- /* if DF was selected, but this DF is not indicated */
- i = 0;
- while (sim->path[i + 1])
- i++;
- if (ntohs(mfdf->file_id) != sim->path[i]) {
- LOGP(DSIM, LOGL_NOTICE, "Path %04x != %04x\n",
- ntohs(mfdf->file_id), sim->path[i]);
- goto sim_error;
- }
- /* if DF was selected, but type is not indicated */
- if (mfdf->tof != GSM1111_TOF_DF) {
- LOGP(DSIM, LOGL_NOTICE, "TOF error\n");
- goto sim_error;
- }
- /* now continue */
- msgb_free(msg);
- return sim_process_job(ms);
- /* step 1: after selecting EF, request response of SELECT */
- case SIM_JST_SELECT_EF:
- /* not enough data */
- if (sw2 < 14) {
- LOGP(DSIM, LOGL_NOTICE, "expecting minimum 14 bytes\n");
- goto sim_error;
- }
- /* request response */
- sim->job_state = SIM_JST_SELECT_EF_RESP;
- gsm1111_tx_get_response(ms, sw2);
- msgb_free(msg);
- return 0;
- /* step 2: after getting response of selecting EF, do file command */
- case SIM_JST_SELECT_EF_RESP:
- if (length < 14) {
- LOGP(DSIM, LOGL_NOTICE, "expecting minimum 14 bytes\n");
- goto sim_error;
- }
- ef = (struct gsm1111_response_ef *)data;
- /* if EF was selected, but type is not indicated */
- if (ntohs(ef->file_id) != sim->file) {
- LOGP(DSIM, LOGL_NOTICE, "EF ID %04x != %04x\n",
- ntohs(ef->file_id), sim->file);
- goto sim_error;
- }
- /* get length of file */
- ef_len = ntohs(ef->file_size);
- /* do file command */
- sim->job_state = SIM_JST_WAIT_FILE;
- switch (sh->job_type) {
- case SIM_JOB_READ_BINARY:
- // FIXME: do chunks when greater or equal 256 bytes */
- gsm1111_tx_read_binary(ms, 0, ef_len);
- break;
- case SIM_JOB_UPDATE_BINARY:
- // FIXME: do chunks when greater or equal 256 bytes */
- if (ef_len < payload_len) {
- LOGP(DSIM, LOGL_NOTICE, "selected file is "
- "smaller (%d) than data to update "
- "(%d)\n", ef_len, payload_len);
- goto request_error;
- }
- gsm1111_tx_update_binary(ms, 0, payload, payload_len);
- break;
- case SIM_JOB_READ_RECORD:
- gsm1111_tx_read_record(ms, sh->rec_no, sh->rec_mode,
- ef_len);
- break;
- case SIM_JOB_UPDATE_RECORD:
- if (ef_len != payload_len) {
- LOGP(DSIM, LOGL_NOTICE, "selected file length "
- "(%d) does not equal record to update "
- "(%d)\n", ef_len, payload_len);
- goto request_error;
- }
- gsm1111_tx_update_record(ms, sh->rec_no, sh->rec_mode,
- payload, payload_len);
- break;
- case SIM_JOB_SEEK_RECORD:
- gsm1111_tx_seek(ms, sh->seek_type_mode, data, length);
- break;
- case SIM_JOB_INCREASE:
- if (length != 4) {
- LOGP(DSIM, LOGL_ERROR, "expecting uint32_t as "
- "value lenght, but got %d bytes\n",
- length);
- goto request_error;
- }
- gsm1111_tx_increase(ms, *((uint32_t *)data));
- break;
- case SIM_JOB_INVALIDATE:
- gsm1111_tx_invalidate(ms);
- break;
- case SIM_JOB_REHABILITATE:
- gsm1111_tx_rehabilitate(ms);
- break;
- }
- msgb_free(msg);
- return 0;
- /* step 3: after processing file command, job is done */
- case SIM_JST_WAIT_FILE:
- /* reply job with data */
- gsm_sim_reply(ms, SIM_JOB_OK, data, length);
- msgb_free(msg);
- return 0;
- /* step 1: after running GSM algorithm, request response */
- case SIM_JST_RUN_GSM_ALGO:
- /* not enough data */
- if (sw2 < 12) {
- LOGP(DSIM, LOGL_NOTICE, "expecting minimum 12 bytes\n");
- goto sim_error;
- }
- /* request response */
- sim->job_state = SIM_JST_RUN_GSM_ALGO_RESP;
- gsm1111_tx_get_response(ms, sw2);
- msgb_free(msg);
- return 0;
- /* step 2: after processing GSM command, job is done */
- case SIM_JST_RUN_GSM_ALGO_RESP:
- /* reply job with data */
- gsm_sim_reply(ms, SIM_JOB_OK, data, length);
- msgb_free(msg);
- return 0;
- case SIM_JST_PIN1_UNLOCK:
- case SIM_JST_PIN1_CHANGE:
- case SIM_JST_PIN1_DISABLE:
- case SIM_JST_PIN1_ENABLE:
- case SIM_JST_PIN1_UNBLOCK:
- case SIM_JST_PIN2_UNLOCK:
- case SIM_JST_PIN2_CHANGE:
- case SIM_JST_PIN2_UNBLOCK:
- /* reply job with data */
- gsm_sim_reply(ms, SIM_JOB_OK, data, length);
- msgb_free(msg);
- return 0;
- }
-
- LOGP(DSIM, LOGL_ERROR, "unknown state %u, please fix!\n",
- sim->job_state);
- goto request_error;
-}
-
-/*
- * API
- */
-
-/* open access to sim */
-uint32_t sim_open(struct osmocom_ms *ms,
- void (*cb)(struct osmocom_ms *ms, struct msgb *msg))
-{
- struct gsm_sim *sim = &ms->sim;
- struct gsm_sim_handler *handler;
-
- /* create handler and attach */
- handler = talloc_zero(l23_ctx, struct gsm_sim_handler);
- if (!handler)
- return 0;
- handler->handle = new_handle++;
- handler->cb = cb;
- llist_add_tail(&handler->entry, &sim->handlers);
-
- return handler->handle;
-}
-
-/* close access to sim */
-void sim_close(struct osmocom_ms *ms, uint32_t handle)
-{
- struct gsm_sim *sim = &ms->sim;
- struct gsm_sim_handler *handler;
-
- handler = sim_get_handler(sim, handle);
- if (!handle)
- return;
-
- /* kill ourself */
- llist_del(&handler->entry);
- talloc_free(handler);
-}
-
-/* send job */
-void sim_job(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm_sim *sim = &ms->sim;
-
- msgb_enqueue(&sim->jobs, msg);
-}
-
-/*
- * init
- */
-
-int gsm_sim_init(struct osmocom_ms *ms)
-{
- struct gsm_sim *sim = &ms->sim;
-
- /* current path is undefined, forching MF */
- sim->path[0] = 0x0bad;
- sim->path[1] = 0;
- sim->file = 0;
-
- INIT_LLIST_HEAD(&sim->handlers);
- INIT_LLIST_HEAD(&sim->jobs);
-
- LOGP(DSIM, LOGL_INFO, "init SIM client\n");
-
- return 0;
-}
-
-int gsm_sim_exit(struct osmocom_ms *ms)
-{
- struct gsm_sim *sim = &ms->sim;
- struct gsm_sim_handler *handler, *handler2;
- struct msgb *msg;
-
- LOGP(DSIM, LOGL_INFO, "exit SIM client\n");
-
- /* remove pending job msg */
- if (sim->job_msg) {
- msgb_free(sim->job_msg);
- sim->job_msg = NULL;
- }
- /* flush handlers */
- llist_for_each_entry_safe(handler, handler2, &sim->handlers, entry)
- sim_close(ms, handler->handle);
- /* flush jobs */
- while ((msg = msgb_dequeue(&sim->jobs)))
- msgb_free(msg);
-
- return 0;
-}
-
-
-
-
diff --git a/Src/osmoconbb/src/host/layer23/src/common/sysinfo.c b/Src/osmoconbb/src/host/layer23/src/common/sysinfo.c
deleted file mode 100644
index b26bfe2..0000000
--- a/Src/osmoconbb/src/host/layer23/src/common/sysinfo.c
+++ /dev/null
@@ -1,859 +0,0 @@
-/*
- * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <arpa/inet.h>
-
-#include <osmocom/core/bitvec.h>
-
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/networks.h>
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/sysinfo.h>
-
-#define MIN(a, b) ((a < b) ? a : b)
-
-/*
- * dumping
- */
-
-// FIXME: move to libosmocore
-char *gsm_print_arfcn(uint16_t arfcn)
-{
- static char text[10];
-
- sprintf(text, "%d", arfcn & 1023);
- if ((arfcn & ARFCN_PCS))
- strcat(text, "(PCS)");
- else if (arfcn >= 512 && arfcn <= 885)
- strcat(text, "(DCS)");
-
- return text;
-}
-
-/* check if the cell 'talks' about DCS (0) or PCS (1) */
-uint8_t gsm_refer_pcs(uint16_t arfcn, struct gsm48_sysinfo *s)
-{
- /* If ARFCN is PCS band, the cell refers to PCS */
- if ((arfcn & ARFCN_PCS))
- return 1;
-
- /* If no SI1 is available, we assume DCS. Be sure to call this
- * function only if SI 1 is available. */
- if (!s->si1)
- return 0;
-
- /* If band indicator indicates PCS band, the cell refers to PCSThe */
- return s->band_ind;
-}
-
-int gsm48_sysinfo_dump(struct gsm48_sysinfo *s, uint16_t arfcn,
- void (*print)(void *, const char *, ...), void *priv, uint8_t *freq_map)
-{
- char buffer[81];
- int i, j, k, index;
- int refer_pcs = gsm_refer_pcs(arfcn, s);
-
- /* available sysinfos */
- print(priv, "ARFCN = %s channels 512+ refer to %s\n",
- gsm_print_arfcn(arfcn),
- (refer_pcs) ? "PCS (1900)" : "DCS (1800)");
- print(priv, "Available SYSTEM INFORMATIONS =");
- if (s->si1)
- print(priv, " 1");
- if (s->si2)
- print(priv, " 2");
- if (s->si2bis)
- print(priv, " 2bis");
- if (s->si2ter)
- print(priv, " 2ter");
- if (s->si3)
- print(priv, " 3");
- if (s->si4)
- print(priv, " 4");
- if (s->si5)
- print(priv, " 5");
- if (s->si5bis)
- print(priv, " 5bis");
- if (s->si5ter)
- print(priv, " 5ter");
- if (s->si6)
- print(priv, " 6");
- print(priv, "\n");
- print(priv, "\n");
-
- /* frequency list */
- j = 0; k = 0;
- for (i = 0; i < 1024; i++) {
- if ((s->freq[i].mask & FREQ_TYPE_SERV)) {
- if (!k) {
- sprintf(buffer, "serv. cell : ");
- j = strlen(buffer);
- }
- if (j >= 75) {
- buffer[j - 1] = '\0';
- print(priv, "%s\n", buffer);
- sprintf(buffer, " ");
- j = strlen(buffer);
- }
- sprintf(buffer + j, "%d,", i);
- j = strlen(buffer);
- k++;
- }
- }
- if (j) {
- buffer[j - 1] = '\0';
- print(priv, "%s\n", buffer);
- }
- j = 0; k = 0;
- for (i = 0; i < 1024; i++) {
- if ((s->freq[i].mask & FREQ_TYPE_NCELL)) {
- if (!k) {
- sprintf(buffer, "SI2 (neigh.) BA=%d: ",
- s->nb_ba_ind_si2);
- j = strlen(buffer);
- }
- if (j >= 70) {
- buffer[j - 1] = '\0';
- print(priv, "%s\n", buffer);
- sprintf(buffer, " ");
- j = strlen(buffer);
- }
- sprintf(buffer + j, "%d,", i);
- j = strlen(buffer);
- k++;
- }
- }
- if (j) {
- buffer[j - 1] = '\0';
- print(priv, "%s\n", buffer);
- }
- j = 0; k = 0;
- for (i = 0; i < 1024; i++) {
- if ((s->freq[i].mask & FREQ_TYPE_REP)) {
- if (!k) {
- sprintf(buffer, "SI5 (report) BA=%d: ",
- s->nb_ba_ind_si5);
- j = strlen(buffer);
- }
- if (j >= 70) {
- buffer[j - 1] = '\0';
- print(priv, "%s\n", buffer);
- sprintf(buffer, " ");
- j = strlen(buffer);
- }
- sprintf(buffer + j, "%d,", i);
- j = strlen(buffer);
- k++;
- }
- }
- if (j) {
- buffer[j - 1] = '\0';
- print(priv, "%s\n", buffer);
- }
- print(priv, "\n");
-
- /* frequency map */
- for (i = 0; i < 1024; i += 64) {
- sprintf(buffer, " %3d ", i);
- for (j = 0; j < 64; j++) {
- index = i+j;
- if (refer_pcs && index >= 512 && index <= 885)
- index = index-512+1024;
- if ((s->freq[i+j].mask & FREQ_TYPE_SERV))
- buffer[j + 5] = 'S';
- else if ((s->freq[i+j].mask & FREQ_TYPE_NCELL)
- && (s->freq[i+j].mask & FREQ_TYPE_REP))
- buffer[j + 5] = 'b';
- else if ((s->freq[i+j].mask & FREQ_TYPE_NCELL))
- buffer[j + 5] = 'n';
- else if ((s->freq[i+j].mask & FREQ_TYPE_REP))
- buffer[j + 5] = 'r';
- else if (!freq_map || (freq_map[index >> 3]
- & (1 << (index & 7))))
- buffer[j + 5] = '.';
- else
- buffer[j + 5] = ' ';
- }
- for (; j < 64; j++)
- buffer[j + 5] = ' ';
- sprintf(buffer + 69, " %d", i + 63);
- print(priv, "%s\n", buffer);
- }
- print(priv, " 'S' = serv. cell 'n' = SI2 (neigh.) 'r' = SI5 (rep.) "
- "'b' = SI2+SI5\n\n");
-
- /* serving cell */
- print(priv, "Serving Cell:\n");
- print(priv, " BSIC = %d,%d MCC = %s MNC = %s LAC = 0x%04x Cell ID "
- "= 0x%04x\n", s->bsic >> 3, s->bsic & 0x7,
- gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc), s->lac,
- s->cell_id);
- print(priv, " Country = %s Network Name = %s\n", gsm_get_mcc(s->mcc),
- gsm_get_mnc(s->mcc, s->mnc));
- print(priv, " MAX_RETRANS = %d TX_INTEGER = %d re-establish = %s\n",
- s->max_retrans, s->tx_integer,
- (s->reest_denied) ? "denied" : "allowed");
- print(priv, " Cell barred = %s barred classes =",
- (s->cell_barr ? "yes" : "no"));
- for (i = 0; i < 16; i++) {
- if ((s->class_barr & (1 << i)))
- print(priv, " C%d", i);
- }
- print(priv, "\n");
- if (s->sp)
- print(priv, " CBQ = %d CRO = %d TEMP_OFFSET = %d "
- "PENALTY_TIME = %d\n", s->sp_cbq, s->sp_cro, s->sp_to,
- s->sp_pt);
- if (s->nb_ncc_permitted_si2) {
- print(priv, "NCC Permitted BCCH =");
- for (i = 0; i < 8; i++)
- if ((s->nb_ncc_permitted_si2 & (1 << i)))
- print(priv, " %d", i);
- print(priv, "\n");
- }
- if (s->nb_ncc_permitted_si6) {
- print(priv, "NCC Permitted SACCH/TCH =");
- for (i = 0; i < 8; i++)
- if ((s->nb_ncc_permitted_si6 & (1 << i)))
- print(priv, " %d", i);
- print(priv, "\n");
- }
- print(priv, "\n");
-
- /* neighbor cell */
- print(priv, "Neighbor Cell:\n");
- print(priv, " MAX_RETRANS = %d TX_INTEGER = %d re-establish = %s\n",
- s->nb_max_retrans, s->nb_tx_integer,
- (s->nb_reest_denied) ? "denied" : "allowed");
- print(priv, " Cell barred = %s barred classes =",
- (s->nb_cell_barr ? "yes" : "no"));
- for (i = 0; i < 16; i++) {
- if ((s->nb_class_barr & (1 << i)))
- print(priv, " C%d", i);
- }
- print(priv, "\n");
- print(priv, "\n");
-
- /* cell selection */
- print(priv, "MX_TXPWR_MAX_CCCH = %d CRH = %d RXLEV_MIN = %d "
- "NECI = %d ACS = %d\n", s->ms_txpwr_max_cch,
- s->cell_resel_hyst_db, s->rxlev_acc_min_db, s->neci, s->acs);
-
- /* bcch options */
- print(priv, "BCCH link timeout = %d DTX = %d PWRC = %d\n",
- s->bcch_radio_link_timeout, s->bcch_dtx, s->bcch_pwrc);
-
- /* sacch options */
- print(priv, "SACCH link timeout = %d DTX = %d PWRC = %d\n",
- s->sacch_radio_link_timeout, s->sacch_dtx, s->sacch_pwrc);
-
- /* control channel */
- switch(s->ccch_conf) {
- case 0:
- case 2:
- case 4:
- case 6:
- print(priv, "CCCH Config = %d CCCH", (s->ccch_conf >> 1) + 1);
- break;
- case 1:
- print(priv, "CCCH Config = 1 CCCH + SDCCH");
- break;
- default:
- print(priv, "CCCH Config = reserved");
- }
- print(priv, " BS-PA-MFMS = %d Attachment = %s\n",
- s->pag_mf_periods, (s->att_allowed) ? "allowed" : "denied");
- print(priv, "BS-AG_BLKS_RES = %d ", s->bs_ag_blks_res);
- if (s->t3212)
- print(priv, "T3212 = %d sec.\n", s->t3212);
- else
- print(priv, "T3212 = disabled\n", s->t3212);
-
- /* channel description */
- if (s->h)
- print(priv, "chan_nr = 0x%02x TSC = %d MAIO = %d HSN = %d\n",
- s->chan_nr, s->tsc, s->maio, s->hsn);
- else
- print(priv, "chan_nr = 0x%02x TSC = %d ARFCN = %d\n",
- s->chan_nr, s->tsc, s->arfcn);
- print(priv, "\n");
-
- return 0;
-}
-
-/*
- * decoding
- */
-
-int gsm48_decode_lai(struct gsm48_loc_area_id *lai, uint16_t *mcc,
- uint16_t *mnc, uint16_t *lac)
-{
- *mcc = ((lai->digits[0] & 0x0f) << 8)
- | (lai->digits[0] & 0xf0)
- | (lai->digits[1] & 0x0f);
- *mnc = ((lai->digits[2] & 0x0f) << 8)
- | (lai->digits[2] & 0xf0)
- | ((lai->digits[1] & 0xf0) >> 4);
- *lac = ntohs(lai->lac);
-
- return 0;
-}
-
-int gsm48_decode_chan_h0(struct gsm48_chan_desc *cd, uint8_t *tsc,
- uint16_t *arfcn)
-{
- *tsc = cd->h0.tsc;
- *arfcn = cd->h0.arfcn_low | (cd->h0.arfcn_high << 8);
-
- return 0;
-}
-
-int gsm48_decode_chan_h1(struct gsm48_chan_desc *cd, uint8_t *tsc,
- uint8_t *maio, uint8_t *hsn)
-{
- *tsc = cd->h1.tsc;
- *maio = cd->h1.maio_low | (cd->h1.maio_high << 2);
- *hsn = cd->h1.hsn;
-
- return 0;
-}
-
-/* decode "Cell Channel Description" (10.5.2.1b) and other frequency lists */
-static int decode_freq_list(struct gsm_sysinfo_freq *f, uint8_t *cd,
- uint8_t len, uint8_t mask, uint8_t frqt)
-{
-#if 0
- /* only Bit map 0 format for P-GSM */
- if ((cd[0] & 0xc0 & mask) != 0x00 &&
- (set->p_gsm && !set->e_gsm && !set->r_gsm && !set->dcs))
- return 0;
-#endif
-
- return gsm48_decode_freq_list(f, cd, len, mask, frqt);
-}
-
-/* decode "Cell Selection Parameters" (10.5.2.4) */
-static int gsm48_decode_cell_sel_param(struct gsm48_sysinfo *s,
- struct gsm48_cell_sel_par *cs)
-{
- s->ms_txpwr_max_cch = cs->ms_txpwr_max_ccch;
- s->cell_resel_hyst_db = cs->cell_resel_hyst * 2;
- s->rxlev_acc_min_db = cs->rxlev_acc_min - 110;
- s->neci = cs->neci;
- s->acs = cs->acs;
-
- return 0;
-}
-
-/* decode "Cell Options (BCCH)" (10.5.2.3) */
-static int gsm48_decode_cellopt_bcch(struct gsm48_sysinfo *s,
- struct gsm48_cell_options *co)
-{
- s->bcch_radio_link_timeout = (co->radio_link_timeout + 1) * 4;
- s->bcch_dtx = co->dtx;
- s->bcch_pwrc = co->pwrc;
-
- return 0;
-}
-
-/* decode "Cell Options (SACCH)" (10.5.2.3a) */
-static int gsm48_decode_cellopt_sacch(struct gsm48_sysinfo *s,
- struct gsm48_cell_options *co)
-{
- s->sacch_radio_link_timeout = (co->radio_link_timeout + 1) * 4;
- s->sacch_dtx = co->dtx;
- s->sacch_pwrc = co->pwrc;
-
- return 0;
-}
-
-/* decode "Control Channel Description" (10.5.2.11) */
-static int gsm48_decode_ccd(struct gsm48_sysinfo *s,
- struct gsm48_control_channel_descr *cc)
-{
- s->ccch_conf = cc->ccch_conf;
- s->bs_ag_blks_res = cc->bs_ag_blks_res;
- s->att_allowed = cc->att;
- s->pag_mf_periods = cc->bs_pa_mfrms + 2;
- s->t3212 = cc->t3212 * 360; /* convert deci-hours to seconds */
-
- return 0;
-}
-
-/* decode "Mobile Allocation" (10.5.2.21) */
-int gsm48_decode_mobile_alloc(struct gsm_sysinfo_freq *freq,
- uint8_t *ma, uint8_t len, uint16_t *hopping, uint8_t *hopp_len, int si4)
-{
- int i, j = 0;
- uint16_t f[len << 3];
-
- /* not more than 64 hopping indexes allowed in IE */
- if (len > 8)
- return -EINVAL;
-
- /* tabula rasa */
- *hopp_len = 0;
- if (si4) {
- for (i = 0; i < 1024; i++)
- freq[i].mask &= ~FREQ_TYPE_HOPP;
- }
-
- /* generating list of all frequencies (1..1023,0) */
- for (i = 1; i <= 1024; i++) {
- if ((freq[i & 1023].mask & FREQ_TYPE_SERV)) {
- LOGP(DRR, LOGL_INFO, "Serving cell ARFCN #%d: %d\n",
- j, i & 1023);
- f[j++] = i & 1023;
- if (j == (len << 3))
- break;
- }
- }
-
- /* fill hopping table with frequency index given by IE
- * and set hopping type bits
- */
- for (i = 0; i < (len << 3); i++) {
- /* if bit is set, this frequency index is used for hopping */
- if ((ma[len - 1 - (i >> 3)] & (1 << (i & 7)))) {
- LOGP(DRR, LOGL_INFO, "Hopping ARFCN: %d (bit %d)\n",
- i, f[i]);
- /* index higher than entries in list ? */
- if (i >= j) {
- LOGP(DRR, LOGL_NOTICE, "Mobile Allocation "
- "hopping index %d exceeds maximum "
- "number of cell frequencies. (%d)\n",
- i + 1, j);
- break;
- }
- hopping[(*hopp_len)++] = f[i];
- if (si4)
- freq[f[i]].mask |= FREQ_TYPE_HOPP;
- }
- }
-
- return 0;
-}
-
-/* Rach Control decode tables */
-static uint8_t gsm48_max_retrans[4] = {
- 1, 2, 4, 7
-};
-static uint8_t gsm48_tx_integer[16] = {
- 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 20, 25, 32, 50
-};
-
-/* decode "RACH Control Parameter" (10.5.2.29) */
-static int gsm48_decode_rach_ctl_param(struct gsm48_sysinfo *s,
- struct gsm48_rach_control *rc)
-{
- s->reest_denied = rc->re;
- s->cell_barr = rc->cell_bar;
- s->tx_integer = gsm48_tx_integer[rc->tx_integer];
- s->max_retrans = gsm48_max_retrans[rc->max_trans];
- s->class_barr = (rc->t2 << 8) | rc->t3;
-
- return 0;
-}
-static int gsm48_decode_rach_ctl_neigh(struct gsm48_sysinfo *s,
- struct gsm48_rach_control *rc)
-{
- s->nb_reest_denied = rc->re;
- s->nb_cell_barr = rc->cell_bar;
- s->nb_tx_integer = gsm48_tx_integer[rc->tx_integer];
- s->nb_max_retrans = gsm48_max_retrans[rc->max_trans];
- s->nb_class_barr = (rc->t2 << 8) | rc->t3;
-
- return 0;
-}
-
-/* decode "SI 1 Rest Octets" (10.5.2.32) */
-static int gsm48_decode_si1_rest(struct gsm48_sysinfo *s, uint8_t *si,
- uint8_t len)
-{
- struct bitvec bv;
-
- memset(&bv, 0, sizeof(bv));
- bv.data_len = len;
- bv.data = si;
-
- /* Optional Selection Parameters */
- if (bitvec_get_bit_high(&bv) == H) {
- s->nch = 1;
- s->nch_position = bitvec_get_uint(&bv, 5);
- } else
- s->nch = 0;
- if (bitvec_get_bit_high(&bv) == H)
- s->band_ind = 1;
- else
- s->band_ind = 0;
-
- return 0;
-}
-
-/* decode "SI 3 Rest Octets" (10.5.2.34) */
-static int gsm48_decode_si3_rest(struct gsm48_sysinfo *s, uint8_t *si,
- uint8_t len)
-{
- struct bitvec bv;
-
- memset(&bv, 0, sizeof(bv));
- bv.data_len = len;
- bv.data = si;
-
- /* Optional Selection Parameters */
- if (bitvec_get_bit_high(&bv) == H) {
- s->sp = 1;
- s->sp_cbq = bitvec_get_uint(&bv, 1);
- s->sp_cro = bitvec_get_uint(&bv, 6);
- s->sp_to = bitvec_get_uint(&bv, 3);
- s->sp_pt = bitvec_get_uint(&bv, 5);
- } else
- s->sp = 0;
- /* Optional Power Offset */
- if (bitvec_get_bit_high(&bv) == H) {
- s->po = 1;
- s->po_value = bitvec_get_uint(&bv, 3);
- } else
- s->po = 0;
- /* System Onformation 2ter Indicator */
- if (bitvec_get_bit_high(&bv) == H)
- s->si2ter_ind = 1;
- else
- s->si2ter_ind = 0;
- /* Early Classark Sending Control */
- if (bitvec_get_bit_high(&bv) == H)
- s->ecsm = 1;
- else
- s->ecsm = 0;
- /* Scheduling if and where */
- if (bitvec_get_bit_high(&bv) == H) {
- s->sched = 1;
- s->sched_where = bitvec_get_uint(&bv, 3);
- } else
- s->sched = 0;
- /* GPRS Indicator */
- if (bitvec_get_bit_high(&bv) == H) {
- s->gprs = 1;
- s->gprs_ra_colour = bitvec_get_uint(&bv, 3);
- s->gprs_si13_pos = bitvec_get_uint(&bv, 1);
- } else
- s->gprs = 0;
-
- return 0;
-}
-
-/* decode "SI 4 Rest Octets" (10.5.2.35) */
-static int gsm48_decode_si4_rest(struct gsm48_sysinfo *s, uint8_t *si,
- uint8_t len)
-{
- struct bitvec bv;
-
- memset(&bv, 0, sizeof(bv));
- bv.data_len = len;
- bv.data = si;
-
- /* Optional Selection Parameters */
- if (bitvec_get_bit_high(&bv) == H) {
- s->sp = 1;
- s->sp_cbq = bitvec_get_uint(&bv, 1);
- s->sp_cro = bitvec_get_uint(&bv, 6);
- s->sp_to = bitvec_get_uint(&bv, 3);
- s->sp_pt = bitvec_get_uint(&bv, 5);
- } else
- s->sp = 0;
- /* Optional Power Offset */
- if (bitvec_get_bit_high(&bv) == H) {
- s->po = 1;
- s->po_value = bitvec_get_uint(&bv, 3);
- } else
- s->po = 0;
- /* GPRS Indicator */
- if (bitvec_get_bit_high(&bv) == H) {
- s->gprs = 1;
- s->gprs_ra_colour = bitvec_get_uint(&bv, 3);
- s->gprs_si13_pos = bitvec_get_uint(&bv, 1);
- } else
- s->gprs = 0;
- // todo: more rest octet bits
-
- return 0;
-}
-
-/* decode "SI 6 Rest Octets" (10.5.2.35a) */
-static int gsm48_decode_si6_rest(struct gsm48_sysinfo *s, uint8_t *si,
- uint8_t len)
-{
- return 0;
-}
-
-int gsm48_decode_sysinfo1(struct gsm48_sysinfo *s,
- struct gsm48_system_information_type_1 *si, int len)
-{
- int payload_len = len - sizeof(*si);
-
- memcpy(s->si1_msg, si, MIN(len, sizeof(s->si1_msg)));
-
- /* Cell Channel Description */
- decode_freq_list(s->freq, si->cell_channel_description,
- sizeof(si->cell_channel_description), 0xce, FREQ_TYPE_SERV);
- /* RACH Control Parameter */
- gsm48_decode_rach_ctl_param(s, &si->rach_control);
- /* SI 1 Rest Octets */
- if (payload_len)
- gsm48_decode_si1_rest(s, si->rest_octets, payload_len);
-
- s->si1 = 1;
-
- if (s->si4) {
- LOGP(DRR, LOGL_NOTICE, "Now updating previously received "
- "SYSTEM INFORMATION 4\n");
- gsm48_decode_sysinfo4(s,
- (struct gsm48_system_information_type_4 *) s->si4_msg,
- sizeof(s->si4_msg));
- }
-
- return 0;
-}
-
-int gsm48_decode_sysinfo2(struct gsm48_sysinfo *s,
- struct gsm48_system_information_type_2 *si, int len)
-{
- memcpy(s->si2_msg, si, MIN(len, sizeof(s->si2_msg)));
-
- /* Neighbor Cell Description */
- s->nb_ext_ind_si2 = (si->bcch_frequency_list[0] >> 6) & 1;
- s->nb_ba_ind_si2 = (si->bcch_frequency_list[0] >> 5) & 1;
- decode_freq_list(s->freq, si->bcch_frequency_list,
- sizeof(si->bcch_frequency_list), 0xce, FREQ_TYPE_NCELL_2);
- /* NCC Permitted */
- s->nb_ncc_permitted_si2 = si->ncc_permitted;
- /* RACH Control Parameter */
- gsm48_decode_rach_ctl_neigh(s, &si->rach_control);
-
- s->si2 = 1;
-
- return 0;
-}
-
-int gsm48_decode_sysinfo2bis(struct gsm48_sysinfo *s,
- struct gsm48_system_information_type_2bis *si, int len)
-{
- memcpy(s->si2b_msg, si, MIN(len, sizeof(s->si2b_msg)));
-
- /* Neighbor Cell Description */
- s->nb_ext_ind_si2bis = (si->bcch_frequency_list[0] >> 6) & 1;
- s->nb_ba_ind_si2bis = (si->bcch_frequency_list[0] >> 5) & 1;
- decode_freq_list(s->freq, si->bcch_frequency_list,
- sizeof(si->bcch_frequency_list), 0xce, FREQ_TYPE_NCELL_2bis);
- /* RACH Control Parameter */
- gsm48_decode_rach_ctl_neigh(s, &si->rach_control);
-
- s->si2bis = 1;
-
- return 0;
-}
-
-int gsm48_decode_sysinfo2ter(struct gsm48_sysinfo *s,
- struct gsm48_system_information_type_2ter *si, int len)
-{
- memcpy(s->si2t_msg, si, MIN(len, sizeof(s->si2t_msg)));
-
- /* Neighbor Cell Description 2 */
- s->nb_multi_rep_si2ter = (si->ext_bcch_frequency_list[0] >> 6) & 3;
- s->nb_ba_ind_si2ter = (si->ext_bcch_frequency_list[0] >> 5) & 1;
- decode_freq_list(s->freq, si->ext_bcch_frequency_list,
- sizeof(si->ext_bcch_frequency_list), 0x8e,
- FREQ_TYPE_NCELL_2ter);
-
- s->si2ter = 1;
-
- return 0;
-}
-
-int gsm48_decode_sysinfo3(struct gsm48_sysinfo *s,
- struct gsm48_system_information_type_3 *si, int len)
-{
- int payload_len = len - sizeof(*si);
-
- memcpy(s->si3_msg, si, MIN(len, sizeof(s->si3_msg)));
-
- /* Cell Identity */
- s->cell_id = ntohs(si->cell_identity);
- /* LAI */
- gsm48_decode_lai(&si->lai, &s->mcc, &s->mnc, &s->lac);
- /* Control Channel Description */
- gsm48_decode_ccd(s, &si->control_channel_desc);
- /* Cell Options (BCCH) */
- gsm48_decode_cellopt_bcch(s, &si->cell_options);
- /* Cell Selection Parameters */
- gsm48_decode_cell_sel_param(s, &si->cell_sel_par);
- /* RACH Control Parameter */
- gsm48_decode_rach_ctl_param(s, &si->rach_control);
- /* SI 3 Rest Octets */
- if (payload_len >= 4)
- gsm48_decode_si3_rest(s, si->rest_octets, payload_len);
-
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 3 (mcc %s mnc %s "
- "lac 0x%04x)\n", gsm_print_mcc(s->mcc),
- gsm_print_mnc(s->mnc), s->lac);
-
- s->si3 = 1;
-
- return 0;
-}
-
-int gsm48_decode_sysinfo4(struct gsm48_sysinfo *s,
- struct gsm48_system_information_type_4 *si, int len)
-{
- int payload_len = len - sizeof(*si);
-
- uint8_t *data = si->data;
- struct gsm48_chan_desc *cd;
-
- memcpy(s->si4_msg, si, MIN(len, sizeof(s->si4_msg)));
-
- /* LAI */
- gsm48_decode_lai(&si->lai, &s->mcc, &s->mnc, &s->lac);
- /* Cell Selection Parameters */
- gsm48_decode_cell_sel_param(s, &si->cell_sel_par);
- /* RACH Control Parameter */
- gsm48_decode_rach_ctl_param(s, &si->rach_control);
-
- /* CBCH Channel Description */
- if (payload_len >= 1 && data[0] == GSM48_IE_CBCH_CHAN_DESC) {
- if (payload_len < 4) {
-short_read:
- LOGP(DRR, LOGL_NOTICE, "Short read!\n");
- return -EIO;
- }
- cd = (struct gsm48_chan_desc *) (data + 1);
- s->chan_nr = cd->chan_nr;
- if (cd->h0.h) {
- s->h = 1;
- gsm48_decode_chan_h1(cd, &s->tsc, &s->maio, &s->hsn);
- } else {
- s->h = 0;
- gsm48_decode_chan_h0(cd, &s->tsc, &s->arfcn);
- }
- payload_len -= 4;
- data += 4;
- }
- /* CBCH Mobile Allocation */
- if (payload_len >= 1 && data[0] == GSM48_IE_CBCH_MOB_AL) {
- if (payload_len < 1 || payload_len < 2 + data[1])
- goto short_read;
- if (!s->si1) {
- LOGP(DRR, LOGL_NOTICE, "Ignoring CBCH allocation of "
- "SYSTEM INFORMATION 4 until SI 1 is "
- "received.\n");
- gsm48_decode_mobile_alloc(s->freq, data + 2, data[1],
- s->hopping, &s->hopp_len, 1);
- }
- payload_len -= 2 + data[1];
- data += 2 + data[1];
- }
- /* SI 4 Rest Octets */
- if (payload_len > 0)
- gsm48_decode_si4_rest(s, data, payload_len);
-
- s->si4 = 1;
-
- return 0;
-}
-
-int gsm48_decode_sysinfo5(struct gsm48_sysinfo *s,
- struct gsm48_system_information_type_5 *si, int len)
-{
- memcpy(s->si5_msg, si, MIN(len, sizeof(s->si5_msg)));
-
- /* Neighbor Cell Description */
- s->nb_ext_ind_si5 = (si->bcch_frequency_list[0] >> 6) & 1;
- s->nb_ba_ind_si5 = (si->bcch_frequency_list[0] >> 5) & 1;
- decode_freq_list(s->freq, si->bcch_frequency_list,
- sizeof(si->bcch_frequency_list), 0xce, FREQ_TYPE_REP_5);
-
- s->si5 = 1;
-
- return 0;
-}
-
-int gsm48_decode_sysinfo5bis(struct gsm48_sysinfo *s,
- struct gsm48_system_information_type_5bis *si, int len)
-{
- memcpy(s->si5b_msg, si, MIN(len, sizeof(s->si5b_msg)));
-
- /* Neighbor Cell Description */
- s->nb_ext_ind_si5bis = (si->bcch_frequency_list[0] >> 6) & 1;
- s->nb_ba_ind_si5bis = (si->bcch_frequency_list[0] >> 5) & 1;
- decode_freq_list(s->freq, si->bcch_frequency_list,
- sizeof(si->bcch_frequency_list), 0xce, FREQ_TYPE_REP_5bis);
-
- s->si5bis = 1;
-
- return 0;
-}
-
-int gsm48_decode_sysinfo5ter(struct gsm48_sysinfo *s,
- struct gsm48_system_information_type_5ter *si, int len)
-{
- memcpy(s->si5t_msg, si, MIN(len, sizeof(s->si5t_msg)));
-
- /* Neighbor Cell Description */
- s->nb_multi_rep_si5ter = (si->bcch_frequency_list[0] >> 6) & 3;
- s->nb_ba_ind_si5ter = (si->bcch_frequency_list[0] >> 5) & 1;
- decode_freq_list(s->freq, si->bcch_frequency_list,
- sizeof(si->bcch_frequency_list), 0x8e, FREQ_TYPE_REP_5ter);
-
- s->si5ter = 1;
-
- return 0;
-}
-
-int gsm48_decode_sysinfo6(struct gsm48_sysinfo *s,
- struct gsm48_system_information_type_6 *si, int len)
-{
- int payload_len = len - sizeof(*si);
-
- memcpy(s->si6_msg, si, MIN(len, sizeof(s->si6_msg)));
-
- /* Cell Identity */
- if (s->si6 && s->cell_id != ntohs(si->cell_identity))
- LOGP(DRR, LOGL_INFO, "Cell ID on SI 6 differs from previous "
- "read.\n");
- s->cell_id = ntohs(si->cell_identity);
- /* LAI */
- gsm48_decode_lai(&si->lai, &s->mcc, &s->mnc, &s->lac);
- /* Cell Options (SACCH) */
- gsm48_decode_cellopt_sacch(s, &si->cell_options);
- /* NCC Permitted */
- s->nb_ncc_permitted_si6 = si->ncc_permitted;
- /* SI 6 Rest Octets */
- if (payload_len >= 4)
- gsm48_decode_si6_rest(s, si->rest_octets, payload_len);
-
- s->si6 = 1;
-
- return 0;
-}
-
diff --git a/Src/osmoconbb/src/host/layer23/src/misc/Makefile.am b/Src/osmoconbb/src/host/layer23/src/misc/Makefile.am
deleted file mode 100644
index a4cabac..0000000
--- a/Src/osmoconbb/src/host/layer23/src/misc/Makefile.am
+++ /dev/null
@@ -1,16 +0,0 @@
-INCLUDES = $(all_includes) -I$(top_srcdir)/include
-AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS)
-LDADD = ../common/liblayer23.a $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCODEC_LIBS)
-
-bin_PROGRAMS = bcch_scan ccch_scan echo_test cell_log cbch_sniff catcher
-
-bcch_scan_SOURCES = ../common/main.c app_bcch_scan.c bcch_scan.c
-ccch_scan_SOURCES = ../common/main.c app_ccch_scan.c rslms.c
-echo_test_SOURCES = ../common/main.c app_echo_test.c
-cell_log_LDADD = $(LDADD) -lm
-cell_log_SOURCES = ../common/main.c app_cell_log.c cell_log.c \
- ../../../gsmmap/geo.c
-cbch_sniff_SOURCES = ../common/main.c app_cbch_sniff.c
-catcher_LDADD = $(LDADD) -lm
-catcher_SOURCES = ../common/main.c app_catcher.c catcher.c \
- ../../../gsmmap/geo.c
diff --git a/Src/osmoconbb/src/host/layer23/src/misc/app_bcch_scan.c b/Src/osmoconbb/src/host/layer23/src/misc/app_bcch_scan.c
deleted file mode 100644
index 4c31f1a..0000000
--- a/Src/osmoconbb/src/host/layer23/src/misc/app_bcch_scan.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/* "Application" code of the layer2/3 stack */
-
-/* (C) 2010 by Holger Hans Peter Freyther
- * (C) 2010 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/l1ctl.h>
-#include <osmocom/bb/common/lapdm.h>
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/l23_app.h>
-#include <osmocom/bb/misc/layer3.h>
-
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/select.h>
-#include <osmocom/core/signal.h>
-
-#include <l1ctl_proto.h>
-
-static int signal_cb(unsigned int subsys, unsigned int signal,
- void *handler_data, void *signal_data)
-{
- struct osmocom_ms *ms;
-
- if (subsys != SS_L1CTL)
- return 0;
-
- switch (signal) {
- case S_L1CTL_RESET:
- ms = signal_data;
- return fps_start(ms);
- }
- return 0;
-}
-
-int l23_app_init(struct osmocom_ms *ms)
-{
- /* don't do layer3_init() as we don't want an actualy L3 */
- fps_init(ms);
- l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
- return osmo_signal_register_handler(SS_L1CTL, &signal_cb, NULL);
-}
-
-static struct l23_app_info info = {
- .copyright = "Copyright (C) 2010 Harald Welte <laforge@gnumonks.org>\n",
- .contribution = "Contributions by Holger Hans Peter Freyther\n",
-};
-
-struct l23_app_info *l23_app_info()
-{
- return &info;
-}
diff --git a/Src/osmoconbb/src/host/layer23/src/misc/app_catcher.c b/Src/osmoconbb/src/host/layer23/src/misc/app_catcher.c
deleted file mode 100644
index 27290be..0000000
--- a/Src/osmoconbb/src/host/layer23/src/misc/app_catcher.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/* "Application" code of the layer2/3 stack */
-
-/* (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <signal.h>
-#include <stdlib.h>
-#include <time.h>
-#include <getopt.h>
-
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/l1ctl.h>
-#include <osmocom/bb/common/l23_app.h>
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/gps.h>
-#include <osmocom/bb/misc/cell_log.h>
-
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/utils.h>
-
-#include <l1ctl_proto.h>
-
-extern struct log_target *stderr_target;
-extern void *l23_ctx;
-
-char *logname = "/var/log/osmocom.log";
-int RACH_MAX = 2;
-
-int _scan_work(struct osmocom_ms *ms)
-{
- return 0;
-}
-
-int _scan_exit(struct osmocom_ms *ms)
-{
- /* in case there is a lockup during exit */
- signal(SIGINT, SIG_DFL);
- signal(SIGHUP, SIG_DFL);
- signal(SIGTERM, SIG_DFL);
- signal(SIGPIPE, SIG_DFL);
-
- scan_exit();
-
- return 0;
-}
-
-int l23_app_init(struct osmocom_ms *ms)
-{
- int rc;
-
- srand(time(NULL));
-
-// log_parse_category_mask(stderr_target, "DL1C:DRSL:DRR:DGPS:DSUM");
- log_parse_category_mask(stderr_target, "DSUM");
- log_set_log_level(stderr_target, LOGL_INFO);
-
- l23_app_work = _scan_work;
- l23_app_exit = _scan_exit;
-
- rc = scan_init(ms);
- if (rc)
- return rc;
-
- l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
- printf("Mobile initialized, please start phone now!\n");
- return 0;
-}
-
-static int l23_cfg_supported()
-{
- return L23_OPT_TAP | L23_OPT_DBG;
-}
-
-static int l23_getopt_options(struct option **options)
-{
- static struct option opts [] = {
- {"logfile", 1, 0, 'l'},
- {"rach", 1, 0, 'r'},
- {"no-rach", 1, 0, 'n'},
-#ifdef _HAVE_GPSD
- {"gpsd-host", 1, 0, 'g'},
- {"gpsd-port", 1, 0, 'p'},
-#endif
- {"gps", 1, 0, 'g'},
- {"baud", 1, 0, 'b'}
- };
-
- *options = opts;
- return ARRAY_SIZE(opts);
-}
-
-static int l23_cfg_print_help()
-{
- printf("\nApplication specific\n");
- printf(" -l --logfile LOGFILE Logfile for the cell log.\n");
- printf(" -r --rach RACH Nr. of RACH bursts to send.\n");
- printf(" -n --no-rach Send no rach bursts.\n");
- printf(" -g --gpsd-host HOST 127.0.0.1. gpsd host.\n");
- printf(" -p --port PORT 2947. gpsd port\n");
- printf(" -f --gps DEVICE /dev/ttyACM0. GPS serial device.\n");
- printf(" -b --baud BAUDRAT The baud rate of the GPS device\n");
-
- return 0;
-}
-
-static int l23_cfg_handle(int c, const char *optarg)
-{
- switch (c) {
- case 'l':
- logname = talloc_strdup(l23_ctx, optarg);
- break;
- case 'r':
- RACH_MAX = atoi(optarg);
- break;
- case 'n':
- RACH_MAX = 0;
- break;
- case 'g':
-#ifdef _HAVE_GPSD
- snprintf(g.gpsd_host, ARRAY_SIZE(g.gpsd_host), "%s", optarg);
- /* force string terminator */
- g.gpsd_host[ARRAY_SIZE(g.gpsd_host) - 1] = '\0';
- if (g.gps_type != GPS_TYPE_UNDEF)
- goto cmd_line_error;
- g.gps_type = GPS_TYPE_GPSD;
- LOGP(DGPS, LOGL_INFO, "Using gpsd host %s\n", g.gpsd_host);
-#else
- printf("Gpsd support not compiled.\n");
- exit(1);
-#endif
- break;
- case 'p':
-#ifdef _HAVE_GPSD
- snprintf(g.gpsd_port, ARRAY_SIZE(g.gpsd_port), "%s", optarg);
- /* force string terminator */
- g.gpsd_port[ARRAY_SIZE(g.gpsd_port) - 1] = '\0';
- g.gps_type = GPS_TYPE_GPSD;
- LOGP(DGPS, LOGL_INFO, "Using gpsd port %s\n", g.gpsd_port);
-#else
- printf("Gpsd support not compiled.\n");
- exit(1);
-#endif
- break;
- case 'f':
- snprintf(g.device, ARRAY_SIZE(g.device), "%s", optarg);
- /* force string terminator */
- g.device[ARRAY_SIZE(g.device) - 1] = '\0';
- if (g.gps_type != GPS_TYPE_UNDEF)
- goto cmd_line_error;
- g.gps_type = GPS_TYPE_SERIAL;
- LOGP(DGPS, LOGL_INFO, "Using GPS serial device %s\n", g.device);
- break;
- case 'b':
- g.baud = atoi(optarg);
- g.gps_type = GPS_TYPE_SERIAL;
- LOGP(DGPS, LOGL_INFO, "Setting GPS baudrate to %u\n", g.baud);
- break;
- }
- return 0;
-
-cmd_line_error:
- printf("\nYou can't specify both gpsd and serial gps!!\n\n");
- exit(1);
-}
-
-static struct l23_app_info info = {
- .copyright = "Copyright (C) 2010 Andreas Eversberg\n",
- .getopt_string = "g:p:l:r:nf:b:",
- .cfg_supported = l23_cfg_supported,
- .cfg_getopt_opt = l23_getopt_options,
- .cfg_handle_opt = l23_cfg_handle,
- .cfg_print_help = l23_cfg_print_help,
-};
-
-struct l23_app_info *l23_app_info()
-{
- return &info;
-}
diff --git a/Src/osmoconbb/src/host/layer23/src/misc/app_cbch_sniff.c b/Src/osmoconbb/src/host/layer23/src/misc/app_cbch_sniff.c
deleted file mode 100644
index fb043db..0000000
--- a/Src/osmoconbb/src/host/layer23/src/misc/app_cbch_sniff.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/* CBCH passive sniffer */
-
-/* (C) 2010 by Holger Hans Peter Freyther
- * (C) 2010 by Harald Welte <laforge@gnumonks.org>
- * (C) 2010 by Alex Badea <vamposdecampos@gmail.com>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/l1ctl.h>
-#include <osmocom/bb/common/lapdm.h>
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/l23_app.h>
-#include <osmocom/bb/misc/layer3.h>
-
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/select.h>
-#include <osmocom/core/signal.h>
-#include <osmocom/gsm/rsl.h>
-
-#include <l1ctl_proto.h>
-
-struct osmocom_ms *g_ms;
-struct gsm48_sysinfo g_sysinfo = {};
-
-static int try_cbch(struct osmocom_ms *ms, struct gsm48_sysinfo *s)
-{
- if (!s->si1 || !s->si4)
- return 0;
- if (!s->chan_nr) {
- LOGP(DRR, LOGL_INFO, "no CBCH chan_nr found\n");
- return 0;
- }
-
- if (s->h) {
- LOGP(DRR, LOGL_INFO, "chan_nr = 0x%02x TSC = %d MAIO = %d "
- "HSN = %d hseq (%d): %s\n",
- s->chan_nr, s->tsc, s->maio, s->hsn,
- s->hopp_len,
- osmo_hexdump((unsigned char *) s->hopping, s->hopp_len * 2));
- return l1ctl_tx_dm_est_req_h1(ms,
- s->maio, s->hsn, s->hopping, s->hopp_len,
- s->chan_nr, s->tsc,
- GSM48_CMODE_SIGN, 0);
- } else {
- LOGP(DRR, LOGL_INFO, "chan_nr = 0x%02x TSC = %d ARFCN = %d\n",
- s->chan_nr, s->tsc, s->arfcn);
- return l1ctl_tx_dm_est_req_h0(ms, s->arfcn,
- s->chan_nr, s->tsc, GSM48_CMODE_SIGN, 0);
- }
-}
-
-
-/* receive BCCH at RR layer */
-static int bcch(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_system_information_type_header *sih = msgb_l3(msg);
- struct gsm48_sysinfo *s = &g_sysinfo;
-
- if (msgb_l3len(msg) != 23) {
- LOGP(DRR, LOGL_NOTICE, "Invalid BCCH message length\n");
- return -EINVAL;
- }
- switch (sih->system_information) {
- case GSM48_MT_RR_SYSINFO_1:
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 1\n");
- gsm48_decode_sysinfo1(s,
- (struct gsm48_system_information_type_1 *) sih,
- msgb_l3len(msg));
- return try_cbch(ms, s);
- case GSM48_MT_RR_SYSINFO_4:
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 4\n");
- gsm48_decode_sysinfo4(s,
- (struct gsm48_system_information_type_4 *) sih,
- msgb_l3len(msg));
- return try_cbch(ms, s);
- default:
- return 0;
- }
-}
-
-static int unit_data_ind(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- struct tlv_parsed tv;
- uint8_t ch_type, ch_subch, ch_ts;
-
- DEBUGP(DRSL, "RSLms UNIT DATA IND chan_nr=0x%02x link_id=0x%02x\n",
- rllh->chan_nr, rllh->link_id);
-
- rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh));
- if (!TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) {
- DEBUGP(DRSL, "UNIT_DATA_IND without L3 INFO ?!?\n");
- return -EIO;
- }
- msg->l3h = (uint8_t *) TLVP_VAL(&tv, RSL_IE_L3_INFO);
-
- rsl_dec_chan_nr(rllh->chan_nr, &ch_type, &ch_subch, &ch_ts);
- switch (ch_type) {
- case RSL_CHAN_BCCH:
- return bcch(ms, msg);
- default:
- return 0;
- }
-}
-
-static int rcv_rll(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- int msg_type = rllh->c.msg_type;
-
- if (msg_type == RSL_MT_UNIT_DATA_IND) {
- unit_data_ind(ms, msg);
- } else
- LOGP(DRSL, LOGL_NOTICE, "RSLms message unhandled\n");
-
- msgb_free(msg);
-
- return 0;
-}
-
-static int rcv_rsl(struct msgb *msg, struct lapdm_entity *le, void *l3ctx)
-{
- struct osmocom_ms *ms = l3ctx;
- struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
- int rc = 0;
-
- switch (rslh->msg_discr & 0xfe) {
- case ABIS_RSL_MDISC_RLL:
- rc = rcv_rll(ms, msg);
- break;
- default:
- LOGP(DRSL, LOGL_NOTICE, "unknown RSLms msg_discr 0x%02x\n",
- rslh->msg_discr);
- msgb_free(msg);
- rc = -EINVAL;
- break;
- }
-
- return rc;
-}
-
-static int signal_cb(unsigned int subsys, unsigned int signal,
- void *handler_data, void *signal_data)
-{
- struct osmocom_ms *ms;
-
- if (subsys != SS_L1CTL)
- return 0;
-
- switch (signal) {
- case S_L1CTL_RESET:
- case S_L1CTL_FBSB_ERR:
- ms = g_ms;
- return l1ctl_tx_fbsb_req(ms, ms->test_arfcn,
- L1CTL_FBSB_F_FB01SB, 100, 0, CCCH_MODE_COMBINED);
- case S_L1CTL_FBSB_RESP:
- return 0;
- }
- return 0;
-}
-
-int l23_app_init(struct osmocom_ms *ms)
-{
- /* don't do layer3_init() as we don't want an actualy L3 */
-
- g_ms = ms;
- lapdm_channel_set_l3(&ms->lapdm_channel, &rcv_rsl, ms);
-
- l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
- /* FIXME: L1CTL_RES_T_FULL doesn't reset dedicated mode
- * (if previously set), so we release it here. */
- l1ctl_tx_dm_rel_req(ms);
- return osmo_signal_register_handler(SS_L1CTL, &signal_cb, NULL);
-}
-
-static struct l23_app_info info = {
- .copyright = "Copyright (C) 2010 Harald Welte <laforge@gnumonks.org>\n",
- .contribution = "Contributions by Holger Hans Peter Freyther\n",
-};
-
-struct l23_app_info *l23_app_info()
-{
- return &info;
-}
diff --git a/Src/osmoconbb/src/host/layer23/src/misc/app_ccch_scan.c b/Src/osmoconbb/src/host/layer23/src/misc/app_ccch_scan.c
deleted file mode 100644
index 2f60505..0000000
--- a/Src/osmoconbb/src/host/layer23/src/misc/app_ccch_scan.c
+++ /dev/null
@@ -1,483 +0,0 @@
-/* CCCH passive sniffer */
-/* (C) 2010-2011 by Holger Hans Peter Freyther
- * (C) 2010 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdint.h>
-#include <errno.h>
-#include <stdio.h>
-
-#include <osmocom/core/msgb.h>
-#include <osmocom/gsm/rsl.h>
-#include <osmocom/gsm/tlv.h>
-#include <osmocom/gsm/gsm48_ie.h>
-#include <osmocom/gsm/gsm48.h>
-#include <osmocom/core/signal.h>
-#include <osmocom/gsm/protocol/gsm_04_08.h>
-
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/lapdm.h>
-#include <osmocom/bb/misc/rslms.h>
-#include <osmocom/bb/misc/layer3.h>
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/l1ctl.h>
-#include <osmocom/bb/common/l23_app.h>
-
-#include <l1ctl_proto.h>
-
-static struct {
- int has_si1;
- int ccch_mode;
- int ccch_enabled;
- int rach_count;
- struct gsm_sysinfo_freq cell_arfcns[1024];
-} app_state;
-
-
-static void dump_bcch(struct osmocom_ms *ms, uint8_t tc, const uint8_t *data)
-{
- struct gsm48_system_information_type_header *si_hdr;
- si_hdr = (struct gsm48_system_information_type_header *) data;
-
- /* GSM 05.02 §6.3.1.3 Mapping of BCCH data */
- switch (si_hdr->system_information) {
- case GSM48_MT_RR_SYSINFO_1:
-#ifdef BCCH_TC_CHECK
- if (tc != 0)
- LOGP(DRR, LOGL_ERROR, "SI1 on the wrong TC: %d\n", tc);
-#endif
- if (!app_state.has_si1) {
- struct gsm48_system_information_type_1 *si1 =
- (struct gsm48_system_information_type_1 *)data;
-
- gsm48_decode_freq_list(app_state.cell_arfcns,
- si1->cell_channel_description,
- sizeof(si1->cell_channel_description),
- 0xff, 0x01);
-
- app_state.has_si1 = 1;
- LOGP(DRR, LOGL_ERROR, "SI1 received.\n");
- }
- break;
- case GSM48_MT_RR_SYSINFO_2:
-#ifdef BCCH_TC_CHECK
- if (tc != 1)
- LOGP(DRR, LOGL_ERROR, "SI2 on the wrong TC: %d\n", tc);
-#endif
- break;
- case GSM48_MT_RR_SYSINFO_3:
-#ifdef BCCH_TC_CHECK
- if (tc != 2 && tc != 6)
- LOGP(DRR, LOGL_ERROR, "SI3 on the wrong TC: %d\n", tc);
-#endif
- if (app_state.ccch_mode == CCCH_MODE_NONE) {
- struct gsm48_system_information_type_3 *si3 =
- (struct gsm48_system_information_type_3 *)data;
-
- if (si3->control_channel_desc.ccch_conf == RSL_BCCH_CCCH_CONF_1_C)
- app_state.ccch_mode = CCCH_MODE_COMBINED;
- else
- app_state.ccch_mode = CCCH_MODE_NON_COMBINED;
-
- l1ctl_tx_ccch_mode_req(ms, app_state.ccch_mode);
- }
- break;
- case GSM48_MT_RR_SYSINFO_4:
-#ifdef BCCH_TC_CHECK
- if (tc != 3 && tc != 7)
- LOGP(DRR, LOGL_ERROR, "SI4 on the wrong TC: %d\n", tc);
-#endif
- break;
- case GSM48_MT_RR_SYSINFO_5:
- break;
- case GSM48_MT_RR_SYSINFO_6:
- break;
- case GSM48_MT_RR_SYSINFO_7:
-#ifdef BCCH_TC_CHECK
- if (tc != 7)
- LOGP(DRR, LOGL_ERROR, "SI7 on the wrong TC: %d\n", tc);
-#endif
- break;
- case GSM48_MT_RR_SYSINFO_8:
-#ifdef BCCH_TC_CHECK
- if (tc != 3)
- LOGP(DRR, LOGL_ERROR, "SI8 on the wrong TC: %d\n", tc);
-#endif
- break;
- case GSM48_MT_RR_SYSINFO_9:
-#ifdef BCCH_TC_CHECK
- if (tc != 4)
- LOGP(DRR, LOGL_ERROR, "SI9 on the wrong TC: %d\n", tc);
-#endif
- break;
- case GSM48_MT_RR_SYSINFO_13:
-#ifdef BCCH_TC_CHECK
- if (tc != 4 && tc != 0)
- LOGP(DRR, LOGL_ERROR, "SI13 on the wrong TC: %d\n", tc);
-#endif
- break;
- case GSM48_MT_RR_SYSINFO_16:
-#ifdef BCCH_TC_CHECK
- if (tc != 6)
- LOGP(DRR, LOGL_ERROR, "SI16 on the wrong TC: %d\n", tc);
-#endif
- break;
- case GSM48_MT_RR_SYSINFO_17:
-#ifdef BCCH_TC_CHECK
- if (tc != 2)
- LOGP(DRR, LOGL_ERROR, "SI17 on the wrong TC: %d\n", tc);
-#endif
- break;
- case GSM48_MT_RR_SYSINFO_2bis:
-#ifdef BCCH_TC_CHECK
- if (tc != 5)
- LOGP(DRR, LOGL_ERROR, "SI2bis on the wrong TC: %d\n", tc);
-#endif
- break;
- case GSM48_MT_RR_SYSINFO_2ter:
-#ifdef BCCH_TC_CHECK
- if (tc != 5 && tc != 4)
- LOGP(DRR, LOGL_ERROR, "SI2ter on the wrong TC: %d\n", tc);
-#endif
- break;
- case GSM48_MT_RR_SYSINFO_5bis:
- break;
- case GSM48_MT_RR_SYSINFO_5ter:
- break;
- default:
- fprintf(stderr, "\tUnknown SI");
- break;
- };
-}
-
-
-/**
- * This method used to send a l1ctl_tx_dm_est_req_h0 or
- * a l1ctl_tx_dm_est_req_h1 to the layer1 to follow this
- * assignment. The code has been removed.
- */
-static int gsm48_rx_imm_ass(struct msgb *msg, struct osmocom_ms *ms)
-{
- struct gsm48_imm_ass *ia = msgb_l3(msg);
- uint8_t ch_type, ch_subch, ch_ts;
-
- /* Discard packet TBF assignement */
- if (ia->page_mode & 0xf0)
- return 0;
-
- /* FIXME: compare RA and GSM time with when we sent RACH req */
-
- rsl_dec_chan_nr(ia->chan_desc.chan_nr, &ch_type, &ch_subch, &ch_ts);
-
- if (!ia->chan_desc.h0.h) {
- /* Non-hopping */
- uint16_t arfcn;
-
- arfcn = ia->chan_desc.h0.arfcn_low | (ia->chan_desc.h0.arfcn_high << 8);
-
- LOGP(DRR, LOGL_NOTICE, "GSM48 IMM ASS (ra=0x%02x, chan_nr=0x%02x, "
- "ARFCN=%u, TS=%u, SS=%u, TSC=%u) ", ia->req_ref.ra,
- ia->chan_desc.chan_nr, arfcn, ch_ts, ch_subch,
- ia->chan_desc.h0.tsc);
-
- } else {
- /* Hopping */
- uint8_t maio, hsn, ma_len;
- uint16_t ma[64], arfcn;
- int i, j, k;
-
- hsn = ia->chan_desc.h1.hsn;
- maio = ia->chan_desc.h1.maio_low | (ia->chan_desc.h1.maio_high << 2);
-
- LOGP(DRR, LOGL_NOTICE, "GSM48 IMM ASS (ra=0x%02x, chan_nr=0x%02x, "
- "HSN=%u, MAIO=%u, TS=%u, SS=%u, TSC=%u) ", ia->req_ref.ra,
- ia->chan_desc.chan_nr, hsn, maio, ch_ts, ch_subch,
- ia->chan_desc.h1.tsc);
-
- /* decode mobile allocation */
- ma_len = 0;
- for (i=1, j=0; i<=1024; i++) {
- arfcn = i & 1023;
- if (app_state.cell_arfcns[arfcn].mask & 0x01) {
- k = ia->mob_alloc_len - (j>>3) - 1;
- if (ia->mob_alloc[k] & (1 << (j&7))) {
- ma[ma_len++] = arfcn;
- }
- j++;
- }
- }
- }
-
- LOGPC(DRR, LOGL_NOTICE, "\n");
- return 0;
-}
-
-static const char *pag_print_mode(int mode)
-{
- switch (mode) {
- case 0:
- return "Normal paging";
- case 1:
- return "Extended paging";
- case 2:
- return "Paging reorganization";
- case 3:
- return "Same as before";
- default:
- return "invalid";
- }
-}
-
-static char *chan_need(int need)
-{
- switch (need) {
- case 0:
- return "any";
- case 1:
- return "sdch";
- case 2:
- return "tch/f";
- case 3:
- return "tch/h";
- default:
- return "invalid";
- }
-}
-
-static char *mi_type_to_string(int type)
-{
- switch (type) {
- case GSM_MI_TYPE_NONE:
- return "none";
- case GSM_MI_TYPE_IMSI:
- return "imsi";
- case GSM_MI_TYPE_IMEI:
- return "imei";
- case GSM_MI_TYPE_IMEISV:
- return "imeisv";
- case GSM_MI_TYPE_TMSI:
- return "tmsi";
- default:
- return "invalid";
- }
-}
-
-/**
- * This can contain two MIs. The size checking is a bit of a mess.
- */
-static int gsm48_rx_paging_p1(struct msgb *msg, struct osmocom_ms *ms)
-{
- struct gsm48_paging1 *pag;
- int len1, len2, mi_type, tag;
- char mi_string[GSM48_MI_SIZE];
-
- /* is there enough room for the header + LV? */
- if (msgb_l3len(msg) < sizeof(*pag) + 2) {
- LOGP(DRR, LOGL_ERROR, "PagingRequest is too short.\n");
- return -1;
- }
-
- pag = msgb_l3(msg);
- len1 = pag->data[0];
- mi_type = pag->data[1] & GSM_MI_TYPE_MASK;
-
- if (msgb_l3len(msg) < sizeof(*pag) + 2 + len1) {
- LOGP(DRR, LOGL_ERROR, "PagingRequest with wrong MI\n");
- return -1;
- }
-
- if (mi_type != GSM_MI_TYPE_NONE) {
- gsm48_mi_to_string(mi_string, sizeof(mi_string), &pag->data[1], len1);
- LOGP(DRR, LOGL_NOTICE, "Paging1: %s chan %s to %s M(%s) \n",
- pag_print_mode(pag->pag_mode),
- chan_need(pag->cneed1),
- mi_type_to_string(mi_type),
- mi_string);
- }
-
- /* check if we have a MI type in here */
- if (msgb_l3len(msg) < sizeof(*pag) + 2 + len1 + 3)
- return 0;
-
- tag = pag->data[2 + len1 + 0];
- len2 = pag->data[2 + len1 + 1];
- mi_type = pag->data[2 + len1 + 2] & GSM_MI_TYPE_MASK;
- if (tag == GSM48_IE_MOBILE_ID && mi_type != GSM_MI_TYPE_NONE) {
- if (msgb_l3len(msg) < sizeof(*pag) + 2 + len1 + 3 + len2) {
- LOGP(DRR, LOGL_ERROR, "Optional MI does not fit here.\n");
- return -1;
- }
-
- gsm48_mi_to_string(mi_string, sizeof(mi_string), &pag->data[2 + len1 + 2], len2);
- LOGP(DRR, LOGL_NOTICE, "Paging2: %s chan %s to %s M(%s) \n",
- pag_print_mode(pag->pag_mode),
- chan_need(pag->cneed2),
- mi_type_to_string(mi_type),
- mi_string);
- }
- return 0;
-}
-
-static int gsm48_rx_paging_p2(struct msgb *msg, struct osmocom_ms *ms)
-{
- struct gsm48_paging2 *pag;
- int tag, len, mi_type;
- char mi_string[GSM48_MI_SIZE];
-
- if (msgb_l3len(msg) < sizeof(*pag)) {
- LOGP(DRR, LOGL_ERROR, "Paging2 message is too small.\n");
- return -1;
- }
-
- pag = msgb_l3(msg);
- LOGP(DRR, LOGL_NOTICE, "Paging1: %s chan %s to TMSI M(0x%x) \n",
- pag_print_mode(pag->pag_mode),
- chan_need(pag->cneed1), pag->tmsi1);
- LOGP(DRR, LOGL_NOTICE, "Paging2: %s chan %s to TMSI M(0x%x) \n",
- pag_print_mode(pag->pag_mode),
- chan_need(pag->cneed1), pag->tmsi2);
-
- /* no optional element */
- if (msgb_l3len(msg) < sizeof(*pag) + 3)
- return 0;
-
- tag = pag->data[0];
- len = pag->data[1];
- mi_type = pag->data[2] & GSM_MI_TYPE_MASK;
-
- if (tag != GSM48_IE_MOBILE_ID)
- return 0;
-
- if (msgb_l3len(msg) < sizeof(*pag) + 3 + len) {
- LOGP(DRR, LOGL_ERROR, "Optional MI does not fit in here\n");
- return -1;
- }
-
- gsm48_mi_to_string(mi_string, sizeof(mi_string), &pag->data[2], len);
- LOGP(DRR, LOGL_NOTICE, "Paging3: %s chan %s to %s M(%s) \n",
- pag_print_mode(pag->pag_mode),
- "n/a ",
- mi_type_to_string(mi_type),
- mi_string);
-
- return 0;
-}
-
-int gsm48_rx_ccch(struct msgb *msg, struct osmocom_ms *ms)
-{
- struct gsm48_system_information_type_header *sih = msgb_l3(msg);
- int rc = 0;
-
- if (sih->rr_protocol_discriminator != GSM48_PDISC_RR)
- LOGP(DRR, LOGL_ERROR, "PCH pdisc != RR\n");
-
- switch (sih->system_information) {
- case GSM48_MT_RR_PAG_REQ_1:
- gsm48_rx_paging_p1(msg, ms);
- break;
- case GSM48_MT_RR_PAG_REQ_2:
- gsm48_rx_paging_p2(msg, ms);
- break;
- case GSM48_MT_RR_PAG_REQ_3:
- LOGP(DRR, LOGL_ERROR, "PAGING of type 3 is not implemented.\n");
- break;
- case GSM48_MT_RR_IMM_ASS:
- gsm48_rx_imm_ass(msg, ms);
- break;
- case GSM48_MT_RR_NOTIF_NCH:
- /* notification for voice call groups and such */
- break;
- case 0x07:
- /* wireshark know that this is SI2 quater and for 3G interop */
- break;
- default:
- LOGP(DRR, LOGL_NOTICE, "unknown PCH/AGCH type 0x%02x\n",
- sih->system_information);
- rc = -EINVAL;
- }
-
- return rc;
-}
-
-int gsm48_rx_bcch(struct msgb *msg, struct osmocom_ms *ms)
-{
- /* FIXME: we have lost the gsm frame time until here, need to store it
- * in some msgb context */
- //dump_bcch(dl->time.tc, ccch->data);
- dump_bcch(ms, 0, msg->l3h);
-
- /* Req channel logic */
- if (app_state.ccch_enabled && (app_state.rach_count < 2)) {
- l1ctl_tx_rach_req(ms, app_state.rach_count, 0,
- app_state.ccch_mode == CCCH_MODE_COMBINED);
- app_state.rach_count++;
- }
-
- return 0;
-}
-
-void layer3_app_reset(void)
-{
- /* Reset state */
- app_state.has_si1 = 0;
- app_state.ccch_mode = CCCH_MODE_NONE;
- app_state.ccch_enabled = 0;
- app_state.rach_count = 0;
-
- memset(&app_state.cell_arfcns, 0x00, sizeof(app_state.cell_arfcns));
-}
-
-static int signal_cb(unsigned int subsys, unsigned int signal,
- void *handler_data, void *signal_data)
-{
- struct osmocom_ms *ms;
-
- if (subsys != SS_L1CTL)
- return 0;
-
- switch (signal) {
- case S_L1CTL_RESET:
- ms = signal_data;
- layer3_app_reset();
- return l1ctl_tx_fbsb_req(ms, ms->test_arfcn,
- L1CTL_FBSB_F_FB01SB, 100, 0,
- CCCH_MODE_NONE);
- break;
- }
- return 0;
-}
-
-
-int l23_app_init(struct osmocom_ms *ms)
-{
- osmo_signal_register_handler(SS_L1CTL, &signal_cb, NULL);
- l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
- return layer3_init(ms);
-}
-
-static struct l23_app_info info = {
- .copyright = "Copyright (C) 2010 Harald Welte <laforge@gnumonks.org>\n",
- .contribution = "Contributions by Holger Hans Peter Freyther\n",
-};
-
-struct l23_app_info *l23_app_info()
-{
- return &info;
-}
diff --git a/Src/osmoconbb/src/host/layer23/src/misc/app_cell_log.c b/Src/osmoconbb/src/host/layer23/src/misc/app_cell_log.c
deleted file mode 100644
index 27290be..0000000
--- a/Src/osmoconbb/src/host/layer23/src/misc/app_cell_log.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/* "Application" code of the layer2/3 stack */
-
-/* (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <signal.h>
-#include <stdlib.h>
-#include <time.h>
-#include <getopt.h>
-
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/l1ctl.h>
-#include <osmocom/bb/common/l23_app.h>
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/gps.h>
-#include <osmocom/bb/misc/cell_log.h>
-
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/utils.h>
-
-#include <l1ctl_proto.h>
-
-extern struct log_target *stderr_target;
-extern void *l23_ctx;
-
-char *logname = "/var/log/osmocom.log";
-int RACH_MAX = 2;
-
-int _scan_work(struct osmocom_ms *ms)
-{
- return 0;
-}
-
-int _scan_exit(struct osmocom_ms *ms)
-{
- /* in case there is a lockup during exit */
- signal(SIGINT, SIG_DFL);
- signal(SIGHUP, SIG_DFL);
- signal(SIGTERM, SIG_DFL);
- signal(SIGPIPE, SIG_DFL);
-
- scan_exit();
-
- return 0;
-}
-
-int l23_app_init(struct osmocom_ms *ms)
-{
- int rc;
-
- srand(time(NULL));
-
-// log_parse_category_mask(stderr_target, "DL1C:DRSL:DRR:DGPS:DSUM");
- log_parse_category_mask(stderr_target, "DSUM");
- log_set_log_level(stderr_target, LOGL_INFO);
-
- l23_app_work = _scan_work;
- l23_app_exit = _scan_exit;
-
- rc = scan_init(ms);
- if (rc)
- return rc;
-
- l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
- printf("Mobile initialized, please start phone now!\n");
- return 0;
-}
-
-static int l23_cfg_supported()
-{
- return L23_OPT_TAP | L23_OPT_DBG;
-}
-
-static int l23_getopt_options(struct option **options)
-{
- static struct option opts [] = {
- {"logfile", 1, 0, 'l'},
- {"rach", 1, 0, 'r'},
- {"no-rach", 1, 0, 'n'},
-#ifdef _HAVE_GPSD
- {"gpsd-host", 1, 0, 'g'},
- {"gpsd-port", 1, 0, 'p'},
-#endif
- {"gps", 1, 0, 'g'},
- {"baud", 1, 0, 'b'}
- };
-
- *options = opts;
- return ARRAY_SIZE(opts);
-}
-
-static int l23_cfg_print_help()
-{
- printf("\nApplication specific\n");
- printf(" -l --logfile LOGFILE Logfile for the cell log.\n");
- printf(" -r --rach RACH Nr. of RACH bursts to send.\n");
- printf(" -n --no-rach Send no rach bursts.\n");
- printf(" -g --gpsd-host HOST 127.0.0.1. gpsd host.\n");
- printf(" -p --port PORT 2947. gpsd port\n");
- printf(" -f --gps DEVICE /dev/ttyACM0. GPS serial device.\n");
- printf(" -b --baud BAUDRAT The baud rate of the GPS device\n");
-
- return 0;
-}
-
-static int l23_cfg_handle(int c, const char *optarg)
-{
- switch (c) {
- case 'l':
- logname = talloc_strdup(l23_ctx, optarg);
- break;
- case 'r':
- RACH_MAX = atoi(optarg);
- break;
- case 'n':
- RACH_MAX = 0;
- break;
- case 'g':
-#ifdef _HAVE_GPSD
- snprintf(g.gpsd_host, ARRAY_SIZE(g.gpsd_host), "%s", optarg);
- /* force string terminator */
- g.gpsd_host[ARRAY_SIZE(g.gpsd_host) - 1] = '\0';
- if (g.gps_type != GPS_TYPE_UNDEF)
- goto cmd_line_error;
- g.gps_type = GPS_TYPE_GPSD;
- LOGP(DGPS, LOGL_INFO, "Using gpsd host %s\n", g.gpsd_host);
-#else
- printf("Gpsd support not compiled.\n");
- exit(1);
-#endif
- break;
- case 'p':
-#ifdef _HAVE_GPSD
- snprintf(g.gpsd_port, ARRAY_SIZE(g.gpsd_port), "%s", optarg);
- /* force string terminator */
- g.gpsd_port[ARRAY_SIZE(g.gpsd_port) - 1] = '\0';
- g.gps_type = GPS_TYPE_GPSD;
- LOGP(DGPS, LOGL_INFO, "Using gpsd port %s\n", g.gpsd_port);
-#else
- printf("Gpsd support not compiled.\n");
- exit(1);
-#endif
- break;
- case 'f':
- snprintf(g.device, ARRAY_SIZE(g.device), "%s", optarg);
- /* force string terminator */
- g.device[ARRAY_SIZE(g.device) - 1] = '\0';
- if (g.gps_type != GPS_TYPE_UNDEF)
- goto cmd_line_error;
- g.gps_type = GPS_TYPE_SERIAL;
- LOGP(DGPS, LOGL_INFO, "Using GPS serial device %s\n", g.device);
- break;
- case 'b':
- g.baud = atoi(optarg);
- g.gps_type = GPS_TYPE_SERIAL;
- LOGP(DGPS, LOGL_INFO, "Setting GPS baudrate to %u\n", g.baud);
- break;
- }
- return 0;
-
-cmd_line_error:
- printf("\nYou can't specify both gpsd and serial gps!!\n\n");
- exit(1);
-}
-
-static struct l23_app_info info = {
- .copyright = "Copyright (C) 2010 Andreas Eversberg\n",
- .getopt_string = "g:p:l:r:nf:b:",
- .cfg_supported = l23_cfg_supported,
- .cfg_getopt_opt = l23_getopt_options,
- .cfg_handle_opt = l23_cfg_handle,
- .cfg_print_help = l23_cfg_print_help,
-};
-
-struct l23_app_info *l23_app_info()
-{
- return &info;
-}
diff --git a/Src/osmoconbb/src/host/layer23/src/misc/app_echo_test.c b/Src/osmoconbb/src/host/layer23/src/misc/app_echo_test.c
deleted file mode 100644
index 3d937d2..0000000
--- a/Src/osmoconbb/src/host/layer23/src/misc/app_echo_test.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/* TEST code, regularly transmit ECHO REQ packet to L1 */
-
-/* (C) 2010 by Holger Hans Peter Freyther
- * (C) 2010 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/l1ctl.h>
-#include <osmocom/bb/common/lapdm.h>
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/l23_app.h>
-#include <osmocom/bb/misc/layer3.h>
-
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/select.h>
-
-
-static struct {
- struct osmo_timer_list timer;
-} test_data;
-
-static void test_tmr_cb(void *data)
-{
- struct osmocom_ms *ms = data;
-
- l1ctl_tx_echo_req(ms, 62);
- osmo_timer_schedule(&test_data.timer, 1, 0);
-}
-
-int l23_app_init(struct osmocom_ms *ms)
-{
- test_data.timer.cb = &test_tmr_cb;
- test_data.timer.data = ms;
-
- osmo_timer_schedule(&test_data.timer, 1, 0);
-
- return 0;
-}
-
-static struct l23_app_info info = {
- .copyright = "Copyright (C) 2010 Harald Welte <laforge@gnumonks.org>\n",
- .contribution = "Contributions by Holger Hans Peter Freyther\n",
-};
-
-struct l23_app_info *l23_app_info()
-{
- return &info;
-}
diff --git a/Src/osmoconbb/src/host/layer23/src/misc/bcch_scan.c b/Src/osmoconbb/src/host/layer23/src/misc/bcch_scan.c
deleted file mode 100644
index ddd0eea..0000000
--- a/Src/osmoconbb/src/host/layer23/src/misc/bcch_scan.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/* BCCH Scanning code for OsmocomBB */
-
-/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-
-#include <l1ctl_proto.h>
-
-#include <osmocom/core/logging.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/signal.h>
-#include <osmocom/core/timer.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/gsm/tlv.h>
-#include <osmocom/gsm/gsm_utils.h>
-#include <osmocom/gsm/protocol/gsm_04_08.h>
-#include <osmocom/gsm/protocol/gsm_08_58.h>
-#include <osmocom/gsm/rsl.h>
-
-#include <osmocom/bb/common/l1ctl.h>
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/lapdm.h>
-#include <osmocom/bb/common/logging.h>
-
-/* somewhere in 05.08 */
-#define MAX_CELLS_IN_BA 32
-
-/* Information about a single cell / BCCH */
-struct cell_info {
- struct llist_head list;
-
- uint16_t band_arfcn;
- uint8_t bsic;
- uint8_t rxlev;
-
- struct {
- uint16_t mcc; /* Mobile Country Code */
- uint16_t mnc; /* Mobile Network Code */
- uint16_t lac; /* Location Area Code */
- uint16_t rac; /* Routing Area Code */
- uint16_t cid; /* Cell ID */
- } id;
- uint16_t ba_arfcn[MAX_CELLS_IN_BA];
- uint8_t ba_arfcn_num;
-
- struct {
- int32_t fn_delta; /* delta to current L1 fn */
- int16_t qbit_delta;
- int16_t afc_delta;
- } l1_sync;
-};
-
-#define AFS_F_PM_DONE 0x01
-#define AFS_F_TESTED 0x02
-#define AFS_F_BCCH 0x04
-struct arfcn_state {
- uint8_t rxlev;
- uint8_t flags;
-};
-
-enum bscan_state {
- BSCAN_S_NONE,
- BSCAN_S_WAIT_DATA,
- BSCAN_S_DONE,
-};
-
-enum fps_state {
- FPS_S_NONE,
- FPS_S_PM_GSM900,
- FPS_S_PM_EGSM900,
- FPS_S_PM_GSM1800,
- FPS_S_BINFO,
-};
-
-struct full_power_scan {
- /* Full Power Scan */
- enum fps_state fps_state;
- struct arfcn_state arfcn_state[1024];
-
- struct osmocom_ms *ms;
-
- /* BCCH info part */
- enum bscan_state state;
- struct llist_head cell_list;
- struct cell_info *cur_cell;
- uint16_t cur_arfcn;
- struct osmo_timer_list timer;
-};
-
-static struct full_power_scan fps;
-
-static int get_next_arfcn(struct full_power_scan *fps)
-{
- unsigned int i;
- uint8_t best_rxlev = 0;
- int best_arfcn = -1;
-
- for (i = 0; i < ARRAY_SIZE(fps->arfcn_state); i++) {
- struct arfcn_state *af = &fps->arfcn_state[i];
- /* skip ARFCN's where we don't have a PM */
- if (!(af->flags & AFS_F_PM_DONE))
- continue;
- /* skip ARFCN's that we already tested */
- if (af->flags & AFS_F_TESTED)
- continue;
- /* if current arfcn_state is better than best so far,
- * select it */
- if (af->rxlev > best_rxlev) {
- best_rxlev = af->rxlev;
- best_arfcn = i;
- }
- }
- printf("arfcn=%d rxlev=%u\n", best_arfcn, best_rxlev);
- return best_arfcn;
-}
-
-static struct cell_info *cell_info_alloc(void)
-{
- struct cell_info *ci = talloc_zero(NULL, struct cell_info);
- return ci;
-}
-
-static void cell_info_free(struct cell_info *ci)
-{
- talloc_free(ci);
-}
-
-/* start to scan for one ARFCN */
-static int _cinfo_start_arfcn(unsigned int band_arfcn)
-{
- int rc;
-
- /* ask L1 to try to tune to new ARFCN */
- /* FIXME: decode band */
- rc = l1ctl_tx_fbsb_req(fps.ms, band_arfcn,
- L1CTL_FBSB_F_FB01SB, 100, 0, CCCH_MODE_COMBINED);
- if (rc < 0)
- return rc;
-
- /* allocate new cell info structure */
- fps.cur_cell = cell_info_alloc();
- fps.cur_arfcn = band_arfcn;
- fps.cur_cell->band_arfcn = band_arfcn;
- /* FIXME: start timer in case we never get a sync */
- fps.state = BSCAN_S_WAIT_DATA;
- osmo_timer_schedule(&fps.timer, 2, 0);
-
- return 0;
-}
-
-
-static void cinfo_next_cell(void *data)
-{
- int rc;
-
- /* we've been waiting for BCCH info */
- fps.arfcn_state[fps.cur_arfcn].flags |= AFS_F_TESTED;
- /* if there is a BCCH, we need to add the collected BCCH
- * information to our list */
-
- if (fps.arfcn_state[fps.cur_arfcn].flags & AFS_F_BCCH)
- llist_add(&fps.cur_cell->list, &fps.cell_list);
- else
- cell_info_free(fps.cur_cell);
-
- rc = get_next_arfcn(&fps);
- if (rc < 0) {
- fps.state = BSCAN_S_DONE;
- return;
- }
- /* start syncing to the next ARFCN */
- _cinfo_start_arfcn(rc);
-}
-
-static void cinfo_timer_cb(void *data)
-{
- switch (fps.state) {
- case BSCAN_S_WAIT_DATA:
- cinfo_next_cell(data);
- break;
- }
-}
-
-/* Update cell_info for current cell with received BCCH info */
-static int rx_bcch_info(const uint8_t *data)
-{
- struct cell_info *ci = fps.cur_cell;
- struct gsm48_system_information_type_header *si_hdr;
- si_hdr = (struct gsm48_system_information_type_header *) data;;
-
- /* we definitely have a BCCH on this channel */
- fps.arfcn_state[ci->band_arfcn].flags |= AFS_F_BCCH;
-
- switch (si_hdr->system_information) {
- case GSM48_MT_RR_SYSINFO_1:
- /* FIXME: CA, RACH control */
- break;
- case GSM48_MT_RR_SYSINFO_2:
- /* FIXME: BA, NCC, RACH control */
- break;
- case GSM48_MT_RR_SYSINFO_3:
- /* FIXME: cell_id, LAI */
- break;
- case GSM48_MT_RR_SYSINFO_4:
- /* FIXME: LAI */
- break;
- }
- return 0;
-}
-
-/* Update L1/SCH information (AFC/QBIT/FN offset, BSIC) */
-static int rx_sch_info()
-{
- /* FIXME */
-}
-
-static int bscan_sig_cb(unsigned int subsys, unsigned int signal,
- void *handler_data, void *signal_data)
-{
- struct cell_info *ci = fps.cur_cell;
- struct osmocom_ms *ms;
- struct osmobb_meas_res *mr;
- uint16_t arfcn;
- int rc;
-
- if (subsys != SS_L1CTL)
- return 0;
-
- switch (signal) {
- case S_L1CTL_PM_RES:
- mr = signal_data;
- /* check if PM result is for same MS */
- if (fps.ms != mr->ms)
- return 0;
- arfcn = mr->band_arfcn & 0x3ff;
- /* update RxLev and notice that PM was done */
- fps.arfcn_state[arfcn].rxlev = mr->rx_lev;
- fps.arfcn_state[arfcn].flags |= AFS_F_PM_DONE;
- break;
- case S_L1CTL_PM_DONE:
- ms = signal_data;
- switch (fps.fps_state) {
- case FPS_S_PM_GSM900:
- fps.fps_state = FPS_S_PM_EGSM900;
- return l1ctl_tx_pm_req_range(ms, 955, 1023);
- case FPS_S_PM_EGSM900:
- fps.fps_state = FPS_S_PM_GSM1800;
- return l1ctl_tx_pm_req_range(ms, 512, 885);
- case FPS_S_PM_GSM1800:
- /* power measurement has finished, we can start
- * to actually iterate over the ARFCN's and try
- * to sync to BCCHs */
- fps.fps_state = FPS_S_BINFO;
- rc = get_next_arfcn(&fps);
- if (rc < 0) {
- fps.state = BSCAN_S_DONE;
- return;
- }
- _cinfo_start_arfcn(rc);
- break;
- }
- break;
- case S_L1CTL_FBSB_RESP:
- /* We actually got a FCCH/SCH burst */
-#if 0
- fps.arfcn_state[ci->band_arfcn].flags |= AFS_F_BCCH;
- /* fallthrough */
-#else
- break;
-#endif
- case S_L1CTL_FBSB_ERR:
- /* We timed out, move on */
- if (fps.state == BSCAN_S_WAIT_DATA)
- cinfo_next_cell(NULL);
- break;
- }
- return 0;
-}
-
-/* start the full power scan */
-int fps_start(struct osmocom_ms *ms)
-{
- memset(&fps, 0, sizeof(fps));
- fps.ms = ms;
-
- fps.timer.cb = cinfo_timer_cb;
- fps.timer.data = &fps;
-
- /* Start by scanning the good old GSM900 band */
- fps.fps_state = FPS_S_PM_GSM900;
- return l1ctl_tx_pm_req_range(ms, 0, 124);
-}
-
-int fps_init(void)
-{
- return osmo_signal_register_handler(SS_L1CTL, &bscan_sig_cb, NULL);
-}
diff --git a/Src/osmoconbb/src/host/layer23/src/misc/catcher.c b/Src/osmoconbb/src/host/layer23/src/misc/catcher.c
deleted file mode 100644
index 1a9c33c..0000000
--- a/Src/osmoconbb/src/host/layer23/src/misc/catcher.c
+++ /dev/null
@@ -1,820 +0,0 @@
-/* Cell Scanning code for OsmocomBB */
-
-/* (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-#include <errno.h>
-
-#include <l1ctl_proto.h>
-
-#include <osmocom/core/logging.h>
-#include <osmocom/core/timer.h>
-#include <osmocom/core/signal.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/gsm/gsm_utils.h>
-#include <osmocom/gsm/protocol/gsm_04_08.h>
-#include <osmocom/gsm/rsl.h>
-
-#include <osmocom/bb/common/l1ctl.h>
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/lapdm.h>
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/networks.h>
-#include <osmocom/bb/common/gps.h>
-#include <osmocom/bb/misc/cell_log.h>
-#include "../../../gsmmap/geo.h"
-
-#define READ_WAIT 2, 0
-#define RACH_WAIT 0, 900000
-#define MIN_RXLEV -106
-#define MAX_DIST 2000
-
-enum {
- SCAN_STATE_PM,
- SCAN_STATE_SYNC,
- SCAN_STATE_READ,
- SCAN_STATE_RACH,
-};
-
-/* ranges of bands */
-static uint16_t band_range[][2] = {{0, 124}, {512, 885}, {955, 1023}, {0, 0}};
-
-#define INFO_FLG_PM 1
-#define INFO_FLG_SYNC 2
-#define INFO_FLG_SI1 4
-#define INFO_FLG_SI2 8
-#define INFO_FLG_SI2bis 16
-#define INFO_FLG_SI2ter 32
-#define INFO_FLG_SI3 64
-#define INFO_FLG_SI4 128
-
-static struct osmocom_ms *ms;
-static struct osmo_timer_list timer;
-
-static struct pm_info {
- uint16_t flags;
- int8_t rxlev;
-} pm[1024];
-
-static int started = 0;
-static int state;
-static int8_t min_rxlev = MIN_RXLEV;
-static int sync_count;
-static int pm_index, pm_gps_valid;
-static double pm_gps_x, pm_gps_y, pm_gps_z;
-static int arfcn;
-static int rach_count;
-static FILE *logfp = NULL;
-extern char *logname;
-extern int RACH_MAX;
-
-
-static struct gsm48_sysinfo sysinfo;
-
-static struct log_si {
- uint16_t flags;
- uint8_t bsic;
- int8_t rxlev;
- uint16_t mcc, mnc, lac, cellid;
- uint8_t ta;
- double latitude, longitude;
-} log_si;
-
-struct rach_ref {
- uint8_t valid;
- uint8_t cr;
- uint8_t t1, t2, t3;
-} rach_ref;
-
-#define LOGFILE(fmt, args...) \
- fprintf(logfp, fmt, ## args);
-#define LOGFLUSH() \
- fflush(logfp);
-
-static void start_sync(void);
-static void start_rach(void);
-static void start_pm(void);
-
-static void log_gps(void)
-{
- if (!g.enable || !g.valid)
- return;
- LOGFILE("position %.8f %.8f\n", g.longitude, g.latitude);
-}
-
-static void log_time(void)
-{
- time_t now;
-
- if (g.enable && g.valid)
- now = g.gmt;
- else
- time(&now);
- LOGFILE("time %lu\n", now);
-}
-
-static void log_frame(char *tag, uint8_t *data)
-{
- int i;
-
- LOGFILE("%s", tag);
- for (i = 0; i < 23; i++)
- LOGFILE(" %02x", *data++);
- LOGFILE("\n");
-}
-
-static void log_pm(void)
-{
- int count = 0, i;
-
- LOGFILE("[power]\n");
- log_time();
- log_gps();
- for (i = 0; i <= 1023; i++) {
- if ((pm[i].flags & INFO_FLG_PM)) {
- if (!count)
- LOGFILE("arfcn %d", i);
- LOGFILE(" %d", pm[i].rxlev);
- count++;
- if (count == 12) {
- LOGFILE("\n");
- count = 0;
- }
- } else {
- if (count) {
- LOGFILE("\n");
- count = 0;
- }
- }
- }
- if (count)
- LOGFILE("\n");
-
- LOGFILE("\n");
- LOGFLUSH();
-}
-
-static void log_sysinfo(void)
-{
- struct rx_meas_stat *meas = &ms->meas;
- struct gsm48_sysinfo *s = &sysinfo;
- int8_t rxlev;
- char ta_str[32] = "";
-
- if (log_si.ta != 0xff)
- sprintf(ta_str, " TA=%d", log_si.ta);
-
- LOGP(DSUM, LOGL_INFO, "Cell: ARFCN=%d MCC=%s MNC=%s (%s, %s)%s\n",
- arfcn, gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc),
- gsm_get_mcc(s->mcc), gsm_get_mnc(s->mcc, s->mnc), ta_str);
-
- LOGFILE("[sysinfo]\n");
- LOGFILE("arfcn %d\n", s->arfcn);
- log_time();
- log_gps();
- LOGFILE("bsic %d,%d\n", s->bsic >> 3, s->bsic & 7);
- rxlev = meas->rxlev / meas->frames - 110;
- LOGFILE("rxlev %d\n", rxlev);
- if (s->si1)
- log_frame("si1", s->si1_msg);
- if (s->si2)
- log_frame("si2", s->si2_msg);
- if (s->si2bis)
- log_frame("si2bis", s->si2b_msg);
- if (s->si2ter)
- log_frame("si2ter", s->si2t_msg);
- if (s->si3)
- log_frame("si3", s->si3_msg);
- if (s->si4)
- log_frame("si4", s->si4_msg);
- if (log_si.ta != 0xff)
- LOGFILE("ta %d\n", log_si.ta);
-
- LOGFILE("\n");
- LOGFLUSH();
-}
-
-static void timeout_cb(void *arg)
-{
- switch (state) {
- case SCAN_STATE_READ:
- LOGP(DRR, LOGL_INFO, "Timeout reading BCCH\n");
- start_sync();
- break;
- case SCAN_STATE_RACH:
- LOGP(DRR, LOGL_INFO, "Timeout on RACH\n");
- rach_count++;
- start_rach();
- break;
- }
-}
-
-static void stop_timer(void)
-{
- if (osmo_timer_pending(&timer))
- osmo_timer_del(&timer);
-}
-
-static void start_timer(int sec, int micro)
-{
- stop_timer();
- timer.cb = timeout_cb;
- timer.data = ms;
- osmo_timer_schedule(&timer, sec, micro);
-}
-
-static void start_rach(void)
-{
- struct gsm48_sysinfo *s = &sysinfo;
- uint8_t chan_req_val, chan_req_mask;
- struct msgb *nmsg;
- struct abis_rsl_cchan_hdr *ncch;
-
- if (rach_count == RACH_MAX) {
- log_sysinfo();
- start_sync();
- return;
- }
-
- state = SCAN_STATE_RACH;
-
- if (s->neci) {
- chan_req_mask = 0x0f;
- chan_req_val = 0x01;
- LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x "
- "(OTHER with NECI)\n", chan_req_val);
- } else {
- chan_req_mask = 0x1f;
- chan_req_val = 0xe0;
- LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (OTHER no NECI)\n",
- chan_req_val);
- }
-
- rach_ref.valid = 0;
- rach_ref.cr = random();
- rach_ref.cr &= chan_req_mask;
- rach_ref.cr |= chan_req_val;
-
- nmsg = msgb_alloc_headroom(RSL_ALLOC_SIZE+RSL_ALLOC_HEADROOM,
- RSL_ALLOC_HEADROOM, "GSM 04.06 RSL");
- if (!nmsg)
- return;
- nmsg->l2h = nmsg->data;
- ncch = (struct abis_rsl_cchan_hdr *) msgb_put(nmsg, sizeof(*ncch)
- + 4 + 2 + 2);
- rsl_init_cchan_hdr(ncch, RSL_MT_CHAN_RQD);
- ncch->chan_nr = RSL_CHAN_RACH;
- ncch->data[0] = RSL_IE_REQ_REFERENCE;
- ncch->data[1] = rach_ref.cr;
- ncch->data[2] = (s->ccch_conf == 1) << 7;
- ncch->data[3] = 0;
- ncch->data[4] = RSL_IE_ACCESS_DELAY;
- ncch->data[5] = 0; /* no delay */
- ncch->data[6] = RSL_IE_MS_POWER;
- ncch->data[7] = 0; /* full power */
-
- start_timer(RACH_WAIT);
-
- lapdm_rslms_recvmsg(nmsg, &ms->lapdm_channel);
-}
-
-static void start_sync(void)
-{
- int rxlev = -128;
- int i, dist = 0;
- char dist_str[32] = "";
-
- arfcn = 0xffff;
- for (i = 0; i <= 1023; i++) {
- if ((pm[i].flags & INFO_FLG_PM)
- && !(pm[i].flags & INFO_FLG_SYNC)) {
- if (pm[i].rxlev > rxlev) {
- rxlev = pm[i].rxlev;
- arfcn = i;
- }
- }
- }
- /* if GPS becomes valid, like after exitting a tunnel */
- if (!pm_gps_valid && g.valid) {
- pm_gps_valid = 1;
- geo2space(&pm_gps_x, &pm_gps_y, &pm_gps_z, g.longitude,
- g.latitude);
- }
- if (pm_gps_valid && g.valid) {
- double x, y, z;
-
- geo2space(&x, &y, &z, g.longitude, g.latitude);
- dist = distinspace(pm_gps_x, pm_gps_y, pm_gps_z, x, y, z);
- sprintf(dist_str, " dist %d", (int)dist);
- }
- if (dist > MAX_DIST || arfcn == 0xffff || rxlev < min_rxlev) {
- memset(pm, 0, sizeof(pm));
- pm_index = 0;
- sync_count = 0;
- start_pm();
- return;
- }
- pm[arfcn].flags |= INFO_FLG_SYNC;
- LOGP(DSUM, LOGL_INFO, "Sync ARFCN %d (rxlev %d, %d syncs "
- "left)%s\n", arfcn, pm[arfcn].rxlev, sync_count--, dist_str);
- memset(&sysinfo, 0, sizeof(sysinfo));
- sysinfo.arfcn = arfcn;
- state = SCAN_STATE_SYNC;
- l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
- l1ctl_tx_fbsb_req(ms, arfcn, L1CTL_FBSB_F_FB01SB, 100, 0,
- CCCH_MODE_NONE);
-}
-
-static void start_pm(void)
-{
- uint16_t from, to;
-
- state = SCAN_STATE_PM;
- from = band_range[pm_index][0];
- to = band_range[pm_index][1];
-
- if (from == 0 && to == 0) {
- LOGP(DSUM, LOGL_INFO, "Measurement done\n");
- pm_gps_valid = g.enable && g.valid;
- if (pm_gps_valid)
- geo2space(&pm_gps_x, &pm_gps_y, &pm_gps_z,
- g.longitude, g.latitude);
- log_pm();
- start_sync();
- return;
- }
- LOGP(DSUM, LOGL_INFO, "Measure from %d to %d\n", from, to);
- l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
- l1ctl_tx_pm_req_range(ms, from, to);
-}
-
-static int signal_cb(unsigned int subsys, unsigned int signal,
- void *handler_data, void *signal_data)
-{
- struct osmobb_meas_res *mr;
- struct osmobb_fbsb_res *fr;
- uint16_t index;
-
- if (subsys != SS_L1CTL)
- return 0;
-
- switch (signal) {
- case S_L1CTL_PM_RES:
- mr = signal_data;
- index = mr->band_arfcn & 0x3ff;
- pm[index].flags |= INFO_FLG_PM;
- pm[index].rxlev = mr->rx_lev - 110;
- if (pm[index].rxlev >= min_rxlev)
- sync_count++;
-// printf("rxlev %d = %d (sync_count %d)\n", index, pm[index].rxlev, sync_count);
- break;
- case S_L1CTL_PM_DONE:
- pm_index++;
- start_pm();
- break;
- case S_L1CTL_FBSB_RESP:
- fr = signal_data;
- sysinfo.bsic = fr->bsic;
- state = SCAN_STATE_READ;
- memset(&ms->meas, 0, sizeof(ms->meas));
- memset(&log_si, 0, sizeof(log_si));
- log_si.flags |= INFO_FLG_SYNC;
- log_si.ta = 0xff; /* invalid */
- start_timer(READ_WAIT);
- LOGP(DRR, LOGL_INFO, "Synchronized, start reading\n");
- break;
- case S_L1CTL_FBSB_ERR:
- LOGP(DRR, LOGL_INFO, "Sync failed\n");
- start_sync();
- break;
- case S_L1CTL_RESET:
- if (started)
- break;
- started = 1;
- memset(pm, 0, sizeof(pm));
- pm_index = 0;
- sync_count = 0;
- start_pm();
- }
- return 0;
-}
-
-static int ta_result(uint8_t ta)
-{
- stop_timer();
-
- if (ta == 0xff)
- LOGP(DSUM, LOGL_INFO, "Got assignment reject\n");
- else {
- LOGP(DSUM, LOGL_DEBUG, "Got assignment TA = %d\n", ta);
- log_si.ta = ta;
- }
-
- log_sysinfo();
- start_sync();
-
- return 0;
-}
-
-/* match request reference agains request */
-static int match_ra(struct osmocom_ms *ms, struct gsm48_req_ref *ref)
-{
- uint8_t ia_t1, ia_t2, ia_t3;
-
- /* filter confirmed RACH requests only */
- if (rach_ref.valid && ref->ra == rach_ref.cr) {
- ia_t1 = ref->t1;
- ia_t2 = ref->t2;
- ia_t3 = (ref->t3_high << 3) | ref->t3_low;
- if (ia_t1 == rach_ref.t1 && ia_t2 == rach_ref.t2
- && ia_t3 == rach_ref.t3) {
- LOGP(DRR, LOGL_INFO, "request %02x matches "
- "(fn=%d,%d,%d)\n", ref->ra, ia_t1, ia_t2,
- ia_t3);
- return 1;
- } else
- LOGP(DRR, LOGL_INFO, "request %02x matches but not "
- "frame number (IMM.ASS fn=%d,%d,%d != RACH "
- "fn=%d,%d,%d)\n", ref->ra, ia_t1, ia_t2, ia_t3,
- rach_ref.t1, rach_ref.t2, rach_ref.t3);
- }
-
- return 0;
-}
-
-/* 9.1.18 IMMEDIATE ASSIGNMENT is received */
-static int imm_ass(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_imm_ass *ia = msgb_l3(msg);
-
- LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT:\n");
-
- if (state != SCAN_STATE_RACH) {
- LOGP(DRR, LOGL_INFO, "Not for us, no request.\n");
- return 0;
- }
-
- /* request ref */
- if (match_ra(ms, &ia->req_ref)) {
- return ta_result(ia->timing_advance);
- }
- LOGP(DRR, LOGL_INFO, "Request, but not for us.\n");
-
- return 0;
-}
-
-/* 9.1.19 IMMEDIATE ASSIGNMENT EXTENDED is received */
-static int imm_ass_ext(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_imm_ass_ext *ia = msgb_l3(msg);
-
- LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT EXTENDED:\n");
-
- if (state != SCAN_STATE_RACH) {
- LOGP(DRR, LOGL_INFO, "Not for us, no request.\n");
- return 0;
- }
-
- /* request ref 1 */
- if (match_ra(ms, &ia->req_ref1)) {
- return ta_result(ia->timing_advance1);
- }
- /* request ref 2 */
- if (match_ra(ms, &ia->req_ref2)) {
- return ta_result(ia->timing_advance2);
- }
- LOGP(DRR, LOGL_INFO, "Request, but not for us.\n");
-
- return 0;
-}
-
-/* 9.1.20 IMMEDIATE ASSIGNMENT REJECT is received */
-static int imm_ass_rej(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_imm_ass_rej *ia = msgb_l3(msg);
- int i;
- struct gsm48_req_ref *req_ref;
-
- LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT REJECT:\n");
-
- if (state != SCAN_STATE_RACH) {
- LOGP(DRR, LOGL_INFO, "Not for us, no request.\n");
- return 0;
- }
-
- for (i = 0; i < 4; i++) {
- /* request reference */
- req_ref = (struct gsm48_req_ref *)
- (((uint8_t *)&ia->req_ref1) + i * 4);
- LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT REJECT "
- "(ref 0x%02x)\n", req_ref->ra);
- if (match_ra(ms, req_ref)) {
- return ta_result(0xff);
- }
- }
-
- return 0;
-}
-
-/* receive CCCH at RR layer */
-static int pch_agch(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_system_information_type_header *sih = msgb_l3(msg);
-
- switch (sih->system_information) {
- case GSM48_MT_RR_PAG_REQ_1:
- case GSM48_MT_RR_PAG_REQ_2:
- case GSM48_MT_RR_PAG_REQ_3:
- return 0;
- case GSM48_MT_RR_IMM_ASS:
- return imm_ass(ms, msg);
- case GSM48_MT_RR_IMM_ASS_EXT:
- return imm_ass_ext(ms, msg);
- case GSM48_MT_RR_IMM_ASS_REJ:
- return imm_ass_rej(ms, msg);
- default:
- return -EINVAL;
- }
-}
-
-/* check if sysinfo is complete, change to RACH state */
-static int new_sysinfo(void)
-{
- struct gsm48_sysinfo *s = &sysinfo;
-
- /* restart timer */
- start_timer(READ_WAIT);
-
- /* mandatory */
- if (!s->si1 || !s->si2 || !s->si3 || !s->si4) {
- LOGP(DRR, LOGL_INFO, "not all mandatory SI received\n");
- return 0;
- }
-
- /* extended band */
- if (s->nb_ext_ind_si2 && !s->si2bis) {
- LOGP(DRR, LOGL_INFO, "extended ba, but si2bis not received\n");
- return 0;
- }
-
- /* 2ter */
- if (s->si2ter_ind && !s->si2ter) {
- LOGP(DRR, LOGL_INFO, "si2ter_ind, but si2ter not received\n");
- return 0;
- }
-
- LOGP(DRR, LOGL_INFO, "Sysinfo complete\n");
-
- stop_timer();
-
- rach_count = 0;
- start_rach();
-
- return 0;
-}
-
-/* receive BCCH at RR layer */
-static int bcch(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_sysinfo *s = &sysinfo;
- struct gsm48_system_information_type_header *sih = msgb_l3(msg);
- uint8_t ccch_mode;
-
- if (msgb_l3len(msg) != 23) {
- LOGP(DRR, LOGL_NOTICE, "Invalid BCCH message length\n");
- return -EINVAL;
- }
- switch (sih->system_information) {
- case GSM48_MT_RR_SYSINFO_1:
- if (!memcmp(sih, s->si1_msg, sizeof(s->si1_msg)))
- return 0;
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 1\n");
- gsm48_decode_sysinfo1(s,
- (struct gsm48_system_information_type_1 *) sih,
- msgb_l3len(msg));
- return new_sysinfo();
- case GSM48_MT_RR_SYSINFO_2:
- if (!memcmp(sih, s->si2_msg, sizeof(s->si2_msg)))
- return 0;
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2\n");
- gsm48_decode_sysinfo2(s,
- (struct gsm48_system_information_type_2 *) sih,
- msgb_l3len(msg));
- return new_sysinfo();
- case GSM48_MT_RR_SYSINFO_2bis:
- if (!memcmp(sih, s->si2b_msg, sizeof(s->si2b_msg)))
- return 0;
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2bis\n");
- gsm48_decode_sysinfo2bis(s,
- (struct gsm48_system_information_type_2bis *) sih,
- msgb_l3len(msg));
- return new_sysinfo();
- case GSM48_MT_RR_SYSINFO_2ter:
- if (!memcmp(sih, s->si2t_msg, sizeof(s->si2t_msg)))
- return 0;
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2ter\n");
- gsm48_decode_sysinfo2ter(s,
- (struct gsm48_system_information_type_2ter *) sih,
- msgb_l3len(msg));
- return new_sysinfo();
- case GSM48_MT_RR_SYSINFO_3:
- if (!memcmp(sih, s->si3_msg, sizeof(s->si3_msg)))
- return 0;
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 3\n");
- gsm48_decode_sysinfo3(s,
- (struct gsm48_system_information_type_3 *) sih,
- msgb_l3len(msg));
- ccch_mode = (s->ccch_conf == 1) ? CCCH_MODE_COMBINED :
- CCCH_MODE_NON_COMBINED;
- LOGP(DRR, LOGL_INFO, "Changing CCCH_MODE to %d\n", ccch_mode);
- l1ctl_tx_ccch_mode_req(ms, ccch_mode);
- return new_sysinfo();
- case GSM48_MT_RR_SYSINFO_4:
- if (!memcmp(sih, s->si4_msg, sizeof(s->si4_msg)))
- return 0;
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 4\n");
- gsm48_decode_sysinfo4(s,
- (struct gsm48_system_information_type_4 *) sih,
- msgb_l3len(msg));
- return new_sysinfo();
- default:
- return -EINVAL;
- }
-}
-
-static int unit_data_ind(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- struct tlv_parsed tv;
- uint8_t ch_type, ch_subch, ch_ts;
-
- DEBUGP(DRSL, "RSLms UNIT DATA IND chan_nr=0x%02x link_id=0x%02x\n",
- rllh->chan_nr, rllh->link_id);
-
- rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh));
- if (!TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) {
- DEBUGP(DRSL, "UNIT_DATA_IND without L3 INFO ?!?\n");
- return -EIO;
- }
- msg->l3h = (uint8_t *) TLVP_VAL(&tv, RSL_IE_L3_INFO);
-
- if (state != SCAN_STATE_READ && state != SCAN_STATE_RACH) {
- return -EINVAL;
- }
-
- rsl_dec_chan_nr(rllh->chan_nr, &ch_type, &ch_subch, &ch_ts);
- switch (ch_type) {
- case RSL_CHAN_PCH_AGCH:
- return pch_agch(ms, msg);
- case RSL_CHAN_BCCH:
- return bcch(ms, msg);
-#if 0
- case RSL_CHAN_Bm_ACCHs:
- case RSL_CHAN_Lm_ACCHs:
- case RSL_CHAN_SDCCH4_ACCH:
- case RSL_CHAN_SDCCH8_ACCH:
- return rx_acch(ms, msg);
-#endif
- default:
- LOGP(DRSL, LOGL_NOTICE, "RSL with chan_nr 0x%02x unknown.\n",
- rllh->chan_nr);
- return -EINVAL;
- }
-}
-
-static int rcv_rll(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- int msg_type = rllh->c.msg_type;
-
- if (msg_type == RSL_MT_UNIT_DATA_IND) {
- unit_data_ind(ms, msg);
- } else
- LOGP(DRSL, LOGL_NOTICE, "RSLms message unhandled\n");
-
- msgb_free(msg);
-
- return 0;
-}
-
-int chan_conf(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct abis_rsl_cchan_hdr *ch = msgb_l2(msg);
- struct gsm48_req_ref *ref = (struct gsm48_req_ref *) (ch->data + 1);
-
- if (msgb_l2len(msg) < sizeof(*ch) + sizeof(*ref)) {
- LOGP(DRR, LOGL_ERROR, "CHAN_CNF too slort\n");
- return -EINVAL;
- }
-
- rach_ref.valid = 1;
- rach_ref.t1 = ref->t1;
- rach_ref.t2 = ref->t2;
- rach_ref.t3 = ref->t3_low | (ref->t3_high << 3);
-
- return 0;
-}
-
-static int rcv_cch(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct abis_rsl_cchan_hdr *ch = msgb_l2(msg);
- int msg_type = ch->c.msg_type;
- int rc;
-
- LOGP(DRSL, LOGL_INFO, "Received '%s' from layer1\n",
- rsl_msg_name(msg_type));
-
- if (state == SCAN_STATE_RACH && msg_type == RSL_MT_CHAN_CONF) {
- rc = chan_conf(ms, msg);
- msgb_free(msg);
- return rc;
- }
-
- LOGP(DRSL, LOGL_NOTICE, "RSLms message unhandled\n");
- msgb_free(msg);
- return 0;
-}
-
-static int rcv_rsl(struct msgb *msg, struct lapdm_entity *le, void *l3ctx)
-{
- struct osmocom_ms *ms = l3ctx;
- struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
- int rc = 0;
-
- switch (rslh->msg_discr & 0xfe) {
- case ABIS_RSL_MDISC_RLL:
- rc = rcv_rll(ms, msg);
- break;
- case ABIS_RSL_MDISC_COM_CHAN:
- rc = rcv_cch(ms, msg);
- break;
- default:
- LOGP(DRSL, LOGL_NOTICE, "unknown RSLms msg_discr 0x%02x\n",
- rslh->msg_discr);
- msgb_free(msg);
- rc = -EINVAL;
- break;
- }
-
- return rc;
-}
-
-int scan_init(struct osmocom_ms *_ms)
-{
- ms = _ms;
- osmo_signal_register_handler(SS_L1CTL, &signal_cb, NULL);
- memset(&timer, 0, sizeof(timer));
- lapdm_channel_set_l3(&ms->lapdm_channel, &rcv_rsl, ms);
- g.enable = 1;
- osmo_gps_init();
- if (osmo_gps_open())
- g.enable = 0;
-
- if (!strcmp(logname, "-"))
- logfp = stdout;
- else
- logfp = fopen(logname, "a");
- if (!logfp) {
- fprintf(stderr, "Failed to open logfile '%s'\n", logname);
- scan_exit();
- return -errno;
- }
- LOGP(DSUM, LOGL_INFO, "Scanner initialized\n");
-
- return 0;
-}
-
-int scan_exit(void)
-{
- LOGP(DSUM, LOGL_INFO, "Scanner exit\n");
- if (g.valid)
- osmo_gps_close();
- if (logfp)
- fclose(logfp);
- osmo_signal_unregister_handler(SS_L1CTL, &signal_cb, NULL);
- stop_timer();
-
- return 0;
-}
diff --git a/Src/osmoconbb/src/host/layer23/src/misc/cell_log.c b/Src/osmoconbb/src/host/layer23/src/misc/cell_log.c
deleted file mode 100644
index 1a9c33c..0000000
--- a/Src/osmoconbb/src/host/layer23/src/misc/cell_log.c
+++ /dev/null
@@ -1,820 +0,0 @@
-/* Cell Scanning code for OsmocomBB */
-
-/* (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-#include <errno.h>
-
-#include <l1ctl_proto.h>
-
-#include <osmocom/core/logging.h>
-#include <osmocom/core/timer.h>
-#include <osmocom/core/signal.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/gsm/gsm_utils.h>
-#include <osmocom/gsm/protocol/gsm_04_08.h>
-#include <osmocom/gsm/rsl.h>
-
-#include <osmocom/bb/common/l1ctl.h>
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/lapdm.h>
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/networks.h>
-#include <osmocom/bb/common/gps.h>
-#include <osmocom/bb/misc/cell_log.h>
-#include "../../../gsmmap/geo.h"
-
-#define READ_WAIT 2, 0
-#define RACH_WAIT 0, 900000
-#define MIN_RXLEV -106
-#define MAX_DIST 2000
-
-enum {
- SCAN_STATE_PM,
- SCAN_STATE_SYNC,
- SCAN_STATE_READ,
- SCAN_STATE_RACH,
-};
-
-/* ranges of bands */
-static uint16_t band_range[][2] = {{0, 124}, {512, 885}, {955, 1023}, {0, 0}};
-
-#define INFO_FLG_PM 1
-#define INFO_FLG_SYNC 2
-#define INFO_FLG_SI1 4
-#define INFO_FLG_SI2 8
-#define INFO_FLG_SI2bis 16
-#define INFO_FLG_SI2ter 32
-#define INFO_FLG_SI3 64
-#define INFO_FLG_SI4 128
-
-static struct osmocom_ms *ms;
-static struct osmo_timer_list timer;
-
-static struct pm_info {
- uint16_t flags;
- int8_t rxlev;
-} pm[1024];
-
-static int started = 0;
-static int state;
-static int8_t min_rxlev = MIN_RXLEV;
-static int sync_count;
-static int pm_index, pm_gps_valid;
-static double pm_gps_x, pm_gps_y, pm_gps_z;
-static int arfcn;
-static int rach_count;
-static FILE *logfp = NULL;
-extern char *logname;
-extern int RACH_MAX;
-
-
-static struct gsm48_sysinfo sysinfo;
-
-static struct log_si {
- uint16_t flags;
- uint8_t bsic;
- int8_t rxlev;
- uint16_t mcc, mnc, lac, cellid;
- uint8_t ta;
- double latitude, longitude;
-} log_si;
-
-struct rach_ref {
- uint8_t valid;
- uint8_t cr;
- uint8_t t1, t2, t3;
-} rach_ref;
-
-#define LOGFILE(fmt, args...) \
- fprintf(logfp, fmt, ## args);
-#define LOGFLUSH() \
- fflush(logfp);
-
-static void start_sync(void);
-static void start_rach(void);
-static void start_pm(void);
-
-static void log_gps(void)
-{
- if (!g.enable || !g.valid)
- return;
- LOGFILE("position %.8f %.8f\n", g.longitude, g.latitude);
-}
-
-static void log_time(void)
-{
- time_t now;
-
- if (g.enable && g.valid)
- now = g.gmt;
- else
- time(&now);
- LOGFILE("time %lu\n", now);
-}
-
-static void log_frame(char *tag, uint8_t *data)
-{
- int i;
-
- LOGFILE("%s", tag);
- for (i = 0; i < 23; i++)
- LOGFILE(" %02x", *data++);
- LOGFILE("\n");
-}
-
-static void log_pm(void)
-{
- int count = 0, i;
-
- LOGFILE("[power]\n");
- log_time();
- log_gps();
- for (i = 0; i <= 1023; i++) {
- if ((pm[i].flags & INFO_FLG_PM)) {
- if (!count)
- LOGFILE("arfcn %d", i);
- LOGFILE(" %d", pm[i].rxlev);
- count++;
- if (count == 12) {
- LOGFILE("\n");
- count = 0;
- }
- } else {
- if (count) {
- LOGFILE("\n");
- count = 0;
- }
- }
- }
- if (count)
- LOGFILE("\n");
-
- LOGFILE("\n");
- LOGFLUSH();
-}
-
-static void log_sysinfo(void)
-{
- struct rx_meas_stat *meas = &ms->meas;
- struct gsm48_sysinfo *s = &sysinfo;
- int8_t rxlev;
- char ta_str[32] = "";
-
- if (log_si.ta != 0xff)
- sprintf(ta_str, " TA=%d", log_si.ta);
-
- LOGP(DSUM, LOGL_INFO, "Cell: ARFCN=%d MCC=%s MNC=%s (%s, %s)%s\n",
- arfcn, gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc),
- gsm_get_mcc(s->mcc), gsm_get_mnc(s->mcc, s->mnc), ta_str);
-
- LOGFILE("[sysinfo]\n");
- LOGFILE("arfcn %d\n", s->arfcn);
- log_time();
- log_gps();
- LOGFILE("bsic %d,%d\n", s->bsic >> 3, s->bsic & 7);
- rxlev = meas->rxlev / meas->frames - 110;
- LOGFILE("rxlev %d\n", rxlev);
- if (s->si1)
- log_frame("si1", s->si1_msg);
- if (s->si2)
- log_frame("si2", s->si2_msg);
- if (s->si2bis)
- log_frame("si2bis", s->si2b_msg);
- if (s->si2ter)
- log_frame("si2ter", s->si2t_msg);
- if (s->si3)
- log_frame("si3", s->si3_msg);
- if (s->si4)
- log_frame("si4", s->si4_msg);
- if (log_si.ta != 0xff)
- LOGFILE("ta %d\n", log_si.ta);
-
- LOGFILE("\n");
- LOGFLUSH();
-}
-
-static void timeout_cb(void *arg)
-{
- switch (state) {
- case SCAN_STATE_READ:
- LOGP(DRR, LOGL_INFO, "Timeout reading BCCH\n");
- start_sync();
- break;
- case SCAN_STATE_RACH:
- LOGP(DRR, LOGL_INFO, "Timeout on RACH\n");
- rach_count++;
- start_rach();
- break;
- }
-}
-
-static void stop_timer(void)
-{
- if (osmo_timer_pending(&timer))
- osmo_timer_del(&timer);
-}
-
-static void start_timer(int sec, int micro)
-{
- stop_timer();
- timer.cb = timeout_cb;
- timer.data = ms;
- osmo_timer_schedule(&timer, sec, micro);
-}
-
-static void start_rach(void)
-{
- struct gsm48_sysinfo *s = &sysinfo;
- uint8_t chan_req_val, chan_req_mask;
- struct msgb *nmsg;
- struct abis_rsl_cchan_hdr *ncch;
-
- if (rach_count == RACH_MAX) {
- log_sysinfo();
- start_sync();
- return;
- }
-
- state = SCAN_STATE_RACH;
-
- if (s->neci) {
- chan_req_mask = 0x0f;
- chan_req_val = 0x01;
- LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x "
- "(OTHER with NECI)\n", chan_req_val);
- } else {
- chan_req_mask = 0x1f;
- chan_req_val = 0xe0;
- LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (OTHER no NECI)\n",
- chan_req_val);
- }
-
- rach_ref.valid = 0;
- rach_ref.cr = random();
- rach_ref.cr &= chan_req_mask;
- rach_ref.cr |= chan_req_val;
-
- nmsg = msgb_alloc_headroom(RSL_ALLOC_SIZE+RSL_ALLOC_HEADROOM,
- RSL_ALLOC_HEADROOM, "GSM 04.06 RSL");
- if (!nmsg)
- return;
- nmsg->l2h = nmsg->data;
- ncch = (struct abis_rsl_cchan_hdr *) msgb_put(nmsg, sizeof(*ncch)
- + 4 + 2 + 2);
- rsl_init_cchan_hdr(ncch, RSL_MT_CHAN_RQD);
- ncch->chan_nr = RSL_CHAN_RACH;
- ncch->data[0] = RSL_IE_REQ_REFERENCE;
- ncch->data[1] = rach_ref.cr;
- ncch->data[2] = (s->ccch_conf == 1) << 7;
- ncch->data[3] = 0;
- ncch->data[4] = RSL_IE_ACCESS_DELAY;
- ncch->data[5] = 0; /* no delay */
- ncch->data[6] = RSL_IE_MS_POWER;
- ncch->data[7] = 0; /* full power */
-
- start_timer(RACH_WAIT);
-
- lapdm_rslms_recvmsg(nmsg, &ms->lapdm_channel);
-}
-
-static void start_sync(void)
-{
- int rxlev = -128;
- int i, dist = 0;
- char dist_str[32] = "";
-
- arfcn = 0xffff;
- for (i = 0; i <= 1023; i++) {
- if ((pm[i].flags & INFO_FLG_PM)
- && !(pm[i].flags & INFO_FLG_SYNC)) {
- if (pm[i].rxlev > rxlev) {
- rxlev = pm[i].rxlev;
- arfcn = i;
- }
- }
- }
- /* if GPS becomes valid, like after exitting a tunnel */
- if (!pm_gps_valid && g.valid) {
- pm_gps_valid = 1;
- geo2space(&pm_gps_x, &pm_gps_y, &pm_gps_z, g.longitude,
- g.latitude);
- }
- if (pm_gps_valid && g.valid) {
- double x, y, z;
-
- geo2space(&x, &y, &z, g.longitude, g.latitude);
- dist = distinspace(pm_gps_x, pm_gps_y, pm_gps_z, x, y, z);
- sprintf(dist_str, " dist %d", (int)dist);
- }
- if (dist > MAX_DIST || arfcn == 0xffff || rxlev < min_rxlev) {
- memset(pm, 0, sizeof(pm));
- pm_index = 0;
- sync_count = 0;
- start_pm();
- return;
- }
- pm[arfcn].flags |= INFO_FLG_SYNC;
- LOGP(DSUM, LOGL_INFO, "Sync ARFCN %d (rxlev %d, %d syncs "
- "left)%s\n", arfcn, pm[arfcn].rxlev, sync_count--, dist_str);
- memset(&sysinfo, 0, sizeof(sysinfo));
- sysinfo.arfcn = arfcn;
- state = SCAN_STATE_SYNC;
- l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
- l1ctl_tx_fbsb_req(ms, arfcn, L1CTL_FBSB_F_FB01SB, 100, 0,
- CCCH_MODE_NONE);
-}
-
-static void start_pm(void)
-{
- uint16_t from, to;
-
- state = SCAN_STATE_PM;
- from = band_range[pm_index][0];
- to = band_range[pm_index][1];
-
- if (from == 0 && to == 0) {
- LOGP(DSUM, LOGL_INFO, "Measurement done\n");
- pm_gps_valid = g.enable && g.valid;
- if (pm_gps_valid)
- geo2space(&pm_gps_x, &pm_gps_y, &pm_gps_z,
- g.longitude, g.latitude);
- log_pm();
- start_sync();
- return;
- }
- LOGP(DSUM, LOGL_INFO, "Measure from %d to %d\n", from, to);
- l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
- l1ctl_tx_pm_req_range(ms, from, to);
-}
-
-static int signal_cb(unsigned int subsys, unsigned int signal,
- void *handler_data, void *signal_data)
-{
- struct osmobb_meas_res *mr;
- struct osmobb_fbsb_res *fr;
- uint16_t index;
-
- if (subsys != SS_L1CTL)
- return 0;
-
- switch (signal) {
- case S_L1CTL_PM_RES:
- mr = signal_data;
- index = mr->band_arfcn & 0x3ff;
- pm[index].flags |= INFO_FLG_PM;
- pm[index].rxlev = mr->rx_lev - 110;
- if (pm[index].rxlev >= min_rxlev)
- sync_count++;
-// printf("rxlev %d = %d (sync_count %d)\n", index, pm[index].rxlev, sync_count);
- break;
- case S_L1CTL_PM_DONE:
- pm_index++;
- start_pm();
- break;
- case S_L1CTL_FBSB_RESP:
- fr = signal_data;
- sysinfo.bsic = fr->bsic;
- state = SCAN_STATE_READ;
- memset(&ms->meas, 0, sizeof(ms->meas));
- memset(&log_si, 0, sizeof(log_si));
- log_si.flags |= INFO_FLG_SYNC;
- log_si.ta = 0xff; /* invalid */
- start_timer(READ_WAIT);
- LOGP(DRR, LOGL_INFO, "Synchronized, start reading\n");
- break;
- case S_L1CTL_FBSB_ERR:
- LOGP(DRR, LOGL_INFO, "Sync failed\n");
- start_sync();
- break;
- case S_L1CTL_RESET:
- if (started)
- break;
- started = 1;
- memset(pm, 0, sizeof(pm));
- pm_index = 0;
- sync_count = 0;
- start_pm();
- }
- return 0;
-}
-
-static int ta_result(uint8_t ta)
-{
- stop_timer();
-
- if (ta == 0xff)
- LOGP(DSUM, LOGL_INFO, "Got assignment reject\n");
- else {
- LOGP(DSUM, LOGL_DEBUG, "Got assignment TA = %d\n", ta);
- log_si.ta = ta;
- }
-
- log_sysinfo();
- start_sync();
-
- return 0;
-}
-
-/* match request reference agains request */
-static int match_ra(struct osmocom_ms *ms, struct gsm48_req_ref *ref)
-{
- uint8_t ia_t1, ia_t2, ia_t3;
-
- /* filter confirmed RACH requests only */
- if (rach_ref.valid && ref->ra == rach_ref.cr) {
- ia_t1 = ref->t1;
- ia_t2 = ref->t2;
- ia_t3 = (ref->t3_high << 3) | ref->t3_low;
- if (ia_t1 == rach_ref.t1 && ia_t2 == rach_ref.t2
- && ia_t3 == rach_ref.t3) {
- LOGP(DRR, LOGL_INFO, "request %02x matches "
- "(fn=%d,%d,%d)\n", ref->ra, ia_t1, ia_t2,
- ia_t3);
- return 1;
- } else
- LOGP(DRR, LOGL_INFO, "request %02x matches but not "
- "frame number (IMM.ASS fn=%d,%d,%d != RACH "
- "fn=%d,%d,%d)\n", ref->ra, ia_t1, ia_t2, ia_t3,
- rach_ref.t1, rach_ref.t2, rach_ref.t3);
- }
-
- return 0;
-}
-
-/* 9.1.18 IMMEDIATE ASSIGNMENT is received */
-static int imm_ass(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_imm_ass *ia = msgb_l3(msg);
-
- LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT:\n");
-
- if (state != SCAN_STATE_RACH) {
- LOGP(DRR, LOGL_INFO, "Not for us, no request.\n");
- return 0;
- }
-
- /* request ref */
- if (match_ra(ms, &ia->req_ref)) {
- return ta_result(ia->timing_advance);
- }
- LOGP(DRR, LOGL_INFO, "Request, but not for us.\n");
-
- return 0;
-}
-
-/* 9.1.19 IMMEDIATE ASSIGNMENT EXTENDED is received */
-static int imm_ass_ext(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_imm_ass_ext *ia = msgb_l3(msg);
-
- LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT EXTENDED:\n");
-
- if (state != SCAN_STATE_RACH) {
- LOGP(DRR, LOGL_INFO, "Not for us, no request.\n");
- return 0;
- }
-
- /* request ref 1 */
- if (match_ra(ms, &ia->req_ref1)) {
- return ta_result(ia->timing_advance1);
- }
- /* request ref 2 */
- if (match_ra(ms, &ia->req_ref2)) {
- return ta_result(ia->timing_advance2);
- }
- LOGP(DRR, LOGL_INFO, "Request, but not for us.\n");
-
- return 0;
-}
-
-/* 9.1.20 IMMEDIATE ASSIGNMENT REJECT is received */
-static int imm_ass_rej(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_imm_ass_rej *ia = msgb_l3(msg);
- int i;
- struct gsm48_req_ref *req_ref;
-
- LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT REJECT:\n");
-
- if (state != SCAN_STATE_RACH) {
- LOGP(DRR, LOGL_INFO, "Not for us, no request.\n");
- return 0;
- }
-
- for (i = 0; i < 4; i++) {
- /* request reference */
- req_ref = (struct gsm48_req_ref *)
- (((uint8_t *)&ia->req_ref1) + i * 4);
- LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT REJECT "
- "(ref 0x%02x)\n", req_ref->ra);
- if (match_ra(ms, req_ref)) {
- return ta_result(0xff);
- }
- }
-
- return 0;
-}
-
-/* receive CCCH at RR layer */
-static int pch_agch(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_system_information_type_header *sih = msgb_l3(msg);
-
- switch (sih->system_information) {
- case GSM48_MT_RR_PAG_REQ_1:
- case GSM48_MT_RR_PAG_REQ_2:
- case GSM48_MT_RR_PAG_REQ_3:
- return 0;
- case GSM48_MT_RR_IMM_ASS:
- return imm_ass(ms, msg);
- case GSM48_MT_RR_IMM_ASS_EXT:
- return imm_ass_ext(ms, msg);
- case GSM48_MT_RR_IMM_ASS_REJ:
- return imm_ass_rej(ms, msg);
- default:
- return -EINVAL;
- }
-}
-
-/* check if sysinfo is complete, change to RACH state */
-static int new_sysinfo(void)
-{
- struct gsm48_sysinfo *s = &sysinfo;
-
- /* restart timer */
- start_timer(READ_WAIT);
-
- /* mandatory */
- if (!s->si1 || !s->si2 || !s->si3 || !s->si4) {
- LOGP(DRR, LOGL_INFO, "not all mandatory SI received\n");
- return 0;
- }
-
- /* extended band */
- if (s->nb_ext_ind_si2 && !s->si2bis) {
- LOGP(DRR, LOGL_INFO, "extended ba, but si2bis not received\n");
- return 0;
- }
-
- /* 2ter */
- if (s->si2ter_ind && !s->si2ter) {
- LOGP(DRR, LOGL_INFO, "si2ter_ind, but si2ter not received\n");
- return 0;
- }
-
- LOGP(DRR, LOGL_INFO, "Sysinfo complete\n");
-
- stop_timer();
-
- rach_count = 0;
- start_rach();
-
- return 0;
-}
-
-/* receive BCCH at RR layer */
-static int bcch(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_sysinfo *s = &sysinfo;
- struct gsm48_system_information_type_header *sih = msgb_l3(msg);
- uint8_t ccch_mode;
-
- if (msgb_l3len(msg) != 23) {
- LOGP(DRR, LOGL_NOTICE, "Invalid BCCH message length\n");
- return -EINVAL;
- }
- switch (sih->system_information) {
- case GSM48_MT_RR_SYSINFO_1:
- if (!memcmp(sih, s->si1_msg, sizeof(s->si1_msg)))
- return 0;
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 1\n");
- gsm48_decode_sysinfo1(s,
- (struct gsm48_system_information_type_1 *) sih,
- msgb_l3len(msg));
- return new_sysinfo();
- case GSM48_MT_RR_SYSINFO_2:
- if (!memcmp(sih, s->si2_msg, sizeof(s->si2_msg)))
- return 0;
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2\n");
- gsm48_decode_sysinfo2(s,
- (struct gsm48_system_information_type_2 *) sih,
- msgb_l3len(msg));
- return new_sysinfo();
- case GSM48_MT_RR_SYSINFO_2bis:
- if (!memcmp(sih, s->si2b_msg, sizeof(s->si2b_msg)))
- return 0;
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2bis\n");
- gsm48_decode_sysinfo2bis(s,
- (struct gsm48_system_information_type_2bis *) sih,
- msgb_l3len(msg));
- return new_sysinfo();
- case GSM48_MT_RR_SYSINFO_2ter:
- if (!memcmp(sih, s->si2t_msg, sizeof(s->si2t_msg)))
- return 0;
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2ter\n");
- gsm48_decode_sysinfo2ter(s,
- (struct gsm48_system_information_type_2ter *) sih,
- msgb_l3len(msg));
- return new_sysinfo();
- case GSM48_MT_RR_SYSINFO_3:
- if (!memcmp(sih, s->si3_msg, sizeof(s->si3_msg)))
- return 0;
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 3\n");
- gsm48_decode_sysinfo3(s,
- (struct gsm48_system_information_type_3 *) sih,
- msgb_l3len(msg));
- ccch_mode = (s->ccch_conf == 1) ? CCCH_MODE_COMBINED :
- CCCH_MODE_NON_COMBINED;
- LOGP(DRR, LOGL_INFO, "Changing CCCH_MODE to %d\n", ccch_mode);
- l1ctl_tx_ccch_mode_req(ms, ccch_mode);
- return new_sysinfo();
- case GSM48_MT_RR_SYSINFO_4:
- if (!memcmp(sih, s->si4_msg, sizeof(s->si4_msg)))
- return 0;
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 4\n");
- gsm48_decode_sysinfo4(s,
- (struct gsm48_system_information_type_4 *) sih,
- msgb_l3len(msg));
- return new_sysinfo();
- default:
- return -EINVAL;
- }
-}
-
-static int unit_data_ind(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- struct tlv_parsed tv;
- uint8_t ch_type, ch_subch, ch_ts;
-
- DEBUGP(DRSL, "RSLms UNIT DATA IND chan_nr=0x%02x link_id=0x%02x\n",
- rllh->chan_nr, rllh->link_id);
-
- rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh));
- if (!TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) {
- DEBUGP(DRSL, "UNIT_DATA_IND without L3 INFO ?!?\n");
- return -EIO;
- }
- msg->l3h = (uint8_t *) TLVP_VAL(&tv, RSL_IE_L3_INFO);
-
- if (state != SCAN_STATE_READ && state != SCAN_STATE_RACH) {
- return -EINVAL;
- }
-
- rsl_dec_chan_nr(rllh->chan_nr, &ch_type, &ch_subch, &ch_ts);
- switch (ch_type) {
- case RSL_CHAN_PCH_AGCH:
- return pch_agch(ms, msg);
- case RSL_CHAN_BCCH:
- return bcch(ms, msg);
-#if 0
- case RSL_CHAN_Bm_ACCHs:
- case RSL_CHAN_Lm_ACCHs:
- case RSL_CHAN_SDCCH4_ACCH:
- case RSL_CHAN_SDCCH8_ACCH:
- return rx_acch(ms, msg);
-#endif
- default:
- LOGP(DRSL, LOGL_NOTICE, "RSL with chan_nr 0x%02x unknown.\n",
- rllh->chan_nr);
- return -EINVAL;
- }
-}
-
-static int rcv_rll(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- int msg_type = rllh->c.msg_type;
-
- if (msg_type == RSL_MT_UNIT_DATA_IND) {
- unit_data_ind(ms, msg);
- } else
- LOGP(DRSL, LOGL_NOTICE, "RSLms message unhandled\n");
-
- msgb_free(msg);
-
- return 0;
-}
-
-int chan_conf(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct abis_rsl_cchan_hdr *ch = msgb_l2(msg);
- struct gsm48_req_ref *ref = (struct gsm48_req_ref *) (ch->data + 1);
-
- if (msgb_l2len(msg) < sizeof(*ch) + sizeof(*ref)) {
- LOGP(DRR, LOGL_ERROR, "CHAN_CNF too slort\n");
- return -EINVAL;
- }
-
- rach_ref.valid = 1;
- rach_ref.t1 = ref->t1;
- rach_ref.t2 = ref->t2;
- rach_ref.t3 = ref->t3_low | (ref->t3_high << 3);
-
- return 0;
-}
-
-static int rcv_cch(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct abis_rsl_cchan_hdr *ch = msgb_l2(msg);
- int msg_type = ch->c.msg_type;
- int rc;
-
- LOGP(DRSL, LOGL_INFO, "Received '%s' from layer1\n",
- rsl_msg_name(msg_type));
-
- if (state == SCAN_STATE_RACH && msg_type == RSL_MT_CHAN_CONF) {
- rc = chan_conf(ms, msg);
- msgb_free(msg);
- return rc;
- }
-
- LOGP(DRSL, LOGL_NOTICE, "RSLms message unhandled\n");
- msgb_free(msg);
- return 0;
-}
-
-static int rcv_rsl(struct msgb *msg, struct lapdm_entity *le, void *l3ctx)
-{
- struct osmocom_ms *ms = l3ctx;
- struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
- int rc = 0;
-
- switch (rslh->msg_discr & 0xfe) {
- case ABIS_RSL_MDISC_RLL:
- rc = rcv_rll(ms, msg);
- break;
- case ABIS_RSL_MDISC_COM_CHAN:
- rc = rcv_cch(ms, msg);
- break;
- default:
- LOGP(DRSL, LOGL_NOTICE, "unknown RSLms msg_discr 0x%02x\n",
- rslh->msg_discr);
- msgb_free(msg);
- rc = -EINVAL;
- break;
- }
-
- return rc;
-}
-
-int scan_init(struct osmocom_ms *_ms)
-{
- ms = _ms;
- osmo_signal_register_handler(SS_L1CTL, &signal_cb, NULL);
- memset(&timer, 0, sizeof(timer));
- lapdm_channel_set_l3(&ms->lapdm_channel, &rcv_rsl, ms);
- g.enable = 1;
- osmo_gps_init();
- if (osmo_gps_open())
- g.enable = 0;
-
- if (!strcmp(logname, "-"))
- logfp = stdout;
- else
- logfp = fopen(logname, "a");
- if (!logfp) {
- fprintf(stderr, "Failed to open logfile '%s'\n", logname);
- scan_exit();
- return -errno;
- }
- LOGP(DSUM, LOGL_INFO, "Scanner initialized\n");
-
- return 0;
-}
-
-int scan_exit(void)
-{
- LOGP(DSUM, LOGL_INFO, "Scanner exit\n");
- if (g.valid)
- osmo_gps_close();
- if (logfp)
- fclose(logfp);
- osmo_signal_unregister_handler(SS_L1CTL, &signal_cb, NULL);
- stop_timer();
-
- return 0;
-}
diff --git a/Src/osmoconbb/src/host/layer23/src/misc/rslms.c b/Src/osmoconbb/src/host/layer23/src/misc/rslms.c
deleted file mode 100644
index 68956f9..0000000
--- a/Src/osmoconbb/src/host/layer23/src/misc/rslms.c
+++ /dev/null
@@ -1,151 +0,0 @@
-/* RSLms - GSM 08.58 like protocol between L2 and L3 of GSM Um interface */
-
-/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdint.h>
-#include <errno.h>
-#include <stdio.h>
-
-#include <osmocom/core/msgb.h>
-#include <osmocom/gsm/rsl.h>
-#include <osmocom/gsm/tlv.h>
-#include <osmocom/gsm/protocol/gsm_04_08.h>
-
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/lapdm.h>
-#include <osmocom/bb/misc/rslms.h>
-#include <osmocom/bb/misc/layer3.h>
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/l1ctl.h>
-
-/* Send a 'simple' RLL request to L2 */
-int rslms_tx_rll_req(struct osmocom_ms *ms, uint8_t msg_type,
- uint8_t chan_nr, uint8_t link_id)
-{
- struct msgb *msg;
-
- msg = rsl_rll_simple(msg_type, chan_nr, link_id, 1);
-
- return lapdm_rslms_recvmsg(msg, &ms->lapdm_channel);
-}
-
-/* Send a RLL request (including L3 info) to L2 */
-int rslms_tx_rll_req_l3(struct osmocom_ms *ms, uint8_t msg_type,
- uint8_t chan_nr, uint8_t link_id, struct msgb *msg)
-{
- rsl_rll_push_l3(msg, msg_type, chan_nr, link_id, 1);
-
- return lapdm_rslms_recvmsg(msg, &ms->lapdm_channel);
-}
-
-static int rslms_rx_udata_ind(struct msgb *msg, struct osmocom_ms *ms)
-{
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- struct tlv_parsed tv;
- int rc = 0;
-
- DEBUGP(DRSL, "RSLms UNIT DATA IND chan_nr=0x%02x link_id=0x%02x\n",
- rllh->chan_nr, rllh->link_id);
-
- rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh));
- if (!TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) {
- DEBUGP(DRSL, "UNIT_DATA_IND without L3 INFO ?!?\n");
- return -EIO;
- }
- msg->l3h = (uint8_t *) TLVP_VAL(&tv, RSL_IE_L3_INFO);
-
- if (rllh->chan_nr == RSL_CHAN_PCH_AGCH) {
- rc = gsm48_rx_ccch(msg, ms);
- } else if (rllh->chan_nr == RSL_CHAN_BCCH) {
- rc = gsm48_rx_bcch(msg, ms);
- }
-
- return rc;
-}
-
-static int rslms_rx_rll(struct msgb *msg, struct osmocom_ms *ms)
-{
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- int rc = 0;
-
- switch (rllh->c.msg_type) {
- case RSL_MT_DATA_IND:
- DEBUGP(DRSL, "RSLms DATA IND\n");
- /* FIXME: implement this */
- break;
- case RSL_MT_UNIT_DATA_IND:
- rc = rslms_rx_udata_ind(msg, ms);
- break;
- case RSL_MT_EST_IND:
- DEBUGP(DRSL, "RSLms EST IND\n");
- /* FIXME: implement this */
- break;
- case RSL_MT_EST_CONF:
- DEBUGP(DRSL, "RSLms EST CONF\n");
- /* FIXME: implement this */
- break;
- case RSL_MT_REL_CONF:
- DEBUGP(DRSL, "RSLms REL CONF\n");
- /* FIXME: implement this */
- break;
- case RSL_MT_ERROR_IND:
- DEBUGP(DRSL, "RSLms ERR IND\n");
- /* FIXME: implement this */
- break;
- default:
- LOGP(DRSL, LOGL_NOTICE, "unknown RSLms message type "
- "0x%02x\n", rllh->c.msg_type);
- rc = -EINVAL;
- break;
- }
- msgb_free(msg);
- return rc;
-}
-
-/* input function that L2 calls when sending messages up to L3 */
-static int layer3_from_layer2(struct msgb *msg, struct lapdm_entity *le, void *ctx)
-{
- struct osmocom_ms *ms = ctx;
- struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
- int rc = 0;
-
- switch (rslh->msg_discr & 0xfe) {
- case ABIS_RSL_MDISC_RLL:
- rc = rslms_rx_rll(msg, ms);
- break;
- default:
- /* FIXME: implement this */
- LOGP(DRSL, LOGL_NOTICE, "unknown RSLms msg_discr 0x%02x\n",
- rslh->msg_discr);
- msgb_free(msg);
- rc = -EINVAL;
- break;
- }
-
- return rc;
-}
-
-int layer3_init(struct osmocom_ms *ms)
-{
- lapdm_channel_set_l3(&ms->lapdm_channel, &layer3_from_layer2, ms);
-
- return 0;
-}
diff --git a/Src/osmoconbb/src/host/layer23/src/mobile/Makefile.am b/Src/osmoconbb/src/host/layer23/src/mobile/Makefile.am
deleted file mode 100644
index e5cf76a..0000000
--- a/Src/osmoconbb/src/host/layer23/src/mobile/Makefile.am
+++ /dev/null
@@ -1,15 +0,0 @@
-INCLUDES = $(all_includes) -I$(top_srcdir)/include
-AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS)
-LDADD = ../common/liblayer23.a $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCODEC_LIBS)
-
-noinst_LIBRARIES = libmobile.a
-libmobile_a_SOURCES = gsm322.c gsm48_cc.c gsm48_mm.c gsm48_rr.c \
- mnccms.c settings.c subscriber.c support.c \
- transaction.c vty_interface.c voice.c
-
-bin_PROGRAMS = mobile
-
-mobile_SOURCES = main.c app_mobile.c
-mobile_LDADD = libmobile.a $(LDADD)
-
-
diff --git a/Src/osmoconbb/src/host/layer23/src/mobile/app_mobile.c b/Src/osmoconbb/src/host/layer23/src/mobile/app_mobile.c
deleted file mode 100644
index 8b3b552..0000000
--- a/Src/osmoconbb/src/host/layer23/src/mobile/app_mobile.c
+++ /dev/null
@@ -1,404 +0,0 @@
-/* "Application" code of the layer2/3 stack */
-
-/* (C) 2010 by Holger Hans Peter Freyther
- * (C) 2010 by Harald Welte <laforge@gnumonks.org>
- * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <errno.h>
-#include <signal.h>
-
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/l1l2_interface.h>
-#include <osmocom/bb/common/l1ctl.h>
-#include <osmocom/bb/common/lapdm.h>
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/gps.h>
-#include <osmocom/bb/mobile/gsm48_rr.h>
-#include <osmocom/bb/mobile/vty.h>
-#include <osmocom/bb/mobile/app_mobile.h>
-#include <osmocom/bb/mobile/mncc.h>
-#include <osmocom/bb/mobile/voice.h>
-#include <osmocom/vty/telnet_interface.h>
-
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/select.h>
-#include <osmocom/core/signal.h>
-
-#include <l1ctl_proto.h>
-
-extern void *l23_ctx;
-extern struct llist_head ms_list;
-extern int vty_reading;
-
-int mncc_recv_mobile(struct osmocom_ms *ms, int msg_type, void *arg);
-int mncc_recv_dummy(struct osmocom_ms *ms, int msg_type, void *arg);
-int (*mncc_recv_app)(struct osmocom_ms *ms, int, void *);
-static int quit;
-
-/* handle ms instance */
-int mobile_work(struct osmocom_ms *ms)
-{
- int work = 0, w;
-
- do {
- w = 0;
- w |= gsm48_rsl_dequeue(ms);
- w |= gsm48_rr_dequeue(ms);
- w |= gsm48_mmxx_dequeue(ms);
- w |= gsm48_mmr_dequeue(ms);
- w |= gsm48_mmevent_dequeue(ms);
- w |= gsm322_plmn_dequeue(ms);
- w |= gsm322_cs_dequeue(ms);
- w |= gsm_sim_job_dequeue(ms);
- w |= mncc_dequeue(ms);
- if (w)
- work = 1;
- } while (w);
- return work;
-}
-
-/* run ms instance, if layer1 is available */
-int mobile_signal_cb(unsigned int subsys, unsigned int signal,
- void *handler_data, void *signal_data)
-{
- struct osmocom_ms *ms;
- struct gsm_settings *set;
- struct msgb *nmsg;
-
- if (subsys != SS_L1CTL)
- return 0;
-
- switch (signal) {
- case S_L1CTL_RESET:
- ms = signal_data;
- set = &ms->settings;
-
- if (ms->started)
- break;
-
- /* insert test card, if enabled */
- switch (set->sim_type) {
- case GSM_SIM_TYPE_READER:
- /* trigger sim card reader process */
- gsm_subscr_simcard(ms);
- break;
- case GSM_SIM_TYPE_TEST:
- gsm_subscr_testcard(ms, set->test_rplmn_mcc,
- set->test_rplmn_mnc, set->test_lac,
- set->test_tmsi);
- break;
- default:
- /* no SIM, trigger PLMN selection process */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_SWITCH_ON);
- if (!nmsg)
- return -ENOMEM;
- gsm322_plmn_sendmsg(ms, nmsg);
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_SWITCH_ON);
- if (!nmsg)
- return -ENOMEM;
- gsm322_cs_sendmsg(ms, nmsg);
- }
-
- ms->started = 1;
- }
- return 0;
-}
-
-/* power-off ms instance */
-int mobile_exit(struct osmocom_ms *ms, int force)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
-
- if (!force && ms->started) {
- struct msgb *nmsg;
-
- ms->shutdown = 1; /* going down */
- nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_IMSI_DETACH);
- if (!nmsg)
- return -ENOMEM;
- gsm48_mmevent_msg(mm->ms, nmsg);
-
- return -EBUSY;
- }
-
- gsm322_exit(ms);
- gsm48_mm_exit(ms);
- gsm48_rr_exit(ms);
- gsm_subscr_exit(ms);
- gsm48_cc_exit(ms);
- gsm_sim_exit(ms);
- lapdm_channel_exit(&ms->lapdm_channel);
-
- ms->shutdown = 2; /* being down */
- vty_notify(ms, NULL);
- vty_notify(ms, "Power off!\n");
- printf("Power off! (MS %s)\n", ms->name);
-
- return 0;
-}
-
-/* power-on ms instance */
-int mobile_init(struct osmocom_ms *ms)
-{
- int rc;
-
- gsm_settings_arfcn(ms);
-
- lapdm_channel_init(&ms->lapdm_channel, LAPDM_MODE_MS);
- lapdm_channel_set_l1(&ms->lapdm_channel, l1ctl_ph_prim_cb, ms);
-
- gsm_sim_init(ms);
- gsm48_cc_init(ms);
- gsm_voice_init(ms);
- gsm_subscr_init(ms);
- gsm48_rr_init(ms);
- gsm48_mm_init(ms);
- INIT_LLIST_HEAD(&ms->trans_list);
- gsm322_init(ms);
-
- rc = layer2_open(ms, ms->settings.layer2_socket_path);
- if (rc < 0) {
- fprintf(stderr, "Failed during layer2_open()\n");
- ms->l2_wq.bfd.fd = -1;
- mobile_exit(ms, 1);
- return rc;
- }
-
-#if 0
- rc = sap_open(ms, ms->settings.sap_socket_path);
- if (rc < 0) {
- fprintf(stderr, "Failed during sap_open(), no SIM reader\n");
- ms->sap_wq.bfd.fd = -1;
- mobile_exit(ms, 1);
- return rc;
- }
-#endif
-
- gsm_random_imei(&ms->settings);
-
- ms->shutdown = 0;
- ms->started = 0;
-
- if (!strcmp(ms->settings.imei, "000000000000000")) {
- printf("***\nWarning: Mobile '%s' has default IMEI: %s\n",
- ms->name, ms->settings.imei);
- printf("This could relate your identitiy to other users with "
- "default IMEI.\n***\n");
- }
-
- l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
- printf("Mobile '%s' initialized, please start phone now!\n", ms->name);
- return 0;
-}
-
-/* create ms instance */
-struct osmocom_ms *mobile_new(char *name)
-{
- static struct osmocom_ms *ms;
-
- ms = talloc_zero(l23_ctx, struct osmocom_ms);
- if (!ms) {
- fprintf(stderr, "Failed to allocate MS\n");
- exit(1);
- }
- llist_add_tail(&ms->entity, &ms_list);
-
- strcpy(ms->name, name);
-
- ms->l2_wq.bfd.fd = -1;
- ms->sap_wq.bfd.fd = -1;
-
- gsm_support_init(ms);
- gsm_settings_init(ms);
-
- ms->shutdown = 2; /* being down */
-
- if (mncc_recv_app) {
- struct msgb *msg;
-
- msg = msgb_alloc(sizeof(struct gsm_mncc), "MNCC");
- if (msg) {
- struct gsm_mncc *mncc = (struct gsm_mncc *)msg->data;
-
- mncc->msg_type = MS_NEW;
- mncc_recv_app(ms, mncc->msg_type, mncc);
- }
- ms->mncc_entity.mncc_recv = mncc_recv_app;
- } else if (ms->settings.ch_cap == GSM_CAP_SDCCH)
- ms->mncc_entity.mncc_recv = mncc_recv_dummy;
- else
- ms->mncc_entity.mncc_recv = mncc_recv_mobile;
-
-
- return ms;
-}
-
-/* destroy ms instance */
-int mobile_delete(struct osmocom_ms *ms, int force)
-{
- int rc;
-
- ms->deleting = 1;
-
- if (ms->shutdown == 0 || (ms->shutdown == 1 && force)) {
- rc = mobile_exit(ms, force);
- if (rc < 0)
- return rc;
- }
-
- if (mncc_recv_app) {
- struct msgb *msg;
-
- msg = msgb_alloc(sizeof(struct gsm_mncc), "MNCC");
- if (msg) {
- struct gsm_mncc *mncc = (struct gsm_mncc *)msg->data;
-
- mncc->msg_type = MS_DELETE;
- mncc_recv_app(ms, mncc->msg_type, mncc);
- }
- }
-
- return 0;
-}
-
-/* handle global shutdown */
-int global_signal_cb(unsigned int subsys, unsigned int signal,
- void *handler_data, void *signal_data)
-{
- struct osmocom_ms *ms, *ms2;
-
- if (subsys != SS_GLOBAL)
- return 0;
-
- switch (signal) {
- case S_GLOBAL_SHUTDOWN:
- llist_for_each_entry_safe(ms, ms2, &ms_list, entity)
- mobile_delete(ms, quit);
-
- /* if second signal is received, force to exit */
- quit = 1;
- break;
- }
- return 0;
-}
-
-/* global work handler */
-int l23_app_work(int *_quit)
-{
- struct osmocom_ms *ms, *ms2;
- int work = 0;
-
- llist_for_each_entry_safe(ms, ms2, &ms_list, entity) {
- if (ms->shutdown != 2)
- work |= mobile_work(ms);
- if (ms->shutdown == 2) {
- if (ms->l2_wq.bfd.fd > -1) {
- layer2_close(ms);
- ms->l2_wq.bfd.fd = -1;
- }
-
- if (ms->sap_wq.bfd.fd > -1) {
- sap_close(ms);
- ms->sap_wq.bfd.fd = -1;
- }
-
- if (ms->deleting) {
- gsm_settings_exit(ms);
- llist_del(&ms->entity);
- talloc_free(ms);
- work = 1;
- }
- }
- }
-
- /* return, if a shutdown was scheduled (quit = 1) */
- *_quit = quit;
- return work;
-}
-
-/* global exit */
-int l23_app_exit(void)
-{
- osmo_signal_unregister_handler(SS_L1CTL, &gsm322_l1_signal, NULL);
- osmo_signal_unregister_handler(SS_L1CTL, &mobile_signal_cb, NULL);
- osmo_signal_unregister_handler(SS_GLOBAL, &global_signal_cb, NULL);
-
- osmo_gps_close();
-
- return 0;
-}
-
-static struct vty_app_info vty_info = {
- .name = "OsmocomBB",
- .version = PACKAGE_VERSION,
- .go_parent_cb = ms_vty_go_parent,
-};
-
-/* global init */
-int l23_app_init(int (*mncc_recv)(struct osmocom_ms *ms, int, void *),
- const char *config_file, uint16_t vty_port)
-{
- struct telnet_connection dummy_conn;
- int rc = 0;
-
- mncc_recv_app = mncc_recv;
-
- osmo_gps_init();
-
- vty_init(&vty_info);
- ms_vty_init();
- dummy_conn.priv = NULL;
- vty_reading = 1;
- if (config_file != NULL) {
- rc = vty_read_config_file(config_file, &dummy_conn);
- if (rc < 0) {
- fprintf(stderr, "Failed to parse the config file:"
- " '%s'\n", config_file);
- fprintf(stderr, "Please check or create config file"
- " using: 'touch %s'\n", config_file);
- return rc;
- }
- }
- vty_reading = 0;
- telnet_init(l23_ctx, NULL, vty_port);
- if (rc < 0)
- return rc;
- printf("VTY available on port %u.\n", vty_port);
-
- osmo_signal_register_handler(SS_GLOBAL, &global_signal_cb, NULL);
- osmo_signal_register_handler(SS_L1CTL, &mobile_signal_cb, NULL);
- osmo_signal_register_handler(SS_L1CTL, &gsm322_l1_signal, NULL);
-
- if (llist_empty(&ms_list)) {
- struct osmocom_ms *ms;
-
- printf("No Mobile Station defined, creating: MS '1'\n");
- ms = mobile_new("1");
- if (ms)
- mobile_init(ms);
- }
-
- quit = 0;
-
- return 0;
-}
-
diff --git a/Src/osmoconbb/src/host/layer23/src/mobile/gsm322.c b/Src/osmoconbb/src/host/layer23/src/mobile/gsm322.c
deleted file mode 100644
index 9384743..0000000
--- a/Src/osmoconbb/src/host/layer23/src/mobile/gsm322.c
+++ /dev/null
@@ -1,5168 +0,0 @@
-/*
- * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdint.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <time.h>
-
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/gsm/gsm48.h>
-#include <osmocom/gsm/gsm_utils.h>
-#include <osmocom/core/signal.h>
-
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/l1ctl.h>
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/networks.h>
-#include <osmocom/bb/mobile/vty.h>
-#include <osmocom/bb/mobile/app_mobile.h>
-
-#include <l1ctl_proto.h>
-
-const char *ba_version = "osmocom BA V1\n";
-
-extern void *l23_ctx;
-
-static void gsm322_cs_timeout(void *arg);
-static int gsm322_cs_select(struct osmocom_ms *ms, int index, uint16_t mcc,
- uint16_t mnc, int any);
-static int gsm322_m_switch_on(struct osmocom_ms *ms, struct msgb *msg);
-static void gsm322_any_timeout(void *arg);
-static int gsm322_nb_scan(struct osmocom_ms *ms);
-static int gsm322_nb_synced(struct gsm322_cellsel *cs, int yes);
-static int gsm322_nb_read(struct gsm322_cellsel *cs, int yes);
-static int gsm322_c_camp_any_cell(struct osmocom_ms *ms, struct msgb *msg);
-static int gsm322_nb_start(struct osmocom_ms *ms, int synced);
-static void gsm322_cs_loss(void *arg);
-static int gsm322_nb_meas_ind(struct osmocom_ms *ms, uint16_t arfcn,
- uint8_t rx_lev);
-
-#define SYNC_RETRIES 1
-#define SYNC_RETRIES_SERVING 2
-
-/* time for trying to sync and read BCCH of neighbour cell again
- * NOTE: This value is not defined by TS, i think. */
-#define GSM58_TRY_AGAIN 30
-
-/* time for reading BCCH of neighbour cell again */
-#define GSM58_READ_AGAIN 300
-
-/* number of neighbour cells to monitor */
-#define GSM58_NB_NUMBER 6
-
-/* Timeout for reading BCCH of neighbour cells */
-#define GSM322_NB_TIMEOUT 2
-
-/* number of neighbour cells to measure for average */
-#define RLA_C_NUM 4
-
-/* wait before doing neighbour cell reselecton due to a better cell again */
-#define GSM58_RESEL_THRESHOLD 15
-
-//#define TEST_INCLUDE_SERV
-
-/*
- * notes
- */
-
-/* Cell selection process
- *
- * The process depends on states and events (finites state machine).
- *
- * During states of cell selection or cell re-selection, the search for a cell
- * is performed in two steps:
- *
- * 1. Measurement of received level of all relevant frequencies (rx-lev)
- *
- * 2. Receive system information messages of all relevant frequencies
- *
- * During this process, the results are stored in a list of all frequencies.
- * This list is checked whenever a cell is selected. It depends on the results
- * if the cell is 'suitable' and 'allowable' to 'camp' on.
- *
- * This list is also used to generate a list of available networks.
- *
- * The states are:
- *
- * - cs->list[0..(1023+299)].xxx for each cell, where
- * - flags and rxlev are used to store outcome of cell scanning process
- * - sysinfo pointing to sysinfo memory, allocated temporarily
- * - cs->selected and cs->sel_* states of the current / last selected cell.
- *
- *
- * There are special states: GSM322_HPLMN_SEARCH, GSM322_PLMN_SEARCH
- * and GSM322_ANY_SEARCH:
- *
- * GSM322_HPLMN_SEARCH is used to find a HPLMN. This is triggered
- * by automatic cell selection.
- *
- * GSM322_PLMN_SEARCH is triggered when network search process is started.
- * It will do a complete search. Also it is used before selecting PLMN from list.
- *
- * GSM322_ANY_SEARCH is similar to GSM322_PLMN_SEARCH, but it is done while
- * camping on any cell. If there is a suitable and allowable cell found,
- * it is indicated to the PLMN search process.
- *
- */
-
-/* PLMN selection process
- *
- * The PLMN (Public Land Mobile Network = Operator's Network) has two different
- * search processes:
- *
- * 1. Automatic search
- *
- * 2. Manual search
- *
- * The process depends on states and events (finites state machine).
- *
- */
-
-/* File format of BA list:
- *
- * uint16_t mcc
- * uint16_t mcc
- * uint8_t freq[128+38];
- * where frequency 0 is bit 0 of first byte
- *
- * If not end-of-file, the next BA list is stored.
- */
-
-/* List of lists:
- *
- * * subscr->plmn_list
- *
- * The "PLMN Selector list" stores prefered networks to select during PLMN
- * search process. This list is also stored in the SIM.
- *
- * * subscr->plmn_na
- *
- * The "forbidden PLMNs" list stores all networks that rejected us. The stored
- * network will not be used when searching PLMN automatically. This list is
- * also stored din the SIM.
- *
- * * plmn->forbidden_la
- *
- * The "forbidden LAs for roaming" list stores all location areas where roaming
- * was not allowed.
- *
- * * cs->list[1024+299]
- *
- * This list stores measurements and cell informations during cell selection
- * process. It can be used to speed up repeated cell selection.
- *
- * * cs->ba_list
- *
- * This list stores a map of frequencies used for a PLMN. If this lists exists
- * for a PLMN, it helps to speedup cell scan process.
- *
- * * plmn->sorted_plmn
- *
- * This list is generated whenever a PLMN search is started and a list of PLMNs
- * is required. It consists of home PLMN, PLMN Selector list, and PLMNs found
- * during scan process.
- *
- *
- * Cell re-selection process
- *
- * The cell re-selection process takes place when a "serving cell" is selected.
- * The neighbour cells to be monitored for re-selection are given via SI2* of
- * the serving cell.
- *
- * Therefore a list of neighbour cells is created or updated, when the cell
- * allocation is received or changed by the network.
- *
- * All neighbour cells are monitored, but only up to 6 of the strongest cells
- * are synced to, in order to read the BCCH data. A timer is used to re-read
- * the BCCH data after 5 minutes. This timer is also used if sync or read
- * fails.
- *
- * The C1 and C2 criterion is calculated for the currently monitored neigbour
- * cells. During this process, a better neighbour cell will trigger cell
- * re-selection.
- *
- * The cell re-selection is similar to the cell selection process, except that
- * only neighbour cells are searched in order of their quality criterion C2.
- *
- * During camping, and monitoring neighbour cells, it is possible to enter
- * dedicated mode at any time.
- *
- */
-
-/*
- * event messages
- */
-
-static const struct value_string gsm322_event_names[] = {
- { GSM322_EVENT_SWITCH_ON, "EVENT_SWITCH_ON" },
- { GSM322_EVENT_SWITCH_OFF, "EVENT_SWITCH_OFF" },
- { GSM322_EVENT_SIM_INSERT, "EVENT_SIM_INSERT" },
- { GSM322_EVENT_SIM_REMOVE, "EVENT_SIM_REMOVE" },
- { GSM322_EVENT_REG_FAILED, "EVENT_REG_FAILED" },
- { GSM322_EVENT_ROAMING_NA, "EVENT_ROAMING_NA" },
- { GSM322_EVENT_INVALID_SIM, "EVENT_INVALID_SIM" },
- { GSM322_EVENT_REG_SUCCESS, "EVENT_REG_SUCCESS" },
- { GSM322_EVENT_NEW_PLMN, "EVENT_NEW_PLMN" },
- { GSM322_EVENT_ON_PLMN, "EVENT_ON_PLMN" },
- { GSM322_EVENT_PLMN_SEARCH_START,"EVENT_PLMN_SEARCH_START" },
- { GSM322_EVENT_PLMN_SEARCH_END, "EVENT_PLMN_SEARCH_END" },
- { GSM322_EVENT_USER_RESEL, "EVENT_USER_RESEL" },
- { GSM322_EVENT_PLMN_AVAIL, "EVENT_PLMN_AVAIL" },
- { GSM322_EVENT_CHOOSE_PLMN, "EVENT_CHOOSE_PLMN" },
- { GSM322_EVENT_SEL_MANUAL, "EVENT_SEL_MANUAL" },
- { GSM322_EVENT_SEL_AUTO, "EVENT_SEL_AUTO" },
- { GSM322_EVENT_CELL_FOUND, "EVENT_CELL_FOUND" },
- { GSM322_EVENT_NO_CELL_FOUND, "EVENT_NO_CELL_FOUND" },
- { GSM322_EVENT_LEAVE_IDLE, "EVENT_LEAVE_IDLE" },
- { GSM322_EVENT_RET_IDLE, "EVENT_RET_IDLE" },
- { GSM322_EVENT_CELL_RESEL, "EVENT_CELL_RESEL" },
- { GSM322_EVENT_SYSINFO, "EVENT_SYSINFO" },
- { GSM322_EVENT_HPLMN_SEARCH, "EVENT_HPLMN_SEARCH" },
- { 0, NULL }
-};
-
-const char *get_event_name(int value)
-{
- return get_value_string(gsm322_event_names, value);
-}
-
-
-/* allocate a 03.22 event message */
-struct msgb *gsm322_msgb_alloc(int msg_type)
-{
- struct msgb *msg;
- struct gsm322_msg *gm;
-
- msg = msgb_alloc_headroom(sizeof(*gm), 0, "GSM 03.22 event");
- if (!msg)
- return NULL;
-
- gm = (struct gsm322_msg *)msgb_put(msg, sizeof(*gm));
- gm->msg_type = msg_type;
-
- return msg;
-}
-
-/* queue PLMN selection message */
-int gsm322_plmn_sendmsg(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
-
- msgb_enqueue(&plmn->event_queue, msg);
-
- return 0;
-}
-
-/* queue cell selection message */
-int gsm322_cs_sendmsg(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
-
- msgb_enqueue(&cs->event_queue, msg);
-
- return 0;
-}
-
-/*
- * support
- */
-
-uint16_t index2arfcn(int index)
-{
- if (index >= 1024)
- return (index-1024+512) | ARFCN_PCS;
- return index;
-}
-
-int arfcn2index(uint16_t arfcn)
-{
- if ((arfcn & ARFCN_PCS) && arfcn >= 512 && arfcn <= 810)
- return (arfcn & 1023)-512+1024;
- return arfcn & 1023;
-}
-
-static char *bargraph(int value, int min, int max)
-{
- static char bar[128];
-
- /* shift value to the range of min..max */
- if (value < min)
- value = 0;
- else if (value > max)
- value = max - min;
- else
- value -= min;
-
- memset(bar, '=', value);
- bar[value] = '\0';
-
- return bar;
-}
-
-static int class_of_band(struct osmocom_ms *ms, int band)
-{
- struct gsm_settings *set = &ms->settings;
-
- switch (band) {
- case GSM_BAND_450:
- case GSM_BAND_480:
- return set->class_400;
- break;
- case GSM_BAND_850:
- return set->class_850;
- break;
- case GSM_BAND_1800:
- return set->class_dcs;
- break;
- case GSM_BAND_1900:
- return set->class_pcs;
- break;
- }
-
- return set->class_900;
-}
-
-char *gsm_print_rxlev(uint8_t rxlev)
-{
- static char string[5];
- if (rxlev == 0)
- return "<=-110";
- if (rxlev >= 63)
- return ">=-47";
- sprintf(string, "-%d", 110 - rxlev);
- return string;
-}
-
-/* GSM 05.08 6.4 (special class 3 DCS 1800 MS case is omitted ) */
-static int16_t calculate_c1(int log, int8_t rla_c, int8_t rxlev_acc_min,
- int8_t ms_txpwr_max_cch, int8_t p)
-{
- int16_t a, b, c1, max_b_0;
-
- a = rla_c - rxlev_acc_min;
- b = ms_txpwr_max_cch - p;
-
- max_b_0 = (b > 0) ? b : 0;
-
- c1 = a - max_b_0;
-
- LOGP(log, LOGL_INFO, "A (RLA_C (%d) - RXLEV_ACC_MIN (%d)) = %d\n",
- rla_c, rxlev_acc_min, a);
- LOGP(log, LOGL_INFO, "B (MS_TXPWR_MAX_CCH (%d) - p (%d)) = %d\n",
- ms_txpwr_max_cch, p, b);
- LOGP(log, LOGL_INFO, "C1 (A - MAX(B,0)) = %d\n", c1);
-
- return c1;
-}
-
-static int16_t calculate_c2(int16_t c1, int serving, int last_serving,
- int cell_resel_param_ind, uint8_t cell_resel_off, int t,
- uint8_t penalty_time, uint8_t temp_offset) {
- int16_t c2;
-
- c2 = c1;
-
- /* no reselect parameters. same process for serving and neighbour cells */
- if (!cell_resel_param_ind) {
- LOGP(DNB, LOGL_INFO, "C2 = C1 = %d (because no extended "
- "re-selection parameters available)\n", c2);
- return c2;
- }
-
- /* special case, if PENALTY_TIME is '11111' */
- if (penalty_time == 31) {
- c2 -= (cell_resel_off << 1);
- LOGP(DNB, LOGL_INFO, "C2 = C1 - CELL_RESELECT_OFFSET (%d) = %d "
- "(special case)\n", cell_resel_off, c2);
- return c2;
- }
-
- c2 += (cell_resel_off << 1);
-
- /* parameters for serving cell */
- if (serving) {
- LOGP(DNB, LOGL_INFO, "C2 = C1 + CELL_RESELECT_OFFSET (%d) = %d "
- "(serving cell)\n", cell_resel_off, c2);
- return c2;
- }
-
- /* the cell is the last serving cell */
- if (last_serving) {
- LOGP(DNB, LOGL_INFO, "C2 = C1 + CELL_RESELECT_OFFSET (%d) = %d "
- "(last serving cell)\n", cell_resel_off, c2);
- return c2;
- }
-
- /* penatly time reached */
- if (t >= (penalty_time + 1) * 20) {
- LOGP(DNB, LOGL_INFO, "C2 = C1 + CELL_RESELECT_OFFSET (%d) = %d "
- "(PENALTY_TIME reached)\n", cell_resel_off, c2);
- return c2;
- }
-
- /* penalty time not reached, substract temporary offset */
- if (temp_offset < 7)
- c2 -= temp_offset * 10;
- else
- c2 = -1000; /* infinite */
- LOGP(DNB, LOGL_INFO, "C2 = C1 + CELL_RESELECT_OFFSET (%d) = %d "
- "(PENALTY_TIME not reached, %d seconds left)\n", cell_resel_off,
- c2, (penalty_time + 1) * 20 - t);
- return c2;
-}
-
-static int gsm322_sync_to_cell(struct gsm322_cellsel *cs,
- struct gsm322_neighbour * neighbour, int camping)
-{
- struct osmocom_ms *ms = cs->ms;
- struct gsm48_sysinfo *s = cs->si;
- struct rx_meas_stat *meas = &ms->meas;
-
- if (cs->sync_pending) {
- LOGP(DCS, LOGL_INFO, "Sync to ARFCN=%s, but there is a sync "
- "already pending\n",gsm_print_arfcn(cs->arfcn));
- return 0;
- }
-
- cs->ccch_state = GSM322_CCCH_ST_INIT;
- if (s && s->si3) {
- if (s->ccch_conf == 1) {
- LOGP(DCS, LOGL_INFO, "Sync to ARFCN=%s rxlev=%s "
- "(Sysinfo, ccch mode COMB)\n",
- gsm_print_arfcn(cs->arfcn),
- gsm_print_rxlev(cs->list[cs->arfci].rxlev));
- cs->ccch_mode = CCCH_MODE_COMBINED;
- } else {
- LOGP(DCS, LOGL_INFO, "Sync to ARFCN=%s rxlev=%s "
- "(Sysinfo, ccch mode NON-COMB)\n",
- gsm_print_arfcn(cs->arfcn),
- gsm_print_rxlev(cs->list[cs->arfci].rxlev));
- cs->ccch_mode = CCCH_MODE_NON_COMBINED;
- }
- } else {
- LOGP(DCS, LOGL_INFO, "Sync to ARFCN=%s rxlev=%s (No sysinfo "
- "yet, ccch mode NONE)\n", gsm_print_arfcn(cs->arfcn),
- gsm_print_rxlev(cs->list[cs->arfci].rxlev));
- cs->ccch_mode = CCCH_MODE_NONE;
- }
-
- meas->frames = meas->snr = meas->berr = meas->rxlev = 0;
- cs->rxlev_dbm = cs->rxlev_count = 0;
-
- cs->neighbour = neighbour;
-
- if (camping) {
- cs->rla_c_dbm = -128;
- cs->c12_valid = 0;
- /* keep neighbour cells! if they are old, they are re-read
- * anyway, because re-read timer has expired. */
- }
-
- cs->sync_pending = 1;
- l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
- return l1ctl_tx_fbsb_req(ms, cs->arfcn,
- L1CTL_FBSB_F_FB01SB, 100, 0,
- cs->ccch_mode);
-}
-
-/* this is called whenever the serving cell is unselectied */
-static void gsm322_unselect_cell(struct gsm322_cellsel *cs)
-{
- if (!cs->selected)
- return;
-
- LOGP(DCS, LOGL_INFO, "Unselecting serving cell.\n");
-
- cs->selected = 0;
- if (cs->si)
- cs->si->si5 = 0; /* unset SI5* */
- cs->si = NULL;
- memset(&cs->sel_si, 0, sizeof(cs->sel_si));
- cs->sel_mcc = cs->sel_mnc = cs->sel_lac = cs->sel_id = 0;
-}
-
-/* print to DCS logging */
-static void print_dcs(void *priv, const char *fmt, ...)
-{
- static char buffer[256] = "";
- int in = strlen(buffer);
- va_list args;
-
- va_start(args, fmt);
- vsnprintf(buffer + in, sizeof(buffer) - in - 1, fmt, args);
- buffer[sizeof(buffer) - in - 1] = '\0';
- va_end(args);
-
- if (buffer[0] && buffer[strlen(buffer) - 1] == '\n') {
- LOGP(DCS, LOGL_INFO, "%s", buffer);
- buffer[0] = '\0';
- }
-}
-
-/* del forbidden LA */
-int gsm322_del_forbidden_la(struct osmocom_ms *ms, uint16_t mcc,
- uint16_t mnc, uint16_t lac)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct gsm322_la_list *la;
-
- llist_for_each_entry(la, &plmn->forbidden_la, entry) {
- if (la->mcc == mcc && la->mnc == mnc && la->lac == lac) {
- LOGP(DPLMN, LOGL_INFO, "Delete from list of forbidden "
- "LAs (mcc=%s, mnc=%s, lac=%04x)\n",
- gsm_print_mcc(mcc), gsm_print_mnc(mnc), lac);
- llist_del(&la->entry);
- talloc_free(la);
- return 0;
- }
- }
-
- return -EINVAL;
-}
-
-/* add forbidden LA */
-int gsm322_add_forbidden_la(struct osmocom_ms *ms, uint16_t mcc,
- uint16_t mnc, uint16_t lac, uint8_t cause)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct gsm322_la_list *la;
-
- LOGP(DPLMN, LOGL_INFO, "Add to list of forbidden LAs "
- "(mcc=%s, mnc=%s, lac=%04x)\n", gsm_print_mcc(mcc),
- gsm_print_mnc(mnc), lac);
- la = talloc_zero(l23_ctx, struct gsm322_la_list);
- if (!la)
- return -ENOMEM;
- la->mcc = mcc;
- la->mnc = mnc;
- la->lac = lac;
- la->cause = cause;
- llist_add_tail(&la->entry, &plmn->forbidden_la);
-
- return 0;
-}
-
-/* search forbidden LA */
-int gsm322_is_forbidden_la(struct osmocom_ms *ms, uint16_t mcc, uint16_t mnc,
- uint16_t lac)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct gsm322_la_list *la;
-
- llist_for_each_entry(la, &plmn->forbidden_la, entry) {
- if (la->mcc == mcc && la->mnc == mnc && la->lac == lac)
- return 1;
- }
-
- return 0;
-}
-
-/* search for PLMN in all BA lists */
-static struct gsm322_ba_list *gsm322_find_ba_list(struct gsm322_cellsel *cs,
- uint16_t mcc, uint16_t mnc)
-{
- struct gsm322_ba_list *ba, *ba_found = NULL;
-
- /* search for BA list */
- llist_for_each_entry(ba, &cs->ba_list, entry) {
- if (ba->mcc == mcc
- && ba->mnc == mnc) {
- ba_found = ba;
- break;
- }
- }
-
- return ba_found;
-}
-
-/* search available PLMN */
-int gsm322_is_plmn_avail_and_allow(struct gsm322_cellsel *cs, uint16_t mcc,
- uint16_t mnc)
-{
- int i;
-
- for (i = 0; i <= 1023+299; i++) {
- if ((cs->list[i].flags & GSM322_CS_FLAG_TEMP_AA)
- && cs->list[i].sysinfo
- && cs->list[i].sysinfo->mcc == mcc
- && cs->list[i].sysinfo->mnc == mnc)
- return 1;
- }
-
- return 0;
-}
-
-/* search available HPLMN */
-int gsm322_is_hplmn_avail(struct gsm322_cellsel *cs, char *imsi)
-{
- int i;
-
- for (i = 0; i <= 1023+299; i++) {
- if ((cs->list[i].flags & GSM322_CS_FLAG_SYSINFO)
- && cs->list[i].sysinfo
- && gsm_match_mnc(cs->list[i].sysinfo->mcc,
- cs->list[i].sysinfo->mnc, imsi))
- return 1;
- }
-
- return 0;
-}
-
-static const struct value_string gsm322_nb_state_names[] = {
- { GSM322_NB_NEW, "new" },
- { GSM322_NB_NOT_SUP, "not sup" },
- { GSM322_NB_RLA_C, "RLA_C" },
- { GSM322_NB_NO_SYNC, "no sync" },
- { GSM322_NB_NO_BCCH, "no BCCH" },
- { GSM322_NB_SYSINFO, "SYSINFO" },
- { 0, NULL }
-};
-
-const char *get_nb_state_name(int value)
-{
- return get_value_string(gsm322_nb_state_names, value);
-}
-
-
-/*
- * timer
- */
-
-/*plmn search timer event */
-static void plmn_timer_timeout(void *arg)
-{
- struct gsm322_plmn *plmn = arg;
- struct msgb *nmsg;
-
- LOGP(DPLMN, LOGL_INFO, "HPLMN search timer has fired.\n");
-
- /* indicate PLMN selection T timeout */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_HPLMN_SEARCH);
- if (!nmsg)
- return;
- gsm322_plmn_sendmsg(plmn->ms, nmsg);
-}
-
-/* start plmn search timer */
-static void start_plmn_timer(struct gsm322_plmn *plmn, int secs)
-{
- LOGP(DPLMN, LOGL_INFO, "Starting HPLMN search timer with %d minutes.\n",
- secs / 60);
- plmn->timer.cb = plmn_timer_timeout;
- plmn->timer.data = plmn;
- osmo_timer_schedule(&plmn->timer, secs, 0);
-}
-
-/* stop plmn search timer */
-static void stop_plmn_timer(struct gsm322_plmn *plmn)
-{
- if (osmo_timer_pending(&plmn->timer)) {
- LOGP(DPLMN, LOGL_INFO, "Stopping pending timer.\n");
- osmo_timer_del(&plmn->timer);
- }
-}
-
-/* start cell selection timer */
-void start_cs_timer(struct gsm322_cellsel *cs, int sec, int micro)
-{
- LOGP(DCS, LOGL_DEBUG, "Starting CS timer with %d seconds.\n", sec);
- cs->timer.cb = gsm322_cs_timeout;
- cs->timer.data = cs;
- osmo_timer_schedule(&cs->timer, sec, micro);
-}
-
-/* stop cell selection timer */
-static void stop_cs_timer(struct gsm322_cellsel *cs)
-{
- if (osmo_timer_pending(&cs->timer)) {
- LOGP(DCS, LOGL_DEBUG, "stopping pending CS timer.\n");
- osmo_timer_del(&cs->timer);
- }
-}
-
-/* the following timer is used to search again for allowable cell, after
- * loss of coverage. (loss of any allowed PLMN) */
-
-/* start any cell selection timer */
-void start_any_timer(struct gsm322_cellsel *cs, int sec, int micro)
-{
- LOGP(DCS, LOGL_DEBUG, "Starting 'any cell selection' timer with %d "
- "seconds.\n", sec);
- cs->any_timer.cb = gsm322_any_timeout;
- cs->any_timer.data = cs;
- osmo_timer_schedule(&cs->any_timer, sec, micro);
-}
-
-/* stop cell selection timer */
-static void stop_any_timer(struct gsm322_cellsel *cs)
-{
- if (osmo_timer_pending(&cs->any_timer)) {
- LOGP(DCS, LOGL_DEBUG, "stopping pending 'any cell selection' "
- "timer.\n");
- osmo_timer_del(&cs->any_timer);
- }
-}
-
-/*
- * state change
- */
-
-static const struct value_string gsm322_a_state_names[] = {
- { GSM322_A0_NULL, "A0 null"},
- { GSM322_A1_TRYING_RPLMN, "A1 trying RPLMN"},
- { GSM322_A2_ON_PLMN, "A2 on PLMN"},
- { GSM322_A3_TRYING_PLMN, "A3 trying PLMN"},
- { GSM322_A4_WAIT_FOR_PLMN, "A4 wait for PLMN to appear"},
- { GSM322_A5_HPLMN_SEARCH, "A5 HPLMN search"},
- { GSM322_A6_NO_SIM, "A6 no SIM inserted"},
- { 0, NULL }
-};
-
-const char *get_a_state_name(int value)
-{
- return get_value_string(gsm322_a_state_names, value);
-}
-
-static const struct value_string gsm322_m_state_names[] = {
- { GSM322_M0_NULL, "M0 null"},
- { GSM322_M1_TRYING_RPLMN, "M1 trying RPLMN"},
- { GSM322_M2_ON_PLMN, "M2 on PLMN"},
- { GSM322_M3_NOT_ON_PLMN, "M3 not on PLMN"},
- { GSM322_M4_TRYING_PLMN, "M4 trying PLMN"},
- { GSM322_M5_NO_SIM, "M5 no SIM inserted"},
- { 0, NULL }
-};
-
-const char *get_m_state_name(int value)
-{
- return get_value_string(gsm322_m_state_names, value);
-}
-
-static const struct value_string gsm322_cs_state_names[] = {
- { GSM322_C0_NULL, "C0 null"},
- { GSM322_C1_NORMAL_CELL_SEL, "C1 normal cell selection"},
- { GSM322_C2_STORED_CELL_SEL, "C2 stored cell selection"},
- { GSM322_C3_CAMPED_NORMALLY, "C3 camped normally"},
- { GSM322_C4_NORMAL_CELL_RESEL, "C4 normal cell re-selection"},
- { GSM322_C5_CHOOSE_CELL, "C5 choose cell"},
- { GSM322_C6_ANY_CELL_SEL, "C6 any cell selection"},
- { GSM322_C7_CAMPED_ANY_CELL, "C7 camped on any cell"},
- { GSM322_C8_ANY_CELL_RESEL, "C8 any cell re-selection"},
- { GSM322_C9_CHOOSE_ANY_CELL, "C9 choose any cell"},
- { GSM322_CONNECTED_MODE_1, "connected mode 1"},
- { GSM322_CONNECTED_MODE_2, "connected mode 2"},
- { GSM322_PLMN_SEARCH, "PLMN search"},
- { GSM322_HPLMN_SEARCH, "HPLMN search"},
- { GSM322_ANY_SEARCH, "ANY search"},
- { 0, NULL }
-};
-
-const char *get_cs_state_name(int value)
-{
- return get_value_string(gsm322_cs_state_names, value);
-}
-
-/* new automatic PLMN search state */
-static void new_a_state(struct gsm322_plmn *plmn, int state)
-{
- if (plmn->ms->settings.plmn_mode != PLMN_MODE_AUTO) {
- LOGP(DPLMN, LOGL_FATAL, "not in auto mode, please fix!\n");
- return;
- }
-
- stop_plmn_timer(plmn);
-
- LOGP(DPLMN, LOGL_INFO, "new state '%s' -> '%s'\n",
- get_a_state_name(plmn->state), get_a_state_name(state));
-
- plmn->state = state;
-}
-
-/* new manual PLMN search state */
-static void new_m_state(struct gsm322_plmn *plmn, int state)
-{
- if (plmn->ms->settings.plmn_mode != PLMN_MODE_MANUAL) {
- LOGP(DPLMN, LOGL_FATAL, "not in manual mode, please fix!\n");
- return;
- }
-
- LOGP(DPLMN, LOGL_INFO, "new state '%s' -> '%s'\n",
- get_m_state_name(plmn->state), get_m_state_name(state));
-
- plmn->state = state;
-}
-
-/* new Cell selection state */
-static void new_c_state(struct gsm322_cellsel *cs, int state)
-{
- LOGP(DCS, LOGL_INFO, "new state '%s' -> '%s'\n",
- get_cs_state_name(cs->state), get_cs_state_name(state));
-
- /* stop cell selection timer, if running */
- stop_cs_timer(cs);
-
- /* stop scanning of power measurement */
- if (cs->powerscan) {
- LOGP(DCS, LOGL_INFO, "changing state while power scanning\n");
- l1ctl_tx_reset_req(cs->ms, L1CTL_RES_T_FULL);
- cs->powerscan = 0;
- }
-
- cs->state = state;
-}
-
-/*
- * list of PLMNs
- */
-
-/* 4.4.3 create sorted list of PLMN
- *
- * the source of entries are
- *
- * - HPLMN
- * - entries found in the SIM's PLMN Selector list
- * - scanned PLMNs above -85 dB (random order)
- * - scanned PLMNs below or equal -85 (by received level)
- *
- * NOTE:
- *
- * The list only includes networks found at last scan.
- *
- * The list always contains HPLMN if available, even if not used by PLMN
- * search process at some conditions.
- *
- * The list contains all PLMNs even if not allowed, so entries have to be
- * removed when selecting from the list. (In case we use manual cell selection,
- * we need to provide non-allowed networks also.)
- */
-static int gsm322_sort_list(struct osmocom_ms *ms)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm_sub_plmn_list *sim_entry;
- struct gsm_sub_plmn_na *na_entry;
- struct llist_head temp_list;
- struct gsm322_plmn_list *temp, *found;
- struct llist_head *lh, *lh2;
- int i, entries, move;
- int8_t search = 0;
-
- /* flush list */
- llist_for_each_safe(lh, lh2, &plmn->sorted_plmn) {
- llist_del(lh);
- talloc_free(lh);
- }
-
- /* Create a temporary list of all networks */
- INIT_LLIST_HEAD(&temp_list);
- for (i = 0; i <= 1023+299; i++) {
- if (!(cs->list[i].flags & GSM322_CS_FLAG_TEMP_AA)
- || !cs->list[i].sysinfo)
- continue;
-
- /* search if network has multiple cells */
- found = NULL;
- llist_for_each_entry(temp, &temp_list, entry) {
- if (temp->mcc == cs->list[i].sysinfo->mcc
- && temp->mnc == cs->list[i].sysinfo->mnc) {
- found = temp;
- break;
- }
- }
- /* update or create */
- if (found) {
- if (cs->list[i].rxlev > found->rxlev)
- found->rxlev = cs->list[i].rxlev;
- } else {
- temp = talloc_zero(l23_ctx, struct gsm322_plmn_list);
- if (!temp)
- return -ENOMEM;
- temp->mcc = cs->list[i].sysinfo->mcc;
- temp->mnc = cs->list[i].sysinfo->mnc;
- temp->rxlev = cs->list[i].rxlev;
- llist_add_tail(&temp->entry, &temp_list);
- }
- }
-
- /* move Home PLMN, if in list, else add it */
- if (subscr->sim_valid) {
- found = NULL;
- llist_for_each_entry(temp, &temp_list, entry) {
- if (gsm_match_mnc(temp->mcc, temp->mnc, subscr->imsi)) {
- found = temp;
- break;
- }
- }
- if (found) {
- /* move */
- llist_del(&found->entry);
- llist_add_tail(&found->entry, &plmn->sorted_plmn);
- }
- }
-
- /* move entries if in SIM's PLMN Selector list */
- llist_for_each_entry(sim_entry, &subscr->plmn_list, entry) {
- found = NULL;
- llist_for_each_entry(temp, &temp_list, entry) {
- if (temp->mcc == sim_entry->mcc
- && temp->mnc == sim_entry->mnc) {
- found = temp;
- break;
- }
- }
- if (found) {
- llist_del(&found->entry);
- llist_add_tail(&found->entry, &plmn->sorted_plmn);
- }
- }
-
- /* move PLMN above -85 dBm in random order */
- entries = 0;
- llist_for_each_entry(temp, &temp_list, entry) {
- if (rxlev2dbm(temp->rxlev) > -85)
- entries++;
- }
- while(entries) {
- move = random() % entries;
- i = 0;
- llist_for_each_entry(temp, &temp_list, entry) {
- if (rxlev2dbm(temp->rxlev) > -85) {
- if (i == move) {
- llist_del(&temp->entry);
- llist_add_tail(&temp->entry,
- &plmn->sorted_plmn);
- break;
- }
- i++;
- }
- }
- entries--;
- }
-
- /* move ohter PLMN in decreasing order */
- while(1) {
- found = NULL;
- llist_for_each_entry(temp, &temp_list, entry) {
- if (!found
- || temp->rxlev > search) {
- search = temp->rxlev;
- found = temp;
- }
- }
- if (!found)
- break;
- llist_del(&found->entry);
- llist_add_tail(&found->entry, &plmn->sorted_plmn);
- }
-
- /* mark forbidden PLMNs, if in list of forbidden networks */
- i = 0;
- llist_for_each_entry(temp, &plmn->sorted_plmn, entry) {
- llist_for_each_entry(na_entry, &subscr->plmn_na, entry) {
- if (temp->mcc == na_entry->mcc
- && temp->mnc == na_entry->mnc) {
- temp->cause = na_entry->cause;
- break;
- }
- }
- LOGP(DPLMN, LOGL_INFO, "Creating Sorted PLMN list. "
- "(%02d: mcc %s mnc %s allowed %s rx-lev %s)\n",
- i, gsm_print_mcc(temp->mcc),
- gsm_print_mnc(temp->mnc), (temp->cause) ? "no ":"yes",
- gsm_print_rxlev(temp->rxlev));
- i++;
- }
-
- gsm322_dump_sorted_plmn(ms);
-
- return 0;
-}
-
-/*
- * handler for automatic search
- */
-
-/* go On PLMN state */
-static int gsm322_a_go_on_plmn(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct gsm_subscriber *subscr = &ms->subscr;
-
- new_a_state(plmn, GSM322_A2_ON_PLMN);
-
- /* start timer, if on VPLMN of home country OR special case */
- if (!gsm_match_mnc(plmn->mcc, plmn->mnc, subscr->imsi)
- && (subscr->always_search_hplmn
- || gsm_match_mcc(plmn->mcc, subscr->imsi))
- && subscr->sim_valid && subscr->t6m_hplmn)
- start_plmn_timer(plmn, subscr->t6m_hplmn * 360);
- else
- stop_plmn_timer(plmn);
-
- return 0;
-}
-
-/* go to Wait for PLMNs to appear state */
-static int gsm322_a_go_wait_for_plmns(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct msgb *nmsg;
- struct gsm322_msg *ngm;
-
- new_a_state(plmn, GSM322_A4_WAIT_FOR_PLMN);
-
- /* we must forward this, otherwhise "Any cell selection"
- * will not start automatically.
- */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_NEW_PLMN);
- if (!nmsg)
- return -ENOMEM;
- ngm = (struct gsm322_msg *) nmsg->data;
- ngm->limited = 1;
- gsm322_cs_sendmsg(ms, nmsg);
-
- return 0;
-}
-
-/* no (more) PLMN in list */
-static int gsm322_a_no_more_plmn(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct msgb *nmsg;
- int found;
-
- /* any allowable PLMN available? */
- found = gsm322_cs_select(ms, -1, 0, 0, 0);
-
- /* if no PLMN in list:
- * this means that we are at a point where we camp on any cell or
- * no cell ist available. */
- if (found < 0) {
- if (subscr->plmn_valid) {
- LOGP(DPLMN, LOGL_INFO, "Not any PLMN allowable. "
- "Do limited search with RPLMN.\n");
- plmn->mcc = subscr->plmn_mcc;
- plmn->mnc = subscr->plmn_mnc;
- } else
- if (subscr->sim_valid) {
- LOGP(DPLMN, LOGL_INFO, "Not any PLMN allowable. "
- "Do limited search with HPLMN.\n");
- plmn->mcc = subscr->mcc;
- plmn->mnc = subscr->mnc;
- } else {
- LOGP(DPLMN, LOGL_INFO, "Not any PLMN allowable. "
- "Do limited search with no PLMN.\n");
- plmn->mcc = 0;
- plmn->mnc = 0;
- }
-
- return gsm322_a_go_wait_for_plmns(ms, msg);
- }
-
- /* select first PLMN in list */
- plmn->mcc = cs->list[found].sysinfo->mcc;
- plmn->mnc = cs->list[found].sysinfo->mnc;
-
- LOGP(DPLMN, LOGL_INFO, "PLMN available after searching PLMN list "
- "(mcc=%s mnc=%s %s, %s)\n",
- gsm_print_mcc(plmn->mcc), gsm_print_mnc(plmn->mnc),
- gsm_get_mcc(plmn->mcc), gsm_get_mnc(plmn->mcc, plmn->mnc));
-
- /* indicate New PLMN */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_NEW_PLMN);
- if (!nmsg)
- return -ENOMEM;
- gsm322_cs_sendmsg(ms, nmsg);
-
- /* go On PLMN */
- return gsm322_a_go_on_plmn(ms, msg);
-}
-
-/* select first PLMN in list */
-static int gsm322_a_sel_first_plmn(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct msgb *nmsg;
- struct gsm322_plmn_list *plmn_entry;
- struct gsm322_plmn_list *plmn_first = NULL;
- int i;
-
- /* generate list */
- gsm322_sort_list(ms);
-
- /* select first entry */
- i = 0;
- llist_for_each_entry(plmn_entry, &plmn->sorted_plmn, entry) {
- /* if last selected PLMN was HPLMN, we skip that */
- if (gsm_match_mnc(plmn_entry->mcc, plmn_entry->mnc,
- subscr->imsi)
- && plmn_entry->mcc == plmn->mcc
- && plmn_entry->mnc == plmn->mnc) {
- LOGP(DPLMN, LOGL_INFO, "Skip HPLMN, because it was "
- "previously selected.\n");
- i++;
- continue;
- }
- /* select first allowed network */
- if (!plmn_entry->cause) {
- plmn_first = plmn_entry;
- break;
- }
- LOGP(DPLMN, LOGL_INFO, "Skip PLMN (%02d: mcc=%s, mnc=%s), "
- "because it is not allowed (cause %d).\n", i,
- gsm_print_mcc(plmn_entry->mcc),
- gsm_print_mnc(plmn_entry->mnc),
- plmn_entry->cause);
- i++;
- }
- plmn->plmn_curr = i;
-
- /* if no PLMN in list */
- if (!plmn_first) {
- LOGP(DPLMN, LOGL_INFO, "No PLMN in list.\n");
- gsm322_a_no_more_plmn(ms, msg);
-
- return 0;
- }
-
- LOGP(DPLMN, LOGL_INFO, "Selecting PLMN from list. (%02d: mcc=%s "
- "mnc=%s %s, %s)\n", plmn->plmn_curr,
- gsm_print_mcc(plmn_first->mcc), gsm_print_mnc(plmn_first->mnc),
- gsm_get_mcc(plmn_first->mcc),
- gsm_get_mnc(plmn_first->mcc, plmn_first->mnc));
-
- /* set current network */
- plmn->mcc = plmn_first->mcc;
- plmn->mnc = plmn_first->mnc;
-
- new_a_state(plmn, GSM322_A3_TRYING_PLMN);
-
- /* indicate New PLMN */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_NEW_PLMN);
- if (!nmsg)
- return -ENOMEM;
- gsm322_cs_sendmsg(ms, nmsg);
-
- return 0;
-}
-
-/* select next PLMN in list */
-static int gsm322_a_sel_next_plmn(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct msgb *nmsg;
- struct gsm322_plmn_list *plmn_entry;
- struct gsm322_plmn_list *plmn_next = NULL;
- int i, ii;
-
- /* select next entry from list */
- i = 0;
- ii = plmn->plmn_curr + 1;
- llist_for_each_entry(plmn_entry, &plmn->sorted_plmn, entry) {
- /* skip previously selected networks */
- if (i < ii) {
- i++;
- continue;
- }
- /* select next allowed network */
- if (!plmn_entry->cause) {
- plmn_next = plmn_entry;
- break;
- }
- LOGP(DPLMN, LOGL_INFO, "Skip PLMN (%02d: mcc=%s, mnc=%s), "
- "because it is not allowed (cause %d).\n", i,
- gsm_print_mcc(plmn_entry->mcc),
- gsm_print_mnc(plmn_entry->mnc),
- plmn_entry->cause);
- i++;
- }
- plmn->plmn_curr = i;
-
- /* if no more PLMN in list */
- if (!plmn_next) {
- LOGP(DPLMN, LOGL_INFO, "No more PLMN in list.\n");
- gsm322_a_no_more_plmn(ms, msg);
- return 0;
- }
-
- /* set next network */
- plmn->mcc = plmn_next->mcc;
- plmn->mnc = plmn_next->mnc;
-
- LOGP(DPLMN, LOGL_INFO, "Selecting PLMN from list. (%02d: mcc=%s "
- "mnc=%s %s, %s)\n", plmn->plmn_curr,
- gsm_print_mcc(plmn->mcc), gsm_print_mnc(plmn->mnc),
- gsm_get_mcc(plmn->mcc), gsm_get_mnc(plmn->mcc, plmn->mnc));
-
- new_a_state(plmn, GSM322_A3_TRYING_PLMN);
-
- /* indicate New PLMN */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_NEW_PLMN);
- if (!nmsg)
- return -ENOMEM;
- gsm322_cs_sendmsg(ms, nmsg);
-
- return 0;
-}
-
-/* User re-selection event */
-static int gsm322_a_user_resel(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm322_plmn *plmn = &ms->plmn;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm322_plmn_list *plmn_entry;
- struct gsm322_plmn_list *plmn_found = NULL;
- struct msgb *nmsg;
-
- if (!subscr->sim_valid) {
- return 0;
- }
-
- /* try again later, if not idle */
- if (cs->state == GSM322_CONNECTED_MODE_1
- || cs->state == GSM322_CONNECTED_MODE_2) {
- LOGP(DPLMN, LOGL_INFO, "Not idle, rejecting.\n");
-
- return 0;
- }
-
- /* search current PLMN in list */
- llist_for_each_entry(plmn_entry, &plmn->sorted_plmn, entry) {
- if (plmn_entry->mcc == plmn->mcc
- && plmn_entry->mnc == plmn->mnc) {
- plmn_found = plmn_entry;
- break;
- }
- }
-
- /* abort if list is empty */
- if (!plmn_found) {
- LOGP(DPLMN, LOGL_INFO, "Selected PLMN not in list, strange!\n");
- return 0;
- }
-
- LOGP(DPLMN, LOGL_INFO, "Movin selected PLMN to the bottom of the list "
- "and restarting PLMN search process.\n");
-
- /* move entry to end of list */
- llist_del(&plmn_found->entry);
- llist_add_tail(&plmn_found->entry, &plmn->sorted_plmn);
-
- /* tell MM that we selected a PLMN */
- nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_USER_PLMN_SEL);
- if (!nmsg)
- return -ENOMEM;
- gsm48_mmevent_msg(ms, nmsg);
-
- /* select first PLMN in list */
- return gsm322_a_sel_first_plmn(ms, msg);
-}
-
-/* PLMN becomes available */
-static int gsm322_a_plmn_avail(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm322_msg *gm = (struct gsm322_msg *) msg->data;
-
- if (subscr->plmn_valid && plmn->mcc == gm->mcc
- && plmn->mnc == gm->mnc) {
- struct msgb *nmsg;
-
- new_m_state(plmn, GSM322_A1_TRYING_RPLMN);
-
- LOGP(DPLMN, LOGL_INFO, "Last selected PLMN becomes available "
- "again.\n");
-
- /* indicate New PLMN */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_NEW_PLMN);
- if (!nmsg)
- return -ENOMEM;
- gsm322_cs_sendmsg(ms, nmsg);
-
- return 0;
-
- } else {
- /* select first PLMN in list */
- LOGP(DPLMN, LOGL_INFO, "Some PLMN became available, start PLMN "
- "search process.\n");
- return gsm322_a_sel_first_plmn(ms, msg);
- }
-}
-
-/* loss of radio coverage */
-static int gsm322_a_loss_of_radio(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- int found;
-
- /* any allowable PLMN available */
- found = gsm322_cs_select(ms, -1, 0, 0, 0);
-
- /* if PLMN in list */
- if (found >= 0) {
- LOGP(DPLMN, LOGL_INFO, "PLMN available (mcc=%s mnc=%s "
- "%s, %s)\n", gsm_print_mcc(
- cs->list[found].sysinfo->mcc),
- gsm_print_mnc(cs->list[found].sysinfo->mnc),
- gsm_get_mcc(cs->list[found].sysinfo->mcc),
- gsm_get_mnc(cs->list[found].sysinfo->mcc,
- cs->list[found].sysinfo->mnc));
- return gsm322_a_sel_first_plmn(ms, msg);
- }
-
- LOGP(DPLMN, LOGL_INFO, "PLMN not available after loss of coverage.\n");
-
- return gsm322_a_go_wait_for_plmns(ms, msg);
-}
-
-/* MS is switched on OR SIM is inserted OR removed */
-static int gsm322_a_switch_on(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm322_plmn *plmn = &ms->plmn;
- struct msgb *nmsg;
-
- if (!subscr->sim_valid) {
- LOGP(DSUM, LOGL_INFO, "SIM is removed\n");
- LOGP(DPLMN, LOGL_INFO, "SIM is removed\n");
- new_a_state(plmn, GSM322_A6_NO_SIM);
-
- return 0;
- }
-
- /* if there is a registered PLMN */
- if (subscr->plmn_valid) {
- /* select the registered PLMN */
- plmn->mcc = subscr->plmn_mcc;
- plmn->mnc = subscr->plmn_mnc;
-
- LOGP(DSUM, LOGL_INFO, "Start search of last registered PLMN "
- "(mcc=%s mnc=%s %s, %s)\n", gsm_print_mcc(plmn->mcc),
- gsm_print_mnc(plmn->mnc), gsm_get_mcc(plmn->mcc),
- gsm_get_mnc(plmn->mcc, plmn->mnc));
- LOGP(DPLMN, LOGL_INFO, "Use RPLMN (mcc=%s mnc=%s "
- "%s, %s)\n", gsm_print_mcc(plmn->mcc),
- gsm_print_mnc(plmn->mnc), gsm_get_mcc(plmn->mcc),
- gsm_get_mnc(plmn->mcc, plmn->mnc));
-
- new_a_state(plmn, GSM322_A1_TRYING_RPLMN);
-
- /* indicate New PLMN */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_NEW_PLMN);
- if (!nmsg)
- return -ENOMEM;
- gsm322_cs_sendmsg(ms, nmsg);
-
- return 0;
- }
-
- plmn->mcc = plmn->mnc = 0;
-
- /* initiate search at cell selection */
- LOGP(DSUM, LOGL_INFO, "Search for network\n");
- LOGP(DPLMN, LOGL_INFO, "Switch on, no RPLMN, start PLMN search "
- "first.\n");
-
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_PLMN_SEARCH_START);
- if (!nmsg)
- return -ENOMEM;
- gsm322_cs_sendmsg(ms, nmsg);
-
- return 0;
-}
-
-/* MS is switched off */
-static int gsm322_a_switch_off(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
-
- new_a_state(plmn, GSM322_A0_NULL);
-
- return 0;
-}
-
-static int gsm322_a_sim_insert(struct osmocom_ms *ms, struct msgb *msg)
-{
- LOGP(DPLMN, LOGL_INFO, "SIM already inserted when switched on.\n");
- return 0;
-}
-
-/* SIM is removed */
-static int gsm322_a_sim_removed(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct msgb *nmsg;
-
- /* indicate SIM remove to cell selection process */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_SIM_REMOVE);
- if (!nmsg)
- return -ENOMEM;
- gsm322_cs_sendmsg(ms, nmsg);
-
- /* flush list of PLMNs */
- gsm_subscr_del_forbidden_plmn(&ms->subscr, 0, 0);
-
- return gsm322_a_switch_on(ms, msg);
-}
-
-/* location update response: "Roaming not allowed" */
-static int gsm322_a_roaming_na(struct osmocom_ms *ms, struct msgb *msg)
-{
- /* store in list of forbidden LAs is done in gsm48* */
-
- return gsm322_a_sel_first_plmn(ms, msg);
-}
-
-/* On VPLMN of home country and timeout occurs */
-static int gsm322_a_hplmn_search_start(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct msgb *nmsg;
-
- /* try again later, if not idle and not camping */
- if (cs->state != GSM322_C3_CAMPED_NORMALLY) {
- LOGP(DPLMN, LOGL_INFO, "Not camping normally, wait some more."
- "\n");
- start_plmn_timer(plmn, 60);
-
- return 0;
- }
-
- new_a_state(plmn, GSM322_A5_HPLMN_SEARCH);
-
- /* initiate search at cell selection */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_HPLMN_SEARCH);
- if (!nmsg)
- return -ENOMEM;
- gsm322_cs_sendmsg(ms, nmsg);
-
- return 0;
-}
-
-/* manual mode selected */
-static int gsm322_a_sel_manual(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct msgb *nmsg;
-
- /* restart state machine */
- gsm322_a_switch_off(ms, msg);
- ms->settings.plmn_mode = PLMN_MODE_MANUAL;
- gsm322_m_switch_on(ms, msg);
-
- nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_USER_PLMN_SEL);
- if (!nmsg)
- return -ENOMEM;
- gsm48_mmevent_msg(ms, nmsg);
-
- return 0;
-}
-
-/*
- * handler for manual search
- */
-
-/* display PLMNs and to Not on PLMN */
-static int gsm322_m_display_plmns(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_msg *gm = (struct gsm322_msg *) msg->data;
- int msg_type = gm->msg_type;
- struct gsm322_plmn *plmn = &ms->plmn;
- struct gsm_sub_plmn_list *temp;
- struct msgb *nmsg;
- struct gsm322_msg *ngm;
-
- /* generate list */
- gsm322_sort_list(ms);
-
- vty_notify(ms, NULL);
- switch (msg_type) {
- case GSM322_EVENT_REG_FAILED:
- vty_notify(ms, "Failed to register to network %s, %s "
- "(%s, %s)\n",
- gsm_print_mcc(plmn->mcc), gsm_print_mnc(plmn->mnc),
- gsm_get_mcc(plmn->mcc),
- gsm_get_mnc(plmn->mcc, plmn->mnc));
- break;
- case GSM322_EVENT_NO_CELL_FOUND:
- vty_notify(ms, "No cell found for network %s, %s "
- "(%s, %s)\n",
- gsm_print_mcc(plmn->mcc), gsm_print_mnc(plmn->mnc),
- gsm_get_mcc(plmn->mcc),
- gsm_get_mnc(plmn->mcc, plmn->mnc));
- break;
- case GSM322_EVENT_ROAMING_NA:
- vty_notify(ms, "Roaming not allowed to network %s, %s "
- "(%s, %s)\n",
- gsm_print_mcc(plmn->mcc), gsm_print_mnc(plmn->mnc),
- gsm_get_mcc(plmn->mcc),
- gsm_get_mnc(plmn->mcc, plmn->mnc));
- break;
- }
-
- if (llist_empty(&plmn->sorted_plmn))
- vty_notify(ms, "Search network!\n");
- else {
- vty_notify(ms, "Search or select from network:\n");
- llist_for_each_entry(temp, &plmn->sorted_plmn, entry)
- vty_notify(ms, " Network %s, %s (%s, %s)\n",
- gsm_print_mcc(temp->mcc),
- gsm_print_mnc(temp->mnc),
- gsm_get_mcc(temp->mcc),
- gsm_get_mnc(temp->mcc, temp->mnc));
- }
-
- /* go Not on PLMN state */
- new_m_state(plmn, GSM322_M3_NOT_ON_PLMN);
-
- /* we must forward this, otherwhise "Any cell selection"
- * will not start automatically.
- * this way we get back to the last PLMN, in case we gained
- * our coverage back.
- */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_NEW_PLMN);
- if (!nmsg)
- return -ENOMEM;
- ngm = (struct gsm322_msg *) nmsg->data;
- ngm->limited = 1;
- gsm322_cs_sendmsg(ms, nmsg);
-
- return 0;
-}
-
-/* user starts reselection */
-static int gsm322_m_user_resel(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct msgb *nmsg;
-
- /* unselect PLMN. after search, the process will wait until a PLMN is
- * selected by the user. this prevents from switching back to the
- * last selected PLMN and destroying the list of scanned networks.
- */
- plmn->mcc = plmn->mnc = 0;
-
- if (!subscr->sim_valid) {
- return 0;
- }
-
- /* try again later, if not idle */
- if (cs->state == GSM322_CONNECTED_MODE_1
- || cs->state == GSM322_CONNECTED_MODE_2) {
- LOGP(DPLMN, LOGL_INFO, "Not idle, rejecting.\n");
-
- return 0;
- }
-
- /* initiate search at cell selection */
- LOGP(DPLMN, LOGL_INFO, "User re-select, start PLMN search first.\n");
-
- /* tell MM that we selected a PLMN */
- nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_USER_PLMN_SEL);
- if (!nmsg)
- return -ENOMEM;
- gsm48_mmevent_msg(ms, nmsg);
-
- /* triffer PLMN search */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_PLMN_SEARCH_START);
- if (!nmsg)
- return -ENOMEM;
- gsm322_cs_sendmsg(ms, nmsg);
-
- return 0;
-}
-
-/* MS is switched on OR SIM is inserted OR removed */
-static int gsm322_m_switch_on(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm322_plmn *plmn = &ms->plmn;
- struct msgb *nmsg;
-
- if (!subscr->sim_valid) {
- LOGP(DSUM, LOGL_INFO, "SIM is removed\n");
- LOGP(DPLMN, LOGL_INFO, "Switch on without SIM.\n");
- new_m_state(plmn, GSM322_M5_NO_SIM);
-
- return 0;
- }
-
- /* if there is a registered PLMN */
- if (subscr->plmn_valid) {
- struct msgb *nmsg;
-
- /* select the registered PLMN */
- plmn->mcc = subscr->plmn_mcc;
- plmn->mnc = subscr->plmn_mnc;
-
- LOGP(DSUM, LOGL_INFO, "Start search of last registered PLMN "
- "(mcc=%s mnc=%s %s, %s)\n", gsm_print_mcc(plmn->mcc),
- gsm_print_mnc(plmn->mnc), gsm_get_mcc(plmn->mcc),
- gsm_get_mnc(plmn->mcc, plmn->mnc));
- LOGP(DPLMN, LOGL_INFO, "Use RPLMN (mcc=%s mnc=%s "
- "%s, %s)\n", gsm_print_mcc(plmn->mcc),
- gsm_print_mnc(plmn->mnc), gsm_get_mcc(plmn->mcc),
- gsm_get_mnc(plmn->mcc, plmn->mnc));
-
- new_m_state(plmn, GSM322_M1_TRYING_RPLMN);
-
- /* indicate New PLMN */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_NEW_PLMN);
- if (!nmsg)
- return -ENOMEM;
- gsm322_cs_sendmsg(ms, nmsg);
-
- return 0;
- }
-
- plmn->mcc = plmn->mnc = 0;
-
- /* initiate search at cell selection */
- LOGP(DSUM, LOGL_INFO, "Search for network\n");
- LOGP(DPLMN, LOGL_INFO, "Switch on, start PLMN search first.\n");
-
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_PLMN_SEARCH_START);
- if (!nmsg)
- return -ENOMEM;
- gsm322_cs_sendmsg(ms, nmsg);
-
- return 0;
-}
-
-/* MS is switched off */
-static int gsm322_m_switch_off(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
-
- stop_plmn_timer(plmn);
-
- new_m_state(plmn, GSM322_M0_NULL);
-
- return 0;
-}
-
-static int gsm322_m_sim_insert(struct osmocom_ms *ms, struct msgb *msg)
-{
- LOGP(DPLMN, LOGL_INFO, "SIM already inserted when switched on.\n");
- return 0;
-}
-
-/* SIM is removed */
-static int gsm322_m_sim_removed(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct msgb *nmsg;
-
- stop_plmn_timer(plmn);
-
- /* indicate SIM remove to cell selection process */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_SIM_REMOVE);
- if (!nmsg)
- return -ENOMEM;
- gsm322_cs_sendmsg(ms, nmsg);
-
- /* flush list of PLMNs */
- gsm_subscr_del_forbidden_plmn(&ms->subscr, 0, 0);
-
- return gsm322_m_switch_on(ms, msg);
-}
-
-/* go to On PLMN state */
-static int gsm322_m_go_on_plmn(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct gsm_subscriber *subscr = &ms->subscr;
-
- /* set last registered PLMN */
- subscr->plmn_valid = 1;
- subscr->plmn_mcc = plmn->mcc;
- subscr->plmn_mnc = plmn->mnc;
-
- new_m_state(plmn, GSM322_M2_ON_PLMN);
-
- return 0;
-}
-
-/* previously selected PLMN becomes available again */
-static int gsm322_m_plmn_avail(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct msgb *nmsg;
-
- new_m_state(plmn, GSM322_M1_TRYING_RPLMN);
-
- LOGP(DPLMN, LOGL_INFO, "Last selected PLMN becomes available again.\n");
-
- /* indicate New PLMN */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_NEW_PLMN);
- if (!nmsg)
- return -ENOMEM;
- gsm322_cs_sendmsg(ms, nmsg);
-
- return 0;
-}
-
-/* the user has selected given PLMN */
-static int gsm322_m_choose_plmn(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm322_msg *gm = (struct gsm322_msg *) msg->data;
- struct msgb *nmsg;
-
- /* use user selection */
- plmn->mcc = gm->mcc;
- plmn->mnc = gm->mnc;
-
- LOGP(DPLMN, LOGL_INFO, "User selects PLMN. (mcc=%s mnc=%s "
- "%s, %s)\n", gsm_print_mcc(plmn->mcc), gsm_print_mnc(plmn->mnc),
- gsm_get_mcc(plmn->mcc), gsm_get_mnc(plmn->mcc, plmn->mnc));
-
- /* if selected PLMN is in list of forbidden PLMNs */
- gsm_subscr_del_forbidden_plmn(subscr, plmn->mcc, plmn->mnc);
-
- new_m_state(plmn, GSM322_M4_TRYING_PLMN);
-
- /* tell MM that we selected a PLMN */
- nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_USER_PLMN_SEL);
- if (!nmsg)
- return -ENOMEM;
- gsm48_mmevent_msg(ms, nmsg);
-
- /* indicate New PLMN */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_NEW_PLMN);
- if (!nmsg)
- return -ENOMEM;
- gsm322_cs_sendmsg(ms, nmsg);
-
- return 0;
-}
-
-/* auto mode selected */
-static int gsm322_m_sel_auto(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct msgb *nmsg;
-
- /* restart state machine */
- gsm322_m_switch_off(ms, msg);
- ms->settings.plmn_mode = PLMN_MODE_AUTO;
- gsm322_a_switch_on(ms, msg);
-
- nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_USER_PLMN_SEL);
- if (!nmsg)
- return -ENOMEM;
- gsm48_mmevent_msg(ms, nmsg);
-
- return 0;
-}
-
-/* if no cell is found in other states than in *_TRYING_* states */
-static int gsm322_am_no_cell_found(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct msgb *nmsg;
-
- /* Tell cell selection process to handle "no cell found". */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_NO_CELL_FOUND);
- if (!nmsg)
- return -ENOMEM;
- gsm322_cs_sendmsg(ms, nmsg);
-
- return 0;
-}
-
-/*
- * cell scanning process
- */
-
-/* select a suitable and allowable cell */
-static int gsm322_cs_select(struct osmocom_ms *ms, int index, uint16_t mcc,
- uint16_t mnc, int any)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm_settings *set = &ms->settings;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm48_sysinfo *s;
- int start, end, i, found = -1, power = 0;
- uint8_t flags, mask;
- uint16_t acc_class;
- int16_t c1;
- enum gsm_band band;
- int class;
-
- /* set our access class depending on the cell selection type */
- if (any) {
- acc_class = subscr->acc_class | 0x0400; /* add emergency */
- LOGP(DCS, LOGL_DEBUG, "Select using access class with "
- "Emergency class.\n");
- } else {
- acc_class = subscr->acc_class;
- LOGP(DCS, LOGL_DEBUG, "Select using access class \n");
- }
-
- /* flags to match */
- mask = GSM322_CS_FLAG_SUPPORT | GSM322_CS_FLAG_POWER
- | GSM322_CS_FLAG_SIGNAL | GSM322_CS_FLAG_SYSINFO;
- if (cs->state == GSM322_C2_STORED_CELL_SEL
- || cs->state == GSM322_C5_CHOOSE_CELL)
- mask |= GSM322_CS_FLAG_BA;
- flags = mask; /* all masked flags are requied */
-
- /* loop through all scanned frequencies and select cell.
- * if an index is given (arfci), we just check this cell only */
- if (index >= 0)
- start = end = index;
- else
- start = 0; end = 1023+299;
- for (i = start; i <= end; i++) {
- cs->list[i].flags &= ~GSM322_CS_FLAG_TEMP_AA;
- s = cs->list[i].sysinfo;
-
- /* channel has no informations for us */
- if (!s || (cs->list[i].flags & mask) != flags) {
- continue;
- }
-
- /* check C1 criteria not fullfilled */
- // TODO: class 3 DCS mobile
- band = gsm_arfcn2band(index2arfcn(i));
- class = class_of_band(ms, band);
- c1 = calculate_c1(DCS, rxlev2dbm(cs->list[i].rxlev),
- s->rxlev_acc_min_db,
- ms_pwr_dbm(band, s->ms_txpwr_max_cch),
- ms_class_gmsk_dbm(band, class));
- if (!set->stick && c1 < 0) {
- LOGP(DCS, LOGL_INFO, "Skip ARFCN %s: C1 criterion "
- "not met. (C1 = %d)\n",
- gsm_print_arfcn(index2arfcn(i)), c1);
- continue;
- }
-
- /* if cell is barred and we don't override */
- if (!subscr->acc_barr
- && (cs->list[i].flags & GSM322_CS_FLAG_BARRED)) {
- LOGP(DCS, LOGL_INFO, "Skip ARFCN %s: Cell is "
- "barred.\n", gsm_print_arfcn(index2arfcn(i)));
- continue;
- }
-
- /* if we have no access to the cell and we don't override */
- if (!subscr->acc_barr
- && !(acc_class & (s->class_barr ^ 0xffff))) {
- LOGP(DCS, LOGL_INFO, "Skip ARFCN %s: Class is "
- "barred for our access. (access=%04x "
- "barred=%04x)\n",
- gsm_print_arfcn(index2arfcn(i)),
- acc_class, s->class_barr);
- continue;
- }
-
- /* store temporary available and allowable flag */
- cs->list[i].flags |= GSM322_CS_FLAG_TEMP_AA;
-
- /* if cell is in list of forbidden LAs */
- if ((cs->list[i].flags & GSM322_CS_FLAG_FORBIDD)) {
- if (!any) {
- LOGP(DCS, LOGL_INFO, "Skip ARFCN %s: Cell is "
- "in list of forbidden LAs. (mcc=%s "
- "mnc=%s lai=%04x)\n",
- gsm_print_arfcn(index2arfcn(i)),
- gsm_print_mcc(s->mcc),
- gsm_print_mnc(s->mnc), s->lac);
- continue;
- }
- LOGP(DCS, LOGL_INFO, "Accept ARFCN %s: Cell is in "
- "list of forbidden LAs, but we search for any "
- "cell. (mcc=%s mnc=%s lai=%04x)\n",
- gsm_print_arfcn(index2arfcn(i)),
- gsm_print_mcc(s->mcc),
- gsm_print_mnc(s->mnc), s->lac);
- cs->list[i].flags &= ~GSM322_CS_FLAG_TEMP_AA;
- }
-
- /* if cell is in list of forbidden PLMNs */
- if (gsm_subscr_is_forbidden_plmn(subscr, s->mcc, s->mnc)) {
- if (!any) {
- LOGP(DCS, LOGL_INFO, "Skip ARFCN %s: Cell is "
- "in list of forbidden PLMNs. (mcc=%s "
- "mnc=%s)\n",
- gsm_print_arfcn(index2arfcn(i)),
- gsm_print_mcc(s->mcc),
- gsm_print_mnc(s->mnc));
- continue;
- }
- LOGP(DCS, LOGL_INFO, "Accept ARFCN %s: Cell is in list "
- "of forbidden PLMNs, but we search for any "
- "cell. (mcc=%s mnc=%s)\n",
- gsm_print_arfcn(index2arfcn(i)),
- gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc));
- cs->list[i].flags &= ~GSM322_CS_FLAG_TEMP_AA;
- }
-
- /* if we search a specific PLMN, but it does not match */
- if (!any && mcc && (mcc != s->mcc
- || mnc != s->mnc)) {
- LOGP(DCS, LOGL_INFO, "Skip ARFCN %s: PLMN of cell "
- "does not match target PLMN. (mcc=%s "
- "mnc=%s)\n", gsm_print_arfcn(index2arfcn(i)),
- gsm_print_mcc(s->mcc),
- gsm_print_mnc(s->mnc));
- continue;
- }
-
- LOGP(DCS, LOGL_INFO, "Cell ARFCN %s: Cell found, (rxlev=%s "
- "mcc=%s mnc=%s lac=%04x %s, %s)\n",
- gsm_print_arfcn(index2arfcn(i)),
- gsm_print_rxlev(cs->list[i].rxlev),
- gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc), s->lac,
- gsm_get_mcc(s->mcc), gsm_get_mnc(s->mcc, s->mnc));
-
- /* find highest power cell */
- if (found < 0 || cs->list[i].rxlev > power) {
- power = cs->list[i].rxlev;
- found = i;
- }
- }
-
- if (found >= 0)
- LOGP(DCS, LOGL_INFO, "Cell ARFCN %s selected.\n",
- gsm_print_arfcn(index2arfcn(found)));
-
- return found;
-}
-
-/* re-select a suitable and allowable cell */
-static int gsm322_cs_reselect(struct osmocom_ms *ms, uint16_t mcc,
- uint16_t mnc, int any)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm48_sysinfo *s = cs->si;
- int i = cs->arfci;
- uint16_t acc_class;
-
- /* set our access class depending on the cell selection type */
- if (any) {
- acc_class = subscr->acc_class | 0x0400; /* add emergency */
- LOGP(DCS, LOGL_DEBUG, "Select using access class with "
- "Emergency class.\n");
- } else {
- acc_class = subscr->acc_class;
- LOGP(DCS, LOGL_DEBUG, "Select using access class \n");
- }
-
- /* if cell is barred and we don't override */
- if (!subscr->acc_barr
- && (cs->list[i].flags & GSM322_CS_FLAG_BARRED)) {
- LOGP(DCS, LOGL_INFO, "Skip ARFCN %s: Cell is barred.\n",
- gsm_print_arfcn(index2arfcn(i)));
- return -1;
- }
-
- /* if cell is in list of forbidden LAs */
- if (!any && (cs->list[i].flags & GSM322_CS_FLAG_FORBIDD)) {
- LOGP(DCS, LOGL_INFO, "Skip ARFCN %s: Cell is in list of "
- "forbidden LAs. (mcc=%s mnc=%s lai=%04x)\n",
- gsm_print_arfcn(index2arfcn(i)), gsm_print_mcc(s->mcc),
- gsm_print_mnc(s->mnc), s->lac);
- return -1;
- }
-
- /* if cell is in list of forbidden PLMNs */
- if (!any && gsm_subscr_is_forbidden_plmn(subscr, s->mcc, s->mnc)) {
- LOGP(DCS, LOGL_INFO, "Skip ARFCN %s: Cell is in "
- "list of forbidden PLMNs. (mcc=%s mnc=%s)\n",
- gsm_print_arfcn(index2arfcn(i)),
- gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc));
- return -1;
- }
-
- /* if we have no access to the cell and we don't override */
- if (!subscr->acc_barr
- && !(acc_class & (s->class_barr ^ 0xffff))) {
- LOGP(DCS, LOGL_INFO, "Skip ARFCN %s: Class is barred for our "
- "access. (access=%04x barred=%04x)\n",
- gsm_print_arfcn(index2arfcn(i)), acc_class,
- s->class_barr);
- return -1;
- }
-
- /* if we search a specific PLMN, but it does not match */
- if (!any && mcc && (mcc != s->mcc
- || mnc != s->mnc)) {
- LOGP(DCS, LOGL_INFO, "Skip ARFCN %s: PLMN of cell "
- "does not match target PLMN. (mcc=%s mnc=%s)\n",
- gsm_print_arfcn(index2arfcn(i)), gsm_print_mcc(s->mcc),
- gsm_print_mnc(s->mnc));
- return -1;
- }
-
- LOGP(DCS, LOGL_INFO, "Cell ARFCN %s: Neighbour cell accepted, "
- "(rxlev=%s mcc=%s mnc=%s lac=%04x %s, %s)\n",
- gsm_print_arfcn(index2arfcn(i)),
- gsm_print_rxlev(cs->list[i].rxlev),
- gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc), s->lac,
- gsm_get_mcc(s->mcc), gsm_get_mnc(s->mcc, s->mnc));
-
- return i;
-}
-
-/* this processes the end of frequency scanning or cell searches */
-static int gsm322_search_end(struct osmocom_ms *ms)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm322_plmn *plmn = &ms->plmn;
- struct msgb *nmsg;
- struct gsm322_msg *ngm;
- int msg_type = -1; /* no message to be sent */
- int tune_back = 0, mcc = 0, mnc = 0;
- int found;
-
- switch (cs->state) {
- case GSM322_ANY_SEARCH:
- /* special case for 'any cell' search */
- LOGP(DCS, LOGL_INFO, "Any cell search finished.\n");
-
- /* create AA flag */
- found = gsm322_cs_select(ms, -1, 0, 0, 0);
-
- /* if no cell is found, or if we don't wait for any available
- * and allowable PLMN to appear, we just continue to camp */
- if (ms->settings.plmn_mode != PLMN_MODE_AUTO
- || plmn->state != GSM322_A4_WAIT_FOR_PLMN
- || found < 0) {
- tune_back = 1;
- gsm322_c_camp_any_cell(ms, NULL);
- break;
- }
-
- /* indicate available PLMN, include selected PLMN, if found */
- msg_type = GSM322_EVENT_PLMN_AVAIL;
- if (gsm322_is_plmn_avail_and_allow(cs, plmn->mcc, plmn->mnc)) {
- /* set what PLMN becomes available */
- mcc = plmn->mcc;
- mnc = plmn->mnc;
- }
-
- new_c_state(cs, GSM322_C0_NULL);
-
- break;
-
- case GSM322_PLMN_SEARCH:
- /* special case for PLMN search */
- msg_type = GSM322_EVENT_PLMN_SEARCH_END;
- LOGP(DCS, LOGL_INFO, "PLMN search finished.\n");
-
- /* create AA flag */
- gsm322_cs_select(ms, -1, 0, 0, 0);
-
- new_c_state(cs, GSM322_C0_NULL);
-
- break;
-
- case GSM322_HPLMN_SEARCH:
- /* special case for HPLMN search */
- msg_type = GSM322_EVENT_NO_CELL_FOUND;
- LOGP(DCS, LOGL_INFO, "HPLMN search finished, no cell.\n");
-
- new_c_state(cs, GSM322_C3_CAMPED_NORMALLY);
-
- tune_back = 1;
-
- break;
-
- default:
- /* we start normal cell selection if this fails */
- if (cs->state == GSM322_C2_STORED_CELL_SEL
- || cs->state == GSM322_C5_CHOOSE_CELL) {
- /* tell CS to start over */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_NO_CELL_FOUND);
- if (!nmsg)
- return -ENOMEM;
- gsm322_c_event(ms, nmsg);
- msgb_free(nmsg);
-
- break;
- }
-
- /* on other cell selection, indicate "no cell found" */
- /* NOTE: PLMN search process handles it.
- * If not handled there, CS process gets indicated.
- * If we would continue to process CS, then we might get
- * our list of scanned cells disturbed.
- */
- LOGP(DCS, LOGL_INFO, "Cell search finished without result.\n");
- msg_type = GSM322_EVENT_NO_CELL_FOUND;
-
- /* stay in null-state until any cell selectio is triggered or
- * new plmn is indicated.
- */
- new_c_state(cs, GSM322_C0_NULL);
- }
-
- if (msg_type > -1) {
- /* send result to PLMN process, to trigger next CS event */
- nmsg = gsm322_msgb_alloc(msg_type);
- if (!nmsg)
- return -ENOMEM;
- ngm = (struct gsm322_msg *) nmsg->data;
- ngm->mcc = mcc;
- ngm->mnc = mcc;
- gsm322_plmn_sendmsg(ms, nmsg);
- }
-
- if (cs->selected && tune_back) {
- /* tuning back */
- cs->arfcn = cs->sel_arfcn;
- cs->arfci = arfcn2index(cs->arfcn);
- if (!cs->list[cs->arfci].sysinfo)
- cs->list[cs->arfci].sysinfo = talloc_zero(l23_ctx,
- struct gsm48_sysinfo);
- if (!cs->list[cs->arfci].sysinfo)
- exit(-ENOMEM);
- cs->list[cs->arfci].flags |= GSM322_CS_FLAG_SYSINFO;
- memcpy(cs->list[cs->arfci].sysinfo, &cs->sel_si,
- sizeof(struct gsm48_sysinfo));
- cs->si = cs->list[cs->arfci].sysinfo;
- cs->sel_mcc = cs->si->mcc;
- cs->sel_mnc = cs->si->mnc;
- cs->sel_lac = cs->si->lac;
- cs->sel_id = cs->si->cell_id;
- LOGP(DCS, LOGL_INFO, "Tuning back to frequency %s after full "
- "search.\n", gsm_print_arfcn(cs->arfcn));
- cs->sync_retries = SYNC_RETRIES;
- gsm322_sync_to_cell(cs, NULL, 0);
- }
-
- return 0;
-}
-
-
-/* tune to first/next unscanned frequency and search for PLMN */
-static int gsm322_cs_scan(struct osmocom_ms *ms)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- int i;
- int j, band = 0;
- uint8_t mask, flags;
- uint32_t weight = 0, test = cs->scan_state;
-
- /* search for strongest unscanned cell */
- mask = GSM322_CS_FLAG_SUPPORT | GSM322_CS_FLAG_POWER
- | GSM322_CS_FLAG_SIGNAL;
- if (cs->state == GSM322_C2_STORED_CELL_SEL
- || cs->state == GSM322_C5_CHOOSE_CELL)
- mask |= GSM322_CS_FLAG_BA;
- flags = mask; /* all masked flags are requied */
- for (i = 0; i <= 1023+299; i++) {
- j = 0; /* make gcc happy */
- if (!ms->settings.skip_max_per_band) {
- /* skip if band has enough freqs. scanned (3.2.1) */
- for (j = 0; gsm_sup_smax[j].max; j++) {
- if (gsm_sup_smax[j].end >
- gsm_sup_smax[j].start) {
- if (gsm_sup_smax[j].start <= i
- && gsm_sup_smax[j].end >= i)
- break;
- } else {
- if (gsm_sup_smax[j].start <= i
- && 1023 >= i)
- break;
- if (0 <= i
- && gsm_sup_smax[j].end >= i)
- break;
- }
- }
- if (gsm_sup_smax[j].max) {
- if (gsm_sup_smax[j].temp == gsm_sup_smax[j].max)
- continue;
- }
- }
-
- /* search for unscanned frequency */
- if ((cs->list[i].flags & mask) == flags) {
- /* weight depends on the power level
- * if it is the same, it depends on arfcn
- */
- test = cs->list[i].rxlev + 1;
- test = (test << 16) | i;
- if (test >= cs->scan_state)
- continue;
- if (test > weight) {
- weight = test;
- band = j;
- }
-
- }
- }
- cs->scan_state = weight;
-
- /* if all frequencies have been searched */
- if (!weight) {
- gsm322_dump_cs_list(cs, GSM322_CS_FLAG_SYSINFO, print_dcs,
- NULL);
-
- /* selection process done, process (negative) result */
- return gsm322_search_end(ms);
- }
-
- /* NOTE: We might already have system information from previous
- * scan. But we need recent informations, so we scan again!
- */
-
- /* Tune to frequency for a while, to receive broadcasts. */
- cs->arfci = weight & 0xffff;
- cs->arfcn = index2arfcn(cs->arfci);
- LOGP(DCS, LOGL_DEBUG, "Scanning frequency %s (rxlev %s).\n",
- gsm_print_arfcn(cs->arfcn),
- gsm_print_rxlev(cs->list[cs->arfci].rxlev));
-
- /* Allocate/clean system information. */
- cs->list[cs->arfci].flags &= ~GSM322_CS_FLAG_SYSINFO;
- if (cs->list[cs->arfci].sysinfo)
- memset(cs->list[cs->arfci].sysinfo, 0,
- sizeof(struct gsm48_sysinfo));
- else
- cs->list[cs->arfci].sysinfo = talloc_zero(l23_ctx,
- struct gsm48_sysinfo);
- if (!cs->list[cs->arfci].sysinfo)
- exit(-ENOMEM);
- cs->si = cs->list[cs->arfci].sysinfo;
- cs->sync_retries = 0;
- gsm322_sync_to_cell(cs, NULL, 0);
-
- /* increase scan counter for each maximum scan range */
- if (!ms->settings.skip_max_per_band && gsm_sup_smax[band].max) {
- LOGP(DCS, LOGL_DEBUG, "%d frequencies left in band %d..%d\n",
- gsm_sup_smax[band].max - gsm_sup_smax[band].temp,
- gsm_sup_smax[band].start, gsm_sup_smax[band].end);
- gsm_sup_smax[band].temp++;
- }
-
- return 0;
-}
-
-/* check if cell is now suitable and allowable */
-static int gsm322_cs_store(struct osmocom_ms *ms)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = cs->si;
- struct gsm322_plmn *plmn = &ms->plmn;
- struct msgb *nmsg;
- struct gsm322_msg *ngm;
- int found, any = 0;
-
- if (cs->state != GSM322_C2_STORED_CELL_SEL
- && cs->state != GSM322_C1_NORMAL_CELL_SEL
- && cs->state != GSM322_C6_ANY_CELL_SEL
- && cs->state != GSM322_C4_NORMAL_CELL_RESEL
- && cs->state != GSM322_C8_ANY_CELL_RESEL
- && cs->state != GSM322_C5_CHOOSE_CELL
- && cs->state != GSM322_C9_CHOOSE_ANY_CELL
- && cs->state != GSM322_ANY_SEARCH
- && cs->state != GSM322_PLMN_SEARCH
- && cs->state != GSM322_HPLMN_SEARCH) {
- LOGP(DCS, LOGL_FATAL, "This must only happen during cell "
- "(re-)selection, please fix!\n");
- return -EINVAL;
- }
-
- /* store sysinfo */
- cs->list[cs->arfci].flags |= GSM322_CS_FLAG_SYSINFO;
- if (s->cell_barr && !(s->sp && s->sp_cbq))
- cs->list[cs->arfci].flags |= GSM322_CS_FLAG_BARRED;
- else
- cs->list[cs->arfci].flags &= ~GSM322_CS_FLAG_BARRED;
-
- /* store selected network */
- if (s->mcc) {
- if (gsm322_is_forbidden_la(ms, s->mcc, s->mnc, s->lac))
- cs->list[cs->arfci].flags |= GSM322_CS_FLAG_FORBIDD;
- else
- cs->list[cs->arfci].flags &= ~GSM322_CS_FLAG_FORBIDD;
- }
-
- LOGP(DCS, LOGL_DEBUG, "Scan frequency %s: Cell found. (rxlev %s "
- "mcc %s mnc %s lac %04x)\n", gsm_print_arfcn(cs->arfcn),
- gsm_print_rxlev(cs->list[cs->arfci].rxlev),
- gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc), s->lac);
-
- /* selected PLMN (auto) becomes available during "any search" */
- if (ms->settings.plmn_mode == PLMN_MODE_AUTO
- && (cs->state == GSM322_ANY_SEARCH
- || cs->state == GSM322_C6_ANY_CELL_SEL
- || cs->state == GSM322_C8_ANY_CELL_RESEL
- || cs->state == GSM322_C9_CHOOSE_ANY_CELL)
- && plmn->state == GSM322_A4_WAIT_FOR_PLMN
- && s->mcc == plmn->mcc && s->mnc == plmn->mnc) {
- LOGP(DCS, LOGL_INFO, "Candidate network to become available "
- "again\n");
- found = gsm322_cs_select(ms, cs->arfci, s->mcc, s->mnc, 0);
- if (found >= 0) {
- LOGP(DCS, LOGL_INFO, "Selected PLMN in \"A4_WAIT_F"
- "OR_PLMN\" state becomes available.\n");
-indicate_plmn_avail:
- /* PLMN becomes available */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_PLMN_AVAIL);
- if (!nmsg)
- return -ENOMEM;
- /* set what PLMN becomes available */
- ngm = (struct gsm322_msg *) nmsg->data;
- ngm->mcc = plmn->mcc;
- ngm->mnc = plmn->mcc;
- gsm322_plmn_sendmsg(ms, nmsg);
-
- new_c_state(cs, GSM322_C0_NULL);
-
- return 0;
- }
- }
-
- /* selected PLMN (manual) becomes available during "any search" */
- if (ms->settings.plmn_mode == PLMN_MODE_MANUAL
- && (cs->state == GSM322_ANY_SEARCH
- || cs->state == GSM322_C6_ANY_CELL_SEL
- || cs->state == GSM322_C8_ANY_CELL_RESEL
- || cs->state == GSM322_C9_CHOOSE_ANY_CELL)
- && plmn->state == GSM322_M3_NOT_ON_PLMN
- && s->mcc == plmn->mcc && s->mnc == plmn->mnc) {
- LOGP(DCS, LOGL_INFO, "Candidate network to become available "
- "again\n");
- found = gsm322_cs_select(ms, cs->arfci, s->mcc, s->mnc, 0);
- if (found >= 0) {
- LOGP(DCS, LOGL_INFO, "Current selected PLMN in \"M3_N"
- "OT_ON_PLMN\" state becomes available.\n");
- goto indicate_plmn_avail;
- }
- }
-
- /* special case for PLMN search */
- if (cs->state == GSM322_PLMN_SEARCH
- || cs->state == GSM322_ANY_SEARCH)
- /* tune to next cell */
- return gsm322_cs_scan(ms);
-
- /* special case for HPLMN search */
- if (cs->state == GSM322_HPLMN_SEARCH) {
- struct gsm_subscriber *subscr = &ms->subscr;
- struct msgb *nmsg;
-
- if (!gsm322_is_hplmn_avail(cs, subscr->imsi))
- /* tune to next cell */
- return gsm322_cs_scan(ms);
-
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_CELL_FOUND);
- LOGP(DCS, LOGL_INFO, "HPLMN search finished, cell found.\n");
- if (!nmsg)
- return -ENOMEM;
- gsm322_plmn_sendmsg(ms, nmsg);
-
- return 0;
- }
-
- /* just see, if we search for any cell */
- if (cs->state == GSM322_C6_ANY_CELL_SEL
- || cs->state == GSM322_C8_ANY_CELL_RESEL
- || cs->state == GSM322_C9_CHOOSE_ANY_CELL)
- any = 1;
-
- if (cs->state == GSM322_C4_NORMAL_CELL_RESEL
- || cs->state == GSM322_C8_ANY_CELL_RESEL)
- found = gsm322_cs_reselect(ms, cs->mcc, cs->mnc, any);
- else
- found = gsm322_cs_select(ms, -1, cs->mcc, cs->mnc, any);
-
- /* if not found */
- if (found < 0) {
- LOGP(DCS, LOGL_INFO, "Cell not suitable and allowable.\n");
- /* tune to next cell */
- if (cs->state == GSM322_C4_NORMAL_CELL_RESEL
- || cs->state == GSM322_C8_ANY_CELL_RESEL)
- return gsm322_nb_scan(ms);
- else
- return gsm322_cs_scan(ms);
- }
-
- LOGP(DCS, LOGL_INFO, "Tune to frequency %d.\n", found);
- /* tune */
- cs->arfci = found;
- cs->arfcn = index2arfcn(cs->arfci);
- cs->si = cs->list[cs->arfci].sysinfo;
- cs->sync_retries = SYNC_RETRIES;
- gsm322_sync_to_cell(cs, NULL, 0);
-
- /* set selected cell */
- cs->selected = 1;
- cs->sel_arfcn = cs->arfcn;
- memcpy(&cs->sel_si, cs->si, sizeof(cs->sel_si));
- cs->sel_mcc = cs->si->mcc;
- cs->sel_mnc = cs->si->mnc;
- cs->sel_lac = cs->si->lac;
- cs->sel_id = cs->si->cell_id;
- if (ms->rrlayer.monitor) {
- vty_notify(ms, "MON: %scell selected ARFCN=%s MCC=%s MNC=%s "
- "LAC=0x%04x cellid=0x%04x (%s %s)\n",
- (any) ? "any " : "", gsm_print_arfcn(cs->sel_arfcn),
- gsm_print_mcc(cs->sel_mcc), gsm_print_mnc(cs->sel_mnc),
- cs->sel_lac, cs->sel_id,
- gsm_get_mcc(cs->sel_mcc),
- gsm_get_mnc(cs->sel_mcc, cs->sel_mnc));
- }
-
- /* tell CS process about available cell */
- LOGP(DCS, LOGL_INFO, "Cell available.\n");
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_CELL_FOUND);
- if (!nmsg)
- return -ENOMEM;
- gsm322_c_event(ms, nmsg);
- msgb_free(nmsg);
-
- return 0;
-}
-
-/* process system information when returing to idle mode */
-struct gsm322_ba_list *gsm322_cs_sysinfo_sacch(struct osmocom_ms *ms)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s;
- struct gsm322_ba_list *ba = NULL;
- int i, refer_pcs;
- uint8_t freq[128+38];
-
- if (!cs) {
- LOGP(DCS, LOGL_INFO, "No BA, because no cell selected\n");
- return ba;
- }
- s = cs->si;
- if (!s) {
- LOGP(DCS, LOGL_INFO, "No BA, because no sysinfo\n");
- return ba;
- }
-
- /* collect system information received during dedicated mode */
- if (s->si5 && (!s->nb_ext_ind_si5 || s->si5bis)) {
- /* find or create ba list */
- ba = gsm322_find_ba_list(cs, s->mcc, s->mnc);
- if (!ba) {
- ba = talloc_zero(l23_ctx, struct gsm322_ba_list);
- if (!ba)
- return NULL;
- ba->mcc = s->mcc;
- ba->mnc = s->mnc;
- llist_add_tail(&ba->entry, &cs->ba_list);
- }
- /* update (add) ba list */
- refer_pcs = gsm_refer_pcs(cs->arfcn, s);
- memset(freq, 0, sizeof(freq));
- for (i = 0; i <= 1023; i++) {
- if ((s->freq[i].mask & (FREQ_TYPE_SERV
- | FREQ_TYPE_NCELL | FREQ_TYPE_REP))) {
- if (refer_pcs && i >= 512 && i <= 810)
- freq[(i-512+1024) >> 3] |= (1 << (i&7));
- else
- freq[i >> 3] |= (1 << (i & 7));
- }
- }
- if (!!memcmp(freq, ba->freq, sizeof(freq))) {
- LOGP(DCS, LOGL_INFO, "New BA list (mcc=%s mnc=%s "
- "%s, %s).\n", gsm_print_mcc(ba->mcc),
- gsm_print_mnc(ba->mnc), gsm_get_mcc(ba->mcc),
- gsm_get_mnc(ba->mcc, ba->mnc));
- memcpy(ba->freq, freq, sizeof(freq));
- }
- }
-
- return ba;
-}
-
-/* store BA whenever a system informations changes */
-static int gsm322_store_ba_list(struct gsm322_cellsel *cs,
- struct gsm48_sysinfo *s)
-{
- struct gsm322_ba_list *ba;
- int i, refer_pcs;
- uint8_t freq[128+38];
-
- /* find or create ba list */
- ba = gsm322_find_ba_list(cs, s->mcc, s->mnc);
- if (!ba) {
- ba = talloc_zero(l23_ctx, struct gsm322_ba_list);
- if (!ba)
- return -ENOMEM;
- ba->mcc = s->mcc;
- ba->mnc = s->mnc;
- llist_add_tail(&ba->entry, &cs->ba_list);
- }
- /* update ba list */
- refer_pcs = gsm_refer_pcs(cs->arfcn, s);
- memset(freq, 0, sizeof(freq));
- freq[(cs->arfci) >> 3] |= (1 << (cs->arfci & 7));
- for (i = 0; i <= 1023; i++) {
- if ((s->freq[i].mask &
- (FREQ_TYPE_SERV | FREQ_TYPE_NCELL | FREQ_TYPE_REP))) {
- if (refer_pcs && i >= 512 && i <= 810)
- freq[(i-512+1024) >> 3] |= (1 << (i & 7));
- else
- freq[i >> 3] |= (1 << (i & 7));
- }
- }
- if (!!memcmp(freq, ba->freq, sizeof(freq))) {
- LOGP(DCS, LOGL_INFO, "New BA list (mcc=%s mnc=%s "
- "%s, %s).\n", gsm_print_mcc(ba->mcc),
- gsm_print_mnc(ba->mnc), gsm_get_mcc(ba->mcc),
- gsm_get_mnc(ba->mcc, ba->mnc));
- memcpy(ba->freq, freq, sizeof(freq));
- }
-
- return 0;
-}
-
-/* process system information during camping on a cell */
-static int gsm322_c_camp_sysinfo_bcch(struct osmocom_ms *ms, struct msgb *msg)
-{
-// struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = cs->si;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm322_msg *gm = (struct gsm322_msg *) msg->data;
- struct msgb *nmsg;
-
- /* start in case we are camping on neighbour cell */
- if ((cs->state == GSM322_C3_CAMPED_NORMALLY
- || cs->state == GSM322_C7_CAMPED_ANY_CELL)
- && (cs->neighbour)) {
- if (s->si3 || s->si4) {
- stop_cs_timer(cs);
- LOGP(DCS, LOGL_INFO, "Relevant sysinfo of neighbour "
- "cell is now received or updated.\n");
- return gsm322_nb_read(cs, 1);
- }
- return 0;
- }
-
- /* Store BA if we have full system info about cells and neigbor cells.
- * Depending on the extended bit in the channel description,
- * we require more or less system informations about neighbor cells
- */
- if (s->mcc
- && s->mnc
- && (gm->sysinfo == GSM48_MT_RR_SYSINFO_1
- || gm->sysinfo == GSM48_MT_RR_SYSINFO_2
- || gm->sysinfo == GSM48_MT_RR_SYSINFO_2bis
- || gm->sysinfo == GSM48_MT_RR_SYSINFO_2ter)
- && s->si1
- && s->si2
- && (!s->nb_ext_ind_si2
- || (s->si2bis && s->nb_ext_ind_si2 && !s->nb_ext_ind_si2bis)
- || (s->si2bis && s->si2ter && s->nb_ext_ind_si2
- && s->nb_ext_ind_si2bis)))
- gsm322_store_ba_list(cs, s);
-
- /* update sel_si, if all relevant system informations received */
- if (s->si1 && s->si2 && s->si3
- && (!s->nb_ext_ind_si2
- || (s->si2bis && s->nb_ext_ind_si2 && !s->nb_ext_ind_si2bis)
- || (s->si2bis && s->si2ter && s->nb_ext_ind_si2
- && s->nb_ext_ind_si2bis))) {
- if (cs->selected) {
- LOGP(DCS, LOGL_INFO, "Sysinfo of selected cell is "
- "now received or updated.\n");
- memcpy(&cs->sel_si, s, sizeof(cs->sel_si));
-
- /* start in case we are camping on serving cell */
- if (cs->state == GSM322_C3_CAMPED_NORMALLY
- || cs->state == GSM322_C7_CAMPED_ANY_CELL)
- gsm322_nb_start(ms, 0);
- }
- }
-
- /* check for barred cell */
- if (gm->sysinfo == GSM48_MT_RR_SYSINFO_1) {
- /* check if cell becomes barred */
- if (!subscr->acc_barr && s->cell_barr
- && !(cs->list[cs->arfci].sysinfo
- && cs->list[cs->arfci].sysinfo->sp
- && cs->list[cs->arfci].sysinfo->sp_cbq)) {
- LOGP(DCS, LOGL_INFO, "Cell becomes barred.\n");
- if (ms->rrlayer.monitor)
- vty_notify(ms, "MON: trigger cell re-selection"
- ": cell becomes barred\n");
- trigger_resel:
- /* mark cell as unscanned */
- cs->list[cs->arfci].flags &= ~GSM322_CS_FLAG_SYSINFO;
- if (cs->list[cs->arfci].sysinfo) {
- LOGP(DCS, LOGL_DEBUG, "free sysinfo arfcn=%s\n",
- gsm_print_arfcn(cs->arfcn));
- talloc_free(cs->list[cs->arfci].sysinfo);
- cs->list[cs->arfci].sysinfo = NULL;
- }
- /* trigger reselection without queueing,
- * because other sysinfo message may be queued
- * before
- */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_CELL_RESEL);
- if (!nmsg)
- return -ENOMEM;
- gsm322_c_event(ms, nmsg);
- msgb_free(nmsg);
-
- return 0;
- }
- /* check if cell access becomes barred */
- if (!((subscr->acc_class & 0xfbff)
- & (s->class_barr ^ 0xffff))) {
- LOGP(DCS, LOGL_INFO, "Cell access becomes barred.\n");
- if (ms->rrlayer.monitor)
- vty_notify(ms, "MON: trigger cell re-selection"
- ": access to cell becomes barred\n");
- goto trigger_resel;
- }
- }
-
- /* check if MCC, MNC, LAC, cell ID changes */
- if (cs->sel_mcc != s->mcc || cs->sel_mnc != s->mnc
- || cs->sel_lac != s->lac) {
- LOGP(DCS, LOGL_NOTICE, "Cell changes location area. "
- "This is not good!\n");
- if (ms->rrlayer.monitor)
- vty_notify(ms, "MON: trigger cell re-selection: "
- "cell changes LAI\n");
- goto trigger_resel;
- }
- if (cs->sel_id != s->cell_id) {
- LOGP(DCS, LOGL_NOTICE, "Cell changes cell ID. "
- "This is not good!\n");
- if (ms->rrlayer.monitor)
- vty_notify(ms, "MON: trigger cell re-selection: "
- "cell changes cell ID\n");
- goto trigger_resel;
- }
-
- return 0;
-}
-
-/* process system information during channel scanning */
-static int gsm322_c_scan_sysinfo_bcch(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = cs->si;
- struct gsm322_msg *gm = (struct gsm322_msg *) msg->data;
-
- /* no sysinfo if we are not done with power scan */
- if (cs->powerscan) {
- LOGP(DCS, LOGL_INFO, "Ignoring sysinfo during power scan.\n");
- return -EINVAL;
- }
-
- /* Store BA if we have full system info about cells and neigbor cells.
- * Depending on the extended bit in the channel description,
- * we require more or less system informations about neighbor cells
- */
- if (s->mcc
- && s->mnc
- && (gm->sysinfo == GSM48_MT_RR_SYSINFO_1
- || gm->sysinfo == GSM48_MT_RR_SYSINFO_2
- || gm->sysinfo == GSM48_MT_RR_SYSINFO_2bis
- || gm->sysinfo == GSM48_MT_RR_SYSINFO_2ter)
- && s->si1
- && s->si2
- && (!s->nb_ext_ind_si2 || s->si2bis)
- && (!s->si2ter_ind || s->si2ter))
- gsm322_store_ba_list(cs, s);
-
- /* all relevant system informations received */
- if (s->si1 && s->si2 && s->si3
- && (!s->nb_ext_ind_si2 || s->si2bis)
- && (!s->si2ter_ind || s->si2ter)) {
- LOGP(DCS, LOGL_DEBUG, "Received relevant sysinfo.\n");
- /* stop timer */
- stop_cs_timer(cs);
-
- //gsm48_sysinfo_dump(s, print_dcs, NULL);
-
- /* store sysinfo and continue scan */
- return gsm322_cs_store(ms);
- }
-
- /* wait for more sysinfo or timeout */
- return 0;
-}
-
-static void gsm322_cs_timeout(void *arg)
-{
- struct gsm322_cellsel *cs = arg;
- struct osmocom_ms *ms = cs->ms;
-
- if (cs->neighbour) {
- LOGP(DCS, LOGL_INFO, "Neighbour cell read failed.\n");
- gsm322_nb_read(cs, 0);
- return;
- }
-
- /* if we have no lock, we retry */
- if (cs->ccch_state != GSM322_CCCH_ST_SYNC)
- LOGP(DCS, LOGL_INFO, "Cell selection failed, sync timeout.\n");
- else
- LOGP(DCS, LOGL_INFO, "Cell selection failed, read timeout.\n");
-
- /* remove system information */
- cs->list[cs->arfci].flags &= ~GSM322_CS_FLAG_SYSINFO;
- if (cs->list[cs->arfci].sysinfo) {
- LOGP(DCS, LOGL_DEBUG, "free sysinfo arfcn=%s\n",
- gsm_print_arfcn(cs->arfcn));
- talloc_free(cs->list[cs->arfci].sysinfo);
- cs->list[cs->arfci].sysinfo = NULL;
- }
-
- /* tune to next cell */
- if (cs->state == GSM322_C4_NORMAL_CELL_RESEL
- || cs->state == GSM322_C8_ANY_CELL_RESEL)
- gsm322_nb_scan(ms);
- else
- gsm322_cs_scan(ms);
-
- return;
-}
-
-/*
- * power scan process
- */
-
-/* search for block of unscanned frequencies and start scanning */
-static int gsm322_cs_powerscan(struct osmocom_ms *ms)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm_settings *set = &ms->settings;
- int i, s = -1, e;
- uint8_t mask, flags;
-
- again:
-
- mask = GSM322_CS_FLAG_SUPPORT | GSM322_CS_FLAG_POWER;
- flags = GSM322_CS_FLAG_SUPPORT;
-
- /* in case of sticking to a cell, we only select it */
- if (set->stick) {
- LOGP(DCS, LOGL_DEBUG, "Scanning power for sticked cell.\n");
- i = arfcn2index(set->stick_arfcn);
- if ((cs->list[i].flags & mask) == flags)
- s = e = i;
- } else {
- /* search for first frequency to scan */
- if (cs->state == GSM322_C2_STORED_CELL_SEL
- || cs->state == GSM322_C5_CHOOSE_CELL) {
- LOGP(DCS, LOGL_DEBUG, "Scanning power for stored BA "
- "list.\n");
- mask |= GSM322_CS_FLAG_BA;
- flags |= GSM322_CS_FLAG_BA;
- } else
- LOGP(DCS, LOGL_DEBUG, "Scanning power for all "
- "frequencies.\n");
- for (i = 0; i <= 1023+299; i++) {
- if ((cs->list[i].flags & mask) == flags) {
- s = e = i;
- break;
- }
- }
- }
-
- /* if there is no more frequency, we can tune to that cell */
- if (s < 0) {
- int found = 0;
-
- /* stop power level scanning */
- cs->powerscan = 0;
-
- /* check if no signal is found */
- for (i = 0; i <= 1023+299; i++) {
- if ((cs->list[i].flags & GSM322_CS_FLAG_SIGNAL))
- found++;
- }
- if (!found) {
- LOGP(DCS, LOGL_INFO, "Found no frequency.\n");
- /* on normal cell selection, start over */
- if (cs->state == GSM322_C1_NORMAL_CELL_SEL) {
- for (i = 0; i <= 1023+299; i++) {
- /* clear flag that this was scanned */
- cs->list[i].flags &=
- ~(GSM322_CS_FLAG_POWER
- | GSM322_CS_FLAG_SIGNAL
- | GSM322_CS_FLAG_SYSINFO);
- }
- goto again;
- }
-
- /* freq. scan process done, process (negative) result */
- return gsm322_search_end(ms);
- }
- LOGP(DCS, LOGL_INFO, "Found %d frequencies.\n", found);
- cs->scan_state = 0xffffffff; /* higher than high */
- /* clear counter of scanned frequencies of each range */
- for (i = 0; gsm_sup_smax[i].max; i++)
- gsm_sup_smax[i].temp = 0;
- return gsm322_cs_scan(ms);
- }
-
- /* search last frequency to scan (en block) */
- e = i;
- if (!set->stick) {
- for (i = s + 1; i <= 1023+299; i++) {
- if (i == 1024)
- break;
- if ((cs->list[i].flags & mask) == flags)
- e = i;
- else
- break;
- }
- }
-
- LOGP(DCS, LOGL_DEBUG, "Scanning frequencies. (%s..%s)\n",
- gsm_print_arfcn(index2arfcn(s)),
- gsm_print_arfcn(index2arfcn(e)));
-
- /* start scan on radio interface */
- if (!cs->powerscan) {
- l1ctl_tx_reset_req(ms, L1CTL_RES_T_FULL);
- cs->powerscan = 1;
- }
- cs->sync_pending = 0;
- return l1ctl_tx_pm_req_range(ms, index2arfcn(s), index2arfcn(e));
-}
-
-int gsm322_l1_signal(unsigned int subsys, unsigned int signal,
- void *handler_data, void *signal_data)
-{
- struct osmocom_ms *ms;
- struct gsm322_cellsel *cs;
- struct osmobb_meas_res *mr;
- struct osmobb_fbsb_res *fr;
- struct osmobb_neigh_pm_ind *ni;
- int i;
- int8_t rxlev;
-
- if (subsys != SS_L1CTL)
- return 0;
-
- switch (signal) {
- case S_L1CTL_PM_RES:
- mr = signal_data;
- ms = mr->ms;
- cs = &ms->cellsel;
- if (!cs->powerscan)
- return -EINVAL;
- i = arfcn2index(mr->band_arfcn);
- rxlev = mr->rx_lev;
- if ((cs->list[i].flags & GSM322_CS_FLAG_POWER)) {
- LOGP(DCS, LOGL_ERROR, "Getting PM for ARFCN %s "
- "twice. Overwriting the first! Please fix "
- "prim_pm.c\n", gsm_print_arfcn(index2arfcn(i)));
- }
- cs->list[i].rxlev = rxlev;
- cs->list[i].flags |= GSM322_CS_FLAG_POWER;
- cs->list[i].flags &= ~GSM322_CS_FLAG_SIGNAL;
- /* if minimum level is reached or if we stick to a cell */
- if (rxlev2dbm(rxlev) >= ms->settings.min_rxlev_db
- || ms->settings.stick) {
- cs->list[i].flags |= GSM322_CS_FLAG_SIGNAL;
- LOGP(DCS, LOGL_INFO, "Found signal (ARFCN %s "
- "rxlev %s (%d))\n",
- gsm_print_arfcn(index2arfcn(i)),
- gsm_print_rxlev(rxlev), rxlev);
- } else
- /* no signal found, free sysinfo, if allocated */
- if (cs->list[i].sysinfo) {
- cs->list[i].flags &= ~GSM322_CS_FLAG_SYSINFO;
- LOGP(DCS, LOGL_DEBUG, "free sysinfo ARFCN=%s\n",
- gsm_print_arfcn(index2arfcn(i)));
- talloc_free(cs->list[i].sysinfo);
- cs->list[i].sysinfo = NULL;
- }
- break;
- case S_L1CTL_PM_DONE:
- LOGP(DCS, LOGL_DEBUG, "Done with power scanning range.\n");
- ms = signal_data;
- cs = &ms->cellsel;
- if (!cs->powerscan)
- return -EINVAL;
- gsm322_cs_powerscan(ms);
- break;
- case S_L1CTL_FBSB_RESP:
- fr = signal_data;
- ms = fr->ms;
- cs = &ms->cellsel;
- if (cs->powerscan)
- return -EINVAL;
- cs->sync_pending = 0;
- if (cs->arfcn != fr->band_arfcn) {
- LOGP(DCS, LOGL_NOTICE, "Channel synched on "
- "wrong ARFCN=%d, syncing on right ARFCN again"
- "...\n", fr->band_arfcn);
- cs->sync_retries = SYNC_RETRIES;
- gsm322_sync_to_cell(cs, cs->neighbour, 0);
- break;
- }
- if (cs->ccch_state == GSM322_CCCH_ST_INIT) {
- LOGP(DCS, LOGL_INFO, "Channel synched. (ARFCN=%s, "
- "snr=%u, BSIC=%u)\n",
- gsm_print_arfcn(cs->arfcn), fr->snr, fr->bsic);
- cs->ccch_state = GSM322_CCCH_ST_SYNC;
- if (cs->si)
- cs->si->bsic = fr->bsic;
-
- /* set timer for reading BCCH */
- if (cs->state == GSM322_C2_STORED_CELL_SEL
- || cs->state == GSM322_C1_NORMAL_CELL_SEL
- || cs->state == GSM322_C6_ANY_CELL_SEL
- || cs->state == GSM322_C4_NORMAL_CELL_RESEL
- || cs->state == GSM322_C8_ANY_CELL_RESEL
- || cs->state == GSM322_C5_CHOOSE_CELL
- || cs->state == GSM322_C9_CHOOSE_ANY_CELL
- || cs->state == GSM322_ANY_SEARCH
- || cs->state == GSM322_PLMN_SEARCH
- || cs->state == GSM322_HPLMN_SEARCH)
- start_cs_timer(cs, ms->support.scan_to, 0);
- // TODO: timer depends on BCCH config
-
- /* set downlink signalling failure criterion */
- ms->meas.ds_fail = ms->meas.dsc = ms->settings.dsc_max;
- LOGP(DRR, LOGL_INFO, "using DSC of %d\n", ms->meas.dsc);
-
- /* start in case we are camping on serving/neighbour
- * cell */
- if (cs->state == GSM322_C3_CAMPED_NORMALLY
- || cs->state == GSM322_C7_CAMPED_ANY_CELL) {
- if (cs->neighbour)
- gsm322_nb_synced(cs, 1);
- else
- gsm322_nb_start(ms, 1);
- }
- }
- break;
- case S_L1CTL_FBSB_ERR:
- fr = signal_data;
- ms = fr->ms;
- cs = &ms->cellsel;
- if (cs->powerscan)
- return -EINVAL;
- cs->sync_pending = 0;
- /* retry */
- if (cs->sync_retries) {
- LOGP(DCS, LOGL_INFO, "Channel sync error, try again\n");
- cs->sync_retries--;
- gsm322_sync_to_cell(cs, cs->neighbour, 0);
- break;
- }
- if (cs->arfcn != fr->band_arfcn) {
- LOGP(DCS, LOGL_NOTICE, "Channel synched failed on "
- "wrong ARFCN=%d, syncing on right ARFCN again"
- "...\n", fr->band_arfcn);
- cs->sync_retries = SYNC_RETRIES;
- gsm322_sync_to_cell(cs, cs->neighbour, 0);
- break;
- }
- LOGP(DCS, LOGL_INFO, "Channel sync error.\n");
- /* no sync, free sysinfo, if allocated */
- if (cs->list[cs->arfci].sysinfo) {
- cs->list[cs->arfci].flags &= ~GSM322_CS_FLAG_SYSINFO;
- LOGP(DCS, LOGL_DEBUG, "free sysinfo ARFCN=%s\n",
- gsm_print_arfcn(index2arfcn(cs->arfci)));
- talloc_free(cs->list[cs->arfci].sysinfo);
- cs->list[cs->arfci].sysinfo = NULL;
-
- }
- if (cs->selected && cs->sel_arfcn == cs->arfcn) {
- LOGP(DCS, LOGL_INFO, "Unselect cell due to sync "
- "error!\n");
- /* unset selected cell */
- gsm322_unselect_cell(cs);
- }
- stop_cs_timer(cs);
-
- /* start in case we are camping on neighbour * cell */
- if (cs->state == GSM322_C3_CAMPED_NORMALLY
- || cs->state == GSM322_C7_CAMPED_ANY_CELL) {
- if (cs->neighbour) {
- gsm322_nb_synced(cs, 0);
- break;
- }
- }
-
- gsm322_cs_loss(cs);
- break;
- case S_L1CTL_LOSS_IND:
- ms = signal_data;
- cs = &ms->cellsel;
- LOGP(DCS, LOGL_INFO, "Loss of CCCH.\n");
- if (cs->selected && cs->sel_arfcn == cs->arfcn) {
- LOGP(DCS, LOGL_INFO, "Unselect cell due to loss\n");
- /* unset selected cell */
- gsm322_unselect_cell(cs);
- }
- stop_cs_timer(cs);
- gsm322_cs_loss(cs);
- break;
- case S_L1CTL_RESET:
- ms = signal_data;
- if (ms->mmlayer.power_off_idle) {
- mobile_exit(ms, 1);
- return 0;
- }
- break;
- case S_L1CTL_NEIGH_PM_IND:
- ni = signal_data;
- ms = ni->ms;
-#ifdef COMMING_LATE_R
- /* in dedicated mode */
- if (ms->rrlayer.dm_est)
- gsm48_rr_meas_ind(ms, ni->band_arfcn, ni->rx_lev);
- else
-#endif
- /* in camping mode */
- if ((ms->cellsel.state == GSM322_C3_CAMPED_NORMALLY
- || ms->cellsel.state == GSM322_C7_CAMPED_ANY_CELL)
- && !ms->cellsel.neighbour)
- gsm322_nb_meas_ind(ms, ni->band_arfcn, ni->rx_lev);
- break;
- }
-
- return 0;
-}
-
-static void gsm322_cs_loss(void *arg)
-{
- struct gsm322_cellsel *cs = arg;
- struct osmocom_ms *ms = cs->ms;
-
- if ((cs->state == GSM322_C3_CAMPED_NORMALLY
- || cs->state == GSM322_C7_CAMPED_ANY_CELL)
- && !cs->neighbour) {
- struct msgb *nmsg;
-
- LOGP(DCS, LOGL_INFO, "Loss of CCCH, Trigger "
- "re-selection.\n");
- if (ms->rrlayer.monitor)
- vty_notify(ms, "MON: trigger cell "
- "re-selection: loss of signal\n");
-
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_CELL_RESEL);
- if (!nmsg)
- return;
- gsm322_c_event(ms, nmsg);
- msgb_free(nmsg);
-
- return;
- } else
- if (cs->state == GSM322_CONNECTED_MODE_1
- || cs->state == GSM322_CONNECTED_MODE_2) {
- LOGP(DCS, LOGL_INFO, "Loss of SACCH, Trigger RR "
- "abort.\n");
-
- /* keep cell info for re-selection */
-
- gsm48_rr_los(ms);
- /* be shure that nothing else is done after here
- * because the function call above may cause
- * to return from idle state and trigger cell re-sel.
- */
-
- return;
- }
-
- gsm322_cs_timeout(cs);
-
- return;
-}
-
-/*
- * handler for cell selection process
- */
-
-/* start any cell search */
-static int gsm322_c_any_search(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- int i;
-
- new_c_state(cs, GSM322_ANY_SEARCH);
-
- /* mark all frequencies as scanned */
- for (i = 0; i <= 1023+299; i++) {
- cs->list[i].flags &= ~(GSM322_CS_FLAG_POWER
- | GSM322_CS_FLAG_SIGNAL
- | GSM322_CS_FLAG_SYSINFO);
- }
-
- /* start power scan */
- return gsm322_cs_powerscan(ms);
-}
-
-/* start PLMN search */
-static int gsm322_c_plmn_search(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- int i;
-
- new_c_state(cs, GSM322_PLMN_SEARCH);
-
- /* mark all frequencies as scanned */
- for (i = 0; i <= 1023+299; i++) {
- cs->list[i].flags &= ~(GSM322_CS_FLAG_POWER
- | GSM322_CS_FLAG_SIGNAL
- | GSM322_CS_FLAG_SYSINFO);
- }
-
- /* unset selected cell */
- gsm322_unselect_cell(cs);
-
- /* start power scan */
- return gsm322_cs_powerscan(ms);
-}
-
-/* start HPLMN search */
-static int gsm322_c_hplmn_search(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- int i, sel_i = arfcn2index(cs->sel_arfcn);
-
- new_c_state(cs, GSM322_HPLMN_SEARCH);
-
- /* mark all frequencies except our own BA as unscanned */
- for (i = 0; i <= 1023+299; i++) {
- if (i != sel_i
- && (cs->list[i].flags & GSM322_CS_FLAG_SYSINFO)
- && !(cs->list[i].flags & GSM322_CS_FLAG_BA)) {
- cs->list[i].flags &= ~(GSM322_CS_FLAG_POWER
- | GSM322_CS_FLAG_SIGNAL
- | GSM322_CS_FLAG_SYSINFO);
- }
- }
-
- /* start power scan */
- return gsm322_cs_powerscan(ms);
-}
-
-/* start stored cell selection */
-static int gsm322_c_stored_cell_sel(struct osmocom_ms *ms,
- struct gsm322_ba_list *ba)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- int i;
-
- /* we weed to rescan */
- for (i = 0; i <= 1023+299; i++) {
- cs->list[i].flags &= ~(GSM322_CS_FLAG_POWER
- | GSM322_CS_FLAG_SIGNAL
- | GSM322_CS_FLAG_SYSINFO);
- }
-
- new_c_state(cs, GSM322_C2_STORED_CELL_SEL);
-
- /* flag all frequencies that are in current band allocation */
- for (i = 0; i <= 1023+299; i++) {
- if ((ba->freq[i >> 3] & (1 << (i & 7))))
- cs->list[i].flags |= GSM322_CS_FLAG_BA;
- else
- cs->list[i].flags &= ~GSM322_CS_FLAG_BA;
- }
-
- /* unset selected cell */
- gsm322_unselect_cell(cs);
-
- /* start power scan */
- return gsm322_cs_powerscan(ms);
-}
-
-/* start noraml cell selection */
-static int gsm322_c_normal_cell_sel(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- int i;
-
- /* except for stored cell selection state, we weed to rescan */
- if (cs->state != GSM322_C2_STORED_CELL_SEL) {
- for (i = 0; i <= 1023+299; i++) {
- cs->list[i].flags &= ~(GSM322_CS_FLAG_POWER
- | GSM322_CS_FLAG_SIGNAL
- | GSM322_CS_FLAG_SYSINFO);
- }
- }
-
- new_c_state(cs, GSM322_C1_NORMAL_CELL_SEL);
-
- /* unset selected cell */
- gsm322_unselect_cell(cs);
-
- /* start power scan */
- return gsm322_cs_powerscan(ms);
-}
-
-/* start any cell selection */
-static int gsm322_c_any_cell_sel(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm322_msg *gm = (struct gsm322_msg *) msg->data;
- int msg_type = gm->msg_type;
-
- /* in case we already tried any cell (re-)selection, power scan again */
- if (cs->state == GSM322_C0_NULL
- || cs->state == GSM322_C6_ANY_CELL_SEL
- || cs->state == GSM322_C8_ANY_CELL_RESEL) {
- int i;
-
- for (i = 0; i <= 1023+299; i++) {
- cs->list[i].flags &= ~(GSM322_CS_FLAG_POWER
- | GSM322_CS_FLAG_SIGNAL
- | GSM322_CS_FLAG_SYSINFO);
- }
-
- /* indicate to MM that we lost coverage.
- * this is the only case where we really have no coverage.
- * we tell MM, so it will enter the "No Cell Avaiable" state. */
- if (msg_type == GSM322_EVENT_NO_CELL_FOUND) {
- struct msgb *nmsg;
-
- /* tell that we have no cell found
- * (not any cell at all) */
- nmsg = gsm48_mmevent_msgb_alloc(
- GSM48_MM_EVENT_NO_CELL_FOUND);
- if (!nmsg)
- return -ENOMEM;
- gsm48_mmevent_msg(ms, nmsg);
- }
- }
-
- new_c_state(cs, GSM322_C6_ANY_CELL_SEL);
-
- cs->mcc = cs->mnc = 0;
-
- /* unset selected cell */
- gsm322_unselect_cell(cs);
-
- /* start power scan */
- return gsm322_cs_powerscan(ms);
-}
-
-static void gsm322_any_timeout(void *arg)
-{
- struct gsm322_cellsel *cs = arg;
- struct osmocom_ms *ms = cs->ms;
-
- /* the timer may still run when not camping, so we ignore it.
- * it will be restarted whenever the 'camped on any cell' state
- * is reached. */
- if (cs->state != GSM322_C7_CAMPED_ANY_CELL)
- return;
-
- /* in case the time has been started before SIM was removed */
- if (!ms->subscr.sim_valid)
- return;
-
- LOGP(DCS, LOGL_INFO, "'Any cell selection timer' timed out. "
- "Starting special search to find allowed PLMNs.\n");
-
- gsm322_c_any_search(ms, NULL);
-}
-
-/* sim is removed, proceed with any cell selection */
-static int gsm322_c_sim_remove(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct llist_head *lh, *lh2;
-
- /* flush list of forbidden LAs */
- llist_for_each_safe(lh, lh2, &plmn->forbidden_la) {
- llist_del(lh);
- talloc_free(lh);
- }
- return gsm322_c_any_cell_sel(ms, msg);
-}
-
-/* start noraml cell re-selection */
-static int gsm322_c_normal_cell_resel(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct msgb *nmsg;
-
- /* store last camped cell. this is required for next cell
- * monitoring reselection criterion */
- cs->last_serving_arfcn = cs->sel_arfcn;
- cs->last_serving_valid = 1;
-
- /* unset selected cell */
- gsm322_unselect_cell(cs);
-
- /* tell MM that we lost coverage */
- nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_LOST_COVERAGE);
- if (!nmsg)
- return -ENOMEM;
- gsm48_mmevent_msg(ms, nmsg);
-
- new_c_state(cs, GSM322_C4_NORMAL_CELL_RESEL);
-
- /* start scanning neighbour cells for reselection */
- return gsm322_nb_scan(ms);
-}
-
-/* start any cell re-selection */
-static int gsm322_c_any_cell_resel(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct msgb *nmsg;
-
- /* store last camped cell. this is required for next cell
- * monitoring reselection criterion */
- cs->last_serving_arfcn = cs->sel_arfcn;
- cs->last_serving_valid = 1;
-
- /* unset selected cell */
- gsm322_unselect_cell(cs);
-
- /* tell MM that we lost coverage */
- nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_LOST_COVERAGE);
- if (!nmsg)
- return -ENOMEM;
- gsm48_mmevent_msg(ms, nmsg);
-
- new_c_state(cs, GSM322_C8_ANY_CELL_RESEL);
-
- /* start scanning neighbour cells for reselection */
- return gsm322_nb_scan(ms);
-}
-
-/* a suitable cell was found, so we camp normally */
-static int gsm322_c_camp_normally(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct msgb *nmsg;
-
- LOGP(DSUM, LOGL_INFO, "Camping normally on cell (ARFCN=%s mcc=%s "
- "mnc=%s %s, %s)\n", gsm_print_arfcn(cs->sel_arfcn),
- gsm_print_mcc(cs->sel_mcc),
- gsm_print_mnc(cs->sel_mnc), gsm_get_mcc(cs->sel_mcc),
- gsm_get_mnc(cs->sel_mcc, cs->sel_mnc));
-
- /* if we did cell reselection, we have a valid last serving cell */
- if (cs->state != GSM322_C4_NORMAL_CELL_RESEL)
- cs->last_serving_valid = 0;
-
- /* tell that we have selected a (new) cell */
- nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_CELL_SELECTED);
- if (!nmsg)
- return -ENOMEM;
- gsm48_mmevent_msg(ms, nmsg);
-
- new_c_state(cs, GSM322_C3_CAMPED_NORMALLY);
-
- return 0;
-}
-
-/* any cell was found, so we camp on any cell */
-static int gsm322_c_camp_any_cell(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct msgb *nmsg;
-
- LOGP(DSUM, LOGL_INFO, "Camping on any cell (ARFCN=%s mcc=%s "
- "mnc=%s %s, %s)\n", gsm_print_arfcn(cs->sel_arfcn),
- gsm_print_mcc(cs->sel_mcc),
- gsm_print_mnc(cs->sel_mnc), gsm_get_mcc(cs->sel_mcc),
- gsm_get_mnc(cs->sel_mcc, cs->sel_mnc));
-
- /* (re-)starting 'any cell selection' timer to look for coverage of
- * allowed PLMNs.
- * start timer, if not running.
- * restart timer, if we just entered the 'camped any cell' state */
- if (ms->subscr.sim_valid
- && (cs->state != GSM322_C8_ANY_CELL_RESEL
- || !osmo_timer_pending(&cs->any_timer))) {
- struct gsm322_plmn *plmn = &ms->plmn;
-
- stop_any_timer(cs);
- if (ms->settings.plmn_mode == PLMN_MODE_MANUAL
- && (!plmn->mcc
- || gsm_subscr_is_forbidden_plmn(&ms->subscr, plmn->mcc,
- plmn->mnc))) {
- LOGP(DCS, LOGL_INFO, "Not starting 'any search' timer, "
- "because no selected PLMN or forbidden\n");
- } else
- start_any_timer(cs, ms->subscr.any_timeout, 0);
- }
-
- /* if we did cell reselection, we have a valid last serving cell */
- if (cs->state != GSM322_C8_ANY_CELL_RESEL)
- cs->last_serving_valid = 0;
-
- /* tell that we have selected a (new) cell.
- * this cell iss not allowable, so the MM state will enter limited
- * service */
- if (cs->state != GSM322_C7_CAMPED_ANY_CELL) {
- nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_CELL_SELECTED);
- if (!nmsg)
- return -ENOMEM;
- gsm48_mmevent_msg(ms, nmsg);
- }
-
- new_c_state(cs, GSM322_C7_CAMPED_ANY_CELL);
-
- return 0;
-}
-
-/* create temporary ba range with given frequency ranges */
-struct gsm322_ba_list *gsm322_cs_ba_range(struct osmocom_ms *ms,
- uint32_t *range, uint8_t ranges, uint8_t refer_pcs)
-{
- static struct gsm322_ba_list ba;
- int lower, higher;
-
- memset(&ba, 0, sizeof(ba));
-
- while(ranges--) {
- lower = *range & 1023;
- higher = (*range >> 16) & 1023;
- if (refer_pcs && lower >= 512 && lower <= 810) {
- if (higher < 512 || higher > 810 || higher < lower) {
- LOGP(DCS, LOGL_NOTICE, "Illegal PCS range: "
- "%d..%d\n", lower, higher);
- range++;
- continue;
- }
- lower += 1024-512;
- higher += 1024-512;
- }
- range++;
- LOGP(DCS, LOGL_INFO, "Use BA range: %s..%s\n",
- gsm_print_arfcn(index2arfcn(lower)),
- gsm_print_arfcn(index2arfcn(higher)));
- /* GSM 05.08 6.3 */
- while (1) {
- ba.freq[lower >> 3] |= 1 << (lower & 7);
- if (lower == higher)
- break;
- lower++;
- /* wrap arround, only if not PCS */
- if (lower == 1024)
- lower = 0;
- }
- }
-
- return &ba;
-}
-
-/* common part of gsm322_c_choose_cell and gsm322_c_choose_any_cell */
-static int gsm322_cs_choose(struct osmocom_ms *ms)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm322_ba_list *ba = NULL;
- int i;
-
- /* NOTE: The call to this function is synchron to RR layer, so
- * we may access the BA range there.
- */
- if (rr->ba_ranges)
- ba = gsm322_cs_ba_range(ms, rr->ba_range, rr->ba_ranges,
- gsm_refer_pcs(cs->sel_arfcn, &cs->sel_si));
- else {
- LOGP(DCS, LOGL_INFO, "No BA range(s), try sysinfo.\n");
- /* get and update BA of last received sysinfo 5* */
- ba = gsm322_cs_sysinfo_sacch(ms);
- if (!ba) {
- LOGP(DCS, LOGL_INFO, "No BA on sysinfo, try stored "
- "BA list.\n");
- ba = gsm322_find_ba_list(cs, cs->sel_si.mcc,
- cs->sel_si.mnc);
- }
- }
-
- if (!ba) {
- struct msgb *nmsg;
-
- LOGP(DCS, LOGL_INFO, "No BA list to use.\n");
-
- /* tell CS to start over */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_NO_CELL_FOUND);
- if (!nmsg)
- return -ENOMEM;
- gsm322_c_event(ms, nmsg);
- msgb_free(nmsg);
-
- return 0;
- }
-
- /* flag all frequencies that are in current band allocation */
- for (i = 0; i <= 1023+299; i++) {
- if (cs->state == GSM322_C5_CHOOSE_CELL) {
- if ((ba->freq[i >> 3] & (1 << (i & 7)))) {
- cs->list[i].flags |= GSM322_CS_FLAG_BA;
- } else {
- cs->list[i].flags &= ~GSM322_CS_FLAG_BA;
- }
- }
- cs->list[i].flags &= ~(GSM322_CS_FLAG_POWER
- | GSM322_CS_FLAG_SIGNAL
- | GSM322_CS_FLAG_SYSINFO);
- }
-
- /* unset selected cell */
- gsm322_unselect_cell(cs);
-
- /* start power scan */
- return gsm322_cs_powerscan(ms);
-}
-
-/* start 'Choose cell' after returning to idle mode */
-static int gsm322_c_choose_cell(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm322_msg *gm = (struct gsm322_msg *) msg->data;
-
- /* After location updating, we choose the last cell */
- if (gm->same_cell) {
- struct msgb *nmsg;
-
- if (!cs->selected) {
- LOGP(DCS, LOGL_INFO, "Cell not selected anymore, "
- "choose cell!\n");
- goto choose;
- }
- cs->arfcn = cs->sel_arfcn;
- cs->arfci = arfcn2index(cs->arfcn);
-
- /* be sure to go to current camping frequency on return */
- LOGP(DCS, LOGL_INFO, "Selecting ARFCN %s. after LOC.UPD.\n",
- gsm_print_arfcn(cs->arfcn));
- cs->sync_retries = SYNC_RETRIES;
- gsm322_sync_to_cell(cs, NULL, 0);
- cs->si = cs->list[cs->arfci].sysinfo;
- if (!cs->si) {
- printf("No SI when ret.idle, please fix!\n");
- exit(0L);
- }
-
- new_c_state(cs, GSM322_C3_CAMPED_NORMALLY);
-
- /* tell that we have selected the cell, so RR returns IDLE */
- nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_CELL_SELECTED);
- if (!nmsg)
- return -ENOMEM;
- gsm48_mmevent_msg(ms, nmsg);
-
- return 0;
- }
-
-choose:
- new_c_state(cs, GSM322_C5_CHOOSE_CELL);
-
- return gsm322_cs_choose(ms);
-}
-
-/* start 'Choose any cell' after returning to idle mode */
-static int gsm322_c_choose_any_cell(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
-
- new_c_state(cs, GSM322_C9_CHOOSE_ANY_CELL);
-
- return gsm322_cs_choose(ms);
-}
-
-/* a new PLMN is selected by PLMN search process */
-static int gsm322_c_new_plmn(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_msg *gm = (struct gsm322_msg *) msg->data;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm322_plmn *plmn = &ms->plmn;
- struct gsm322_ba_list *ba;
-
- cs->mcc = plmn->mcc;
- cs->mnc = plmn->mnc;
-
- if (gm->limited) {
- LOGP(DCS, LOGL_INFO, "Selected PLMN with limited service.\n");
- return gsm322_c_any_cell_sel(ms, msg);
- }
-
- LOGP(DSUM, LOGL_INFO, "Selecting PLMN (mcc=%s mnc=%s %s, %s)\n",
- gsm_print_mcc(cs->mcc), gsm_print_mnc(cs->mnc),
- gsm_get_mcc(cs->mcc), gsm_get_mnc(cs->mcc, cs->mnc));
-
- /* search for BA list */
- ba = gsm322_find_ba_list(cs, plmn->mcc, plmn->mnc);
-
- if (ba) {
- LOGP(DCS, LOGL_INFO, "Start stored cell selection.\n");
- return gsm322_c_stored_cell_sel(ms, ba);
- } else {
- LOGP(DCS, LOGL_INFO, "Start normal cell selection.\n");
- return gsm322_c_normal_cell_sel(ms, msg);
- }
-}
-
-/* go connected mode */
-static int gsm322_c_conn_mode_1(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
-
- /* check for error */
- if (!cs->selected) {
- LOGP(DCS, LOGL_INFO, "No cell selected, please fix!\n");
- exit(0L);
- }
- cs->arfcn = cs->sel_arfcn;
- cs->arfci = arfcn2index(cs->arfcn);
-
- /* maybe we are currently syncing to neighbours */
- stop_cs_timer(cs);
-
- new_c_state(cs, GSM322_CONNECTED_MODE_1);
-
- /* be sure to go to current camping frequency on return */
- LOGP(DCS, LOGL_INFO, "Going to camping (normal) ARFCN %s.\n",
- gsm_print_arfcn(cs->arfcn));
- cs->si = cs->list[cs->arfci].sysinfo;
- if (!cs->si) {
- printf("No SI when leaving idle, please fix!\n");
- exit(0L);
- }
- cs->sync_retries = SYNC_RETRIES;
- gsm322_sync_to_cell(cs, NULL, 1);
-
- return 0;
-}
-
-static int gsm322_c_conn_mode_2(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
-
- /* check for error */
- if (!cs->selected) {
- LOGP(DCS, LOGL_INFO, "No cell selected, please fix!\n");
- exit(0L);
- }
- cs->arfcn = cs->sel_arfcn;
- cs->arfci = arfcn2index(cs->arfcn);
-
- stop_cs_timer(cs);
-
- new_c_state(cs, GSM322_CONNECTED_MODE_2);
-
- /* be sure to go to current camping frequency on return */
- LOGP(DCS, LOGL_INFO, "Going to camping (any cell) ARFCN %s.\n",
- gsm_print_arfcn(cs->arfcn));
- cs->si = cs->list[cs->arfci].sysinfo;
- if (!cs->si) {
- printf("No SI when leaving idle, please fix!\n");
- exit(0L);
- }
- cs->sync_retries = SYNC_RETRIES;
- gsm322_sync_to_cell(cs, NULL, 1);
-
- return 0;
-}
-
-/* switch on */
-static int gsm322_c_switch_on(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
-
- /* if no SIM is is MS */
- if (!subscr->sim_valid) {
- LOGP(DCS, LOGL_INFO, "Switch on without SIM.\n");
- return gsm322_c_any_cell_sel(ms, msg);
- }
- LOGP(DCS, LOGL_INFO, "Switch on with SIM inserted.\n");
-
- /* stay in NULL state until PLMN is selected */
-
- return 0;
-}
-
-/*
- * state machines
- */
-
-/* state machine for automatic PLMN selection events */
-static struct plmnastatelist {
- uint32_t states;
- int type;
- int (*rout) (struct osmocom_ms *ms, struct msgb *msg);
-} plmnastatelist[] = {
- {SBIT(GSM322_A0_NULL),
- GSM322_EVENT_SWITCH_ON, gsm322_a_switch_on},
-
- /* special case for full search */
- {SBIT(GSM322_A0_NULL),
- GSM322_EVENT_PLMN_SEARCH_END, gsm322_a_sel_first_plmn},
-
- {ALL_STATES,
- GSM322_EVENT_SWITCH_OFF, gsm322_a_switch_off},
-
- {SBIT(GSM322_A0_NULL) | SBIT(GSM322_A6_NO_SIM),
- GSM322_EVENT_SIM_INSERT, gsm322_a_switch_on},
-
- {ALL_STATES,
- GSM322_EVENT_SIM_INSERT, gsm322_a_sim_insert},
-
- {ALL_STATES,
- GSM322_EVENT_SIM_REMOVE, gsm322_a_sim_removed},
-
- {ALL_STATES,
- GSM322_EVENT_INVALID_SIM, gsm322_a_sim_removed},
-
- {SBIT(GSM322_A1_TRYING_RPLMN),
- GSM322_EVENT_REG_FAILED, gsm322_a_sel_first_plmn},
-
- {SBIT(GSM322_A1_TRYING_RPLMN),
- GSM322_EVENT_ROAMING_NA, gsm322_a_sel_first_plmn},
-
- {SBIT(GSM322_A1_TRYING_RPLMN),
- GSM322_EVENT_NO_CELL_FOUND, gsm322_a_sel_first_plmn},
-
- {SBIT(GSM322_A1_TRYING_RPLMN) | SBIT(GSM322_A3_TRYING_PLMN),
- GSM322_EVENT_REG_SUCCESS, gsm322_a_go_on_plmn},
-
- {SBIT(GSM322_A2_ON_PLMN),
- GSM322_EVENT_ROAMING_NA, gsm322_a_roaming_na},
-
- {SBIT(GSM322_A2_ON_PLMN),
- GSM322_EVENT_HPLMN_SEARCH, gsm322_a_hplmn_search_start},
-
- {SBIT(GSM322_A2_ON_PLMN),
- GSM322_EVENT_NO_CELL_FOUND, gsm322_a_loss_of_radio},
-
- {SBIT(GSM322_A2_ON_PLMN),
- GSM322_EVENT_USER_RESEL, gsm322_a_user_resel},
-
- {SBIT(GSM322_A3_TRYING_PLMN),
- GSM322_EVENT_REG_FAILED, gsm322_a_sel_next_plmn},
-
- {SBIT(GSM322_A3_TRYING_PLMN),
- GSM322_EVENT_ROAMING_NA, gsm322_a_sel_next_plmn},
-
- {SBIT(GSM322_A3_TRYING_PLMN),
- GSM322_EVENT_NO_CELL_FOUND, gsm322_a_sel_next_plmn},
-
- {SBIT(GSM322_A5_HPLMN_SEARCH),
- GSM322_EVENT_CELL_FOUND, gsm322_a_sel_first_plmn},
-
- {SBIT(GSM322_A5_HPLMN_SEARCH),
- GSM322_EVENT_NO_CELL_FOUND, gsm322_a_go_on_plmn},
-
- {SBIT(GSM322_A4_WAIT_FOR_PLMN),
- GSM322_EVENT_PLMN_AVAIL, gsm322_a_plmn_avail},
-
- {ALL_STATES,
- GSM322_EVENT_SEL_MANUAL, gsm322_a_sel_manual},
-
- {ALL_STATES,
- GSM322_EVENT_NO_CELL_FOUND, gsm322_am_no_cell_found},
-};
-
-#define PLMNASLLEN \
- (sizeof(plmnastatelist) / sizeof(struct plmnastatelist))
-
-static int gsm322_a_event(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct gsm322_msg *gm = (struct gsm322_msg *) msg->data;
- int msg_type = gm->msg_type;
- int rc;
- int i;
-
- LOGP(DPLMN, LOGL_INFO, "(ms %s) Event '%s' for automatic PLMN "
- "selection in state '%s'\n", ms->name, get_event_name(msg_type),
- get_a_state_name(plmn->state));
- /* find function for current state and message */
- for (i = 0; i < PLMNASLLEN; i++)
- if ((msg_type == plmnastatelist[i].type)
- && ((1 << plmn->state) & plmnastatelist[i].states))
- break;
- if (i == PLMNASLLEN) {
- LOGP(DPLMN, LOGL_NOTICE, "Event unhandled at this state.\n");
- return 0;
- }
-
- rc = plmnastatelist[i].rout(ms, msg);
-
- return rc;
-}
-
-/* state machine for manual PLMN selection events */
-static struct plmnmstatelist {
- uint32_t states;
- int type;
- int (*rout) (struct osmocom_ms *ms, struct msgb *msg);
-} plmnmstatelist[] = {
- {SBIT(GSM322_M0_NULL),
- GSM322_EVENT_SWITCH_ON, gsm322_m_switch_on},
-
- {SBIT(GSM322_M0_NULL) | SBIT(GSM322_M3_NOT_ON_PLMN) |
- SBIT(GSM322_M2_ON_PLMN),
- GSM322_EVENT_PLMN_SEARCH_END, gsm322_m_display_plmns},
-
- {ALL_STATES,
- GSM322_EVENT_SWITCH_OFF, gsm322_m_switch_off},
-
- {SBIT(GSM322_M0_NULL) | SBIT(GSM322_M5_NO_SIM),
- GSM322_EVENT_SIM_INSERT, gsm322_m_switch_on},
-
- {ALL_STATES,
- GSM322_EVENT_SIM_INSERT, gsm322_m_sim_insert},
-
- {ALL_STATES,
- GSM322_EVENT_SIM_REMOVE, gsm322_m_sim_removed},
-
- {SBIT(GSM322_M1_TRYING_RPLMN),
- GSM322_EVENT_REG_FAILED, gsm322_m_display_plmns},
-
- {SBIT(GSM322_M1_TRYING_RPLMN),
- GSM322_EVENT_ROAMING_NA, gsm322_m_display_plmns},
-
- {SBIT(GSM322_M1_TRYING_RPLMN),
- GSM322_EVENT_NO_CELL_FOUND, gsm322_m_display_plmns},
-
- {SBIT(GSM322_M1_TRYING_RPLMN),
- GSM322_EVENT_REG_SUCCESS, gsm322_m_go_on_plmn},
-
- {SBIT(GSM322_M2_ON_PLMN),
- GSM322_EVENT_ROAMING_NA, gsm322_m_display_plmns},
-
- /* undocumented case, where we loose coverage */
- {SBIT(GSM322_M2_ON_PLMN),
- GSM322_EVENT_NO_CELL_FOUND, gsm322_m_display_plmns},
-
- {SBIT(GSM322_M1_TRYING_RPLMN) | SBIT(GSM322_M2_ON_PLMN) |
- SBIT(GSM322_M4_TRYING_PLMN),
- GSM322_EVENT_INVALID_SIM, gsm322_m_sim_removed},
-
- {SBIT(GSM322_M3_NOT_ON_PLMN) | SBIT(GSM322_M2_ON_PLMN),
- GSM322_EVENT_USER_RESEL, gsm322_m_user_resel},
-
- {SBIT(GSM322_M3_NOT_ON_PLMN),
- GSM322_EVENT_PLMN_AVAIL, gsm322_m_plmn_avail},
-
- /* choose plmn is only specified when 'not on PLMN', but it makes
- * sense to select cell from other states too. */
- {SBIT(GSM322_M3_NOT_ON_PLMN) | SBIT(GSM322_M2_ON_PLMN) |
- SBIT(GSM322_M1_TRYING_RPLMN) | SBIT(GSM322_M4_TRYING_PLMN),
- GSM322_EVENT_CHOOSE_PLMN, gsm322_m_choose_plmn},
-
- {SBIT(GSM322_M4_TRYING_PLMN),
- GSM322_EVENT_REG_SUCCESS, gsm322_m_go_on_plmn},
-
- /* we also display available PLMNs after trying to register.
- * this is not standard. we need that so the user knows
- * that registration failed, and the user can select a new network. */
- {SBIT(GSM322_M4_TRYING_PLMN),
- GSM322_EVENT_REG_FAILED, gsm322_m_display_plmns},
-
- {SBIT(GSM322_M4_TRYING_PLMN),
- GSM322_EVENT_ROAMING_NA, gsm322_m_display_plmns},
-
- {SBIT(GSM322_M4_TRYING_PLMN),
- GSM322_EVENT_NO_CELL_FOUND, gsm322_m_display_plmns},
-
- {ALL_STATES,
- GSM322_EVENT_SEL_AUTO, gsm322_m_sel_auto},
-
- {ALL_STATES,
- GSM322_EVENT_NO_CELL_FOUND, gsm322_am_no_cell_found},
-};
-
-#define PLMNMSLLEN \
- (sizeof(plmnmstatelist) / sizeof(struct plmnmstatelist))
-
-static int gsm322_m_event(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct gsm322_msg *gm = (struct gsm322_msg *) msg->data;
- int msg_type = gm->msg_type;
- int rc;
- int i;
-
- LOGP(DPLMN, LOGL_INFO, "(ms %s) Event '%s' for manual PLMN selection "
- "in state '%s'\n", ms->name, get_event_name(msg_type),
- get_m_state_name(plmn->state));
- /* find function for current state and message */
- for (i = 0; i < PLMNMSLLEN; i++)
- if ((msg_type == plmnmstatelist[i].type)
- && ((1 << plmn->state) & plmnmstatelist[i].states))
- break;
- if (i == PLMNMSLLEN) {
- LOGP(DPLMN, LOGL_NOTICE, "Event unhandled at this state.\n");
- return 0;
- }
-
- rc = plmnmstatelist[i].rout(ms, msg);
-
- return rc;
-}
-
-/* dequeue GSM 03.22 PLMN events */
-int gsm322_plmn_dequeue(struct osmocom_ms *ms)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct msgb *msg;
- int work = 0;
-
- while ((msg = msgb_dequeue(&plmn->event_queue))) {
- /* send event to PLMN select process */
- if (ms->settings.plmn_mode == PLMN_MODE_AUTO)
- gsm322_a_event(ms, msg);
- else
- gsm322_m_event(ms, msg);
- msgb_free(msg);
- work = 1; /* work done */
- }
-
- return work;
-}
-
-/* state machine for channel selection events */
-static struct cellselstatelist {
- uint32_t states;
- int type;
- int (*rout) (struct osmocom_ms *ms, struct msgb *msg);
-} cellselstatelist[] = {
- {ALL_STATES,
- GSM322_EVENT_SWITCH_ON, gsm322_c_switch_on},
-
- {ALL_STATES,
- GSM322_EVENT_SIM_REMOVE, gsm322_c_sim_remove},
-
- {ALL_STATES,
- GSM322_EVENT_NEW_PLMN, gsm322_c_new_plmn},
-
- {ALL_STATES,
- GSM322_EVENT_PLMN_SEARCH_START, gsm322_c_plmn_search},
-
- {SBIT(GSM322_C1_NORMAL_CELL_SEL) | SBIT(GSM322_C2_STORED_CELL_SEL) |
- SBIT(GSM322_C4_NORMAL_CELL_RESEL) | SBIT(GSM322_C5_CHOOSE_CELL),
- GSM322_EVENT_CELL_FOUND, gsm322_c_camp_normally},
-
- {SBIT(GSM322_C9_CHOOSE_ANY_CELL) | SBIT(GSM322_C6_ANY_CELL_SEL) |
- SBIT(GSM322_C8_ANY_CELL_RESEL),
- GSM322_EVENT_CELL_FOUND, gsm322_c_camp_any_cell},
-
- {SBIT(GSM322_C1_NORMAL_CELL_SEL) | SBIT(GSM322_C6_ANY_CELL_SEL) |
- SBIT(GSM322_C9_CHOOSE_ANY_CELL) | SBIT(GSM322_C8_ANY_CELL_RESEL) |
- SBIT(GSM322_C0_NULL) /* after search */,
- GSM322_EVENT_NO_CELL_FOUND, gsm322_c_any_cell_sel},
-
- {SBIT(GSM322_C2_STORED_CELL_SEL) | SBIT(GSM322_C5_CHOOSE_CELL) |
- SBIT(GSM322_C4_NORMAL_CELL_RESEL),
- GSM322_EVENT_NO_CELL_FOUND, gsm322_c_normal_cell_sel},
-
- {SBIT(GSM322_C3_CAMPED_NORMALLY),
- GSM322_EVENT_LEAVE_IDLE, gsm322_c_conn_mode_1},
-
- {SBIT(GSM322_C7_CAMPED_ANY_CELL),
- GSM322_EVENT_LEAVE_IDLE, gsm322_c_conn_mode_2},
-
- {SBIT(GSM322_CONNECTED_MODE_1),
- GSM322_EVENT_RET_IDLE, gsm322_c_choose_cell},
-
- {SBIT(GSM322_CONNECTED_MODE_2),
- GSM322_EVENT_RET_IDLE, gsm322_c_choose_any_cell},
-
- {SBIT(GSM322_C3_CAMPED_NORMALLY),
- GSM322_EVENT_CELL_RESEL, gsm322_c_normal_cell_resel},
-
- {SBIT(GSM322_C7_CAMPED_ANY_CELL),
- GSM322_EVENT_CELL_RESEL, gsm322_c_any_cell_resel},
-
- {SBIT(GSM322_C7_CAMPED_ANY_CELL),
- GSM322_EVENT_CELL_FOUND, gsm322_c_normal_cell_sel},
-
- {SBIT(GSM322_C1_NORMAL_CELL_SEL) | SBIT(GSM322_C2_STORED_CELL_SEL) |
- SBIT(GSM322_C4_NORMAL_CELL_RESEL) | SBIT(GSM322_C5_CHOOSE_CELL) |
- SBIT(GSM322_C9_CHOOSE_ANY_CELL) | SBIT(GSM322_C8_ANY_CELL_RESEL) |
- SBIT(GSM322_C6_ANY_CELL_SEL) | SBIT(GSM322_ANY_SEARCH) |
- SBIT(GSM322_PLMN_SEARCH) | SBIT(GSM322_HPLMN_SEARCH) ,
- GSM322_EVENT_SYSINFO, gsm322_c_scan_sysinfo_bcch},
-
- {SBIT(GSM322_C3_CAMPED_NORMALLY) | SBIT(GSM322_C7_CAMPED_ANY_CELL),
- GSM322_EVENT_SYSINFO, gsm322_c_camp_sysinfo_bcch},
-
- {SBIT(GSM322_C3_CAMPED_NORMALLY),
- GSM322_EVENT_HPLMN_SEARCH, gsm322_c_hplmn_search},
-};
-
-#define CELLSELSLLEN \
- (sizeof(cellselstatelist) / sizeof(struct cellselstatelist))
-
-int gsm322_c_event(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm322_msg *gm = (struct gsm322_msg *) msg->data;
- int msg_type = gm->msg_type;
- int rc;
- int i;
-
- if (msg_type != GSM322_EVENT_SYSINFO)
- LOGP(DCS, LOGL_INFO, "(ms %s) Event '%s' for Cell selection "
- "in state '%s'\n", ms->name, get_event_name(msg_type),
- get_cs_state_name(cs->state));
- /* find function for current state and message */
- for (i = 0; i < CELLSELSLLEN; i++)
- if ((msg_type == cellselstatelist[i].type)
- && ((1 << cs->state) & cellselstatelist[i].states))
- break;
- if (i == CELLSELSLLEN) {
- if (msg_type != GSM322_EVENT_SYSINFO)
- LOGP(DCS, LOGL_NOTICE, "Event unhandled at this state."
- "\n");
- return 0;
- }
-
- rc = cellselstatelist[i].rout(ms, msg);
-
- return rc;
-}
-
-/* dequeue GSM 03.22 cell selection events */
-int gsm322_cs_dequeue(struct osmocom_ms *ms)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct msgb *msg;
- int work = 0;
-
- while ((msg = msgb_dequeue(&cs->event_queue))) {
- /* send event to cell selection process */
- gsm322_c_event(ms, msg);
- msgb_free(msg);
- work = 1; /* work done */
- }
-
- return work;
-}
-
-/*
- * neighbour cell measurement process in idle mode
- */
-
-static struct gsm322_neighbour *gsm322_nb_alloc(struct gsm322_cellsel *cs,
- uint16_t arfcn)
-{
- struct gsm322_neighbour *nb;
- time_t now;
-
- time(&now);
-
- nb = talloc_zero(l23_ctx, struct gsm322_neighbour);
- if (!nb)
- return 0;
-
- nb->cs = cs;
- nb->arfcn = arfcn;
- nb->rla_c_dbm = -128;
- nb->created = now;
- llist_add_tail(&nb->entry, &cs->nb_list);
-
- return nb;
-}
-
-static void gsm322_nb_free(struct gsm322_neighbour *nb)
-{
- llist_del(&nb->entry);
- talloc_free(nb);
-}
-
-/* check and calculate reselection criterion for all 6 neighbour cells and
- * return, if cell reselection has to be triggered */
-static int gsm322_nb_check(struct osmocom_ms *ms, int any)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm_settings *set = &ms->settings;
- struct gsm48_sysinfo *s;
- int i = 0, reselect = 0;
- uint16_t acc_class;
- int band, class;
- struct gsm322_neighbour *nb;
- time_t now;
- char arfcn_text[10];
-
- time(&now);
-
- /* set out access class depending on the cell selection type */
- if (any) {
- acc_class = (subscr->acc_class | 0x0400); /* add emergency */
- LOGP(DNB, LOGL_DEBUG, "Re-select using access class with "
- "Emergency class.\n");
- } else {
- acc_class = subscr->acc_class;
- LOGP(DNB, LOGL_DEBUG, "Re-select using access class.\n");
- }
-
- if (ms->rrlayer.monitor) {
- vty_notify(ms, "MON: cell ARFCN LAC C1 C2 CRH RLA_C "
- "bargraph\n");
- snprintf(arfcn_text, 10, "%s ",
- gsm_print_arfcn(cs->sel_arfcn));
- arfcn_text[9] = '\0';
- vty_notify(ms, "MON: serving %s 0x%04x %3d %3d %4d "
- "%s\n", arfcn_text, cs->sel_lac, cs->c1, cs->c2,
- cs->rla_c_dbm, bargraph(cs->rla_c_dbm / 2, -55, -24));
- }
-
- /* loop through all neighbour cells and select best cell */
- llist_for_each_entry(nb, &cs->nb_list, entry) {
- LOGP(DNB, LOGL_INFO, "Checking cell of ARFCN %s for cell "
- "re-selection.\n", gsm_print_arfcn(nb->arfcn));
- s = cs->list[arfcn2index(nb->arfcn)].sysinfo;
- nb->checked_for_resel = 0;
- nb->suitable_allowable = 0;
- nb->c12_valid = 1;
- nb->prio_low = 0;
-
- if (nb->state == GSM322_NB_NOT_SUP) {
- LOGP(DNB, LOGL_INFO, "Skip cell: ARFCN not supported."
- "\n");
- if (ms->rrlayer.monitor) {
- snprintf(arfcn_text, 10, "%s ",
- gsm_print_arfcn(nb->arfcn));
- arfcn_text[9] = '\0';
- vty_notify(ms, "MON: nb %2d %s ARFCN not "
- "supported\n", i + 1, arfcn_text);
- }
- goto cont;
- }
- /* check if we have successfully read BCCH */
- if (!s || nb->state != GSM322_NB_SYSINFO) {
- LOGP(DNB, LOGL_INFO, "Skip cell: There are no system "
- "informations available.\n");
- if (ms->rrlayer.monitor) {
- snprintf(arfcn_text, 10, "%s ",
- gsm_print_arfcn(nb->arfcn));
- arfcn_text[9] = '\0';
- vty_notify(ms, "MON: nb %2d %s "
- " %4d %s\n",
- i + 1, arfcn_text, nb->rla_c_dbm,
- bargraph(nb->rla_c_dbm / 2, -55, -24));
- }
- goto cont;
- }
-
- /* get prio */
- if (s->sp && s->sp_cbq)
- nb->prio_low = 1;
-
- /* get C1 & C2 */
- band = gsm_arfcn2band(nb->arfcn);
- class = class_of_band(ms, band);
- nb->c1 = calculate_c1(DNB, nb->rla_c_dbm, s->rxlev_acc_min_db,
- ms_pwr_dbm(band, s->ms_txpwr_max_cch),
- ms_class_gmsk_dbm(band, class));
- nb->c2 = calculate_c2(nb->c1, 0,
- (cs->last_serving_valid
- && cs->last_serving_arfcn == nb->arfcn),
- s->sp, s->sp_cro, now - nb->created, s->sp_pt,
- s->sp_to);
- nb->c12_valid = 1;
-
- /* calculate CRH depending on LAI */
- if (cs->sel_mcc == s->mcc && cs->sel_mnc == s->mnc
- && cs->sel_lac == s->lac) {
- LOGP(DNB, LOGL_INFO, "-> Cell of is in the same LA, "
- "so CRH = 0\n");
- nb->crh = 0;
- } else if (any) {
- LOGP(DNB, LOGL_INFO, "-> Cell of is in a different LA, "
- "but service is limited, so CRH = 0\n");
- nb->crh = 0;
- } else {
- nb->crh = s->cell_resel_hyst_db;
- LOGP(DNB, LOGL_INFO, "-> Cell of is in a different LA, "
- "and service is normal, so CRH = %d\n",
- nb->crh);
- }
-
- if (ms->rrlayer.monitor) {
- snprintf(arfcn_text, 10, "%s ",
- gsm_print_arfcn(nb->arfcn));
- arfcn_text[9] = '\0';
- vty_notify(ms, "MON: nb %2d %s 0x%04x %3d %3d %2d"
- " %4d %s\n", i + 1, arfcn_text, s->lac,
- nb->c1, nb->c2, nb->crh, nb->rla_c_dbm,
- bargraph(nb->rla_c_dbm / 2, -55, -24));
- }
-
- /* if cell is barred and we don't override */
- if (s->cell_barr && !(s->sp && s->sp_cbq)) {
- LOGP(DNB, LOGL_INFO, "Skip cell: Cell is barred.\n");
- goto cont;
- }
-
- /* if we have no access to the cell and we don't override */
- if (!subscr->acc_barr
- && !(acc_class & (s->class_barr ^ 0xffff))) {
- LOGP(DNB, LOGL_INFO, "Skip cell: Class is "
- "barred for our access. (access=%04x "
- "barred=%04x)\n", acc_class, s->class_barr);
- goto cont;
- }
-
- /* check if LA is forbidden */
- if (any && gsm322_is_forbidden_la(ms, s->mcc, s->mnc, s->lac)) {
- LOGP(DNB, LOGL_INFO, "Skip cell: Cell has "
- "forbidden LA.\n");
- goto cont;
- }
-
- /* check if we have same PLMN */
- if (!any && (cs->sel_mcc != s->mcc || cs->sel_mnc != s->mnc)) {
- LOGP(DNB, LOGL_INFO, "Skip cell: PLMN of cell "
- "does not match target PLMN. (cell: mcc=%s "
- "mnc=%s)\n", gsm_print_mcc(s->mcc),
- gsm_print_mnc(s->mnc));
- goto cont;
- }
-
- /* check criterion C1 */
- if (nb->c1 < 0) {
- LOGP(DNB, LOGL_INFO, "Skip cell: C1 criterion "
- " (>0) not met. (C1 = %d)\n", nb->c1);
- goto cont;
- }
-
- /* we can use this cell, if it is better */
- nb->suitable_allowable = 1;
-
- /* check priority */
- if (!cs->prio_low && nb->prio_low) {
- LOGP(DNB, LOGL_INFO, "Skip cell: cell has low "
- "priority, but serving cell has normal "
- "prio.\n");
- goto cont;
- }
- if (cs->prio_low && !nb->prio_low) {
- LOGP(DNB, LOGL_INFO, "Found cell: cell has normal "
- "priority, but serving cell has low prio.\n");
- reselect = 1;
- goto cont;
- }
-
- /* find better cell */
- if (nb->c2 - nb->crh > cs->c2) {
- LOGP(DNB, LOGL_INFO, "Found cell: cell is better "
- "than serving cell.\n");
- reselect = 1;
- goto cont;
- }
-
-cont:
- if (++i == GSM58_NB_NUMBER)
- break;
- }
-
- if (!i) {
- if (ms->rrlayer.monitor)
- vty_notify(ms, "MON: no neighbour cells\n");
- }
-
- if (cs->resel_when + GSM58_RESEL_THRESHOLD >= now) {
- LOGP(DNB, LOGL_INFO, "Found better neighbour cell, but "
- "reselection threshold not reached.\n");
- reselect = 0;
- }
-
- if (reselect && set->stick) {
- LOGP(DNB, LOGL_INFO, "Don't trigger cell re-selection, because "
- "we stick to serving cell.\n");
- reselect = 0;
- }
-
- return reselect;
-}
-
-/* select a suitable and allowable cell */
-static int gsm322_nb_scan(struct osmocom_ms *ms)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm_settings *set = &ms->settings;
- int i = 0;
- struct gsm322_neighbour *nb, *best_nb_low = NULL, *best_nb_normal = 0;
- int16_t best_low = -32768, best_normal = -32768;
-
- if (set->stick) {
- LOGP(DCS, LOGL_DEBUG, "Do not re-select cell, because we stick "
- " to a cell.\n");
- goto no_cell_found;
- }
-
- if (!cs->c12_valid) {
- LOGP(DCS, LOGL_DEBUG, "Do not re-select cell, because there "
- " are no valid C1 and C2.\n");
- goto no_cell_found;
- }
-
- /* loop through all neighbour cells and select best cell */
- llist_for_each_entry(nb, &cs->nb_list, entry) {
- LOGP(DCS, LOGL_INFO, "Checking cell with ARFCN %s for cell "
- "re-selection. (C2 = %d)\n", gsm_print_arfcn(nb->arfcn),
- nb->c2);
- /* track which cells have been checked do far */
- if (nb->checked_for_resel) {
- LOGP(DCS, LOGL_INFO, "Skip cell: alredy tried to "
- "select.\n");
- goto cont;
- }
-
- /* check if we can use this cell */
- if (!nb->suitable_allowable) {
- LOGP(DCS, LOGL_INFO, "Skip cell: not suitable and/or "
- "allowable.\n");
- goto cont;
- }
-
- /* check if cell is "better" */
- if (nb->prio_low) {
- if (nb->c2 - nb->crh > best_low) {
- best_low = nb->c2 - nb->crh;
- best_nb_low = nb;
- }
- } else {
- if (nb->c2 - nb->crh > best_normal) {
- best_normal = nb->c2 - nb->crh;
- best_nb_normal = nb;
- }
- }
-
-cont:
- if (++i == GSM58_NB_NUMBER)
- break;
- }
-
- nb = NULL;
- if (best_nb_normal) {
- nb = best_nb_normal;
- LOGP(DCS, LOGL_INFO, "Best neighbour cell with ARFCN %s "
- "selected. (normal priority)\n",
- gsm_print_arfcn(nb->arfcn));
- }
- if (best_nb_low) {
- nb = best_nb_low;
- LOGP(DCS, LOGL_INFO, "Best neighbour cell with ARFCN %s "
- "selected. (low priority)\n",
- gsm_print_arfcn(nb->arfcn));
- }
- if (!nb) {
- struct msgb *nmsg;
-
- LOGP(DCS, LOGL_INFO, "No (more) acceptable neighbour cell "
- "available\n");
-
-no_cell_found:
- /* Tell cell selection process to handle "no cell found". */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_NO_CELL_FOUND);
- if (!nmsg)
- return -ENOMEM;
- gsm322_cs_sendmsg(ms, nmsg);
-
- return 0;
- }
- nb->checked_for_resel = 1;
-
- /* NOTE: We might already have system information from previous
- * scan. But we need recent informations, so we scan again!
- */
-
- /* Tune to frequency for a while, to receive broadcasts. */
- cs->arfcn = nb->arfcn;
- cs->arfci = arfcn2index(cs->arfcn);
- LOGP(DCS, LOGL_DEBUG, "Scanning ARFCN %s of neighbour "
- "cell during cell reselection.\n", gsm_print_arfcn(cs->arfcn));
- /* Allocate/clean system information. */
- cs->list[cs->arfci].flags &= ~GSM322_CS_FLAG_SYSINFO;
- if (cs->list[cs->arfci].sysinfo)
- memset(cs->list[cs->arfci].sysinfo, 0,
- sizeof(struct gsm48_sysinfo));
- else
- cs->list[cs->arfci].sysinfo = talloc_zero(l23_ctx,
- struct gsm48_sysinfo);
- if (!cs->list[cs->arfci].sysinfo)
- exit(-ENOMEM);
- cs->si = cs->list[cs->arfci].sysinfo;
- cs->sync_retries = SYNC_RETRIES;
- return gsm322_sync_to_cell(cs, NULL, 0);
-}
-
-/* start/modify measurement process with the current list of neighbour cells.
- * only do that if: 1. we are camping 2. we are on serving cell */
-static int gsm322_nb_start(struct osmocom_ms *ms, int synced)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = &cs->sel_si;
- struct gsm322_neighbour *nb, *nb2;
- int i, num;
- uint8_t map[128];
- uint16_t nc[32];
- uint8_t changed = 0;
- int refer_pcs, index;
- uint16_t arfcn;
-
- if (cs->ms->settings.no_neighbour)
- return 0;
-
- if (synced)
- cs->nb_meas_set = 0;
-
- refer_pcs = gsm_refer_pcs(cs->sel_arfcn, s);
-
- /* remove all neighbours that are not in list anymore */
- memset(map, 0, sizeof(map));
- llist_for_each_entry_safe(nb, nb2, &cs->nb_list, entry) {
- i = nb->arfcn & 1023;
- map[i >> 3] |= (1 << (i & 7));
-#ifndef TEST_INCLUDE_SERV
- if (!(s->freq[i].mask & FREQ_TYPE_NCELL)) {
-#else
- if (!(s->freq[i].mask & (FREQ_TYPE_NCELL | FREQ_TYPE_SERV))) {
-#endif
- LOGP(DNB, LOGL_INFO, "Removing neighbour cell %s from "
- "list.\n", gsm_print_arfcn(nb->arfcn));
- gsm322_nb_free(nb);
- changed = 1;
- continue;
- }
-#ifndef TEST_INCLUDE_SERV
- if (nb->arfcn == cs->sel_arfcn) {
- LOGP(DNB, LOGL_INFO, "Removing serving cell %s (former "
- "neighbour cell).\n",
- gsm_print_arfcn(nb->arfcn));
- gsm322_nb_free(nb);
- changed = 1;
- continue;
- }
-#endif
- }
-
- /* add missing entries to list */
- for (i = 0; i <= 1023; i++) {
-#ifndef TEST_INCLUDE_SERV
- if ((s->freq[i].mask & FREQ_TYPE_NCELL) &&
- !(map[i >> 3] & (1 << (i & 7)))) {
-#else
- if ((s->freq[i].mask & (FREQ_TYPE_NCELL | FREQ_TYPE_SERV)) &&
- !(map[i >> 3] & (1 << (i & 7)))) {
-#endif
- index = i;
- if (refer_pcs && i >= 512 && i <= 810)
- index = i-512+1024;
- arfcn = index2arfcn(index);
-#ifndef TEST_INCLUDE_SERV
- if (arfcn == cs->sel_arfcn) {
- LOGP(DNB, LOGL_INFO, "Omitting serving cell %s."
- "\n", gsm_print_arfcn(cs->arfcn));
- continue;
- }
-#endif
- nb = gsm322_nb_alloc(cs, arfcn);
- LOGP(DNB, LOGL_INFO, "Adding neighbour cell %s to "
- "list.\n", gsm_print_arfcn(nb->arfcn));
- if (!(cs->list[index].flags & GSM322_CS_FLAG_SUPPORT))
- nb->state = GSM322_NB_NOT_SUP;
- changed = 1;
- }
- }
-
- /* if nothing has changed, we are done */
- if (!changed && cs->nb_meas_set)
- return 0;
-
- /* start neigbour cell measurement task */
- num = 0;
- llist_for_each_entry(nb, &cs->nb_list, entry) {
- if (nb->state == GSM322_NB_NOT_SUP)
- continue;
- /* it should not happen that there are more than 32 nb-cells */
- if (num == 32)
- break;
- nc[num] = nb->arfcn;
- num++;
- }
- LOGP(DNB, LOGL_INFO, "Sending list of neighbour cells to layer1.\n");
- l1ctl_tx_neigh_pm_req(ms, num, nc);
- cs->nb_meas_set = 1;
-
- return 1;
-}
-
-
-/* a complete set of measurements are received, calculate the RLA_C, sort */
-static int gsm322_nb_trigger_event(struct gsm322_cellsel *cs)
-{
- struct osmocom_ms *ms = cs->ms;
- struct gsm322_neighbour *nb, *nb_sync = NULL, *nb_again = NULL;
- int i = 0;
- time_t now;
-
- time(&now);
-
- /* check the list for reading neighbour cell's BCCH */
- llist_for_each_entry(nb, &cs->nb_list, entry) {
- if (nb->rla_c_dbm >= cs->ms->settings.min_rxlev_db) {
- /* select the strongest unsynced cell */
- if (nb->state == GSM322_NB_RLA_C) {
- nb_sync = nb;
- break;
- }
-#if 0
-if (nb->state == GSM322_NB_SYSINFO) {
-printf("%d time to sync again: %u\n", nb->arfcn, now + GSM58_READ_AGAIN - nb->when);
-}
-#endif
- /* select the strongest cell to be read/try again */
- if (!nb_again) {
- if ((nb->state == GSM322_NB_NO_SYNC
- || nb->state == GSM322_NB_NO_BCCH)
- && nb->when + GSM58_TRY_AGAIN <= now)
- nb_again = nb;
- else
- if (nb->state == GSM322_NB_SYSINFO
- && nb->when + GSM58_READ_AGAIN <= now)
- nb_again = nb;
- }
- }
- if (++i == GSM58_NB_NUMBER)
- break;
- }
-
- /* trigger sync to neighbour cell, priorize the untested cell */
- if (nb_sync || nb_again) {
- if (nb_sync) {
- nb = nb_sync;
- cs->arfcn = nb->arfcn;
- cs->arfci = arfcn2index(cs->arfcn);
- LOGP(DNB, LOGL_INFO, "Syncing to new neighbour cell "
- "%s.\n", gsm_print_arfcn(cs->arfcn));
- } else {
- nb = nb_again;
- cs->arfcn = nb->arfcn;
- cs->arfci = arfcn2index(cs->arfcn);
- LOGP(DNB, LOGL_INFO, "Syncing again to neighbour cell "
- "%s after timerout.\n",
- gsm_print_arfcn(cs->arfcn));
- }
- /* Allocate/clean system information. */
- cs->list[cs->arfci].flags &= ~GSM322_CS_FLAG_SYSINFO;
- if (cs->list[cs->arfci].sysinfo)
- memset(cs->list[cs->arfci].sysinfo, 0,
- sizeof(struct gsm48_sysinfo));
- else
- cs->list[cs->arfci].sysinfo = talloc_zero(l23_ctx,
- struct gsm48_sysinfo);
- if (!cs->list[cs->arfci].sysinfo)
- exit(-ENOMEM);
- cs->si = cs->list[cs->arfci].sysinfo;
- cs->sync_retries = SYNC_RETRIES;
- return gsm322_sync_to_cell(cs, nb, 0);
- }
-
- if (gsm322_nb_check(ms, (cs->state == GSM322_C7_CAMPED_ANY_CELL)) > 0) {
- struct msgb *nmsg;
-
- LOGP(DNB, LOGL_INFO, "Better neighbour cell triggers cell "
- "reselection.\n");
-
- if (ms->rrlayer.monitor)
- vty_notify(ms, "MON: trigger cell re-selection: "
- "better cell\n");
-
- cs->resel_when = now;
-
- /* unset selected cell */
- gsm322_unselect_cell(cs);
-
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_CELL_RESEL);
- if (!nmsg)
- return -ENOMEM;
- gsm322_c_event(ms, nmsg);
- msgb_free(nmsg);
- return 0;
- }
-
- if (cs->neighbour) {
- cs->arfcn = cs->sel_arfcn;
- cs->arfci = arfcn2index(cs->arfcn);
- cs->si = cs->list[cs->arfci].sysinfo;
- if (!cs->si) {
- printf("No SI after neighbour scan, please fix!\n");
- exit(0L);
- }
- LOGP(DNB, LOGL_INFO, "Syncing back to serving cell\n");
- cs->sync_retries = SYNC_RETRIES_SERVING;
- return gsm322_sync_to_cell(cs, NULL, 0);
- }
-
- /* do nothing */
- return 0;
-}
-
-
-/* we (successfully) synced to a neighbour */
-static int gsm322_nb_synced(struct gsm322_cellsel *cs, int yes)
-{
- time_t now;
-
- LOGP(DNB, LOGL_INFO, "%s to neighbour cell %d.\n",
- (yes) ? "Synced" : "Failed to sync", cs->arfcn);
-
- if (yes) {
- start_cs_timer(cs, GSM322_NB_TIMEOUT, 0);
- return 0;
- }
-
- cs->neighbour->state = GSM322_NB_NO_SYNC;
- time(&now);
- cs->neighbour->when = now;
-
- return gsm322_nb_trigger_event(cs);
-}
-
-/* we (successfully) read the neighbour */
-static int gsm322_nb_read(struct gsm322_cellsel *cs, int yes)
-{
- time_t now;
-
- LOGP(DNB, LOGL_INFO, "%s from neighbour cell %d (rxlev %s).\n",
- (yes) ? "Read" : "Failed to read",
- cs->arfcn, gsm_print_rxlev(cs->list[cs->arfci].rxlev));
-
- cs->neighbour->state = (yes) ? GSM322_NB_SYSINFO : GSM322_NB_NO_BCCH;
- time(&now);
- cs->neighbour->when = now;
-
- return gsm322_nb_trigger_event(cs);
-}
-
-/* a complete set of measurements are received, calculate the RLA_C, sort */
-static int gsm322_nb_new_rxlev(struct gsm322_cellsel *cs)
-{
- struct gsm322_neighbour *nb, *strongest_nb;
- int i = 0;
- int8_t strongest;
- struct llist_head sorted;
- struct llist_head *lh, *lh2;
- struct gsm48_sysinfo *s = &cs->sel_si;
- int band = gsm_arfcn2band(cs->arfcn);
- int class = class_of_band(cs->ms, band);
-
-
- /* calculate the RAL_C of serving cell */
- if (cs->rxlev_count) {
- cs->rla_c_dbm = (cs->rxlev_dbm + (cs->rxlev_count / 2))
- / cs->rxlev_count;
- cs->rxlev_dbm = 0;
- cs->rxlev_count = 0;
- }
-
- LOGP(DNB, LOGL_INFO, "RLA_C of serving cell: %d\n", cs->rla_c_dbm);
-
- /* calculate C1 criterion, SI 3 carries complete neighbour cell info */
- cs->prio_low = 0;
- if (s && (s->si3 || s->si4)) {
- cs->c1 = calculate_c1(DNB, cs->rla_c_dbm, s->rxlev_acc_min_db,
- ms_pwr_dbm(band, s->ms_txpwr_max_cch),
- ms_class_gmsk_dbm(band, class));
- cs->c2 = calculate_c2(cs->c1, 1, 0, s->sp, s->sp_cro, 0, s->sp_pt, s->sp_to);
- cs->c12_valid = 1;
-
- if (s->sp && s->sp_cbq)
- cs->prio_low = 1;
- }
-
- /* calculate the RAL_C of neighbours */
- llist_for_each_entry(nb, &cs->nb_list, entry) {
- if (nb->state == GSM322_NB_NOT_SUP)
- continue;
- /* if sysinfo is gone due to scanning, mark neighbour as
- * unscanned. */
- if (nb->state == GSM322_NB_SYSINFO) {
- if (!cs->list[arfcn2index(nb->arfcn)].sysinfo) {
- nb->state = GSM322_NB_NO_BCCH;
- nb->when = 0;
- }
- }
- nb->rla_c_dbm =
- (nb->rxlev_dbm + (nb->rxlev_count / 2))
- / nb->rxlev_count;
- nb->rxlev_count = 0;
- nb->rxlev_dbm = 0;
- if (nb->state == GSM322_NB_NEW)
- nb->state = GSM322_NB_RLA_C;
- }
-
- /* sort the 6 strongest */
- INIT_LLIST_HEAD(&sorted);
-
- /* detach up to 6 of the strongest neighbour cells from list and put
- * them in the "sorted" list */
- while (!llist_empty(&cs->nb_list)) {
- strongest = -128;
- strongest_nb = NULL;
- llist_for_each_entry(nb, &cs->nb_list, entry) {
- if (nb->state == GSM322_NB_NOT_SUP)
- continue;
- if (nb->rla_c_dbm > strongest) {
- strongest = nb->rla_c_dbm;
- strongest_nb = nb;
- }
- }
- if (strongest_nb == NULL) /* this should not happen */
- break;
- LOGP(DNB, LOGL_INFO, "#%d ARFCN=%d RLA_C=%d\n",
- i+1, strongest_nb->arfcn, strongest_nb->rla_c_dbm);
- llist_del(&strongest_nb->entry);
- llist_add(&strongest_nb->entry, &sorted);
- if (++i == GSM58_NB_NUMBER)
- break;
- }
-
- /* take the sorted list and attat it to the head of the neighbour cell
- * list */
- llist_for_each_safe(lh, lh2, &sorted) {
- llist_del(lh);
- llist_add(lh, &cs->nb_list);
- }
-
- return gsm322_nb_trigger_event(cs);
-}
-
-/* accumulate the measurement results and check if there is a complete set for
- * all neighbour cells received. */
-static int gsm322_nb_meas_ind(struct osmocom_ms *ms, uint16_t arfcn,
- uint8_t rx_lev)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm322_neighbour *nb;
- int enough_results = 1, result = 0;
-
- llist_for_each_entry(nb, &cs->nb_list, entry) {
- if (nb->state == GSM322_NB_NOT_SUP)
- continue;
- if (arfcn != nb->arfcn) {
- if (nb->rxlev_count < RLA_C_NUM)
- enough_results = 0;
- continue;
- }
- nb->rxlev_dbm += rx_lev - 110;
- nb->rxlev_count++;
- LOGP(DNB, LOGL_INFO, "Measurement result for ARFCN %s: %d\n",
- gsm_print_arfcn(arfcn), rx_lev - 110);
-
- if (nb->rxlev_count < RLA_C_NUM)
- enough_results = 0;
-
- result = 1;
- }
-
- if (!result)
- LOGP(DNB, LOGL_INFO, "Measurement result for ARFCN %s not "
- "requested. (not a bug)\n", gsm_print_arfcn(arfcn));
-
- if (enough_results)
- return gsm322_nb_new_rxlev(cs);
-
- return 0;
-}
-
-int gsm322_meas(struct osmocom_ms *ms, uint8_t rx_lev)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
-
- if (cs->neighbour)
- return -EINVAL;
-
- cs->rxlev_dbm += rx_lev - 110;
- cs->rxlev_count++;
-
- return 0;
-}
-
-/*
- * dump lists
- */
-
-int gsm322_dump_sorted_plmn(struct osmocom_ms *ms)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct gsm322_plmn_list *temp;
-
- LOGP(DPLMN, LOGL_INFO, "MCC |MNC |allowed|rx-lev\n");
- LOGP(DPLMN, LOGL_INFO, "-------+-------+-------+-------\n");
- llist_for_each_entry(temp, &plmn->sorted_plmn, entry) {
- LOGP(DPLMN, LOGL_INFO, "%s |%s%s |%s |%s\n",
- gsm_print_mcc(temp->mcc), gsm_print_mnc(temp->mnc),
- ((temp->mnc & 0x00f) == 0x00f) ? " ":"",
- (temp->cause) ? "no ":"yes",
- gsm_print_rxlev(temp->rxlev));
- }
-
- return 0;
-}
-
-int gsm322_dump_cs_list(struct gsm322_cellsel *cs, uint8_t flags,
- void (*print)(void *, const char *, ...), void *priv)
-{
- int i;
- struct gsm48_sysinfo *s;
-
- print(priv, "ARFCN |MCC |MNC |LAC |cell ID|forb.LA|prio |"
- "min-db |max-pwr|rx-lev\n");
- print(priv, "-------+-------+-------+-------+-------+-------+-------+"
- "-------+-------+-------\n");
- for (i = 0; i <= 1023+299; i++) {
- s = cs->list[i].sysinfo;
- if (!s || !(cs->list[i].flags & flags))
- continue;
- if (i >= 1024)
- print(priv, "%4dPCS|", i-1024+512);
- else if (i >= 512 && i <= 885)
- print(priv, "%4dDCS|", i);
- else
- print(priv, "%4d |", i);
- if (s->mcc) {
- print(priv, "%s |%s%s |", gsm_print_mcc(s->mcc),
- gsm_print_mnc(s->mnc),
- ((s->mnc & 0x00f) == 0x00f) ? " ":"");
- print(priv, "0x%04x |0x%04x |", s->lac, s->cell_id);
- } else
- print(priv, "n/a |n/a |n/a |n/a |");
- if ((cs->list[i].flags & GSM322_CS_FLAG_SYSINFO)) {
- if ((cs->list[i].flags & GSM322_CS_FLAG_FORBIDD))
- print(priv, "yes |");
- else
- print(priv, "no |");
- if ((cs->list[i].flags & GSM322_CS_FLAG_BARRED))
- print(priv, "barred |");
- else {
- if (cs->list[i].sysinfo->cell_barr)
- print(priv, "low |");
- else
- print(priv, "normal |");
- }
- } else
- print(priv, "n/a |n/a |");
- if (s->si3 || s->si4)
- print(priv, "%4d |%4d |%s\n", s->rxlev_acc_min_db,
- s->ms_txpwr_max_cch,
- gsm_print_rxlev(cs->list[i].rxlev));
- else
- print(priv, "n/a |n/a |n/a\n");
- }
- print(priv, "\n");
-
- return 0;
-}
-
-int gsm322_dump_forbidden_la(struct osmocom_ms *ms,
- void (*print)(void *, const char *, ...), void *priv)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct gsm322_la_list *temp;
-
- print(priv, "MCC |MNC |LAC |cause\n");
- print(priv, "-------+-------+-------+-------\n");
- llist_for_each_entry(temp, &plmn->forbidden_la, entry)
- print(priv, "%s |%s%s |0x%04x |#%d\n",
- gsm_print_mcc(temp->mcc), gsm_print_mnc(temp->mnc),
- ((temp->mnc & 0x00f) == 0x00f) ? " ":"",
- temp->lac, temp->cause);
-
- return 0;
-}
-
-int gsm322_dump_ba_list(struct gsm322_cellsel *cs, uint16_t mcc, uint16_t mnc,
- void (*print)(void *, const char *, ...), void *priv)
-{
- struct gsm322_ba_list *ba;
- int i;
-
- llist_for_each_entry(ba, &cs->ba_list, entry) {
- if (mcc && mnc && (mcc != ba->mcc || mnc != ba->mnc))
- continue;
- print(priv, "Band Allocation of network: MCC %s MNC %s "
- "(%s, %s)\n", gsm_print_mcc(ba->mcc),
- gsm_print_mnc(ba->mnc), gsm_get_mcc(ba->mcc),
- gsm_get_mnc(ba->mcc, ba->mnc));
- for (i = 0; i <= 1023+299; i++) {
- if ((ba->freq[i >> 3] & (1 << (i & 7))))
- print(priv, " %s",
- gsm_print_arfcn(index2arfcn(i)));
- }
- print(priv, "\n");
- }
-
- return 0;
-}
-
-int gsm322_dump_nb_list(struct gsm322_cellsel *cs,
- void (*print)(void *, const char *, ...), void *priv)
-{
- struct gsm48_sysinfo *s;
- struct gsm322_neighbour *nb;
- int i = 0;
-
- if (!cs->selected) {
- print(priv, "No serving cell selected (yet).\n");
- return 0;
- }
- print(priv, "Serving cell:\n\n");
- print(priv, "ARFCN=%s ", gsm_print_arfcn(cs->sel_arfcn));
- print(priv, "RLA_C=%s ", gsm_print_rxlev(cs->rla_c_dbm + 110));
- if (cs->c12_valid)
- print(priv, "C1=%d C2=%d ", cs->c1, cs->c1);
- else
- print(priv, "C1 - C2 - ");
- print(priv, "LAC=0x%04x\n\n", (cs->selected) ? cs->sel_si.lac : 0);
-
- print(priv, "Neighbour cells:\n\n");
- llist_for_each_entry(nb, &cs->nb_list, entry) {
- if (i == 0) {
- print(priv, "# |ARFCN |RLA_C |C1 |C2 |"
- "CRH |prio |LAC |cell ID|usable |"
- "state\n");
- print(priv, "----------------------------------------"
- "----------------------------------------"
- "-------\n");
- } else
- if (i == GSM58_NB_NUMBER)
- print(priv, "--- unmonitored cells: ---\n");
- i++;
- if (cs->last_serving_valid
- && cs->last_serving_arfcn == nb->arfcn)
- print(priv, "%2d last|", i);
- else
- print(priv, "%2d |", i);
- if ((nb->arfcn & ARFCN_PCS))
- print(priv, "%4dPCS|", nb->arfcn & 1023);
- else if (i >= 512 && i <= 885)
- print(priv, "%4dDCS|", nb->arfcn & 1023);
- else
- print(priv, "%4d |", nb->arfcn);
- if (nb->state == GSM322_NB_NOT_SUP) {
- print(priv, " ARFCN not supported\n");
- continue;
- }
- if (nb->rla_c_dbm > -128)
- print(priv, "%6s |",
- gsm_print_rxlev(nb->rla_c_dbm + 110));
- else
- print(priv, "- |");
- if (nb->state == GSM322_NB_SYSINFO && nb->c12_valid)
- print(priv, "%4d |%4d |%4d |", nb->c1, nb->c1,
- nb->crh);
- else
- print(priv, "- |- |- |");
- s = cs->list[arfcn2index(nb->arfcn)].sysinfo;
- if (nb->state == GSM322_NB_SYSINFO && s) {
- print(priv, "%s |0x%04x |0x%04x |",
- (nb->prio_low) ? "low ":"normal", s->lac,
- s->cell_id);
- } else
- print(priv, "- |- |- |");
-
- print(priv, "%s |",
- (nb->suitable_allowable) ? "yes" : "no ");
- print(priv, "%s\n", get_nb_state_name(nb->state));
- }
-
- if (i == 0)
- print(priv, "No neighbour cells available (yet).\n");
-
- return 0;
-}
-
-/*
- * initialization
- */
-
-int gsm322_init(struct osmocom_ms *ms)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct gsm322_cellsel *cs = &ms->cellsel;
- FILE *fp;
- char filename[PATH_MAX];
- int i;
- struct gsm322_ba_list *ba;
- uint8_t buf[4];
- char version[32];
-
- LOGP(DPLMN, LOGL_INFO, "init PLMN process\n");
- LOGP(DCS, LOGL_INFO, "init Cell Selection process\n");
-
- memset(plmn, 0, sizeof(*plmn));
- memset(cs, 0, sizeof(*cs));
- plmn->ms = ms;
- cs->ms = ms;
-
- /* set initial state */
- plmn->state = 0;
- cs->state = 0;
-
- /* init lists */
- INIT_LLIST_HEAD(&plmn->event_queue);
- INIT_LLIST_HEAD(&cs->event_queue);
- INIT_LLIST_HEAD(&plmn->sorted_plmn);
- INIT_LLIST_HEAD(&plmn->forbidden_la);
- INIT_LLIST_HEAD(&cs->ba_list);
- INIT_LLIST_HEAD(&cs->nb_list);
-
- /* set supported frequencies in cell selection list */
- for (i = 0; i <= 1023+299; i++)
- if ((ms->settings.freq_map[i >> 3] & (1 << (i & 7))))
- cs->list[i].flags |= GSM322_CS_FLAG_SUPPORT;
-
- /* read BA list */
- sprintf(filename, "%s/%s.ba", config_dir, ms->name);
- fp = fopen(filename, "r");
- if (fp) {
- int rc;
- char *s_rc;
-
- s_rc = fgets(version, sizeof(version), fp);
- version[sizeof(version) - 1] = '\0';
- if (!s_rc || !!strcmp(ba_version, version)) {
- LOGP(DCS, LOGL_NOTICE, "BA version missmatch, "
- "stored BA list becomes obsolete.\n");
- } else
- while(!feof(fp)) {
- ba = talloc_zero(l23_ctx, struct gsm322_ba_list);
- if (!ba)
- return -ENOMEM;
- rc = fread(buf, 4, 1, fp);
- if (!rc) {
- talloc_free(ba);
- break;
- }
- ba->mcc = (buf[0] << 8) | buf[1];
- ba->mnc = (buf[2] << 8) | buf[3];
- rc = fread(ba->freq, sizeof(ba->freq), 1, fp);
- if (!rc) {
- talloc_free(ba);
- break;
- }
- llist_add_tail(&ba->entry, &cs->ba_list);
- LOGP(DCS, LOGL_INFO, "Read stored BA list (mcc=%s "
- "mnc=%s %s, %s)\n", gsm_print_mcc(ba->mcc),
- gsm_print_mnc(ba->mnc), gsm_get_mcc(ba->mcc),
- gsm_get_mnc(ba->mcc, ba->mnc));
- }
- fclose(fp);
- } else
- LOGP(DCS, LOGL_INFO, "No stored BA list\n");
-
- return 0;
-}
-
-int gsm322_exit(struct osmocom_ms *ms)
-{
- struct gsm322_plmn *plmn = &ms->plmn;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct llist_head *lh, *lh2;
- struct msgb *msg;
- FILE *fp;
- char filename[PATH_MAX];
- struct gsm322_ba_list *ba;
- uint8_t buf[4];
- int i;
-
- LOGP(DPLMN, LOGL_INFO, "exit PLMN process\n");
- LOGP(DCS, LOGL_INFO, "exit Cell Selection process\n");
-
- /* stop cell selection process (if any) */
- new_c_state(cs, GSM322_C0_NULL);
-
- /* stop timers */
- stop_cs_timer(cs);
- stop_any_timer(cs);
- stop_plmn_timer(plmn);
-
- /* flush sysinfo */
- for (i = 0; i <= 1023+299; i++) {
- if (cs->list[i].sysinfo) {
- LOGP(DCS, LOGL_DEBUG, "free sysinfo ARFCN=%s\n",
- gsm_print_arfcn(index2arfcn(i)));
- talloc_free(cs->list[i].sysinfo);
- cs->list[i].sysinfo = NULL;
- }
- cs->list[i].flags = 0;
- }
-
- /* store BA list */
- sprintf(filename, "%s/%s.ba", config_dir, ms->name);
- fp = fopen(filename, "w");
- if (fp) {
- int rc;
-
- fputs(ba_version, fp);
- llist_for_each_entry(ba, &cs->ba_list, entry) {
- buf[0] = ba->mcc >> 8;
- buf[1] = ba->mcc & 0xff;
- buf[2] = ba->mnc >> 8;
- buf[3] = ba->mnc & 0xff;
- rc = fwrite(buf, 4, 1, fp);
- rc = fwrite(ba->freq, sizeof(ba->freq), 1, fp);
- LOGP(DCS, LOGL_INFO, "Write stored BA list (mcc=%s "
- "mnc=%s %s, %s)\n", gsm_print_mcc(ba->mcc),
- gsm_print_mnc(ba->mnc), gsm_get_mcc(ba->mcc),
- gsm_get_mnc(ba->mcc, ba->mnc));
- }
- fclose(fp);
- } else
- LOGP(DCS, LOGL_ERROR, "Failed to write BA list\n");
-
- /* free lists */
- while ((msg = msgb_dequeue(&plmn->event_queue)))
- msgb_free(msg);
- while ((msg = msgb_dequeue(&cs->event_queue)))
- msgb_free(msg);
- llist_for_each_safe(lh, lh2, &plmn->sorted_plmn) {
- llist_del(lh);
- talloc_free(lh);
- }
- llist_for_each_safe(lh, lh2, &plmn->forbidden_la) {
- llist_del(lh);
- talloc_free(lh);
- }
- llist_for_each_safe(lh, lh2, &cs->ba_list) {
- llist_del(lh);
- talloc_free(lh);
- }
- llist_for_each_safe(lh, lh2, &cs->nb_list)
- gsm322_nb_free(container_of(lh, struct gsm322_neighbour,
- entry));
- return 0;
-}
diff --git a/Src/osmoconbb/src/host/layer23/src/mobile/gsm48_cc.c b/Src/osmoconbb/src/host/layer23/src/mobile/gsm48_cc.c
deleted file mode 100644
index 07ee2d9..0000000
--- a/Src/osmoconbb/src/host/layer23/src/mobile/gsm48_cc.c
+++ /dev/null
@@ -1,2181 +0,0 @@
-/*
- * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdint.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/gsm/gsm48.h>
-#include <osmocom/core/talloc.h>
-
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/mobile/mncc.h>
-#include <osmocom/bb/mobile/transaction.h>
-#include <osmocom/bb/mobile/gsm48_cc.h>
-#include <osmocom/bb/mobile/voice.h>
-#include <l1ctl_proto.h>
-
-extern void *l23_ctx;
-
-static int gsm48_cc_tx_release(struct gsm_trans *trans, void *arg);
-static int gsm48_rel_null_free(struct gsm_trans *trans);
-int mncc_release_ind(struct osmocom_ms *ms, struct gsm_trans *trans,
- u_int32_t callref, int location, int value);
-static int gsm48_cc_tx_disconnect(struct gsm_trans *trans, void *arg);
-static int gsm48_cc_tx_connect_ack(struct gsm_trans *trans, void *arg);
-
-/*
- * init
- */
-
-int gsm48_cc_init(struct osmocom_ms *ms)
-{
- struct gsm48_cclayer *cc = &ms->cclayer;
-
- cc->ms = ms;
-
- if (!cc->mncc_upqueue.next == 0)
- return 0;
-
- LOGP(DCC, LOGL_INFO, "init Call Control\n");
-
- INIT_LLIST_HEAD(&cc->mncc_upqueue);
-
- return 0;
-}
-
-int gsm48_cc_exit(struct osmocom_ms *ms)
-{
- struct gsm48_cclayer *cc = &ms->cclayer;
- struct gsm_trans *trans, *trans2;
- struct msgb *msg;
-
- LOGP(DCC, LOGL_INFO, "exit Call Control processes for %s\n", ms->name);
-
- llist_for_each_entry_safe(trans, trans2, &ms->trans_list, entry) {
- if (trans->protocol == GSM48_PDISC_CC)
- LOGP(DCC, LOGL_NOTICE, "Free pendig CC-transaction.\n");
- trans_free(trans);
- }
-
- while ((msg = msgb_dequeue(&cc->mncc_upqueue)))
- msgb_free(msg);
-
- return 0;
-}
-
-/*
- * messages
- */
-
-/* names of MNCC-SAP */
-static const struct value_string gsm_mncc_names[] = {
- { MNCC_SETUP_REQ, "MNCC_SETUP_REQ" },
- { MNCC_SETUP_IND, "MNCC_SETUP_IND" },
- { MNCC_SETUP_RSP, "MNCC_SETUP_RSP" },
- { MNCC_SETUP_CNF, "MNCC_SETUP_CNF" },
- { MNCC_SETUP_COMPL_REQ, "MNCC_SETUP_COMPL_REQ" },
- { MNCC_SETUP_COMPL_IND, "MNCC_SETUP_COMPL_IND" },
- { MNCC_CALL_CONF_IND, "MNCC_CALL_CONF_IND" },
- { MNCC_CALL_PROC_REQ, "MNCC_CALL_PROC_REQ" },
- { MNCC_PROGRESS_REQ, "MNCC_PROGRESS_REQ" },
- { MNCC_ALERT_REQ, "MNCC_ALERT_REQ" },
- { MNCC_ALERT_IND, "MNCC_ALERT_IND" },
- { MNCC_NOTIFY_REQ, "MNCC_NOTIFY_REQ" },
- { MNCC_NOTIFY_IND, "MNCC_NOTIFY_IND" },
- { MNCC_DISC_REQ, "MNCC_DISC_REQ" },
- { MNCC_DISC_IND, "MNCC_DISC_IND" },
- { MNCC_REL_REQ, "MNCC_REL_REQ" },
- { MNCC_REL_IND, "MNCC_REL_IND" },
- { MNCC_REL_CNF, "MNCC_REL_CNF" },
- { MNCC_FACILITY_REQ, "MNCC_FACILITY_REQ" },
- { MNCC_FACILITY_IND, "MNCC_FACILITY_IND" },
- { MNCC_START_DTMF_IND, "MNCC_START_DTMF_IND" },
- { MNCC_START_DTMF_RSP, "MNCC_START_DTMF_RSP" },
- { MNCC_START_DTMF_REJ, "MNCC_START_DTMF_REJ" },
- { MNCC_STOP_DTMF_IND, "MNCC_STOP_DTMF_IND" },
- { MNCC_STOP_DTMF_RSP, "MNCC_STOP_DTMF_RSP" },
- { MNCC_MODIFY_REQ, "MNCC_MODIFY_REQ" },
- { MNCC_MODIFY_IND, "MNCC_MODIFY_IND" },
- { MNCC_MODIFY_RSP, "MNCC_MODIFY_RSP" },
- { MNCC_MODIFY_CNF, "MNCC_MODIFY_CNF" },
- { MNCC_MODIFY_REJ, "MNCC_MODIFY_REJ" },
- { MNCC_HOLD_IND, "MNCC_HOLD_IND" },
- { MNCC_HOLD_CNF, "MNCC_HOLD_CNF" },
- { MNCC_HOLD_REJ, "MNCC_HOLD_REJ" },
- { MNCC_RETRIEVE_IND, "MNCC_RETRIEVE_IND" },
- { MNCC_RETRIEVE_CNF, "MNCC_RETRIEVE_CNF" },
- { MNCC_RETRIEVE_REJ, "MNCC_RETRIEVE_REJ" },
- { MNCC_USERINFO_REQ, "MNCC_USERINFO_REQ" },
- { MNCC_USERINFO_IND, "MNCC_USERINFO_IND" },
- { MNCC_REJ_REQ, "MNCC_REJ_REQ" },
- { MNCC_REJ_IND, "MNCC_REJ_IND" },
- { MNCC_PROGRESS_IND, "MNCC_PROGRESS_IND" },
- { MNCC_CALL_PROC_IND, "MNCC_CALL_PROC_IND" },
- { MNCC_CALL_CONF_REQ, "MNCC_CALL_CONF_REQ" },
- { MNCC_START_DTMF_REQ, "MNCC_START_DTMF_REQ" },
- { MNCC_STOP_DTMF_REQ, "MNCC_STOP_DTMF_REQ" },
- { MNCC_HOLD_REQ, "MNCC_HOLD_REQ " },
- { MNCC_RETRIEVE_REQ, "MNCC_RETRIEVE_REQ" },
- { MNCC_FRAME_RECV, "MNCC_FRAME_RECV" },
- { MNCC_FRAME_DROP, "MNCC_FRAME_DROP" },
- { MNCC_LCHAN_MODIFY, "MNCC_LCHAN_MODIFY" },
- { 0, NULL }
-};
-
-const char *get_mncc_name(int value)
-{
- return get_value_string(gsm_mncc_names, value);
-}
-
-/* push MMCC header and send to MM */
-static int gsm48_cc_to_mm(struct msgb *msg, struct gsm_trans *trans,
- int msg_type)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- struct gsm48_mmxx_hdr *mmh;
- int emergency = 0;
-
- /* Add protocol type and transaction ID */
- gh->proto_discr = trans->protocol | (trans->transaction_id << 4);
-
- /* indicate emergency setup to MM layer */
- if (gh->msg_type == GSM48_MT_CC_EMERG_SETUP)
- emergency = 1;
-
- /* push RR header */
- msgb_push(msg, sizeof(struct gsm48_mmxx_hdr));
- mmh = (struct gsm48_mmxx_hdr *)msg->data;
- mmh->msg_type = msg_type;
- mmh->ref = trans->callref;
- mmh->transaction_id = trans->transaction_id;
- mmh->emergency = emergency;
-
- /* send message to MM */
- LOGP(DCC, LOGL_INFO, "Sending '%s' using %s (callref=%x, "
- "transaction_id=%d)\n", gsm48_cc_msg_name(gh->msg_type),
- get_mmxx_name(msg_type), trans->callref, trans->transaction_id);
- return gsm48_mmxx_downmsg(trans->ms, msg);
-}
-
-/* enqueue message to application (MNCC-SAP) */
-static int mncc_recvmsg(struct osmocom_ms *ms, struct gsm_trans *trans,
- int msg_type, struct gsm_mncc *mncc)
-{
- struct gsm48_cclayer *cc = &ms->cclayer;
- struct msgb *msg;
-
- if (trans)
- LOGP(DCC, LOGL_INFO, "(ms %s ti %x) Sending '%s' to MNCC.\n",
- ms->name, trans->transaction_id,
- get_mncc_name(msg_type));
- else
- LOGP(DCC, LOGL_INFO, "(ms %s ti -) Sending '%s' to MNCC.\n",
- ms->name, get_mncc_name(msg_type));
-
- mncc->msg_type = msg_type;
-
- msg = msgb_alloc(sizeof(struct gsm_mncc), "MNCC");
- if (!msg)
- return -ENOMEM;
- memcpy(msg->data, mncc, sizeof(struct gsm_mncc));
- msgb_enqueue(&cc->mncc_upqueue, msg);
-
- return 0;
-}
-
-/* dequeue messages to layer 4 */
-int mncc_dequeue(struct osmocom_ms *ms)
-{
- struct gsm48_cclayer *cc = &ms->cclayer;
- struct gsm_mncc *mncc;
- struct msgb *msg;
- int work = 0;
-
- while ((msg = msgb_dequeue(&cc->mncc_upqueue))) {
- mncc = (struct gsm_mncc *)msg->data;
- if (ms->mncc_entity.mncc_recv)
- ms->mncc_entity.mncc_recv(ms, mncc->msg_type, mncc);
- work = 1; /* work done */
- msgb_free(msg);
- }
-
- return work;
-}
-
-
-/*
- * state transition
- */
-
-static void new_cc_state(struct gsm_trans *trans, int state)
-{
- if (state > 31 || state < 0)
- return;
-
- DEBUGP(DCC, "new state %s -> %s\n",
- gsm48_cc_state_name(trans->cc.state),
- gsm48_cc_state_name(state));
-
- trans->cc.state = state;
-}
-
-/*
- * timers
- */
-
-/* timeout events of all timers */
-static void gsm48_cc_timeout(void *arg)
-{
- struct gsm_trans *trans = arg;
- int disconnect = 0, release = 0, abort = 1;
- int mo_cause = GSM48_CC_CAUSE_RECOVERY_TIMER;
- int mo_location = GSM48_CAUSE_LOC_PRN_S_LU;
- int l4_cause = GSM48_CC_CAUSE_NORMAL_UNSPEC;
- int l4_location = GSM48_CAUSE_LOC_PRN_S_LU;
- struct gsm_mncc mo_rel, l4_rel;
-
- memset(&mo_rel, 0, sizeof(struct gsm_mncc));
- mo_rel.callref = trans->callref;
- memset(&l4_rel, 0, sizeof(struct gsm_mncc));
- l4_rel.callref = trans->callref;
-
- LOGP(DCC, LOGL_INFO, "Timer T%x has fired.\n", trans->cc.Tcurrent);
-
- switch(trans->cc.Tcurrent) {
- case 0x303:
- /* abort if connection is not already esablished */
- if (trans->cc.state == GSM_CSTATE_MM_CONNECTION_PEND)
- abort = 1;
- else
- release = 1;
- l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND;
- break;
- case 0x305:
- release = 1;
- mo_cause = trans->cc.msg.cause.value;
- mo_location = trans->cc.msg.cause.location;
- break;
- case 0x308:
- if (!trans->cc.T308_second) {
- /* restart T308 a second time */
- gsm48_cc_tx_release(trans, &trans->cc.msg);
- trans->cc.T308_second = 1;
- break; /* stay in release state */
- }
- /* release MM conn, got NULL state, free trans */
- gsm48_rel_null_free(trans);
-
- return;
- case 0x310:
- disconnect = 1;
- l4_cause = GSM48_CC_CAUSE_USER_NOTRESPOND;
- break;
- case 0x313:
- disconnect = 1;
- /* unknown, did not find it in the specs */
- break;
- default:
- release = 1;
- }
-
- if ((release || abort) && trans->callref) {
- /* process release towards layer 4 */
- mncc_release_ind(trans->ms, trans, trans->callref,
- l4_location, l4_cause);
- }
-
- if (disconnect && trans->callref) {
- /* process disconnect towards layer 4 */
- mncc_set_cause(&l4_rel, l4_location, l4_cause);
- mncc_recvmsg(trans->ms, trans, MNCC_DISC_IND, &l4_rel);
- }
-
- /* process disconnect towards mobile station */
- if (disconnect || release || abort) {
- mncc_set_cause(&mo_rel, mo_location, mo_cause);
- mo_rel.cause.diag[0] =
- ((trans->cc.Tcurrent & 0xf00) >> 8) + '0';
- mo_rel.cause.diag[1] =
- ((trans->cc.Tcurrent & 0x0f0) >> 4) + '0';
- mo_rel.cause.diag[2] = (trans->cc.Tcurrent & 0x00f) + '0';
- mo_rel.cause.diag_len = 3;
-
- if (disconnect)
- gsm48_cc_tx_disconnect(trans, &mo_rel);
- if (release)
- gsm48_cc_tx_release(trans, &mo_rel);
- if (abort) {
- /* release MM conn, got NULL state, free trans */
- gsm48_rel_null_free(trans);
- }
- }
-}
-
-/* start various timers */
-static void gsm48_start_cc_timer(struct gsm_trans *trans, int current,
- int sec, int micro)
-{
- LOGP(DCC, LOGL_INFO, "starting timer T%x with %d seconds\n", current,
- sec);
- trans->cc.timer.cb = gsm48_cc_timeout;
- trans->cc.timer.data = trans;
- osmo_timer_schedule(&trans->cc.timer, sec, micro);
- trans->cc.Tcurrent = current;
-}
-
-/* stop various timers */
-static void gsm48_stop_cc_timer(struct gsm_trans *trans)
-{
- if (osmo_timer_pending(&trans->cc.timer)) {
- LOGP(DCC, LOGL_INFO, "stopping pending timer T%x\n",
- trans->cc.Tcurrent);
- osmo_timer_del(&trans->cc.timer);
- trans->cc.Tcurrent = 0;
- }
-}
-
-/*
- * process handlers (misc)
- */
-
-/* Call Control Specific transaction release.
- * gets called by trans_free, DO NOT CALL YOURSELF!
- */
-void _gsm48_cc_trans_free(struct gsm_trans *trans)
-{
- gsm48_stop_cc_timer(trans);
-
- /* disable audio distribution */
- if (trans->ms->mncc_entity.ref == trans->callref)
- trans->ms->mncc_entity.ref = 0;
-
- /* send release to L4, if callref still exists */
- if (trans->callref) {
- /* Ressource unavailable */
- mncc_release_ind(trans->ms, trans, trans->callref,
- GSM48_CAUSE_LOC_PRN_S_LU,
- GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
- }
- if (trans->cc.state != GSM_CSTATE_NULL)
- new_cc_state(trans, GSM_CSTATE_NULL);
-}
-
-/* release MM connection, go NULL state, free transaction */
-static int gsm48_rel_null_free(struct gsm_trans *trans)
-{
- struct msgb *nmsg;
-
- /* release MM connection */
- nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_REL_REQ, trans->callref,
- trans->transaction_id);
- if (!nmsg)
- return -ENOMEM;
- LOGP(DCC, LOGL_INFO, "Sending MMCC_REL_REQ\n");
- gsm48_mmxx_downmsg(trans->ms, nmsg);
-
- new_cc_state(trans, GSM_CSTATE_NULL);
-
- trans->callref = 0;
- trans_free(trans);
-
- return 0;
-}
-
-void mncc_set_cause(struct gsm_mncc *data, int loc, int val)
-{
- data->fields |= MNCC_F_CAUSE;
- data->cause.coding = 0x3;
- data->cause.location = loc;
- data->cause.value = val;
-}
-
-/* send release indication to upper layer */
-int mncc_release_ind(struct osmocom_ms *ms, struct gsm_trans *trans,
- u_int32_t callref, int location, int value)
-{
- struct gsm_mncc rel;
-
- memset(&rel, 0, sizeof(rel));
- rel.callref = callref;
- mncc_set_cause(&rel, location, value);
- return mncc_recvmsg(ms, trans, MNCC_REL_IND, &rel);
-}
-
-/* sending status message in response to unknown message */
-static int gsm48_cc_tx_status(struct gsm_trans *trans, int cause)
-{
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
- uint8_t *cause_ie, *call_state_ie;
-
- LOGP(DCC, LOGL_INFO, "sending STATUS (cause %d)\n", cause);
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
-
- gh->msg_type = GSM48_MT_CC_STATUS;
-
- cause_ie = msgb_put(nmsg, 3);
- cause_ie[0] = 2;
- cause_ie[1] = GSM48_CAUSE_CS_GSM | GSM48_CAUSE_LOC_PRN_S_LU;
- cause_ie[2] = 0x80 | cause;
-
- call_state_ie = msgb_put(nmsg, 1);
- call_state_ie[0] = 0xc0 | trans->cc.state;
-
- return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
-}
-
-/* reply status enquiry */
-static int gsm48_cc_rx_status_enq(struct gsm_trans *trans, struct msgb *msg)
-{
- LOGP(DCC, LOGL_INFO, "received STATUS ENQUIREY\n");
-
- return gsm48_cc_tx_status(trans, GSM48_CC_CAUSE_RESP_STATUS_INQ);
-}
-
-static int gsm48_cc_rx_status(struct gsm_trans *trans, struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct gsm_mncc_cause cause;
-
- if (payload_len < 1 || payload_len < gh->data[0] + 1) {
- LOGP(DCC, LOGL_NOTICE, "Short read of status message "
- "error.\n");
- return -EINVAL;
- }
- gsm48_decode_cause(&cause, gh->data);
-
- LOGP(DCC, LOGL_INFO, "received STATUS (cause %d)\n", cause.value);
-
- return 0;
-}
-
-/*
- * process handlers (mobile originating call establish)
- */
-
-/* on SETUP request from L4, init MM connection */
-static int gsm48_cc_init_mm(struct gsm_trans *trans, void *arg)
-{
- struct msgb *nmsg;
- struct gsm_mncc *data = arg;
- struct gsm48_mmxx_hdr *nmmh;
-
- /* store setup message */
- memcpy(&trans->cc.msg, data, sizeof(struct gsm_mncc));
-
- new_cc_state(trans, GSM_CSTATE_MM_CONNECTION_PEND);
-
- /* establish MM connection */
- nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_EST_REQ, trans->callref,
- trans->transaction_id);
- if (!nmsg)
- return -ENOMEM;
- nmmh = (struct gsm48_mmxx_hdr *) nmsg->data;
- if (data->emergency)
- nmmh->emergency = 1;
- LOGP(DCC, LOGL_INFO, "Sending MMCC_EST_REQ\n");
- return gsm48_mmxx_downmsg(trans->ms, nmsg);
-}
-
-/* abort connection prior SETUP */
-static int gsm48_cc_abort_mm(struct gsm_trans *trans, void *arg)
-{
- struct msgb *nmsg;
-
- /* abort MM connection */
- nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_REL_REQ, trans->callref,
- trans->transaction_id);
- if (!nmsg)
- return -ENOMEM;
- LOGP(DCC, LOGL_INFO, "Sending MMCC_REL_REQ\n");
- gsm48_mmxx_downmsg(trans->ms, nmsg);
-
- new_cc_state(trans, GSM_CSTATE_NULL);
-
- trans->callref = 0;
- trans_free(trans);
-
- return 0;
-}
-
-/* setup message from upper layer */
-static int gsm48_cc_tx_setup(struct gsm_trans *trans)
-{
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
- struct gsm_mncc *setup = &trans->cc.msg;
- int rc, transaction_id;
- uint8_t *ie;
-
- LOGP(DCC, LOGL_INFO, "sending SETUP\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
-
- /* transaction id must not be assigned */
- if (trans->transaction_id != 0xff) { /* unasssigned */
- LOGP(DCC, LOGL_NOTICE, "TX Setup with assigned transaction. "
- "This is not allowed!\n");
- /* Temporarily out of order */
- rc = mncc_release_ind(trans->ms, trans, trans->callref,
- GSM48_CAUSE_LOC_PRN_S_LU,
- GSM48_CC_CAUSE_NORMAL_UNSPEC);
- trans->callref = 0;
- trans_free(trans);
- return rc;
- }
-
- /* Get free transaction_id */
- transaction_id = trans_assign_trans_id(trans->ms, GSM48_PDISC_CC, 0);
- if (transaction_id < 0) {
- /* no free transaction ID */
- rc = mncc_release_ind(trans->ms, trans, trans->callref,
- GSM48_CAUSE_LOC_PRN_S_LU,
- GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
- trans->callref = 0;
- trans_free(trans);
- return rc;
- }
- trans->transaction_id = transaction_id;
-
- gh->msg_type = (setup->emergency) ? GSM48_MT_CC_EMERG_SETUP :
- GSM48_MT_CC_SETUP;
-
- /* actually we have to start it when CM SERVICE REQUEST has been sent,
- * but there is no primitive for that defined. i think it is ok to
- * do it here rather than inventing MMCC-NOTIFY-IND.
- */
- gsm48_start_cc_timer(trans, 0x303, GSM48_T303_MS);
-
- /* bearer capability (optional for emergency calls only) */
- if (setup->fields & MNCC_F_BEARER_CAP)
- gsm48_encode_bearer_cap(nmsg, 0, &setup->bearer_cap);
- if (!setup->emergency) {
- /* facility */
- if (setup->fields & MNCC_F_FACILITY)
- gsm48_encode_facility(nmsg, 0, &setup->facility);
- /* called party BCD number */
- if (setup->fields & MNCC_F_CALLED)
- gsm48_encode_called(nmsg, &setup->called);
- /* user-user */
- if (setup->fields & MNCC_F_USERUSER)
- gsm48_encode_useruser(nmsg, 0, &setup->useruser);
- /* ss version */
- if (setup->fields & MNCC_F_SSVERSION)
- gsm48_encode_ssversion(nmsg, &setup->ssversion);
- /* CLIR suppression */
- if (setup->clir.sup) {
- ie = msgb_put(nmsg, 1);
- ie[0] = GSM48_IE_CLIR_SUPP;
- }
- /* CLIR invocation */
- if (setup->clir.inv) {
- ie = msgb_put(nmsg, 1);
- ie[0] = GSM48_IE_CLIR_INVOC;
- }
- /* cc cap */
- if (setup->fields & MNCC_F_CCCAP)
- gsm48_encode_cccap(nmsg, &setup->cccap);
- }
-
- /* actually MM CONNECTION PENDING */
- new_cc_state(trans, GSM_CSTATE_INITIATED);
-
- return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
-}
-
-/* progress is received from lower layer */
-static int gsm48_cc_rx_progress(struct gsm_trans *trans, struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct tlv_parsed tp;
- struct gsm_mncc progress;
-
- LOGP(DCC, LOGL_INFO, "received PROGRESS\n");
-
- memset(&progress, 0, sizeof(struct gsm_mncc));
- progress.callref = trans->callref;
- tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len,
- GSM48_IE_PROGR_IND, 0);
- /* progress */
- if (TLVP_PRESENT(&tp, GSM48_IE_PROGR_IND)) {
- progress.fields |= MNCC_F_PROGRESS;
- gsm48_decode_progress(&progress.progress,
- TLVP_VAL(&tp, GSM48_IE_PROGR_IND)-1);
- /* store last progress indicator */
- trans->cc.prog_ind = progress.progress.descr;
- }
- /* user-user */
- if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
- progress.fields |= MNCC_F_USERUSER;
- gsm48_decode_useruser(&progress.useruser,
- TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
- }
-
- return mncc_recvmsg(trans->ms, trans, MNCC_PROGRESS_IND, &progress);
-}
-
-/* call proceeding is received from lower layer */
-static int gsm48_cc_rx_call_proceeding(struct gsm_trans *trans,
- struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct tlv_parsed tp;
- struct gsm_mncc call_proc;
-
- LOGP(DCC, LOGL_INFO, "sending CALL PROCEEDING\n");
-
- gsm48_stop_cc_timer(trans);
-
- memset(&call_proc, 0, sizeof(struct gsm_mncc));
- call_proc.callref = trans->callref;
- tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
-#if 0
- /* repeat */
- if (TLVP_PRESENT(&tp, GSM48_IE_REPEAT_CIR))
- call_conf.repeat = 1;
- if (TLVP_PRESENT(&tp, GSM48_IE_REPEAT_SEQ))
- call_conf.repeat = 2;
-#endif
- /* bearer capability */
- if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
- call_proc.fields |= MNCC_F_BEARER_CAP;
- gsm48_decode_bearer_cap(&call_proc.bearer_cap,
- TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
- }
- /* facility */
- if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
- call_proc.fields |= MNCC_F_FACILITY;
- gsm48_decode_facility(&call_proc.facility,
- TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
- }
-
- /* progress */
- if (TLVP_PRESENT(&tp, GSM48_IE_PROGR_IND)) {
- call_proc.fields |= MNCC_F_PROGRESS;
- gsm48_decode_progress(&call_proc.progress,
- TLVP_VAL(&tp, GSM48_IE_PROGR_IND)-1);
- /* store last progress indicator */
- trans->cc.prog_ind = call_proc.progress.descr;
- }
-
- /* start T310, if last progress indicator was 1 or 2 or 64 */
- if (trans->cc.prog_ind == 1
- || trans->cc.prog_ind == 2
- || trans->cc.prog_ind == 64)
- gsm48_start_cc_timer(trans, 0x310, GSM48_T310_MS);
-
- new_cc_state(trans, GSM_CSTATE_MO_CALL_PROC);
-
- return mncc_recvmsg(trans->ms, trans, MNCC_CALL_PROC_IND,
- &call_proc);
-}
-
-/* alerting is received by the lower layer */
-static int gsm48_cc_rx_alerting(struct gsm_trans *trans, struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct tlv_parsed tp;
- struct gsm_mncc alerting;
-
- LOGP(DCC, LOGL_INFO, "received ALERTING\n");
-
- gsm48_stop_cc_timer(trans);
- /* no T301 in MS call control */
-
- memset(&alerting, 0, sizeof(struct gsm_mncc));
- alerting.callref = trans->callref;
- tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
- /* facility */
- if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
- alerting.fields |= MNCC_F_FACILITY;
- gsm48_decode_facility(&alerting.facility,
- TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
- }
- /* progress */
- if (TLVP_PRESENT(&tp, GSM48_IE_PROGR_IND)) {
- alerting.fields |= MNCC_F_PROGRESS;
- gsm48_decode_progress(&alerting.progress,
- TLVP_VAL(&tp, GSM48_IE_PROGR_IND)-1);
- }
- /* user-user */
- if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
- alerting.fields |= MNCC_F_USERUSER;
- gsm48_decode_useruser(&alerting.useruser,
- TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
- }
-
- new_cc_state(trans, GSM_CSTATE_CALL_DELIVERED);
-
- return mncc_recvmsg(trans->ms, trans, MNCC_ALERT_IND,
- &alerting);
-}
-
-/* connect is received from lower layer */
-static int gsm48_cc_rx_connect(struct gsm_trans *trans, struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct tlv_parsed tp;
- struct gsm_mncc connect;
-
- LOGP(DCC, LOGL_INFO, "received CONNECT\n");
-
- gsm48_stop_cc_timer(trans);
-
- memset(&connect, 0, sizeof(struct gsm_mncc));
- connect.callref = trans->callref;
- tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
- /* facility */
- if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
- connect.fields |= MNCC_F_FACILITY;
- gsm48_decode_facility(&connect.facility,
- TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
- }
- /* connected */
- if (TLVP_PRESENT(&tp, GSM48_IE_CONN_BCD)) {
- connect.fields |= MNCC_F_CONNECTED;
- gsm48_decode_connected(&connect.connected,
- TLVP_VAL(&tp, GSM48_IE_CONN_BCD)-1);
- }
- /* progress */
- if (TLVP_PRESENT(&tp, GSM48_IE_PROGR_IND)) {
- connect.fields |= MNCC_F_PROGRESS;
- gsm48_decode_progress(&connect.progress,
- TLVP_VAL(&tp, GSM48_IE_PROGR_IND)-1);
- }
- /* user-user */
- if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
- connect.fields |= MNCC_F_USERUSER;
- gsm48_decode_useruser(&connect.useruser,
- TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
- }
-
- /* ACTIVE state is set during this: */
- gsm48_cc_tx_connect_ack(trans, NULL);
-
- return mncc_recvmsg(trans->ms, trans, MNCC_SETUP_CNF, &connect);
-}
-
-/* connect ack message from upper layer */
-static int gsm48_cc_tx_connect_ack(struct gsm_trans *trans, void *arg)
-{
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
-
- LOGP(DCC, LOGL_INFO, "sending CONNECT ACKNOWLEDGE\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
-
- gh->msg_type = GSM48_MT_CC_CONNECT_ACK;
-
- new_cc_state(trans, GSM_CSTATE_ACTIVE);
-
- return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
-}
-
-/*
- * process handlers (mobile terminating call establish)
- */
-
-/* setup is received from lower layer */
-static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct tlv_parsed tp;
- struct gsm_mncc setup;
-
- LOGP(DCC, LOGL_INFO, "received SETUP\n");
-
- memset(&setup, 0, sizeof(struct gsm_mncc));
- setup.callref = trans->callref;
- tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
-
- /* bearer capability */
- if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
- setup.fields |= MNCC_F_BEARER_CAP;
- gsm48_decode_bearer_cap(&setup.bearer_cap,
- TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
- }
- /* facility */
- if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
- setup.fields |= MNCC_F_FACILITY;
- gsm48_decode_facility(&setup.facility,
- TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
- }
- /* progress */
- if (TLVP_PRESENT(&tp, GSM48_IE_PROGR_IND)) {
- setup.fields |= MNCC_F_PROGRESS;
- gsm48_decode_progress(&setup.progress,
- TLVP_VAL(&tp, GSM48_IE_PROGR_IND)-1);
- }
- /* signal */
- if (TLVP_PRESENT(&tp, GSM48_IE_SIGNAL)) {
- setup.fields |= MNCC_F_SIGNAL;
- gsm48_decode_signal(&setup.signal,
- TLVP_VAL(&tp, GSM48_IE_SIGNAL)-1);
- }
- /* calling party bcd number */
- if (TLVP_PRESENT(&tp, GSM48_IE_CALLING_BCD)) {
- setup.fields |= MNCC_F_CALLING;
- gsm48_decode_calling(&setup.calling,
- TLVP_VAL(&tp, GSM48_IE_CALLING_BCD)-1);
- }
- /* called party bcd number */
- if (TLVP_PRESENT(&tp, GSM48_IE_CALLED_BCD)) {
- setup.fields |= MNCC_F_CALLED;
- gsm48_decode_called(&setup.called,
- TLVP_VAL(&tp, GSM48_IE_CALLED_BCD)-1);
- }
- /* redirecting party bcd number */
- if (TLVP_PRESENT(&tp, GSM48_IE_REDIR_BCD)) {
- setup.fields |= MNCC_F_REDIRECTING;
- gsm48_decode_redirecting(&setup.redirecting,
- TLVP_VAL(&tp, GSM48_IE_REDIR_BCD)-1);
- }
- /* user-user */
- if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
- setup.fields |= MNCC_F_USERUSER;
- gsm48_decode_useruser(&setup.useruser,
- TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
- }
-
- new_cc_state(trans, GSM_CSTATE_CALL_PRESENT);
-
- /* indicate setup to MNCC */
- mncc_recvmsg(trans->ms, trans, MNCC_SETUP_IND, &setup);
-
- return 0;
-}
-
-/* call conf message from upper layer */
-static int gsm48_cc_tx_call_conf(struct gsm_trans *trans, void *arg)
-{
- struct gsm_mncc *confirm = arg;
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
-
- LOGP(DCC, LOGL_INFO, "sending CALL CONFIRMED (proceeding)\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
-
- gh->msg_type = GSM48_MT_CC_CALL_CONF;
-
- new_cc_state(trans, GSM_CSTATE_MO_TERM_CALL_CONF);
-
- /* bearer capability */
- if (confirm->fields & MNCC_F_BEARER_CAP)
- gsm48_encode_bearer_cap(nmsg, 0, &confirm->bearer_cap);
- /* cause */
- if (confirm->fields & MNCC_F_CAUSE)
- gsm48_encode_cause(nmsg, 0, &confirm->cause);
- /* cc cap */
- if (confirm->fields & MNCC_F_CCCAP)
- gsm48_encode_cccap(nmsg, &confirm->cccap);
-
- return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
-}
-
-/* alerting message from upper layer */
-static int gsm48_cc_tx_alerting(struct gsm_trans *trans, void *arg)
-{
- struct gsm_mncc *alerting = arg;
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
-
- LOGP(DCC, LOGL_INFO, "sending ALERTING\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
-
- gh->msg_type = GSM48_MT_CC_ALERTING;
-
- /* facility */
- if (alerting->fields & MNCC_F_FACILITY)
- gsm48_encode_facility(nmsg, 0, &alerting->facility);
- /* user-user */
- if (alerting->fields & MNCC_F_USERUSER)
- gsm48_encode_useruser(nmsg, 0, &alerting->useruser);
- /* ss version */
- if (alerting->fields & MNCC_F_SSVERSION)
- gsm48_encode_ssversion(nmsg, &alerting->ssversion);
-
- new_cc_state(trans, GSM_CSTATE_CALL_RECEIVED);
-
- return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
-}
-
-/* connect message from upper layer */
-static int gsm48_cc_tx_connect(struct gsm_trans *trans, void *arg)
-{
- struct gsm_mncc *connect = arg;
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
-
- LOGP(DCC, LOGL_INFO, "sending CONNECT\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
-
- gh->msg_type = GSM48_MT_CC_CONNECT;
-
- gsm48_stop_cc_timer(trans);
- gsm48_start_cc_timer(trans, 0x313, GSM48_T313_MS);
-
- /* facility */
- if (connect->fields & MNCC_F_FACILITY)
- gsm48_encode_facility(nmsg, 0, &connect->facility);
- /* user-user */
- if (connect->fields & MNCC_F_USERUSER)
- gsm48_encode_useruser(nmsg, 0, &connect->useruser);
- /* ss version */
- if (connect->fields & MNCC_F_SSVERSION)
- gsm48_encode_ssversion(nmsg, &connect->ssversion);
-
- new_cc_state(trans, GSM_CSTATE_CONNECT_REQUEST);
-
- return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
-}
-
-/* connect ack is received from lower layer */
-static int gsm48_cc_rx_connect_ack(struct gsm_trans *trans, struct msgb *msg)
-{
- struct gsm_mncc connect_ack;
-
- LOGP(DCC, LOGL_INFO, "received CONNECT ACKNOWLEDGE\n");
-
- gsm48_stop_cc_timer(trans);
-
- new_cc_state(trans, GSM_CSTATE_ACTIVE);
-
- memset(&connect_ack, 0, sizeof(struct gsm_mncc));
- connect_ack.callref = trans->callref;
- return mncc_recvmsg(trans->ms, trans, MNCC_SETUP_COMPL_IND,
- &connect_ack);
-}
-
-/*
- * process handlers (during active state)
- */
-
-/* notify message from upper layer */
-static int gsm48_cc_tx_notify(struct gsm_trans *trans, void *arg)
-{
- struct gsm_mncc *notify = arg;
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
-
- LOGP(DCC, LOGL_INFO, "sending NOTIFY\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
-
- gh->msg_type = GSM48_MT_CC_NOTIFY;
-
- /* notify */
- gsm48_encode_notify(nmsg, notify->notify);
-
- return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
-}
-
-/* notify is received from lower layer */
-static int gsm48_cc_rx_notify(struct gsm_trans *trans, struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct gsm_mncc notify;
-
- LOGP(DCC, LOGL_INFO, "received NOTIFY\n");
-
- memset(&notify, 0, sizeof(struct gsm_mncc));
- notify.callref = trans->callref;
- /* notify */
- if (payload_len < 1) {
- LOGP(DCC, LOGL_NOTICE, "Short read of notify message error.\n");
- return -EINVAL;
- }
- gsm48_decode_notify(&notify.notify, gh->data);
-
- return mncc_recvmsg(trans->ms, trans, MNCC_NOTIFY_IND, &notify);
-}
-
-/* start dtmf message from upper layer */
-static int gsm48_cc_tx_start_dtmf(struct gsm_trans *trans, void *arg)
-{
- struct gsm_mncc *dtmf = arg;
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
-
- LOGP(DCC, LOGL_INFO, "sending START DTMF\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
-
- gh->msg_type = GSM48_MT_CC_START_DTMF;
-
- /* keypad */
- gsm48_encode_keypad(nmsg, dtmf->keypad);
-
- return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
-}
-
-/* start dtmf ack is received from lower layer */
-static int gsm48_cc_rx_start_dtmf_ack(struct gsm_trans *trans, struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct tlv_parsed tp;
- struct gsm_mncc dtmf;
-
- LOGP(DCC, LOGL_INFO, "received START DTMF ACKNOWLEDGE\n");
-
- memset(&dtmf, 0, sizeof(struct gsm_mncc));
- dtmf.callref = trans->callref;
- tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
- /* keypad facility */
- if (TLVP_PRESENT(&tp, GSM48_IE_KPD_FACILITY)) {
- dtmf.fields |= MNCC_F_KEYPAD;
- gsm48_decode_keypad(&dtmf.keypad,
- TLVP_VAL(&tp, GSM48_IE_KPD_FACILITY)-1);
- }
-
- return mncc_recvmsg(trans->ms, trans, MNCC_START_DTMF_RSP, &dtmf);
-}
-
-/* start dtmf rej is received from lower layer */
-static int gsm48_cc_rx_start_dtmf_rej(struct gsm_trans *trans, struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct gsm_mncc dtmf;
-
- LOGP(DCC, LOGL_INFO, "received START DTMF REJECT\n");
-
- memset(&dtmf, 0, sizeof(struct gsm_mncc));
- dtmf.callref = trans->callref;
- /* cause */
- if (payload_len < 1) {
- LOGP(DCC, LOGL_NOTICE, "Short read of dtmf reject message "
- "error.\n");
- return -EINVAL;
- }
- gsm48_decode_cause(&dtmf.cause, gh->data);
-
- return mncc_recvmsg(trans->ms, trans, MNCC_START_DTMF_REJ, &dtmf);
-}
-
-/* stop dtmf message from upper layer */
-static int gsm48_cc_tx_stop_dtmf(struct gsm_trans *trans, void *arg)
-{
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
-
- LOGP(DCC, LOGL_INFO, "sending STOP DTMF\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
-
- gh->msg_type = GSM48_MT_CC_STOP_DTMF;
-
- return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
-}
-
-/* stop dtmf ack is received from lower layer */
-static int gsm48_cc_rx_stop_dtmf_ack(struct gsm_trans *trans, struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct tlv_parsed tp;
- struct gsm_mncc dtmf;
-
- LOGP(DCC, LOGL_INFO, "received STOP DTMF ACKNOWLEDGE\n");
-
- memset(&dtmf, 0, sizeof(struct gsm_mncc));
- dtmf.callref = trans->callref;
- tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
-
- return mncc_recvmsg(trans->ms, trans, MNCC_STOP_DTMF_RSP, &dtmf);
-}
-
-/* hold message from upper layer */
-static int gsm48_cc_tx_hold(struct gsm_trans *trans, void *arg)
-{
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
-
- LOGP(DCC, LOGL_INFO, "sending HOLD\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
-
- gh->msg_type = GSM48_MT_CC_HOLD;
-
- return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
-}
-
-/* hold ack is received from lower layer */
-static int gsm48_cc_rx_hold_ack(struct gsm_trans *trans, struct msgb *msg)
-{
- struct gsm_mncc hold;
-
- LOGP(DCC, LOGL_INFO, "received HOLD ACKNOWLEDGE\n");
-
- memset(&hold, 0, sizeof(struct gsm_mncc));
- hold.callref = trans->callref;
-
- return mncc_recvmsg(trans->ms, trans, MNCC_HOLD_CNF, &hold);
-}
-
-/* hold rej is received from lower layer */
-static int gsm48_cc_rx_hold_rej(struct gsm_trans *trans, struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct gsm_mncc hold;
-
- LOGP(DCC, LOGL_INFO, "received HOLD REJECT\n");
-
- memset(&hold, 0, sizeof(struct gsm_mncc));
- hold.callref = trans->callref;
- /* cause */
- if (payload_len < 1) {
- LOGP(DCC, LOGL_NOTICE, "Short read of hold reject message "
- "error.\n");
- return -EINVAL;
- }
- gsm48_decode_cause(&hold.cause, gh->data);
-
- return mncc_recvmsg(trans->ms, trans, MNCC_HOLD_REJ, &hold);
-}
-
-/* retrieve message from upper layer */
-static int gsm48_cc_tx_retrieve(struct gsm_trans *trans, void *arg)
-{
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
-
- LOGP(DCC, LOGL_INFO, "sending RETRIEVE\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
-
- gh->msg_type = GSM48_MT_CC_RETR;
-
- return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
-}
-
-/* retrieve ack is received from lower layer */
-static int gsm48_cc_rx_retrieve_ack(struct gsm_trans *trans, struct msgb *msg)
-{
- struct gsm_mncc retrieve;
-
- LOGP(DCC, LOGL_INFO, "received RETRIEVE ACKNOWLEDGE\n");
-
- memset(&retrieve, 0, sizeof(struct gsm_mncc));
- retrieve.callref = trans->callref;
-
- return mncc_recvmsg(trans->ms, trans, MNCC_RETRIEVE_CNF, &retrieve);
-}
-
-/* retrieve rej is received from lower layer */
-static int gsm48_cc_rx_retrieve_rej(struct gsm_trans *trans, struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct gsm_mncc retrieve;
-
- LOGP(DCC, LOGL_INFO, "received RETRIEVE REJECT\n");
-
- memset(&retrieve, 0, sizeof(struct gsm_mncc));
- retrieve.callref = trans->callref;
- /* cause */
- if (payload_len < 1) {
- LOGP(DCC, LOGL_NOTICE, "Short read of retrieve reject message "
- "error.\n");
- return -EINVAL;
- }
- gsm48_decode_cause(&retrieve.cause, gh->data);
-
- return mncc_recvmsg(trans->ms, trans, MNCC_RETRIEVE_REJ, &retrieve);
-}
-
-/* facility message from upper layer or from timer event */
-static int gsm48_cc_tx_facility(struct gsm_trans *trans, void *arg)
-{
- struct gsm_mncc *fac = arg;
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
-
- LOGP(DCC, LOGL_INFO, "sending FACILITY\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
-
- gh->msg_type = GSM48_MT_CC_FACILITY;
-
- /* facility */
- gsm48_encode_facility(nmsg, 1, &fac->facility);
- /* ss version */
- if (fac->fields & MNCC_F_SSVERSION)
- gsm48_encode_ssversion(nmsg, &fac->ssversion);
-
- return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
-}
-
-/* facility is received from lower layer */
-static int gsm48_cc_rx_facility(struct gsm_trans *trans, struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct gsm_mncc fac;
-
- LOGP(DCC, LOGL_INFO, "received FACILITY\n");
-
- memset(&fac, 0, sizeof(struct gsm_mncc));
- fac.callref = trans->callref;
- if (payload_len < 1) {
- LOGP(DCC, LOGL_NOTICE, "Short read of facility message "
- "error.\n");
- return -EINVAL;
- }
- /* facility */
- gsm48_decode_facility(&fac.facility, gh->data);
-
- return mncc_recvmsg(trans->ms, trans, MNCC_FACILITY_IND, &fac);
-}
-
-/* user info message from upper layer or from timer event */
-static int gsm48_cc_tx_userinfo(struct gsm_trans *trans, void *arg)
-{
- struct gsm_mncc *user = arg;
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
-
- LOGP(DCC, LOGL_INFO, "sending USERINFO\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
-
- gh->msg_type = GSM48_MT_CC_USER_INFO;
-
- /* user-user */
- if (user->fields & MNCC_F_USERUSER)
- gsm48_encode_useruser(nmsg, 1, &user->useruser);
- /* more data */
- if (user->more)
- gsm48_encode_more(nmsg);
-
- return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
-}
-
-/* user info is received from lower layer */
-static int gsm48_cc_rx_userinfo(struct gsm_trans *trans, struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct tlv_parsed tp;
- struct gsm_mncc user;
-
- LOGP(DCC, LOGL_INFO, "received USERINFO\n");
-
- memset(&user, 0, sizeof(struct gsm_mncc));
- user.callref = trans->callref;
- if (payload_len < 1) {
- LOGP(DCC, LOGL_NOTICE, "Short read of userinfo message "
- "error.\n");
- return -EINVAL;
- }
- tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len,
- GSM48_IE_USER_USER, 0);
- /* user-user */
- gsm48_decode_useruser(&user.useruser,
- TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
- /* more data */
- if (TLVP_PRESENT(&tp, GSM48_IE_MORE_DATA))
- user.more = 1;
-
- return mncc_recvmsg(trans->ms, trans, MNCC_USERINFO_IND, &user);
-}
-
-/* modify message from upper layer or from timer event */
-static int gsm48_cc_tx_modify(struct gsm_trans *trans, void *arg)
-{
- struct gsm_mncc *modify = arg;
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
-
- LOGP(DCC, LOGL_INFO, "sending MODIFY\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
-
- gh->msg_type = GSM48_MT_CC_MODIFY;
-
- gsm48_start_cc_timer(trans, 0x323, GSM48_T323_MS);
-
- /* bearer capability */
- gsm48_encode_bearer_cap(nmsg, 1, &modify->bearer_cap);
-
- new_cc_state(trans, GSM_CSTATE_MO_TERM_MODIFY);
-
- return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
-}
-
-/* modify complete is received from lower layer */
-static int gsm48_cc_rx_modify_complete(struct gsm_trans *trans,
- struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct gsm_mncc modify;
-
- LOGP(DCC, LOGL_INFO, "received MODIFY COMPLETE\n");
-
- gsm48_stop_cc_timer(trans);
-
- memset(&modify, 0, sizeof(struct gsm_mncc));
- modify.callref = trans->callref;
- if (payload_len < 1) {
- LOGP(DCC, LOGL_NOTICE, "Short read of modify complete message "
- "error.\n");
- return -EINVAL;
- }
- /* bearer capability */
- gsm48_decode_bearer_cap(&modify.bearer_cap, gh->data);
-
- new_cc_state(trans, GSM_CSTATE_ACTIVE);
-
- return mncc_recvmsg(trans->ms, trans, MNCC_MODIFY_CNF, &modify);
-}
-
-/* modify reject is received from lower layer */
-static int gsm48_cc_rx_modify_reject(struct gsm_trans *trans, struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct tlv_parsed tp;
- struct gsm_mncc modify;
-
- LOGP(DCC, LOGL_INFO, "received MODIFY REJECT\n");
-
- gsm48_stop_cc_timer(trans);
-
- memset(&modify, 0, sizeof(struct gsm_mncc));
- modify.callref = trans->callref;
- if (payload_len < 1) {
- LOGP(DCC, LOGL_NOTICE, "Short read of modify reject message "
- "error.\n");
- return -EINVAL;
- }
- tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len,
- GSM48_IE_BEARER_CAP, GSM48_IE_CAUSE);
- /* bearer capability */
- if (TLVP_PRESENT(&tp, GSM48_IE_BEARER_CAP)) {
- modify.fields |= MNCC_F_BEARER_CAP;
- gsm48_decode_bearer_cap(&modify.bearer_cap,
- TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
- }
- /* cause */
- if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
- modify.fields |= MNCC_F_CAUSE;
- gsm48_decode_cause(&modify.cause,
- TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
- }
-
- new_cc_state(trans, GSM_CSTATE_ACTIVE);
-
- return mncc_recvmsg(trans->ms, trans, MNCC_MODIFY_REJ, &modify);
-}
-
-/* modify is received from lower layer */
-static int gsm48_cc_rx_modify(struct gsm_trans *trans, struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct gsm_mncc modify;
-
- LOGP(DCC, LOGL_INFO, "received MODIFY\n");
-
- memset(&modify, 0, sizeof(struct gsm_mncc));
- modify.callref = trans->callref;
- if (payload_len < 1) {
- LOGP(DCC, LOGL_NOTICE, "Short read of modify message error.\n");
- return -EINVAL;
- }
- /* bearer capability */
- gsm48_decode_bearer_cap(&modify.bearer_cap, gh->data);
-
- new_cc_state(trans, GSM_CSTATE_MO_ORIG_MODIFY);
-
- return mncc_recvmsg(trans->ms, trans, MNCC_MODIFY_IND, &modify);
-}
-
-/* modify complete message from upper layer or from timer event */
-static int gsm48_cc_tx_modify_complete(struct gsm_trans *trans, void *arg)
-{
- struct gsm_mncc *modify = arg;
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
-
- LOGP(DCC, LOGL_INFO, "sending MODIFY COMPLETE\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
-
- gh->msg_type = GSM48_MT_CC_MODIFY_COMPL;
-
- /* bearer capability */
- gsm48_encode_bearer_cap(nmsg, 1, &modify->bearer_cap);
-
- new_cc_state(trans, GSM_CSTATE_ACTIVE);
-
- return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
-}
-
-/* modify reject message from upper layer or from timer event */
-static int gsm48_cc_tx_modify_reject(struct gsm_trans *trans, void *arg)
-{
- struct gsm_mncc *modify = arg;
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
-
- LOGP(DCC, LOGL_INFO, "sending MODIFY REJECT\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
-
- gh->msg_type = GSM48_MT_CC_MODIFY_REJECT;
-
- /* bearer capability */
- gsm48_encode_bearer_cap(nmsg, 1, &modify->bearer_cap);
- /* cause */
- gsm48_encode_cause(nmsg, 1, &modify->cause);
-
- new_cc_state(trans, GSM_CSTATE_ACTIVE);
-
- return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
-}
-
-/*
- * process handlers (call clearing)
- */
-
-static struct gsm_mncc_cause default_cause = {
- .location = GSM48_CAUSE_LOC_PRN_S_LU,
- .coding = 0,
- .rec = 0,
- .rec_val = 0,
- .value = GSM48_CC_CAUSE_NORMAL_UNSPEC,
- .diag_len = 0,
- .diag = { 0 },
-};
-
-/* disconnect message from upper layer or from timer event */
-static int gsm48_cc_tx_disconnect(struct gsm_trans *trans, void *arg)
-{
- struct gsm_mncc *disc = arg;
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
-
- LOGP(DCC, LOGL_INFO, "sending DISCONNECT\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
-
- gh->msg_type = GSM48_MT_CC_DISCONNECT;
-
- gsm48_stop_cc_timer(trans);
- gsm48_start_cc_timer(trans, 0x305, GSM48_T305_MS);
-
- /* cause */
- if (disc->fields & MNCC_F_CAUSE)
- gsm48_encode_cause(nmsg, 1, &disc->cause);
- else
- gsm48_encode_cause(nmsg, 1, &default_cause);
-
- /* facility */
- if (disc->fields & MNCC_F_FACILITY)
- gsm48_encode_facility(nmsg, 0, &disc->facility);
- /* progress */
- if (disc->fields & MNCC_F_PROGRESS)
- gsm48_encode_progress(nmsg, 0, &disc->progress);
- /* user-user */
- if (disc->fields & MNCC_F_USERUSER)
- gsm48_encode_useruser(nmsg, 0, &disc->useruser);
- /* ss version */
- if (disc->fields & MNCC_F_SSVERSION)
- gsm48_encode_ssversion(nmsg, &disc->ssversion);
-
- new_cc_state(trans, GSM_CSTATE_DISCONNECT_REQ);
-
- return gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
-}
-
-/* release message from upper layer or from timer event */
-static int gsm48_cc_tx_release(struct gsm_trans *trans, void *arg)
-{
- struct gsm_mncc *rel = arg;
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
-
- LOGP(DCC, LOGL_INFO, "sending RELEASE\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
-
- gh->msg_type = GSM48_MT_CC_RELEASE;
-
- gsm48_stop_cc_timer(trans);
- gsm48_start_cc_timer(trans, 0x308, GSM48_T308_MS);
-
- /* cause */
- if (rel->fields & MNCC_F_CAUSE)
- gsm48_encode_cause(nmsg, 0, &rel->cause);
- /* facility */
- if (rel->fields & MNCC_F_FACILITY)
- gsm48_encode_facility(nmsg, 0, &rel->facility);
- /* user-user */
- if (rel->fields & MNCC_F_USERUSER)
- gsm48_encode_useruser(nmsg, 0, &rel->useruser);
- /* ss version */
- if (rel->fields & MNCC_F_SSVERSION)
- gsm48_encode_ssversion(nmsg, &rel->ssversion);
-
- trans->cc.T308_second = 0;
- memcpy(&trans->cc.msg, rel, sizeof(struct gsm_mncc));
-
- if (trans->cc.state != GSM_CSTATE_RELEASE_REQ)
- new_cc_state(trans, GSM_CSTATE_RELEASE_REQ);
-
- gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
-
-#if 0
- /* release without sending MMCC_REL_REQ */
- new_cc_state(trans, GSM_CSTATE_NULL);
- trans->callref = 0;
- trans_free(trans);
-#endif
-
- return 0;
-}
-
-/* reject message from upper layer */
-static int gsm48_cc_tx_release_compl(struct gsm_trans *trans, void *arg)
-{
- struct gsm_mncc *rel = arg;
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
-
- LOGP(DCC, LOGL_INFO, "sending RELEASE COMPLETE\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
-
- gh->msg_type = GSM48_MT_CC_RELEASE_COMPL;
-
- gsm48_stop_cc_timer(trans);
-
- /* cause */
- if (rel->fields & MNCC_F_CAUSE)
- gsm48_encode_cause(nmsg, 0, &rel->cause);
- /* facility */
- if (rel->fields & MNCC_F_FACILITY)
- gsm48_encode_facility(nmsg, 0, &rel->facility);
- /* user-user */
- if (rel->fields & MNCC_F_USERUSER)
- gsm48_encode_useruser(nmsg, 0, &rel->useruser);
- /* ss version */
- if (rel->fields & MNCC_F_SSVERSION)
- gsm48_encode_ssversion(nmsg, &rel->ssversion);
-
- /* release without sending MMCC_REL_REQ */
- new_cc_state(trans, GSM_CSTATE_NULL);
- trans->callref = 0;
- trans_free(trans);
-
- return 0;
-}
-
-/* disconnect is received from lower layer */
-static int gsm48_cc_rx_disconnect(struct gsm_trans *trans, struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct tlv_parsed tp;
- struct gsm_mncc disc;
-
- LOGP(DCC, LOGL_INFO, "received DISCONNECT\n");
-
- gsm48_stop_cc_timer(trans);
-
- new_cc_state(trans, GSM_CSTATE_DISCONNECT_IND);
-
- memset(&disc, 0, sizeof(struct gsm_mncc));
- disc.callref = trans->callref;
- tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len,
- GSM48_IE_CAUSE, 0);
- /* cause */
- if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
- disc.fields |= MNCC_F_CAUSE;
- gsm48_decode_cause(&disc.cause,
- TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
- }
- /* facility */
- if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
- disc.fields |= MNCC_F_FACILITY;
- gsm48_decode_facility(&disc.facility,
- TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
- }
- /* progress */
- if (TLVP_PRESENT(&tp, GSM48_IE_PROGR_IND)) {
- disc.fields |= MNCC_F_PROGRESS;
- gsm48_decode_progress(&disc.progress,
- TLVP_VAL(&tp, GSM48_IE_PROGR_IND)-1);
- }
- /* user-user */
- if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
- disc.fields |= MNCC_F_USERUSER;
- gsm48_decode_useruser(&disc.useruser,
- TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
- }
-
- /* store disconnect cause for T305 expiry */
- memcpy(&trans->cc.msg, &disc, sizeof(struct gsm_mncc));
-
- return mncc_recvmsg(trans->ms, trans, MNCC_DISC_IND, &disc);
-}
-
-/* release is received from lower layer */
-static int gsm48_cc_rx_release(struct gsm_trans *trans, struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct tlv_parsed tp;
- struct gsm_mncc rel;
-
- LOGP(DCC, LOGL_INFO, "received RELEASE\n");
-
- gsm48_stop_cc_timer(trans);
-
- memset(&rel, 0, sizeof(struct gsm_mncc));
- rel.callref = trans->callref;
- tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
- /* cause */
- if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
- rel.fields |= MNCC_F_CAUSE;
- gsm48_decode_cause(&rel.cause,
- TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
- }
- /* facility */
- if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
- rel.fields |= MNCC_F_FACILITY;
- gsm48_decode_facility(&rel.facility,
- TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
- }
- /* user-user */
- if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
- rel.fields |= MNCC_F_USERUSER;
- gsm48_decode_useruser(&rel.useruser,
- TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
- }
-
- /* in case we receive a relase, when we are already in NULL state */
- if (trans->cc.state == GSM_CSTATE_NULL) {
- LOGP(DCC, LOGL_INFO, "ignoring RELEASE in NULL state\n");
- /* release MM conn, free trans */
- return gsm48_rel_null_free(trans);
- }
- if (trans->cc.state == GSM_CSTATE_RELEASE_REQ) {
- /* release collision 5.4.5 */
- mncc_recvmsg(trans->ms, trans, MNCC_REL_CNF, &rel);
- } else {
- struct msgb *nmsg;
-
- /* forward cause only */
- LOGP(DCC, LOGL_INFO, "sending RELEASE COMPLETE\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
-
- gh->msg_type = GSM48_MT_CC_RELEASE_COMPL;
-
- if (rel.fields & MNCC_F_CAUSE)
- gsm48_encode_cause(nmsg, 0, &rel.cause);
-
- gsm48_cc_to_mm(nmsg, trans, GSM48_MMCC_DATA_REQ);
-
- /* release indication */
- mncc_recvmsg(trans->ms, trans, MNCC_REL_IND, &rel);
- }
-
- /* release MM conn, got NULL state, free trans */
- return gsm48_rel_null_free(trans);
-}
-
-/* release complete is received from lower layer */
-static int gsm48_cc_rx_release_compl(struct gsm_trans *trans, struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct tlv_parsed tp;
- struct gsm_mncc rel;
-
- LOGP(DCC, LOGL_INFO, "received RELEASE COMPLETE\n");
-
- gsm48_stop_cc_timer(trans);
-
- memset(&rel, 0, sizeof(struct gsm_mncc));
- rel.callref = trans->callref;
- tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
- /* cause */
- if (TLVP_PRESENT(&tp, GSM48_IE_CAUSE)) {
- rel.fields |= MNCC_F_CAUSE;
- gsm48_decode_cause(&rel.cause,
- TLVP_VAL(&tp, GSM48_IE_CAUSE)-1);
- }
- /* facility */
- if (TLVP_PRESENT(&tp, GSM48_IE_FACILITY)) {
- rel.fields |= MNCC_F_FACILITY;
- gsm48_decode_facility(&rel.facility,
- TLVP_VAL(&tp, GSM48_IE_FACILITY)-1);
- }
- /* user-user */
- if (TLVP_PRESENT(&tp, GSM48_IE_USER_USER)) {
- rel.fields |= MNCC_F_USERUSER;
- gsm48_decode_useruser(&rel.useruser,
- TLVP_VAL(&tp, GSM48_IE_USER_USER)-1);
- }
-
- if (trans->callref) {
- switch (trans->cc.state) {
- case GSM_CSTATE_CALL_PRESENT:
- mncc_recvmsg(trans->ms, trans,
- MNCC_REJ_IND, &rel);
- break;
- case GSM_CSTATE_RELEASE_REQ:
- mncc_recvmsg(trans->ms, trans,
- MNCC_REL_CNF, &rel);
- break;
- default:
- mncc_recvmsg(trans->ms, trans,
- MNCC_REL_IND, &rel);
- }
- }
-
- /* release MM conn, got NULL state, free trans */
- return gsm48_rel_null_free(trans);
-}
-
-/*
- * state machines
- */
-
-/* state trasitions for MNCC messages (upper layer) */
-static struct downstate {
- u_int32_t states;
- int type;
- int (*rout) (struct gsm_trans *trans, void *arg);
-} downstatelist[] = {
- /* mobile originating call establishment */
- {SBIT(GSM_CSTATE_NULL), /* 5.2.1 */
- MNCC_SETUP_REQ, gsm48_cc_init_mm},
-
- {SBIT(GSM_CSTATE_MM_CONNECTION_PEND), /* 5.2.1 */
- MNCC_REL_REQ, gsm48_cc_abort_mm},
-
- /* mobile terminating call establishment */
- {SBIT(GSM_CSTATE_CALL_PRESENT), /* 5.2.2.3.1 */
- MNCC_CALL_CONF_REQ, gsm48_cc_tx_call_conf},
-
- {SBIT(GSM_CSTATE_MO_TERM_CALL_CONF), /* 5.2.2.3.2 */
- MNCC_ALERT_REQ, gsm48_cc_tx_alerting},
-
- {SBIT(GSM_CSTATE_MO_TERM_CALL_CONF) |
- SBIT(GSM_CSTATE_CALL_RECEIVED), /* 5.2.2.5 */
- MNCC_SETUP_RSP, gsm48_cc_tx_connect},
-
- /* signalling during call */
- {SBIT(GSM_CSTATE_ACTIVE), /* 5.3.1 */
- MNCC_NOTIFY_REQ, gsm48_cc_tx_notify},
-
- {ALL_STATES, /* 5.5.7.1 */
- MNCC_START_DTMF_REQ, gsm48_cc_tx_start_dtmf},
-
- {ALL_STATES, /* 5.5.7.3 */
- MNCC_STOP_DTMF_REQ, gsm48_cc_tx_stop_dtmf},
-
- {SBIT(GSM_CSTATE_ACTIVE),
- MNCC_HOLD_REQ, gsm48_cc_tx_hold},
-
- {SBIT(GSM_CSTATE_ACTIVE),
- MNCC_RETRIEVE_REQ, gsm48_cc_tx_retrieve},
-
- {ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_RELEASE_REQ),
- MNCC_FACILITY_REQ, gsm48_cc_tx_facility},
-
- {SBIT(GSM_CSTATE_ACTIVE),
- MNCC_USERINFO_REQ, gsm48_cc_tx_userinfo},
-
- /* clearing */
- {ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_DISCONNECT_IND) -
- SBIT(GSM_CSTATE_RELEASE_REQ) -
- SBIT(GSM_CSTATE_DISCONNECT_REQ), /* 5.4.3.1 */
- MNCC_DISC_REQ, gsm48_cc_tx_disconnect},
-
- {SBIT(GSM_CSTATE_INITIATED),
- MNCC_REJ_REQ, gsm48_cc_tx_release_compl},
-
- {ALL_STATES - SBIT(GSM_CSTATE_NULL) -
- SBIT(GSM_CSTATE_RELEASE_REQ), /* ??? */
- MNCC_REL_REQ, gsm48_cc_tx_release},
-
- /* modify */
- {SBIT(GSM_CSTATE_ACTIVE),
- MNCC_MODIFY_REQ, gsm48_cc_tx_modify},
-
- {SBIT(GSM_CSTATE_MO_ORIG_MODIFY),
- MNCC_MODIFY_RSP, gsm48_cc_tx_modify_complete},
-
- {SBIT(GSM_CSTATE_MO_ORIG_MODIFY),
- MNCC_MODIFY_REJ, gsm48_cc_tx_modify_reject},
-};
-
-#define DOWNSLLEN \
- (sizeof(downstatelist) / sizeof(struct downstate))
-
-int mncc_send(struct osmocom_ms *ms, int msg_type, void *arg)
-{
- struct gsm_mncc *data = arg;
- struct gsm_trans *trans;
- int i, rc;
-
- /* Find callref */
- trans = trans_find_by_callref(ms, data->callref);
-
- if (!trans) {
- /* check for SETUP message */
- if (msg_type != MNCC_SETUP_REQ) {
- /* Invalid call reference */
- LOGP(DCC, LOGL_NOTICE, "transaction not found\n");
- return mncc_release_ind(ms, NULL, data->callref,
- GSM48_CAUSE_LOC_PRN_S_LU,
- GSM48_CC_CAUSE_INVAL_TRANS_ID);
- }
- if (data->callref >= 0x40000000) {
- LOGP(DCC, LOGL_FATAL, "MNCC ref wrong.\n");
- return mncc_release_ind(ms, NULL, data->callref,
- GSM48_CAUSE_LOC_PRN_S_LU,
- GSM48_CC_CAUSE_INVAL_TRANS_ID);
- }
-
- /* Create transaction */
- trans = trans_alloc(ms, GSM48_PDISC_CC, 0xff, data->callref);
- if (!trans) {
- /* No memory or whatever */
- return mncc_release_ind(ms, NULL, data->callref,
- GSM48_CAUSE_LOC_PRN_S_LU,
- GSM48_CC_CAUSE_RESOURCE_UNAVAIL);
- }
- }
-
- switch (msg_type) {
- case GSM_TCHF_FRAME:
- return gsm_send_voice(ms, arg);
- case MNCC_LCHAN_MODIFY:
- return 0;
- case MNCC_FRAME_RECV:
- ms->mncc_entity.ref = trans->callref;
- gsm48_rr_audio_mode(ms,
- AUDIO_TX_TRAFFIC_REQ | AUDIO_RX_TRAFFIC_IND);
- return 0;
- case MNCC_FRAME_DROP:
- if (ms->mncc_entity.ref == trans->callref)
- ms->mncc_entity.ref = 0;
- gsm48_rr_audio_mode(ms, AUDIO_TX_MICROPHONE | AUDIO_RX_SPEAKER);
- return 0;
- }
-
- /* Find function for current state and message */
- for (i = 0; i < DOWNSLLEN; i++)
- if ((msg_type == downstatelist[i].type)
- && ((1 << trans->cc.state) & downstatelist[i].states))
- break;
- if (i == DOWNSLLEN) {
- LOGP(DCC, LOGL_NOTICE, "Message %d unhandled at state "
- "%d\n", msg_type, trans->cc.state);
- return 0;
- }
-
- rc = downstatelist[i].rout(trans, arg);
-
- return rc;
-}
-
-/* state trasitions for call control messages (lower layer) */
-static struct datastate {
- u_int32_t states;
- int type;
- int (*rout) (struct gsm_trans *trans, struct msgb *msg);
-} datastatelist[] = {
- /* mobile originating call establishment */
- {SBIT(GSM_CSTATE_INITIATED), /* 5.2.1.3 */
- GSM48_MT_CC_CALL_PROC, gsm48_cc_rx_call_proceeding},
-
- {SBIT(GSM_CSTATE_INITIATED) | SBIT(GSM_CSTATE_MO_CALL_PROC) |
- SBIT(GSM_CSTATE_CALL_DELIVERED), /* 5.2.1.4.1 */
- GSM48_MT_CC_PROGRESS, gsm48_cc_rx_progress},
-
- {SBIT(GSM_CSTATE_INITIATED) |
- SBIT(GSM_CSTATE_MO_CALL_PROC), /* 5.2.1.5 */
- GSM48_MT_CC_ALERTING, gsm48_cc_rx_alerting},
-
- {SBIT(GSM_CSTATE_INITIATED) | SBIT(GSM_CSTATE_MO_CALL_PROC) |
- SBIT(GSM_CSTATE_CALL_DELIVERED), /* 5.2.1.6 */
- GSM48_MT_CC_CONNECT, gsm48_cc_rx_connect},
-
- /* mobile terminating call establishment */
- {SBIT(GSM_CSTATE_NULL), /* 5.2.2.1 */
- GSM48_MT_CC_SETUP, gsm48_cc_rx_setup},
-
- {SBIT(GSM_CSTATE_CONNECT_REQUEST), /* 5.2.2.6 */
- GSM48_MT_CC_CONNECT_ACK, gsm48_cc_rx_connect_ack},
-
- /* signalling during call */
- {SBIT(GSM_CSTATE_ACTIVE), /* 5.3.1 */
- GSM48_MT_CC_NOTIFY, gsm48_cc_rx_notify},
-
- {ALL_STATES, /* 8.4 */
- GSM48_MT_CC_STATUS_ENQ, gsm48_cc_rx_status_enq},
-
- {ALL_STATES,
- GSM48_MT_CC_STATUS, gsm48_cc_rx_status},
-
- {ALL_STATES, /* 5.5.7.2 */
- GSM48_MT_CC_START_DTMF_ACK, gsm48_cc_rx_start_dtmf_ack},
-
- {ALL_STATES, /* 5.5.7.2 */
- GSM48_MT_CC_START_DTMF_REJ, gsm48_cc_rx_start_dtmf_rej},
-
- {ALL_STATES, /* 5.5.7.4 */
- GSM48_MT_CC_STOP_DTMF_ACK, gsm48_cc_rx_stop_dtmf_ack},
-
- {SBIT(GSM_CSTATE_ACTIVE),
- GSM48_MT_CC_HOLD_ACK, gsm48_cc_rx_hold_ack},
-
- {SBIT(GSM_CSTATE_ACTIVE),
- GSM48_MT_CC_HOLD_REJ, gsm48_cc_rx_hold_rej},
-
- {SBIT(GSM_CSTATE_ACTIVE),
- GSM48_MT_CC_RETR_ACK, gsm48_cc_rx_retrieve_ack},
-
- {SBIT(GSM_CSTATE_ACTIVE),
- GSM48_MT_CC_RETR_REJ, gsm48_cc_rx_retrieve_rej},
-
- {ALL_STATES - SBIT(GSM_CSTATE_NULL),
- GSM48_MT_CC_FACILITY, gsm48_cc_rx_facility},
-
- {SBIT(GSM_CSTATE_ACTIVE),
- GSM48_MT_CC_USER_INFO, gsm48_cc_rx_userinfo},
-
- /* clearing */
- {ALL_STATES - SBIT(GSM_CSTATE_NULL) - SBIT(GSM_CSTATE_RELEASE_REQ) -
- SBIT(GSM_CSTATE_DISCONNECT_IND), /* 5.4.4.1.1 */
- GSM48_MT_CC_DISCONNECT, gsm48_cc_rx_disconnect},
-
- {ALL_STATES, /* 5.4.3.3 & 5.4.5!!!*/
- GSM48_MT_CC_RELEASE, gsm48_cc_rx_release},
-
- {ALL_STATES, /* 5.4.4.1.3 */
- GSM48_MT_CC_RELEASE_COMPL, gsm48_cc_rx_release_compl},
-
- /* modify */
- {SBIT(GSM_CSTATE_ACTIVE),
- GSM48_MT_CC_MODIFY, gsm48_cc_rx_modify},
-
- {SBIT(GSM_CSTATE_MO_TERM_MODIFY),
- GSM48_MT_CC_MODIFY_COMPL, gsm48_cc_rx_modify_complete},
-
- {SBIT(GSM_CSTATE_MO_TERM_MODIFY),
- GSM48_MT_CC_MODIFY_REJECT, gsm48_cc_rx_modify_reject},
-};
-
-#define DATASLLEN \
- (sizeof(datastatelist) / sizeof(struct datastate))
-
-static int gsm48_cc_data_ind(struct gsm_trans *trans, struct msgb *msg)
-{
- struct osmocom_ms *ms = trans->ms;
- struct gsm48_hdr *gh = msgb_l3(msg);
- int msg_type = gh->msg_type & 0xbf;
- uint8_t transaction_id = ((gh->proto_discr & 0xf0) ^ 0x80) >> 4;
- /* flip */
- int msg_supported = 0; /* determine, if message is supported at all */
- int i, rc;
-
- /* set transaction ID, if not already */
- trans->transaction_id = transaction_id;
-
- /* pull the MMCC header */
- msgb_pull(msg, sizeof(struct gsm48_mmxx_hdr));
-
- LOGP(DCC, LOGL_INFO, "(ms %s) Received '%s' in CC state %s\n", ms->name,
- gsm48_cc_msg_name(msg_type),
- gsm48_cc_state_name(trans->cc.state));
-
- /* find function for current state and message */
- for (i = 0; i < DATASLLEN; i++) {
- if (msg_type == datastatelist[i].type)
- msg_supported = 1;
- if ((msg_type == datastatelist[i].type)
- && ((1 << trans->cc.state) & datastatelist[i].states))
- break;
- }
- if (i == DATASLLEN) {
- if (msg_supported) {
- LOGP(DCC, LOGL_NOTICE, "Message unhandled at this "
- "state.\n");
- return gsm48_cc_tx_status(trans,
- GSM48_REJECT_MSG_TYPE_NOT_COMPATIBLE);
- } else {
- LOGP(DCC, LOGL_NOTICE, "Message not supported.\n");
- return gsm48_cc_tx_status(trans,
- GSM48_REJECT_MSG_TYPE_NOT_IMPLEMENTED);
- }
- }
-
- rc = datastatelist[i].rout(trans, msg);
-
- return rc;
-}
-
-/* receive message from MM layer */
-int gsm48_rcv_cc(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
- int msg_type = mmh->msg_type;
- struct gsm_trans *trans;
- int rc = 0;
-
- trans = trans_find_by_callref(ms, mmh->ref);
- if (!trans) {
- trans = trans_alloc(ms, GSM48_PDISC_CC, mmh->transaction_id,
- mmh->ref);
- if (!trans)
- return -ENOMEM;
- }
-
- LOGP(DCC, LOGL_INFO, "(ms %s) Received '%s' in CC state %s\n", ms->name,
- get_mmxx_name(msg_type),
- gsm48_cc_state_name(trans->cc.state));
-
- switch (msg_type) {
- case GSM48_MMCC_EST_IND:
- /* data included */
- rc = gsm48_cc_data_ind(trans, msg);
- break;
- case GSM48_MMCC_EST_CNF:
- /* send setup after confirm */
- if (trans->cc.state == GSM_CSTATE_MM_CONNECTION_PEND)
- rc = gsm48_cc_tx_setup(trans);
- else
- LOGP(DCC, LOGL_ERROR, "Oops, MMCC-EST-CONF in state "
- "%d?\n", trans->cc.state);
- break;
- case GSM48_MMCC_ERR_IND: /* no supporting re-establishment */
- case GSM48_MMCC_REL_IND:
- /* release L4, release transaction */
- mncc_release_ind(trans->ms, trans, trans->callref,
- GSM48_CAUSE_LOC_PRN_S_LU, mmh->cause);
- /* release without sending MMCC_REL_REQ */
- new_cc_state(trans, GSM_CSTATE_NULL);
- trans->callref = 0;
- trans_free(trans);
- break;
- case GSM48_MMCC_DATA_IND:
- rc = gsm48_cc_data_ind(trans, msg);
- break;
- case GSM48_MMCC_UNIT_DATA_IND:
- break;
- case GSM48_MMCC_SYNC_IND:
- break;
- default:
- LOGP(DCC, LOGL_NOTICE, "Message unhandled.\n");
- rc = -ENOTSUP;
- }
-
- return rc;
-}
-
diff --git a/Src/osmoconbb/src/host/layer23/src/mobile/gsm48_mm.c b/Src/osmoconbb/src/host/layer23/src/mobile/gsm48_mm.c
deleted file mode 100644
index ff936e3..0000000
--- a/Src/osmoconbb/src/host/layer23/src/mobile/gsm48_mm.c
+++ /dev/null
@@ -1,4279 +0,0 @@
-/*
- * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdint.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <arpa/inet.h>
-
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/gsm/gsm48.h>
-#include <osmocom/core/talloc.h>
-
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/networks.h>
-#include <osmocom/bb/common/l1ctl.h>
-#include <osmocom/bb/mobile/gsm48_cc.h>
-#include <osmocom/bb/mobile/app_mobile.h>
-#include <osmocom/bb/mobile/vty.h>
-
-extern void *l23_ctx;
-
-void mm_conn_free(struct gsm48_mm_conn *conn);
-static int gsm48_rcv_rr(struct osmocom_ms *ms, struct msgb *msg);
-static int gsm48_rcv_mmr(struct osmocom_ms *ms, struct msgb *msg);
-static int gsm48_mm_ev(struct osmocom_ms *ms, int msg_type, struct msgb *msg);
-static int gsm48_mm_tx_id_rsp(struct osmocom_ms *ms, uint8_t mi_type);
-static int gsm48_mm_tx_loc_upd_req(struct osmocom_ms *ms);
-static int gsm48_mm_loc_upd_failed(struct osmocom_ms *ms, struct msgb *msg);
-static int gsm48_mm_conn_go_dedic(struct osmocom_ms *ms);
-static int gsm48_mm_init_mm_reject(struct osmocom_ms *ms, struct msgb *msg);
-static int gsm48_mm_data_ind(struct osmocom_ms *ms, struct msgb *msg);
-static void new_mm_state(struct gsm48_mmlayer *mm, int state, int substate);
-static int gsm48_mm_loc_upd_normal(struct osmocom_ms *ms, struct msgb *msg);
-static int gsm48_mm_loc_upd_periodic(struct osmocom_ms *ms, struct msgb *msg);
-static int gsm48_mm_loc_upd(struct osmocom_ms *ms, struct msgb *msg);
-
-/*
- * notes
- */
-
-/*
- * Notes on IMSI detach procedure:
- *
- * At the end of the procedure, the state of MM, RR, cell selection: No SIM.
- *
- * In MM IDLE state, cell available: RR is establised, IMSI detach specific
- * procedure is performed.
- *
- * In MM IDLE state, no cell: State is silently changed to No SIM.
- *
- * During any MM connection state, or Wait for network command: All MM
- * connections (if any) are released locally, and IMSI detach specific
- * procedure is performed.
- *
- * During IMSI detach processing: Request of IMSI detach is ignored.
- *
- * Any other state: The special 'delay_detach' flag is set only. If set, at any
- * state transition we will clear the flag and restart the procedure again.
- *
- * The procedure is not spec conform, but always succeeds.
- *
- */
-
-/* Notes on Service states:
- *
- * There are two PLMN search states:
- *
- * - PLMN SEARCH NORMAL
- * - PLMN SEARCH
- *
- * They are entered, if: (4.2.1.2)
- * - ME is switched on
- * - SIM is inserted
- * - user has asked PLMN selection in certain Service states
- * - coverage is lost in certain Service states
- * - roaming is denied
- * - (optionally see 4.2.1.2)
- *
- * PLMN SEARCH NORMAL state is then entered, if all these conditions are met:
- * - SIM is valid
- * - SIM state is U1
- * - SIM LAI valid
- * - cell selected
- * - cell == SIM LAI
- *
- * Otherwhise PLMN SEARCH is entered.
- *
- * During PLMN SEARCH NORMAL state: (4.2.2.5)
- * - on expirery of T3212: Perform periodic location update, when back
- * to NORMAL SERVICE state.
- * - perform IMSI detach
- * - perform MM connections
- * - respond to paging (if possible)
- *
- * During PLMN SEARCH state: (4.2.2.6)
- * - reject MM connection except for emergency calls
- *
- *
- * The NO CELL AVAILABLE state is entered, if:
- * - no cell found during PLMN search
- *
- * During NO CELL AVAILABLE state:
- * - reject any MM connection
- *
- * The NO IMSI state is entered if:
- * - SIM is invalid
- * - and cell is selected during PLMN SEARCH states
- *
- * During NO IMSO state: (4.2.2.4)
- * - reject MM connection except for emergency calls
- *
- * The LIMITED SERVICE state is entered if:
- * - SIM is valid
- * - and SIM state is U3
- * - and cell is selected
- *
- * During LIMITED SERVICE state: (4.2.2.3)
- * - reject MM connection except for emergency calls
- * - perform location update, if new LAI is entered
- *
- *
- * The LOCATION UPDATE NEEDED state is entered if:
- * - SIM is valid
- * - and location update must be performed for any reason
- *
- * During LOCATION UPDATE NEEDED state:
- * - reject MM connection except for emergency calls
- *
- * In all IDLE states:
- * - on expirery of T3211 or T3213: Perform location update, when back
- * to NORMAL SERVICE state.
- *
- * This state is left if location update is possible and directly enter
- * state ATTEMPTING TO UPDATE and trigger location update.
- * The function gsm48_mm_loc_upd_possible() is used to check this on state
- * change.
- *
- *
- * The ATTEMPTING TO UPDATE state is entered if:
- * - SIM is valid
- * - and SIM state is U2
- * - and cell is selected
- *
- * During ATTEMPTING TO UPDATE state: (4.2.2.2)
- * - on expirery of T3211 or T3213: Perform location updated
- * - on expirery of T3212: Perform location updated
- * - on change of LAI: Perform location update
- * - (abnormal cases unsupported)
- * - accept MM connection for emergency calls
- * - trigger location update on any other MM connection
- * - respond to paging (with IMSI only, because in U2 TMSI is not valid)
- *
- *
- * The NORMAL SERVICE state is entered if:
- * - SIM is valid
- * - and SIM state is U1
- * - and cell is selected
- * - and SIM LAI == cell
- *
- * During NORMAL SERVICE state: (4.2.2.1)
- * - on expirery of T3211 or T3213: Perform location updated
- * - on expirery of T3212: Perform location updated
- * - on change of LAI: Perform location update
- * - perform IMSI detach
- * - perform MM connections
- * - respond to paging
- *
- *
- * gsm48_mm_set_plmn_search() is used enter PLMN SEARCH or PLMN SEARCH NORMAL
- * state. Depending on the conditions above, the appropiate state is selected.
- *
- *
- * gsm48_mm_return_idle() is used to select the Service state when returning
- * to MM IDLE state after cell reselection.
- *
- *
- * If cell selection process indicates NO_CELL_FOUND:
- *
- * - NO CELL AVAILABLE state is entered, if not already.
- *
- * gsm48_mm_no_cell_found() is used to select the Service state.
- *
- *
- * If cell selection process indicates CELL_SELECTED:
- *
- * - NO IMSI state is entered, if no SIM valid.
- * - Otherwise NORMAL SERVICES state is entered, if
- * SIM state is U1, SIM LAI == cell, IMSI is attached, T3212 not expired.
- * - Otherwise NORMAL SERVICES state is entered, if
- * SIM state is U1, SIM LAI == cell, attach not required, T3212 not expired.
- * - Otherwise LIMITED SERVICE state is entered, if
- * CS mode is automatic, cell is forbidden PLMN or forbidden LA.
- * - Otherwise LIMITED SERVICE state is entered, if
- * CS mode is manual, cell is not the selected one.
- * - Otherwise LOCATION UPDATE NEEDED state is entered.
- *
- * gsm48_mm_cell_selected() is used to select the Service state.
- *
- */
-
-/*
- * support functions
- */
-
-/* get supported power level of given arfcn */
-uint8_t gsm48_current_pwr_lev(struct gsm_settings *set, uint16_t arfcn)
-{
- uint8_t pwr_lev;
-
- if (arfcn >= (512 | ARFCN_PCS) && arfcn <= (810 | ARFCN_PCS))
- pwr_lev = set->class_pcs - 1;
- else if (arfcn >= 512 && arfcn <= 885)
- pwr_lev = set->class_dcs - 1;
- else if (arfcn >= 259 && arfcn <= 340)
- pwr_lev = set->class_400 - 1;
- else if (arfcn >= 128 && arfcn <= 251)
- pwr_lev = set->class_850 - 1;
- else
- pwr_lev = set->class_900 - 1;
-
- return pwr_lev;
-}
-
-/* decode network name */
-static int decode_network_name(char *name, int name_len,
- const uint8_t *lv)
-{
- uint8_t in_len = lv[0];
- int length, padding;
-
- name[0] = '\0';
- if (in_len < 1)
- return -EINVAL;
-
- /* must be CB encoded */
- if ((lv[1] & 0x70) != 0x00)
- return -ENOTSUP;
-
- padding = lv[1] & 0x03;
- length = ((in_len - 1) * 8 - padding) / 7;
- if (length <= 0)
- return 0;
- if (length >= name_len)
- length = name_len - 1;
- gsm_7bit_decode(name, lv + 2, length);
- name[length] = '\0';
-
- return length;
-}
-
-/* encode 'mobile identity' */
-int gsm48_encode_mi(uint8_t *buf, struct msgb *msg, struct osmocom_ms *ms,
- uint8_t mi_type)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm_settings *set = &ms->settings;
- uint8_t *ie;
-
- switch(mi_type) {
- case GSM_MI_TYPE_TMSI:
- gsm48_generate_mid_from_tmsi(buf, subscr->tmsi);
- break;
- case GSM_MI_TYPE_IMSI:
- gsm48_generate_mid_from_imsi(buf, subscr->imsi);
- break;
- case GSM_MI_TYPE_IMEI:
- gsm48_generate_mid_from_imsi(buf, set->imei);
- break;
- case GSM_MI_TYPE_IMEISV:
- gsm48_generate_mid_from_imsi(buf, set->imeisv);
- break;
- case GSM_MI_TYPE_NONE:
- default:
- buf[0] = GSM48_IE_MOBILE_ID;
- buf[1] = 1;
- buf[2] = 0xf0;
- break;
- }
- /* alter MI type */
- buf[2] = (buf[2] & ~GSM_MI_TYPE_MASK) | mi_type;
-
- if (msg) {
- /* MI as LV */
- ie = msgb_put(msg, 1 + buf[1]);
- memcpy(ie, buf + 1, 1 + buf[1]);
- }
-
- return 0;
-}
-
-/* encode 'classmark 1' */
-int gsm48_encode_classmark1(struct gsm48_classmark1 *cm, uint8_t rev_lev,
- uint8_t es_ind, uint8_t a5_1, uint8_t pwr_lev)
-{
- memset(cm, 0, sizeof(*cm));
- cm->rev_lev = rev_lev;
- cm->es_ind = es_ind;
- cm->a5_1 = !a5_1;
- cm->pwr_lev = pwr_lev;
-
- return 0;
-}
-
-/*
- * timers
- */
-
-static void timeout_mm_t3210(void *arg)
-{
- struct gsm48_mmlayer *mm = arg;
-
- LOGP(DMM, LOGL_INFO, "timer T3210 (loc. upd. timeout) has fired\n");
- gsm48_mm_ev(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3210, NULL);
-}
-
-static void timeout_mm_t3211(void *arg)
-{
- struct gsm48_mmlayer *mm = arg;
-
- LOGP(DSUM, LOGL_INFO, "Location update retry\n");
- LOGP(DMM, LOGL_INFO, "timer T3211 (loc. upd. retry delay) has fired\n");
- gsm48_mm_ev(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3211, NULL);
-}
-
-static void timeout_mm_t3212(void *arg)
-{
- struct gsm48_mmlayer *mm = arg;
-
- LOGP(DSUM, LOGL_INFO, "Periodic location update\n");
- LOGP(DMM, LOGL_INFO, "timer T3212 (periodic loc. upd. delay) has "
- "fired\n");
-
- /* reset attempt counter when attempting to update (4.4.4.5) */
- if (mm->state == GSM48_MM_ST_MM_IDLE
- && mm->substate == GSM48_MM_SST_ATTEMPT_UPDATE)
- mm->lupd_attempt = 0;
-
- gsm48_mm_ev(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3212, NULL);
-}
-
-static void timeout_mm_t3213(void *arg)
-{
- struct gsm48_mmlayer *mm = arg;
-
- LOGP(DSUM, LOGL_INFO, "Location update retry\n");
- LOGP(DMM, LOGL_INFO, "timer T3213 (delay after RA failure) has "
- "fired\n");
- gsm48_mm_ev(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3213, NULL);
-}
-
-static void timeout_mm_t3230(void *arg)
-{
- struct gsm48_mmlayer *mm = arg;
-
- LOGP(DMM, LOGL_INFO, "timer T3230 (MM connection timeout) has "
- "fired\n");
- gsm48_mm_ev(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3230, NULL);
-}
-
-static void timeout_mm_t3220(void *arg)
-{
- struct gsm48_mmlayer *mm = arg;
-
- LOGP(DMM, LOGL_INFO, "timer T3220 (IMSI detach keepalive) has "
- "fired\n");
- gsm48_mm_ev(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3220, NULL);
-}
-
-static void timeout_mm_t3240(void *arg)
-{
- struct gsm48_mmlayer *mm = arg;
-
- LOGP(DMM, LOGL_INFO, "timer T3240 (RR release timeout) has fired\n");
- gsm48_mm_ev(mm->ms, GSM48_MM_EVENT_TIMEOUT_T3240, NULL);
-}
-
-static void start_mm_t3210(struct gsm48_mmlayer *mm)
-{
- LOGP(DMM, LOGL_INFO, "starting T3210 (loc. upd. timeout) with %d.%d "
- "seconds\n", GSM_T3210_MS);
- mm->t3210.cb = timeout_mm_t3210;
- mm->t3210.data = mm;
- osmo_timer_schedule(&mm->t3210, GSM_T3210_MS);
-}
-
-static void start_mm_t3211(struct gsm48_mmlayer *mm)
-{
- LOGP(DMM, LOGL_INFO, "starting T3211 (loc. upd. retry delay) with "
- "%d.%d seconds\n", GSM_T3211_MS);
- mm->t3211.cb = timeout_mm_t3211;
- mm->t3211.data = mm;
- osmo_timer_schedule(&mm->t3211, GSM_T3211_MS);
-}
-
-static void start_mm_t3212(struct gsm48_mmlayer *mm, int sec)
-{
- /* don't start, if is not available */
- if (!sec)
- return;
-
- LOGP(DMM, LOGL_INFO, "starting T3212 (periodic loc. upd. delay) with "
- "%d seconds\n", sec);
- mm->t3212.cb = timeout_mm_t3212;
- mm->t3212.data = mm;
- osmo_timer_schedule(&mm->t3212, sec, 0);
-}
-
-static void start_mm_t3213(struct gsm48_mmlayer *mm)
-{
- LOGP(DMM, LOGL_INFO, "starting T3213 (delay after RA failure) with "
- "%d.%d seconds\n", GSM_T3213_MS);
- mm->t3213.cb = timeout_mm_t3213;
- mm->t3213.data = mm;
- osmo_timer_schedule(&mm->t3213, GSM_T3213_MS);
-}
-
-static void start_mm_t3220(struct gsm48_mmlayer *mm)
-{
- LOGP(DMM, LOGL_INFO, "starting T3220 (IMSI detach keepalive) with "
- "%d.%d seconds\n", GSM_T3220_MS);
- mm->t3220.cb = timeout_mm_t3220;
- mm->t3220.data = mm;
- osmo_timer_schedule(&mm->t3220, GSM_T3220_MS);
-}
-
-static void start_mm_t3230(struct gsm48_mmlayer *mm)
-{
- LOGP(DMM, LOGL_INFO, "starting T3230 (MM connection timeout) with "
- "%d.%d seconds\n", GSM_T3230_MS);
- mm->t3230.cb = timeout_mm_t3230;
- mm->t3230.data = mm;
- osmo_timer_schedule(&mm->t3230, GSM_T3230_MS);
-}
-
-static void start_mm_t3240(struct gsm48_mmlayer *mm)
-{
- LOGP(DMM, LOGL_INFO, "starting T3240 (RR release timeout) with %d.%d "
- "seconds\n", GSM_T3240_MS);
- mm->t3240.cb = timeout_mm_t3240;
- mm->t3240.data = mm;
- osmo_timer_schedule(&mm->t3240, GSM_T3240_MS);
-}
-
-static void stop_mm_t3210(struct gsm48_mmlayer *mm)
-{
- if (osmo_timer_pending(&mm->t3210)) {
- LOGP(DMM, LOGL_INFO, "stopping pending (loc. upd. timeout) "
- "timer T3210\n");
- osmo_timer_del(&mm->t3210);
- }
-}
-
-static void stop_mm_t3211(struct gsm48_mmlayer *mm)
-{
- if (osmo_timer_pending(&mm->t3211)) {
- LOGP(DMM, LOGL_INFO, "stopping pending (loc. upd. retry "
- "delay) timer T3211\n");
- osmo_timer_del(&mm->t3211);
- }
-}
-
-static void stop_mm_t3212(struct gsm48_mmlayer *mm)
-{
- if (osmo_timer_pending(&mm->t3212)) {
- LOGP(DMM, LOGL_INFO, "stopping pending (periodic loc. upd. "
- "delay) timer T3212\n");
- osmo_timer_del(&mm->t3212);
- }
-}
-
-static void stop_mm_t3213(struct gsm48_mmlayer *mm)
-{
- if (osmo_timer_pending(&mm->t3213)) {
- LOGP(DMM, LOGL_INFO, "stopping pending (delay after RA "
- "failure) timer T3213\n");
- osmo_timer_del(&mm->t3213);
- }
-}
-
-static void stop_mm_t3220(struct gsm48_mmlayer *mm)
-{
- if (osmo_timer_pending(&mm->t3220)) {
- LOGP(DMM, LOGL_INFO, "stopping pending (IMSI detach keepalive) "
- "timer T3220\n");
- osmo_timer_del(&mm->t3220);
- }
-}
-
-static void stop_mm_t3230(struct gsm48_mmlayer *mm)
-{
- if (osmo_timer_pending(&mm->t3230)) {
- LOGP(DMM, LOGL_INFO, "stopping pending (MM connection timeout) "
- "timer T3230\n");
- osmo_timer_del(&mm->t3230);
- }
-}
-
-static void stop_mm_t3240(struct gsm48_mmlayer *mm)
-{
- if (osmo_timer_pending(&mm->t3240)) {
- LOGP(DMM, LOGL_INFO, "stopping pending (RR release timeout) "
- "timer T3240\n");
- osmo_timer_del(&mm->t3240);
- }
-}
-
-static void stop_mm_t3241(struct gsm48_mmlayer *mm)
-{
- /* not implemented, not required */
-}
-
-/*
- * messages
- */
-
-/* names of MM events */
-static const struct value_string gsm48_mmevent_names[] = {
- { GSM48_MM_EVENT_CELL_SELECTED, "MM_EVENT_CELL_SELECTED" },
- { GSM48_MM_EVENT_NO_CELL_FOUND, "MM_EVENT_NO_CELL_FOUND" },
- { GSM48_MM_EVENT_TIMEOUT_T3210, "MM_EVENT_TIMEOUT_T3210" },
- { GSM48_MM_EVENT_TIMEOUT_T3211, "MM_EVENT_TIMEOUT_T3211" },
- { GSM48_MM_EVENT_TIMEOUT_T3212, "MM_EVENT_TIMEOUT_T3212" },
- { GSM48_MM_EVENT_TIMEOUT_T3213, "MM_EVENT_TIMEOUT_T3213" },
- { GSM48_MM_EVENT_TIMEOUT_T3220, "MM_EVENT_TIMEOUT_T3220" },
- { GSM48_MM_EVENT_TIMEOUT_T3230, "MM_EVENT_TIMEOUT_T3230" },
- { GSM48_MM_EVENT_TIMEOUT_T3240, "MM_EVENT_TIMEOUT_T3240" },
- { GSM48_MM_EVENT_IMSI_DETACH, "MM_EVENT_IMSI_DETACH" },
- { GSM48_MM_EVENT_POWER_OFF, "MM_EVENT_POWER_OFF" },
- { GSM48_MM_EVENT_PAGING, "MM_EVENT_PAGING" },
- { GSM48_MM_EVENT_AUTH_RESPONSE, "MM_EVENT_AUTH_RESPONSE" },
- { GSM48_MM_EVENT_SYSINFO, "MM_EVENT_SYSINFO" },
- { GSM48_MM_EVENT_USER_PLMN_SEL, "MM_EVENT_USER_PLMN_SEL" },
- { GSM48_MM_EVENT_LOST_COVERAGE, "MM_EVENT_LOST_COVERAGE" },
- { 0, NULL }
-};
-
-const char *get_mmevent_name(int value)
-{
- return get_value_string(gsm48_mmevent_names, value);
-}
-
-/* names of MM-SAP */
-static const struct value_string gsm48_mm_msg_names[] = {
- { GSM48_MT_MM_IMSI_DETACH_IND, "MT_MM_IMSI_DETACH_IND" },
- { GSM48_MT_MM_LOC_UPD_ACCEPT, "MT_MM_LOC_UPD_ACCEPT" },
- { GSM48_MT_MM_LOC_UPD_REJECT, "MT_MM_LOC_UPD_REJECT" },
- { GSM48_MT_MM_LOC_UPD_REQUEST, "MT_MM_LOC_UPD_REQUEST" },
- { GSM48_MT_MM_AUTH_REJ, "MT_MM_AUTH_REJ" },
- { GSM48_MT_MM_AUTH_REQ, "MT_MM_AUTH_REQ" },
- { GSM48_MT_MM_AUTH_RESP, "MT_MM_AUTH_RESP" },
- { GSM48_MT_MM_ID_REQ, "MT_MM_ID_REQ" },
- { GSM48_MT_MM_ID_RESP, "MT_MM_ID_RESP" },
- { GSM48_MT_MM_TMSI_REALL_CMD, "MT_MM_TMSI_REALL_CMD" },
- { GSM48_MT_MM_TMSI_REALL_COMPL, "MT_MM_TMSI_REALL_COMPL" },
- { GSM48_MT_MM_CM_SERV_ACC, "MT_MM_CM_SERV_ACC" },
- { GSM48_MT_MM_CM_SERV_REJ, "MT_MM_CM_SERV_REJ" },
- { GSM48_MT_MM_CM_SERV_ABORT, "MT_MM_CM_SERV_ABORT" },
- { GSM48_MT_MM_CM_SERV_REQ, "MT_MM_CM_SERV_REQ" },
- { GSM48_MT_MM_CM_SERV_PROMPT, "MT_MM_CM_SERV_PROMPT" },
- { GSM48_MT_MM_CM_REEST_REQ, "MT_MM_CM_REEST_REQ" },
- { GSM48_MT_MM_ABORT, "MT_MM_ABORT" },
- { GSM48_MT_MM_NULL, "MT_MM_NULL" },
- { GSM48_MT_MM_STATUS, "MT_MM_STATUS" },
- { GSM48_MT_MM_INFO, "MT_MM_INFO" },
- { 0, NULL }
-};
-
-const char *get_mm_name(int value)
-{
- return get_value_string(gsm48_mm_msg_names, value);
-}
-
-/* names of MMxx-SAP */
-static const struct value_string gsm48_mmxx_msg_names[] = {
- { GSM48_MMCC_EST_REQ, "MMCC_EST_REQ" },
- { GSM48_MMCC_EST_IND, "MMCC_EST_IND" },
- { GSM48_MMCC_EST_CNF, "MMCC_EST_CNF" },
- { GSM48_MMCC_REL_REQ, "MMCC_REL_REQ" },
- { GSM48_MMCC_REL_IND, "MMCC_REL_IND" },
- { GSM48_MMCC_DATA_REQ, "MMCC_DATA_REQ" },
- { GSM48_MMCC_DATA_IND, "MMCC_DATA_IND" },
- { GSM48_MMCC_UNIT_DATA_REQ, "MMCC_UNIT_DATA_REQ" },
- { GSM48_MMCC_UNIT_DATA_IND, "MMCC_UNIT_DATA_IND" },
- { GSM48_MMCC_SYNC_IND, "MMCC_SYNC_IND" },
- { GSM48_MMCC_REEST_REQ, "MMCC_REEST_REQ" },
- { GSM48_MMCC_REEST_CNF, "MMCC_REEST_CNF" },
- { GSM48_MMCC_ERR_IND, "MMCC_ERR_IND" },
- { GSM48_MMCC_PROMPT_IND, "MMCC_PROMPT_IND" },
- { GSM48_MMCC_PROMPT_REJ, "MMCC_PROMPT_REJ" },
- { GSM48_MMSS_EST_REQ, "MMSS_EST_REQ" },
- { GSM48_MMSS_EST_IND, "MMSS_EST_IND" },
- { GSM48_MMSS_EST_CNF, "MMSS_EST_CNF" },
- { GSM48_MMSS_REL_REQ, "MMSS_REL_REQ" },
- { GSM48_MMSS_REL_IND, "MMSS_REL_IND" },
- { GSM48_MMSS_DATA_REQ, "MMSS_DATA_REQ" },
- { GSM48_MMSS_DATA_IND, "MMSS_DATA_IND" },
- { GSM48_MMSS_UNIT_DATA_REQ, "MMSS_UNIT_DATA_REQ" },
- { GSM48_MMSS_UNIT_DATA_IND, "MMSS_UNIT_DATA_IND" },
- { GSM48_MMSS_REEST_REQ, "MMSS_REEST_REQ" },
- { GSM48_MMSS_REEST_CNF, "MMSS_REEST_CNF" },
- { GSM48_MMSS_ERR_IND, "MMSS_ERR_IND" },
- { GSM48_MMSS_PROMPT_IND, "MMSS_PROMPT_IND" },
- { GSM48_MMSS_PROMPT_REJ, "MMSS_PROMPT_REJ" },
- { GSM48_MMSMS_EST_REQ, "MMSMS_EST_REQ" },
- { GSM48_MMSMS_EST_IND, "MMSMS_EST_IND" },
- { GSM48_MMSMS_EST_CNF, "MMSMS_EST_CNF" },
- { GSM48_MMSMS_REL_REQ, "MMSMS_REL_REQ" },
- { GSM48_MMSMS_REL_IND, "MMSMS_REL_IND" },
- { GSM48_MMSMS_DATA_REQ, "MMSMS_DATA_REQ" },
- { GSM48_MMSMS_DATA_IND, "MMSMS_DATA_IND" },
- { GSM48_MMSMS_UNIT_DATA_REQ, "MMSMS_UNIT_DATA_REQ" },
- { GSM48_MMSMS_UNIT_DATA_IND, "MMSMS_UNIT_DATA_IND" },
- { GSM48_MMSMS_REEST_REQ, "MMSMS_REEST_REQ" },
- { GSM48_MMSMS_REEST_CNF, "MMSMS_REEST_CNF" },
- { GSM48_MMSMS_ERR_IND, "MMSMS_ERR_IND" },
- { GSM48_MMSMS_PROMPT_IND, "MMSMS_PROMPT_IND" },
- { GSM48_MMSMS_PROMPT_REJ, "MMSMS_PROMPT_REJ" },
- { 0, NULL }
-};
-
-const char *get_mmxx_name(int value)
-{
- return get_value_string(gsm48_mmxx_msg_names, value);
-}
-
-/* names of MMR-SAP */
-static const struct value_string gsm48_mmr_msg_names[] = {
- { GSM48_MMR_REG_REQ, "MMR_REG_REQ" },
- { GSM48_MMR_REG_CNF, "MMR_REG_CNF" },
- { GSM48_MMR_NREG_REQ, "MMR_NREG_REQ" },
- { GSM48_MMR_NREG_IND, "MMR_NREG_IND" },
- { 0, NULL }
-};
-
-const char *get_mmr_name(int value)
-{
- return get_value_string(gsm48_mmr_msg_names, value);
-}
-
-/* allocate GSM 04.08 message (MMxx-SAP) */
-struct msgb *gsm48_mmxx_msgb_alloc(int msg_type, uint32_t ref,
- uint8_t transaction_id)
-{
- struct msgb *msg;
- struct gsm48_mmxx_hdr *mmh;
-
- msg = msgb_alloc_headroom(MMXX_ALLOC_SIZE+MMXX_ALLOC_HEADROOM,
- MMXX_ALLOC_HEADROOM, "GSM 04.08 MMxx");
- if (!msg)
- return NULL;
-
- mmh = (struct gsm48_mmxx_hdr *)msgb_put(msg, sizeof(*mmh));
- mmh->msg_type = msg_type;
- mmh->ref = ref;
- mmh->transaction_id = transaction_id;
-
- return msg;
-}
-
-/* allocate MM event message */
-struct msgb *gsm48_mmevent_msgb_alloc(int msg_type)
-{
- struct msgb *msg;
- struct gsm48_mm_event *mme;
-
- msg = msgb_alloc_headroom(sizeof(*mme), 0, "GSM 04.08 MM event");
- if (!msg)
- return NULL;
-
- mme = (struct gsm48_mm_event *)msgb_put(msg, sizeof(*mme));
- mme->msg_type = msg_type;
-
- return msg;
-}
-
-/* allocate MMR message */
-struct msgb *gsm48_mmr_msgb_alloc(int msg_type)
-{
- struct msgb *msg;
- struct gsm48_mmr *mmr;
-
- msg = msgb_alloc_headroom(sizeof(*mmr), 0, "GSM 04.08 MMR");
- if (!msg)
- return NULL;
-
- mmr = (struct gsm48_mmr *)msgb_put(msg, sizeof(*mmr));
- mmr->msg_type = msg_type;
-
- return msg;
-}
-
-/* queue message (MMxx-SAP) */
-int gsm48_mmxx_upmsg(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
-
- msgb_enqueue(&mm->mmxx_upqueue, msg);
-
- return 0;
-}
-
-/* queue message (MMR-SAP) */
-int gsm48_mmr_downmsg(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
-
- msgb_enqueue(&mm->mmr_downqueue, msg);
-
- return 0;
-}
-
-/* queue MM event message */
-int gsm48_mmevent_msg(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
-
- msgb_enqueue(&mm->event_queue, msg);
-
- return 0;
-}
-
-/* dequeue messages (MMxx-SAP) */
-int gsm48_mmxx_dequeue(struct osmocom_ms *ms)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct msgb *msg;
- struct gsm48_mmxx_hdr *mmh;
- int work = 0;
-
- while ((msg = msgb_dequeue(&mm->mmxx_upqueue))) {
- mmh = (struct gsm48_mmxx_hdr *) msg->data;
- switch (mmh->msg_type & GSM48_MMXX_MASK) {
- case GSM48_MMCC_CLASS:
- gsm48_rcv_cc(ms, msg);
- break;
-#if 0
- case GSM48_MMSS_CLASS:
- gsm48_rcv_ss(ms, msg);
- break;
- case GSM48_MMSMS_CLASS:
- gsm48_rcv_sms(ms, msg);
- break;
-#endif
- }
- msgb_free(msg);
- work = 1; /* work done */
- }
-
- return work;
-}
-
-/* dequeue messages (MMR-SAP) */
-int gsm48_mmr_dequeue(struct osmocom_ms *ms)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct msgb *msg;
- struct gsm48_mmr *mmr;
- int work = 0;
-
- while ((msg = msgb_dequeue(&mm->mmr_downqueue))) {
- mmr = (struct gsm48_mmr *) msg->data;
- gsm48_rcv_mmr(ms, msg);
- msgb_free(msg);
- work = 1; /* work done */
- }
-
- return work;
-}
-
-/* dequeue messages (RR-SAP) */
-int gsm48_rr_dequeue(struct osmocom_ms *ms)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct msgb *msg;
- int work = 0;
-
- while ((msg = msgb_dequeue(&mm->rr_upqueue))) {
- /* msg is freed there */
- gsm48_rcv_rr(ms, msg);
- work = 1; /* work done */
- }
-
- return work;
-}
-
-/* dequeue MM event messages */
-int gsm48_mmevent_dequeue(struct osmocom_ms *ms)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm48_mm_event *mme;
- struct msgb *msg;
- int work = 0;
-
- while ((msg = msgb_dequeue(&mm->event_queue))) {
- mme = (struct gsm48_mm_event *) msg->data;
- gsm48_mm_ev(ms, mme->msg_type, msg);
- msgb_free(msg);
- work = 1; /* work done */
- }
-
- return work;
-}
-
-/* push RR header and send to RR */
-static int gsm48_mm_to_rr(struct osmocom_ms *ms, struct msgb *msg,
- int msg_type, uint8_t cause)
-{
- struct gsm48_rr_hdr *rrh;
-
- /* push RR header */
- msgb_push(msg, sizeof(struct gsm48_rr_hdr));
- rrh = (struct gsm48_rr_hdr *) msg->data;
- rrh->msg_type = msg_type;
- rrh->cause = cause;
-
- /* send message to RR */
- return gsm48_rr_downmsg(ms, msg);
-}
-
-/*
- * state transition
- */
-
-const char *gsm48_mm_state_names[] = {
- "NULL",
- "undefined 1",
- "undefined 2",
- "location updating initiated",
- "undefined 4",
- "wait for outgoing MM connection",
- "MM connection active",
- "IMSI detach initiated",
- "process CM service prompt",
- "wait for network command",
- "location updating reject",
- "undefined 11",
- "undefined 12",
- "wait for RR connection (location updating)",
- "wait for RR connection (MM connection)",
- "wait for RR connection (IMSI detach)",
- "undefined 16",
- "wait for re-establishment",
- "wait for RR connection active",
- "MM idle",
- "wait for additional outgoing MM connection",
- "MM_CONN_ACTIVE_VGCS",
- "WAIT_RR_CONN_VGCS",
- "location updating pending",
- "IMSI detach pending",
- "RR connection release not allowed"
-};
-
-const char *gsm48_mm_substate_names[] = {
- "NULL",
- "normal service",
- "attempting to update",
- "limited service",
- "no IMSI",
- "no cell available",
- "location updating needed",
- "PLMN search",
- "PLMN search (normal)",
- "RX_VGCS_NORMAL",
- "RX_VGCS_LIMITED"
-};
-
-/* change state from LOCATION UPDATE NEEDED to ATTEMPTING TO UPDATE */
-static int gsm48_mm_loc_upd_possible(struct gsm48_mmlayer *mm)
-{
- // TODO: check if really possible
- new_mm_state(mm, GSM48_MM_ST_MM_IDLE, GSM48_MM_SST_ATTEMPT_UPDATE);
- return gsm48_mm_loc_upd_normal(mm->ms, NULL);
-}
-
-/* Set new MM state, also new substate in case of MM IDLE state. */
-static void new_mm_state(struct gsm48_mmlayer *mm, int state, int substate)
-{
- struct osmocom_ms *ms = mm->ms;
- struct gsm322_plmn *plmn = &ms->plmn;
-
- /* IDLE -> IDLE */
- if (mm->state == GSM48_MM_ST_MM_IDLE && state == mm->state)
- LOGP(DMM, LOGL_INFO, "new MM IDLE state %s -> %s\n",
- gsm48_mm_substate_names[mm->substate],
- gsm48_mm_substate_names[substate]);
- /* IDLE -> non-IDLE */
- else if (mm->state == GSM48_MM_ST_MM_IDLE)
- LOGP(DMM, LOGL_INFO, "new state MM IDLE, %s -> %s\n",
- gsm48_mm_substate_names[mm->substate],
- gsm48_mm_state_names[state]);
- /* non-IDLE -> IDLE */
- else if (state == GSM48_MM_ST_MM_IDLE)
- LOGP(DMM, LOGL_INFO, "new state %s -> MM IDLE, %s\n",
- gsm48_mm_state_names[mm->state],
- gsm48_mm_substate_names[substate]);
- /* non-IDLE -> non-IDLE */
- else
- LOGP(DMM, LOGL_INFO, "new state %s -> %s\n",
- gsm48_mm_state_names[mm->state],
- gsm48_mm_state_names[state]);
-
- /* display service on new IDLE state */
- if (state == GSM48_MM_ST_MM_IDLE
- && (mm->state != GSM48_MM_ST_MM_IDLE || mm->substate != substate)) {
- switch (substate) {
- case GSM48_MM_SST_NORMAL_SERVICE:
- vty_notify(ms, NULL);
- vty_notify(ms, "On Network, normal service: %s, %s\n",
- gsm_get_mcc(plmn->mcc),
- gsm_get_mnc(plmn->mcc, plmn->mnc));
- break;
- case GSM48_MM_SST_LIMITED_SERVICE:
- vty_notify(ms, NULL);
- vty_notify(ms, "Limited service, emergency calls are "
- "possible.\n");
- break;
- case GSM48_MM_SST_PLMN_SEARCH_NORMAL:
- case GSM48_MM_SST_PLMN_SEARCH:
- vty_notify(ms, NULL);
- vty_notify(ms, "Searching network...\n");
- break;
- case GSM48_MM_SST_NO_IMSI:
- vty_notify(ms, NULL);
- vty_notify(ms, "No SIM, emergency calls are "
- "possible.\n");
- break;
- case GSM48_MM_SST_NO_CELL_AVAIL:
- vty_notify(ms, NULL);
- vty_notify(ms, "No service.\n");
- break;
- case GSM48_MM_SST_ATTEMPT_UPDATE:
- vty_notify(ms, NULL);
- vty_notify(ms, "Trying to registering with "
- "network...\n");
- break;
- }
- }
-
- /* remember most recent substate */
- if (mm->state == GSM48_MM_ST_MM_IDLE)
- mm->mr_substate = mm->substate;
-
- mm->state = state;
- mm->substate = substate;
-
- /* resend detach event, if flag is set */
- if (state == GSM48_MM_ST_MM_IDLE && mm->delay_detach) {
- struct msgb *nmsg;
-
- mm->delay_detach = 0;
-
- nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_IMSI_DETACH);
- if (!nmsg)
- return;
- gsm48_mmevent_msg(ms, nmsg);
- }
-
- /* 4.4.2 start T3212 in MM IDLE mode if not started or has expired */
- if (state == GSM48_MM_ST_MM_IDLE
- && (substate == GSM48_MM_SST_NORMAL_SERVICE
- || substate == GSM48_MM_SST_ATTEMPT_UPDATE)) {
- struct gsm48_sysinfo *s = &mm->ms->cellsel.sel_si;
-
- /* start periodic location update timer */
- if (s->t3212 && !osmo_timer_pending(&mm->t3212)) {
- mm->t3212_value = s->t3212;
- start_mm_t3212(mm, mm->t3212_value);
- }
- /* perform pending location update */
- if (mm->lupd_retry) {
- LOGP(DMM, LOGL_INFO, "Loc. upd. pending (type %d)\n",
- mm->lupd_type);
- mm->lupd_retry = 0;
- gsm48_mm_loc_upd(ms, NULL);
- /* must exit, because this function can be called
- * recursively
- */
- return;
- }
- if (mm->lupd_periodic) {
- LOGP(DMM, LOGL_INFO, "Periodic loc. upd. pending "
- "(type %d)\n", mm->lupd_type);
- mm->lupd_periodic = 0;
- if (s->t3212) /* still required? */
- gsm48_mm_loc_upd_periodic(ms, NULL);
- else
- LOGP(DMM, LOGL_INFO, "but not requred\n");
- /* must exit, because this function can be called
- * recursively
- */
- return;
- }
- }
-
- /* check if location update is possible */
- if (state == GSM48_MM_ST_MM_IDLE
- && substate == GSM48_MM_SST_LOC_UPD_NEEDED) {
- gsm48_mm_loc_upd_possible(mm);
- /* must exit, because this function can be called recursively */
- return;
- }
-}
-
-/* return PLMN SEARCH or PLMN SEARCH NORMAL state */
-static int gsm48_mm_set_plmn_search(struct osmocom_ms *ms)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm322_cellsel *cs = &ms->cellsel;
-
- /* SIM not inserted */
- if (!subscr->sim_valid) {
- LOGP(DMM, LOGL_INFO, "Selecting PLMN SEARCH state, because "
- "no SIM.\n");
- return GSM48_MM_SST_PLMN_SEARCH;
- }
-
- /* SIM not updated */
- if (subscr->ustate != GSM_SIM_U1_UPDATED) {
- LOGP(DMM, LOGL_INFO, "Selecting PLMN SEARCH state, because "
- "SIM not updated.\n");
- return GSM48_MM_SST_PLMN_SEARCH;
- }
- if (subscr->lac == 0x0000 || subscr->lac >= 0xfffe) {
- LOGP(DMM, LOGL_INFO, "Selecting PLMN SEARCH state, because "
- "LAI in SIM not valid.\n");
- return GSM48_MM_SST_PLMN_SEARCH;
- }
-
- /* no cell selected */
- if (!cs->selected) {
- LOGP(DMM, LOGL_INFO, "Selecting PLMN SEARCH state, because "
- "no cell selected.\n");
- return GSM48_MM_SST_PLMN_SEARCH;
- }
-
- /* selected cell's LAI not equal to LAI stored on the sim */
- if (cs->sel_mcc != subscr->mcc
- || cs->sel_mnc != subscr->mnc
- || cs->sel_lac != subscr->lac) {
- LOGP(DMM, LOGL_INFO, "Selecting PLMN SEARCH state, because "
- "LAI of selected cell (MCC %s MNC %s LAC 0x%04x) "
- "!= LAI in SIM (MCC %s MNC %s LAC 0x%04x).\n",
- gsm_print_mcc(cs->sel_mcc), gsm_print_mnc(cs->sel_mnc),
- cs->sel_lac, gsm_print_mcc(subscr->mcc),
- gsm_print_mnc(subscr->mnc), subscr->lac);
- return GSM48_MM_SST_PLMN_SEARCH;
- }
-
- /* SIM is updated in this LA */
- LOGP(DMM, LOGL_INFO, "Selecting PLMN SEARCH NORMAL state.\n");
- return GSM48_MM_SST_PLMN_SEARCH_NORMAL;
-}
-
-/* 4.2.3 when returning to MM IDLE state, this function is called */
-static int gsm48_mm_return_idle(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm322_cellsel *cs = &ms->cellsel;
-
- if (cs->state != GSM322_C3_CAMPED_NORMALLY
- && cs->state != GSM322_C7_CAMPED_ANY_CELL) {
- LOGP(DMM, LOGL_INFO, "Not camping, wait for CS process to "
- "camp, it sends us CELL_SELECTED then.\n");
- return 0;
- }
-
- /* 4.4.4.9 start T3211 when RR is released */
- if (mm->start_t3211) {
- LOGP(DMM, LOGL_INFO, "Starting T3211 after RR release.\n");
- mm->start_t3211 = 0;
- start_mm_t3211(mm);
- }
-
- /* return from location update with "Roaming not allowed" */
- if (mm->state == GSM48_MM_ST_LOC_UPD_REJ && mm->lupd_rej_cause == 13) {
- LOGP(DMM, LOGL_INFO, "Roaming not allowed as returning to "
- "MM IDLE\n");
- new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
- gsm48_mm_set_plmn_search(ms));
-
- return 0;
- }
-
- /* no SIM present or invalid */
- if (!subscr->sim_valid) {
- LOGP(DMM, LOGL_INFO, "SIM invalid as returning to MM IDLE\n");
-
- /* stop periodic location updating */
- mm->lupd_pending = 0;
- stop_mm_t3212(mm); /* 4.4.2 */
-
- new_mm_state(mm, GSM48_MM_ST_MM_IDLE, GSM48_MM_SST_NO_IMSI);
-
- return 0;
- }
-
- /* selected cell equals the registered LAI */
- if (subscr->lac /* valid */
- && cs->sel_mcc == subscr->mcc
- && cs->sel_mnc == subscr->mnc
- && cs->sel_lac == subscr->lac) {
- LOGP(DMM, LOGL_INFO, "We are in registered LAI as returning "
- "to MM IDLE\n");
- /* if SIM not updated (abnormal case as described in 4.4.4.9) */
- if (subscr->ustate != GSM_SIM_U1_UPDATED)
- new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
- GSM48_MM_SST_ATTEMPT_UPDATE);
- else
- new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
- GSM48_MM_SST_NORMAL_SERVICE);
-
- return 0;
- }
-
- if (cs->state == GSM322_C3_CAMPED_NORMALLY) {
- LOGP(DMM, LOGL_INFO, "We are camping normally as returning to "
- "MM IDLE\n");
- if (gsm_subscr_is_forbidden_plmn(subscr, cs->sel_mcc,
- cs->sel_mnc)) {
- /* location update not allowed */
- LOGP(DMM, LOGL_INFO, "Loc. upd. not allowed PLMN.\n");
- new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
- GSM48_MM_SST_LIMITED_SERVICE);
- } else
- if (gsm322_is_forbidden_la(ms, cs->sel_mcc, cs->sel_mnc,
- cs->sel_lac)) {
- /* location update not allowed */
- LOGP(DMM, LOGL_INFO, "Loc. upd. not allowed LA.\n");
- new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
- GSM48_MM_SST_LIMITED_SERVICE);
- } else {
- /* location update allowed */
- LOGP(DMM, LOGL_INFO, "Loc. upd. allowed.\n");
- new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
- GSM48_MM_SST_LOC_UPD_NEEDED);
- }
- } else {
- /* location update not allowed */
- LOGP(DMM, LOGL_INFO, "We are camping on any cell as returning "
- "to MM IDLE\n");
- new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
- GSM48_MM_SST_LIMITED_SERVICE);
- }
-
- return 0;
-}
-
-/* 4.2.1.1 Service state PLMN SEARCH (NORMAL) is left if no cell found */
-static int gsm48_mm_no_cell_found(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
-
- new_mm_state(mm, GSM48_MM_ST_MM_IDLE, GSM48_MM_SST_NO_CELL_AVAIL);
-
- return 0;
-}
-
-/* 4.2.1.1 Service state PLMN SEARCH (NORMAL) / NO CELL AVAILABLE is left
- * if cell selected
- */
-static int gsm48_mm_cell_selected(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm322_plmn *plmn = &ms->plmn;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = &cs->sel_si;
- struct gsm_settings *set = &ms->settings;
-
- /* no SIM is inserted */
- if (!subscr->sim_valid) {
- LOGP(DMM, LOGL_INFO, "SIM invalid as cell is selected.\n");
- new_mm_state(mm, GSM48_MM_ST_MM_IDLE, GSM48_MM_SST_NO_IMSI);
-
- return 0;
- }
-
- /* SIM not updated in this LA */
- if (subscr->ustate == GSM_SIM_U1_UPDATED
- && subscr->lac /* valid */
- && cs->sel_mcc == subscr->mcc
- && cs->sel_mnc == subscr->mnc
- && cs->sel_lac == subscr->lac
- && !mm->lupd_periodic) {
- if (subscr->imsi_attached) {
- struct msgb *nmsg;
-
- LOGP(DMM, LOGL_INFO, "Valid in location area.\n");
- new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
- GSM48_MM_SST_NORMAL_SERVICE);
-
- /* send message to PLMN search process */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_SUCCESS);
- if (!nmsg)
- return -ENOMEM;
- gsm322_plmn_sendmsg(ms, nmsg);
-
- return 0;
- }
- if (!s->att_allowed) {
- struct msgb *nmsg;
-
- LOGP(DMM, LOGL_INFO, "Attachment not required.\n");
- new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
- GSM48_MM_SST_NORMAL_SERVICE);
-
- /* send message to PLMN search process */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_SUCCESS);
- if (!nmsg)
- return -ENOMEM;
- gsm322_plmn_sendmsg(ms, nmsg);
-
- return 0;
- }
- /* else, continue */
- }
-
- /* PLMN mode auto and selected cell is forbidden */
- if (set->plmn_mode == PLMN_MODE_AUTO
- && (!cs->selected
- || gsm_subscr_is_forbidden_plmn(subscr, cs->sel_mcc, cs->sel_mnc)
- || gsm322_is_forbidden_la(ms, cs->sel_mcc, cs->sel_mnc,
- cs->sel_lac))) {
- struct msgb *nmsg;
-
- LOGP(DMM, LOGL_INFO, "Selected cell is forbidden.\n");
- new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
- GSM48_MM_SST_LIMITED_SERVICE);
-
- /* send message to PLMN search process */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_FAILED);
- if (!nmsg)
- return -ENOMEM;
- gsm322_plmn_sendmsg(ms, nmsg);
-
- return 0;
- }
-
- /* PLMN mode manual and selected cell not selected PLMN.
- * in M3 state the PLMN is not selected for registration. */
- if (set->plmn_mode == PLMN_MODE_MANUAL
- && (!cs->selected
- || plmn->mcc != cs->sel_mcc
- || plmn->mnc != cs->sel_mnc
- || plmn->state == GSM322_M3_NOT_ON_PLMN)) {
- struct msgb *nmsg;
-
- LOGP(DMM, LOGL_INFO, "Selected cell not found.\n");
- new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
- GSM48_MM_SST_LIMITED_SERVICE);
-
- /* send message to PLMN search process */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_FAILED);
- if (!nmsg)
- return -ENOMEM;
- gsm322_plmn_sendmsg(ms, nmsg);
-
- return 0;
- }
-
- /* other cases */
- new_mm_state(mm, GSM48_MM_ST_MM_IDLE, GSM48_MM_SST_LOC_UPD_NEEDED);
-
- return 0;
-}
-
-/* 4.2.1.2 Service state PLMN SEARCH (NORMAL) is entered */
-static int gsm48_mm_plmn_search(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
-
- new_mm_state(mm, GSM48_MM_ST_MM_IDLE, gsm48_mm_set_plmn_search(ms));
-
- return 0;
-}
-
-/*
- * init and exit
- */
-
-/* initialize Mobility Management process */
-int gsm48_mm_init(struct osmocom_ms *ms)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
-
- memset(mm, 0, sizeof(*mm));
- mm->ms = ms;
-
- LOGP(DMM, LOGL_INFO, "init Mobility Management process\n");
-
- /* 4.2.1.1 */
- mm->state = GSM48_MM_ST_MM_IDLE;
- mm->substate = gsm48_mm_set_plmn_search(ms);
-
- /* init lists */
- INIT_LLIST_HEAD(&mm->mm_conn);
- INIT_LLIST_HEAD(&mm->rr_upqueue);
- INIT_LLIST_HEAD(&mm->mmxx_upqueue);
- INIT_LLIST_HEAD(&mm->mmr_downqueue);
- INIT_LLIST_HEAD(&mm->event_queue);
-
- return 0;
-}
-
-/* exit MM process */
-int gsm48_mm_exit(struct osmocom_ms *ms)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm48_mm_conn *conn;
- struct msgb *msg;
-
- LOGP(DMM, LOGL_INFO, "exit Mobility Management process\n");
-
- /* flush lists */
- while (!llist_empty(&mm->mm_conn)) {
- conn = llist_entry(mm->mm_conn.next,
- struct gsm48_mm_conn, list);
- mm_conn_free(conn);
- }
- while ((msg = msgb_dequeue(&mm->rr_upqueue)))
- msgb_free(msg);
- while ((msg = msgb_dequeue(&mm->mmxx_upqueue)))
- msgb_free(msg);
- while ((msg = msgb_dequeue(&mm->mmr_downqueue)))
- msgb_free(msg);
- while ((msg = msgb_dequeue(&mm->event_queue)))
- msgb_free(msg);
-
- /* stop timers */
- stop_mm_t3210(mm);
- stop_mm_t3211(mm);
- stop_mm_t3212(mm);
- stop_mm_t3213(mm);
- stop_mm_t3220(mm);
- stop_mm_t3230(mm);
- stop_mm_t3240(mm);
-
- return 0;
-}
-
-/*
- * MM connection management
- */
-
-static const char *gsm48_mmxx_state_names[] = {
- "IDLE",
- "CONN_PEND",
- "DEDICATED",
- "CONN_SUSP",
- "REESTPEND"
-};
-
-uint32_t mm_conn_new_ref = 0x80000001;
-
-/* new MM connection state */
-static void new_conn_state(struct gsm48_mm_conn *conn, int state)
-{
- LOGP(DMM, LOGL_INFO, "(ref %x) new state %s -> %s\n", conn->ref,
- gsm48_mmxx_state_names[conn->state],
- gsm48_mmxx_state_names[state]);
- conn->state = state;
-}
-
-/* find MM connection by protocol+ID */
-struct gsm48_mm_conn *mm_conn_by_id(struct gsm48_mmlayer *mm,
- uint8_t proto, uint8_t transaction_id)
-{
- struct gsm48_mm_conn *conn;
-
- llist_for_each_entry(conn, &mm->mm_conn, list) {
- if (conn->protocol == proto &&
- conn->transaction_id == transaction_id)
- return conn;
- }
- return NULL;
-}
-
-/* find MM connection by reference */
-struct gsm48_mm_conn *mm_conn_by_ref(struct gsm48_mmlayer *mm,
- uint32_t ref)
-{
- struct gsm48_mm_conn *conn;
-
- llist_for_each_entry(conn, &mm->mm_conn, list) {
- if (conn->ref == ref)
- return conn;
- }
- return NULL;
-}
-
-/* create MM connection instance */
-static struct gsm48_mm_conn* mm_conn_new(struct gsm48_mmlayer *mm,
- int proto, uint8_t transaction_id, uint32_t ref)
-{
- struct gsm48_mm_conn *conn = talloc_zero(l23_ctx, struct gsm48_mm_conn);
-
- if (!conn)
- return NULL;
-
- LOGP(DMM, LOGL_INFO, "New MM Connection (proto 0x%02x trans_id %d "
- "ref %d)\n", proto, transaction_id, ref);
-
- conn->mm = mm;
- conn->state = GSM48_MMXX_ST_IDLE;
- conn->transaction_id = transaction_id;
- conn->protocol = proto;
- conn->ref = ref;
-
- llist_add(&conn->list, &mm->mm_conn);
-
- return conn;
-}
-
-/* destroy MM connection instance */
-void mm_conn_free(struct gsm48_mm_conn *conn)
-{
- LOGP(DMM, LOGL_INFO, "Freeing MM Connection\n");
-
- new_conn_state(conn, GSM48_MMXX_ST_IDLE);
-
- llist_del(&conn->list);
-
- talloc_free(conn);
-}
-
-/* support function to release pending/all ongoing MM connections */
-static int gsm48_mm_release_mm_conn(struct osmocom_ms *ms, int abort_any,
- uint8_t cause, int error)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm48_mm_conn *conn, *conn2;
- struct msgb *nmsg;
- struct gsm48_mmxx_hdr *nmmh;
-
- if (abort_any)
- LOGP(DMM, LOGL_INFO, "Release any MM Connection\n");
- else
- LOGP(DMM, LOGL_INFO, "Release pending MM Connections\n");
-
- /* release MM connection(s) */
- llist_for_each_entry_safe(conn, conn2, &mm->mm_conn, list) {
- /* abort any OR the pending connection */
- if (abort_any || conn->state == GSM48_MMXX_ST_CONN_PEND) {
- /* send MMxx-REL-IND */
- nmsg = NULL;
- switch(conn->protocol) {
- case GSM48_PDISC_CC:
- nmsg = gsm48_mmxx_msgb_alloc(
- error ? GSM48_MMCC_ERR_IND
- : GSM48_MMCC_REL_IND, conn->ref,
- conn->transaction_id);
- break;
- case GSM48_PDISC_NC_SS:
- nmsg = gsm48_mmxx_msgb_alloc(
- error ? GSM48_MMSS_ERR_IND
- : GSM48_MMSS_REL_IND, conn->ref,
- conn->transaction_id);
- break;
- case GSM48_PDISC_SMS:
- nmsg = gsm48_mmxx_msgb_alloc(
- error ? GSM48_MMSMS_ERR_IND
- : GSM48_MMSMS_REL_IND, conn->ref,
- conn->transaction_id);
- break;
- }
- if (!nmsg) {
- /* this should not happen */
- mm_conn_free(conn);
- continue; /* skip if not of CC type */
- }
- nmmh = (struct gsm48_mmxx_hdr *)nmsg->data;
- nmmh->cause = cause;
- gsm48_mmxx_upmsg(ms, nmsg);
-
- mm_conn_free(conn);
- }
- }
- return 0;
-}
-
-/*
- * process handlers (Common procedures)
- */
-
-/* sending MM STATUS message */
-static int gsm48_mm_tx_mm_status(struct osmocom_ms *ms, uint8_t cause)
-{
- struct msgb *nmsg;
- struct gsm48_hdr *ngh;
- uint8_t *reject_cause;
-
- LOGP(DMM, LOGL_INFO, "MM STATUS (cause #%d)\n", cause);
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
- reject_cause = msgb_put(nmsg, 1);
-
- ngh->proto_discr = GSM48_PDISC_MM;
- ngh->msg_type = GSM48_MT_MM_STATUS;
- *reject_cause = cause;
-
- /* push RR header and send down */
- return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0);
-}
-
-/* 4.3.1.2 sending TMSI REALLOCATION COMPLETE message */
-static int gsm48_mm_tx_tmsi_reall_cpl(struct osmocom_ms *ms)
-{
- struct msgb *nmsg;
- struct gsm48_hdr *ngh;
-
- LOGP(DMM, LOGL_INFO, "TMSI REALLOCATION COMPLETE\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
-
- ngh->proto_discr = GSM48_PDISC_MM;
- ngh->msg_type = GSM48_MT_MM_TMSI_REALL_COMPL;
-
- /* push RR header and send down */
- return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0);
-}
-
-/* 4.3.1 TMSI REALLOCATION COMMAND is received */
-static int gsm48_mm_rx_tmsi_realloc_cmd(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct gsm48_loc_area_id *lai = (struct gsm48_loc_area_id *) gh->data;
- uint8_t mi_type, *mi;
- uint32_t tmsi;
-
- if (payload_len < sizeof(struct gsm48_loc_area_id) + 2) {
- short_read:
- LOGP(DMM, LOGL_NOTICE, "Short read of TMSI REALLOCATION "
- "COMMAND message error.\n");
- return -EINVAL;
- }
- /* LAI */
- gsm48_decode_lai(lai, &subscr->mcc, &subscr->mnc, &subscr->lac);
- /* MI */
- mi = gh->data + sizeof(struct gsm48_loc_area_id);
- mi_type = mi[1] & GSM_MI_TYPE_MASK;
- switch (mi_type) {
- case GSM_MI_TYPE_TMSI:
- if (payload_len + sizeof(struct gsm48_loc_area_id) < 6
- || mi[0] < 5)
- goto short_read;
- memcpy(&tmsi, mi+2, 4);
- subscr->tmsi = ntohl(tmsi);
- LOGP(DMM, LOGL_INFO, "TMSI 0x%08x (%u) assigned.\n",
- subscr->tmsi, subscr->tmsi);
- gsm48_mm_tx_tmsi_reall_cpl(ms);
- break;
- case GSM_MI_TYPE_IMSI:
- subscr->tmsi = 0xffffffff;
- LOGP(DMM, LOGL_INFO, "TMSI removed.\n");
- gsm48_mm_tx_tmsi_reall_cpl(ms);
- break;
- default:
- subscr->tmsi = 0xffffffff;
- LOGP(DMM, LOGL_NOTICE, "TMSI reallocation with unknown MI "
- "type %d.\n", mi_type);
- gsm48_mm_tx_mm_status(ms, GSM48_REJECT_INCORRECT_MESSAGE);
- }
-
- /* store LOCI on sim */
- gsm_subscr_write_loci(ms);
-
- return 0;
-}
-
-/* 4.3.2.2 AUTHENTICATION REQUEST is received */
-static int gsm48_mm_rx_auth_req(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm_settings *set = &ms->settings;
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct gsm48_auth_req *ar = (struct gsm48_auth_req *) gh->data;
- uint8_t no_sim = 0;
-
- if (payload_len < sizeof(struct gsm48_auth_req)) {
- LOGP(DMM, LOGL_NOTICE, "Short read of AUTHENTICATION REQUEST "
- "message error.\n");
- return -EINVAL;
- }
-
- /* SIM is not available */
- if (!subscr->sim_valid) {
- LOGP(DMM, LOGL_INFO, "AUTHENTICATION REQUEST without SIM\n");
- return gsm48_mm_tx_mm_status(ms,
- GSM48_REJECT_MSG_NOT_COMPATIBLE);
- }
-
- LOGP(DMM, LOGL_INFO, "AUTHENTICATION REQUEST (seq %d)\n", ar->key_seq);
-
- /* key_seq and random
- * in case of test card, there is a dummy response.
- * authentication request is possible during emergency call, if
- * IMSI is known to the network. in case of emergency IMSI, we need to
- * send a dummy response also.
- */
- if (mm->est_cause == RR_EST_CAUSE_EMERGENCY && set->emergency_imsi[0])
- no_sim = 1;
- gsm_subscr_generate_kc(ms, ar->key_seq, ar->rand, no_sim);
-
- /* wait for auth response event from SIM */
- return 0;
-}
-
-/* 4.3.2.2 sending AUTHENTICATION RESPONSE */
-static int gsm48_mm_tx_auth_rsp(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mm_event *mme = (struct gsm48_mm_event *) msg->data;
- struct msgb *nmsg;
- struct gsm48_hdr *ngh;
- uint8_t *sres;
-
- LOGP(DMM, LOGL_INFO, "AUTHENTICATION RESPONSE\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
-
- ngh->proto_discr = GSM48_PDISC_MM;
- ngh->msg_type = GSM48_MT_MM_AUTH_RESP;
-
- /* SRES */
- sres = msgb_put(nmsg, 4);
- memcpy(sres, mme->sres, 4);
-
- /* push RR header and send down */
- return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0);
-}
-
-/* 4.3.2.5 AUTHENTICATION REJECT is received */
-static int gsm48_mm_rx_auth_rej(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm48_mmlayer *mm = &ms->mmlayer;
-
- LOGP(DMM, LOGL_INFO, "AUTHENTICATION REJECT\n");
-
- stop_mm_t3212(mm); /* 4.4.2 */
-
- /* SIM invalid */
- subscr->sim_valid = 0;
-
- /* TMSI and LAI invalid */
- subscr->tmsi = 0xffffffff;
- subscr->lac = 0x0000;
-
- /* key is invalid */
- subscr->key_seq = 7;
-
- /* update status */
- new_sim_ustate(subscr, GSM_SIM_U3_ROAMING_NA);
-
- /* store LOCI on sim */
- gsm_subscr_write_loci(ms);
-
- /* abort IMSI detach procedure */
- if (mm->state == GSM48_MM_ST_IMSI_DETACH_INIT) {
- struct msgb *nmsg;
- struct gsm48_rr_hdr *nrrh;
-
- /* abort RR connection */
- nmsg = gsm48_rr_msgb_alloc(GSM48_RR_ABORT_REQ);
- if (!nmsg)
- return -ENOMEM;
- nrrh = (struct gsm48_rr_hdr *) nmsg->data;
- nrrh->cause = GSM48_RR_CAUSE_NORMAL;
- gsm48_rr_downmsg(ms, nmsg);
-
- /* return to MM IDLE */
- return gsm48_mm_return_idle(ms, NULL);
- }
-
- return 0;
-}
-
-/* 4.3.3.1 IDENTITY REQUEST is received */
-static int gsm48_mm_rx_id_req(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- uint8_t mi_type;
-
- if (payload_len < 1) {
- LOGP(DMM, LOGL_NOTICE, "Short read of IDENTITY REQUEST message "
- "error.\n");
- return -EINVAL;
- }
-
- /* id type */
- mi_type = *gh->data;
- LOGP(DMM, LOGL_INFO, "IDENTITY REQUEST (mi_type %d)\n", mi_type);
-
- /* check if request can be fulfilled */
- if (!subscr->sim_valid && mi_type != GSM_MI_TYPE_IMEI
- && mi_type != GSM_MI_TYPE_IMEISV) {
- LOGP(DMM, LOGL_INFO, "IDENTITY REQUEST without SIM\n");
- return gsm48_mm_tx_mm_status(ms,
- GSM48_REJECT_MSG_NOT_COMPATIBLE);
- }
- if (mi_type == GSM_MI_TYPE_TMSI && subscr->tmsi == 0xffffffff) {
- LOGP(DMM, LOGL_INFO, "IDENTITY REQUEST of TMSI, but we have no "
- "TMSI\n");
- return gsm48_mm_tx_mm_status(ms,
- GSM48_REJECT_MSG_NOT_COMPATIBLE);
- }
-
- return gsm48_mm_tx_id_rsp(ms, mi_type);
-}
-
-/* send IDENTITY RESPONSE message */
-static int gsm48_mm_tx_id_rsp(struct osmocom_ms *ms, uint8_t mi_type)
-{
- struct msgb *nmsg;
- struct gsm48_hdr *ngh;
- uint8_t buf[11];
-
- LOGP(DMM, LOGL_INFO, "IDENTITY RESPONSE\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
-
- ngh->proto_discr = GSM48_PDISC_MM;
- ngh->msg_type = GSM48_MT_MM_ID_RESP;
-
- /* MI */
- gsm48_encode_mi(buf, nmsg, ms, mi_type);
-
- /* push RR header and send down */
- return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0);
-}
-
-/* 4.3.4.1 sending IMSI DETACH INDICATION message */
-static int gsm48_mm_tx_imsi_detach(struct osmocom_ms *ms, int rr_prim)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm_support *sup = &ms->support;
- struct gsm_settings *set = &ms->settings;
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct msgb *nmsg;
- struct gsm48_hdr *ngh;
- uint8_t pwr_lev;
- uint8_t buf[11];
- struct gsm48_classmark1 cm;
-
-
- LOGP(DMM, LOGL_INFO, "IMSI DETACH INDICATION\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
-
- ngh->proto_discr = GSM48_PDISC_MM;
- ngh->msg_type = GSM48_MT_MM_IMSI_DETACH_IND;
-
- /* classmark 1 */
- if (rr_prim == GSM48_RR_EST_REQ)
- pwr_lev = gsm48_current_pwr_lev(set, cs->sel_arfcn);
- else
- pwr_lev = gsm48_current_pwr_lev(set, rr->cd_now.arfcn);
- gsm48_encode_classmark1(&cm, sup->rev_lev, sup->es_ind, set->a5_1,
- pwr_lev);
- msgb_v_put(nmsg, *((uint8_t *)&cm));
- /* MI */
- if (subscr->tmsi != 0xffffffff) { /* have TMSI ? */
- gsm48_encode_mi(buf, nmsg, ms, GSM_MI_TYPE_TMSI);
- LOGP(DMM, LOGL_INFO, " using TMSI 0x%08x\n", subscr->tmsi);
- } else {
- gsm48_encode_mi(buf, nmsg, ms, GSM_MI_TYPE_IMSI);
- LOGP(DMM, LOGL_INFO, " using IMSI %s\n", subscr->imsi);
- }
-
- /* push RR header and send down */
- mm->est_cause = RR_EST_CAUSE_OTHER_SDCCH;
- return gsm48_mm_to_rr(ms, nmsg, rr_prim, mm->est_cause);
-}
-
-/* detach has ended */
-static int gsm48_mm_imsi_detach_end(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct msgb *nmsg;
-
- LOGP(DMM, LOGL_INFO, "IMSI has been detached.\n");
-
- /* stop IMSI detach timer (if running) */
- stop_mm_t3220(mm);
-
-
- /* SIM invalid */
- subscr->sim_valid = 0;
-
- /* wait for RR idle and then power off when IMSI is detached */
- if (ms->shutdown) {
- if (mm->state == GSM48_MM_ST_MM_IDLE) {
- mobile_exit(ms, 1);
- return 0;
- }
- /* power off when MM idle */
- mm->power_off_idle = 1;
-
- /* return to MM IDLE */
- return gsm48_mm_return_idle(ms, NULL);
- }
-
- /* send SIM remove event to gsm322 */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_SIM_REMOVE);
- if (!nmsg)
- return -ENOMEM;
- gsm322_plmn_sendmsg(ms, nmsg);
-
- /* return to MM IDLE */
- return gsm48_mm_return_idle(ms, NULL);
-}
-
-/* start an IMSI detach in MM IDLE */
-static int gsm48_mm_imsi_detach_start(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm48_sysinfo *s = &ms->cellsel.sel_si;
-
- /* we may silently finish IMSI detach */
- if (!s->att_allowed || !subscr->imsi_attached) {
- LOGP(DMM, LOGL_INFO, "IMSI detach not required.\n");
-
- return gsm48_mm_imsi_detach_end(ms, msg);
- }
- LOGP(DMM, LOGL_INFO, "IMSI detach started (MM IDLE)\n");
-
- new_mm_state(mm, GSM48_MM_ST_WAIT_RR_CONN_IMSI_D, 0);
-
- /* establish RR and send IMSI detach */
- return gsm48_mm_tx_imsi_detach(ms, GSM48_RR_EST_REQ);
-}
-
-/* IMSI detach has been sent, wait for RR release */
-static int gsm48_mm_imsi_detach_sent(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
-
- /* start T3220 (4.3.4.1) */
- start_mm_t3220(mm);
-
- LOGP(DMM, LOGL_INFO, "IMSI detach started (Wait for RR release)\n");
-
- new_mm_state(mm, GSM48_MM_ST_IMSI_DETACH_INIT, 0);
-
- return 0;
-}
-
-/* release MM connection and proceed with IMSI detach */
-static int gsm48_mm_imsi_detach_release(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm48_sysinfo *s = &ms->cellsel.sel_si;
-
- /* stop MM connection timer */
- stop_mm_t3230(mm);
-
- /* release all connections */
- gsm48_mm_release_mm_conn(ms, 1, 16, 0);
-
- /* wait for release of RR */
- if (!s->att_allowed || !subscr->imsi_attached) {
- LOGP(DMM, LOGL_INFO, "IMSI detach not required.\n");
- new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
-
- /* power off */
- if (ms->shutdown) {
- mobile_exit(ms, 1);
- return 0;
- }
-
- return 0;
- }
-
- /* send IMSI detach */
- gsm48_mm_tx_imsi_detach(ms, GSM48_RR_DATA_REQ);
-
- /* go to sent state */
- return gsm48_mm_imsi_detach_sent(ms, msg);
-}
-
-/* ignore ongoing IMSI detach */
-static int gsm48_mm_imsi_detach_ignore(struct osmocom_ms *ms, struct msgb *msg)
-{
- return 0;
-}
-
-/* delay until state change (and then retry) */
-static int gsm48_mm_imsi_detach_delay(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
-
- LOGP(DMM, LOGL_INFO, "IMSI detach delayed.\n");
-
- /* remember to detach later */
- mm->delay_detach = 1;
-
- return 0;
-}
-
-/* 4.3.5.2 ABORT is received */
-static int gsm48_mm_rx_abort(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- uint8_t reject_cause;
-
- if (payload_len < 1) {
- LOGP(DMM, LOGL_NOTICE, "Short read of ABORT message error.\n");
- return -EINVAL;
- }
-
- reject_cause = *gh->data;
-
- if (llist_empty(&mm->mm_conn)) {
- LOGP(DMM, LOGL_NOTICE, "ABORT (cause #%d) while no MM "
- "connection is established.\n", reject_cause);
- return gsm48_mm_tx_mm_status(ms,
- GSM48_REJECT_MSG_NOT_COMPATIBLE);
- } else {
- LOGP(DMM, LOGL_NOTICE, "ABORT (cause #%d) while MM connection "
- "is established.\n", reject_cause);
- /* stop MM connection timer */
- stop_mm_t3230(mm);
-
- gsm48_mm_release_mm_conn(ms, 1, 16, 0);
- }
-
- if (reject_cause == GSM48_REJECT_ILLEGAL_ME) {
- /* SIM invalid */
- subscr->sim_valid = 0;
-
- /* TMSI and LAI invalid */
- subscr->tmsi = 0xffffffff;
- subscr->lac = 0x0000;
-
- /* key is invalid */
- subscr->key_seq = 7;
-
- /* update status */
- new_sim_ustate(subscr, GSM_SIM_U3_ROAMING_NA);
-
- /* store LOCI on sim */
- gsm_subscr_write_loci(ms);
-
- /* return to MM IDLE */
- return gsm48_mm_return_idle(ms, NULL);
- }
-
- return 0;
-}
-
-/* 4.3.6.2 MM INFORMATION is received */
-static int gsm48_mm_rx_info(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct tlv_parsed tp;
-
- if (payload_len < 0) {
- LOGP(DMM, LOGL_NOTICE, "Short read of MM INFORMATION message "
- "error.\n");
- return -EINVAL;
- }
- tlv_parse(&tp, &gsm48_mm_att_tlvdef, gh->data, payload_len, 0, 0);
-
- /* long name */
- if (TLVP_PRESENT(&tp, GSM48_IE_NAME_LONG)) {
- decode_network_name(mm->name_long, sizeof(mm->name_long),
- TLVP_VAL(&tp, GSM48_IE_NAME_LONG)-1);
- }
- /* short name */
- if (TLVP_PRESENT(&tp, GSM48_IE_NAME_SHORT)) {
- decode_network_name(mm->name_short, sizeof(mm->name_short),
- TLVP_VAL(&tp, GSM48_IE_NAME_SHORT)-1);
- }
-
- return 0;
-}
-
-/*
- * process handlers for Location Update + IMSI attach (MM specific procedures)
- */
-
-/* 4.4.2 received sysinfo change event */
-static int gsm48_mm_sysinfo(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm48_sysinfo *s = &ms->cellsel.sel_si;
-
- /* t3212 not changed in these states */
- if (mm->state == GSM48_MM_ST_MM_IDLE
- && (mm->substate == GSM48_MM_SST_NO_CELL_AVAIL
- || mm->substate == GSM48_MM_SST_LIMITED_SERVICE
- || mm->substate == GSM48_MM_SST_PLMN_SEARCH
- || mm->substate == GSM48_MM_SST_PLMN_SEARCH_NORMAL))
- return 0;
-
- /* new periodic location update timer timeout */
- if (s->t3212 && s->t3212 != mm->t3212_value) {
- if (osmo_timer_pending(&mm->t3212)) {
- int t;
- struct timeval current_time;
-
- /* get rest time */
- gettimeofday(&current_time, NULL);
- t = mm->t3212.timeout.tv_sec - current_time.tv_sec;
- if (t < 0)
- t = 0;
- LOGP(DMM, LOGL_INFO, "New T3212 while timer is running "
- "(value %d rest %d)\n", s->t3212, t);
-
- /* rest time modulo given value */
- mm->t3212.timeout.tv_sec = current_time.tv_sec
- + (t % s->t3212);
- } else {
- uint32_t rand = random();
-
- LOGP(DMM, LOGL_INFO, "New T3212 while timer is not "
- "running (value %d)\n", s->t3212);
-
- /* value between 0 and given value */
- start_mm_t3212(mm, rand % (s->t3212 + 1));
- }
- mm->t3212_value = s->t3212;
- }
-
- return 0;
-}
-
-/* 4.4.4.1 (re)start location update
- *
- * this function is called by
- * - normal location update
- * - periodic location update
- * - imsi attach (normal loc. upd. function)
- * - retry timers (T3211 and T3213)
- */
-static int gsm48_mm_loc_upd(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = &cs->sel_si;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm_settings *set = &ms->settings;
- struct msgb *nmsg;
- int msg_type;
-
- /* (re)start only if we still require location update */
- if (!mm->lupd_pending) {
- LOGP(DMM, LOGL_INFO, "No loc. upd. pending.\n");
- /* use MM IDLE to selecte the idle state */
- return gsm48_mm_return_idle(ms, NULL);
- }
-
- /* must camp normally */
- if (cs->state != GSM322_C3_CAMPED_NORMALLY) {
- LOGP(DMM, LOGL_INFO, "Loc. upd. not camping normally.\n");
- msg_type = GSM322_EVENT_REG_FAILED;
- stop:
- LOGP(DSUM, LOGL_INFO, "Location updating not possible\n");
- _stop:
- mm->lupd_pending = 0;
-
-#if 0
- /* don't send message, if we got not triggered by PLMN search */
- if (!msg)
- return 0;
-#endif
-
- /* send message to PLMN search process */
- nmsg = gsm322_msgb_alloc(msg_type);
- if (!nmsg)
- return -ENOMEM;
- gsm322_plmn_sendmsg(ms, nmsg);
- /* use MM IDLE to selecte the idle state */
- return gsm48_mm_return_idle(ms, NULL);
- }
-
- /* deny network, if disabled */
- if (set->no_lupd) {
- LOGP(DMM, LOGL_INFO, "Loc. upd. disabled, adding "
- "forbidden PLMN.\n");
- LOGP(DSUM, LOGL_INFO, "Location updating is disabled by "
- "configuration\n");
- gsm_subscr_add_forbidden_plmn(subscr, cs->sel_mcc,
- cs->sel_mnc, GSM48_REJECT_PLMN_NOT_ALLOWED);
- msg_type = GSM322_EVENT_REG_FAILED;
- goto _stop;
- }
-
- /* if LAI is forbidden, don't start */
- if (gsm_subscr_is_forbidden_plmn(subscr, cs->sel_mcc, cs->sel_mnc)) {
- LOGP(DMM, LOGL_INFO, "Loc. upd. not allowed PLMN.\n");
- msg_type = GSM322_EVENT_REG_FAILED;
- goto stop;
- }
- if (gsm322_is_forbidden_la(ms, cs->sel_mcc,
- cs->sel_mnc, cs->sel_lac)) {
- LOGP(DMM, LOGL_INFO, "Loc. upd. not allowed LA.\n");
- msg_type = GSM322_EVENT_REG_FAILED;
- goto stop;
- }
-
- /* 4.4.4.9 if cell is barred, don't start */
- if ((!subscr->acc_barr && s->cell_barr)
- || (!subscr->acc_barr && !((subscr->acc_class & 0xfbff) &
- (s->class_barr ^ 0xffff)))) {
- LOGP(DMM, LOGL_INFO, "Loc. upd. no access.\n");
- msg_type = GSM322_EVENT_REG_FAILED;
- goto stop;
- }
-
- mm->lupd_mcc = cs->sel_mcc;
- mm->lupd_mnc = cs->sel_mnc;
- mm->lupd_lac = cs->sel_lac;
-
- LOGP(DSUM, LOGL_INFO, "Perform location update (MCC %s, MNC %s "
- "LAC 0x%04x)\n", gsm_print_mcc(mm->lupd_mcc),
- gsm_print_mnc(mm->lupd_mnc), mm->lupd_lac);
-
- return gsm48_mm_tx_loc_upd_req(ms);
-}
-
-/* initiate a normal location update / imsi attach */
-static int gsm48_mm_loc_upd_normal(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = &cs->sel_si;
- struct msgb *nmsg;
-
- /* in case we already have a location update going on */
- if (mm->lupd_pending) {
- LOGP(DMM, LOGL_INFO, "Loc. upd. already pending.\n");
-
- return -EBUSY;
- }
-
- /* no location update, if limited service */
- if (cs->state != GSM322_C3_CAMPED_NORMALLY) {
- LOGP(DMM, LOGL_INFO, "Loc. upd. not allowed.\n");
-
-#if 0
- /* don't send message, if we got not triggered by PLMN search */
- if (!msg)
- return 0;
-#endif
-
- /* send message to PLMN search process */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_FAILED);
- if (!nmsg)
- return -ENOMEM;
- gsm322_plmn_sendmsg(ms, nmsg);
-
- return 0;
- }
-
- /* if location update is not required */
- if (subscr->ustate == GSM_SIM_U1_UPDATED
- && cs->selected
- && cs->sel_mcc == subscr->mcc
- && cs->sel_mnc == subscr->mnc
- && cs->sel_lac == subscr->lac
- && (subscr->imsi_attached
- || !s->att_allowed)) {
- LOGP(DMM, LOGL_INFO, "Loc. upd. not required.\n");
- subscr->imsi_attached = 1;
-
- /* go straight to normal service state */
- new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
- GSM48_MM_SST_NORMAL_SERVICE);
-
-#if 0
- /* don't send message, if we got not triggered by PLMN search */
- if (!msg)
- return 0;
-#endif
-
- /* send message to PLMN search process */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_SUCCESS);
- if (!nmsg)
- return -ENOMEM;
- gsm322_plmn_sendmsg(ms, nmsg);
-
- return 0;
- }
-
- /* 4.4.3 is attachment required? */
- if (subscr->ustate == GSM_SIM_U1_UPDATED
- && cs->selected
- && cs->sel_mcc == subscr->mcc
- && cs->sel_mnc == subscr->mnc
- && cs->sel_lac == subscr->lac
- && !subscr->imsi_attached
- && s->att_allowed) {
- /* do location update for IMSI attach */
- LOGP(DMM, LOGL_INFO, "Do Loc. upd. for IMSI attach.\n");
- mm->lupd_type = 2;
- } else {
- /* do normal location update */
- LOGP(DMM, LOGL_INFO, "Do normal Loc. upd.\n");
- mm->lupd_type = 0;
- }
-
- /* start location update */
- mm->lupd_attempt = 0;
- mm->lupd_pending = 1;
- mm->lupd_ra_failure = 0;
-
- return gsm48_mm_loc_upd(ms, msg);
-}
-
-/* initiate a periodic location update */
-static int gsm48_mm_loc_upd_periodic(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
-
- /* in case we already have a location update going on */
- if (mm->lupd_pending) {
- LOGP(DMM, LOGL_INFO, "Loc. upd. already pending.\n");
- return -EBUSY;
- }
-
- /* start periodic location update */
- mm->lupd_type = 1;
- mm->lupd_pending = 1;
- mm->lupd_ra_failure = 0;
-
- return gsm48_mm_loc_upd(ms, msg);
-}
-
-/* ignore location update */
-static int gsm48_mm_loc_upd_ignore(struct osmocom_ms *ms, struct msgb *msg)
-{
- return 0;
-}
-
-/* 9.2.15 send LOCATION UPDATING REQUEST message */
-static int gsm48_mm_tx_loc_upd_req(struct osmocom_ms *ms)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm_settings *set = &ms->settings;
- struct gsm_support *sup = &ms->support;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct msgb *nmsg;
- struct gsm48_hdr *ngh;
- struct gsm48_loc_upd_req *nlu; /* NOTE: mi_len is part of struct */
- uint8_t pwr_lev;
- uint8_t buf[11];
-
- LOGP(DMM, LOGL_INFO, "LOCATION UPDATING REQUEST\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
- nlu = (struct gsm48_loc_upd_req *)msgb_put(nmsg, sizeof(*nlu));
-
- ngh->proto_discr = GSM48_PDISC_MM;
- ngh->msg_type = GSM48_MT_MM_LOC_UPD_REQUEST;
-
- /* location updating type */
- nlu->type = mm->lupd_type;
- /* cipering key */
- nlu->key_seq = subscr->key_seq;
- /* LAI (last SIM stored LAI)
- *
- * NOTE: The TMSI is only valid within a LAI!
- */
- gsm48_encode_lai(&nlu->lai, subscr->mcc, subscr->mnc, subscr->lac);
- LOGP(DMM, LOGL_INFO, " using LAI (mcc %s mnc %s " "lac 0x%04x)\n",
- gsm_print_mcc(subscr->mcc),
- gsm_print_mnc(subscr->mnc), subscr->lac);
- /* classmark 1 */
- pwr_lev = gsm48_current_pwr_lev(set, cs->sel_arfcn);
- gsm48_encode_classmark1(&nlu->classmark1, sup->rev_lev, sup->es_ind,
- set->a5_1, pwr_lev);
- /* MI */
- if (subscr->tmsi != 0xffffffff) { /* have TMSI ? */
- gsm48_encode_mi(buf, NULL, ms, GSM_MI_TYPE_TMSI);
- LOGP(DMM, LOGL_INFO, " using TMSI 0x%08x\n", subscr->tmsi);
- } else {
- gsm48_encode_mi(buf, NULL, ms, GSM_MI_TYPE_IMSI);
- LOGP(DMM, LOGL_INFO, " using IMSI %s\n", subscr->imsi);
- }
- msgb_put(nmsg, buf[1]); /* length is part of nlu */
- memcpy(&nlu->mi_len, buf + 1, 1 + buf[1]);
-
- new_mm_state(mm, GSM48_MM_ST_WAIT_RR_CONN_LUPD, 0);
-
- /* push RR header and send down */
- mm->est_cause = RR_EST_CAUSE_LOC_UPD;
- return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_EST_REQ, mm->est_cause);
-}
-
-/* 4.4.4.1 RR is esablised during location update */
-static int gsm48_mm_est_loc_upd(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
-
- /* start location update timer */
- start_mm_t3210(mm);
-
- new_mm_state(mm, GSM48_MM_ST_LOC_UPD_INIT, 0);
-
- return 0;
-}
-
-/* 4.4.4.6 LOCATION UPDATING ACCEPT is received */
-static int gsm48_mm_rx_loc_upd_acc(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm48_hdr *gh = msgb_l3(msg);
- struct gsm48_loc_area_id *lai = (struct gsm48_loc_area_id *) gh->data;
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- struct tlv_parsed tp;
- struct msgb *nmsg;
-
- if (payload_len < sizeof(struct gsm48_loc_area_id)) {
- short_read:
- LOGP(DMM, LOGL_NOTICE, "Short read of LOCATION UPDATING ACCEPT "
- "message error.\n");
- return -EINVAL;
- }
- tlv_parse(&tp, &gsm48_mm_att_tlvdef,
- gh->data + sizeof(struct gsm48_loc_area_id),
- payload_len - sizeof(struct gsm48_loc_area_id), 0, 0);
-
- /* update has finished */
- mm->lupd_pending = 0;
-
- /* RA was successfull */
- mm->lupd_ra_failure = 0;
-
- /* stop periodic location updating timer */
- stop_mm_t3212(mm); /* 4.4.2 */
-
- /* LAI */
- gsm48_decode_lai(lai, &subscr->mcc, &subscr->mnc, &subscr->lac);
-
- /* stop location update timer */
- stop_mm_t3210(mm);
-
- /* reset attempt counter */
- mm->lupd_attempt = 0;
-
- /* mark SIM as attached */
- subscr->imsi_attached = 1;
-
- /* set the status in the sim to updated */
- new_sim_ustate(subscr, GSM_SIM_U1_UPDATED);
-
- /* store LOCI on sim */
- gsm_subscr_write_loci(ms);
-
- /* set last registered PLMN */
- if (subscr->lac > 0x0000 && subscr->lac < 0xfffe) {
- subscr->plmn_valid = 1;
- subscr->plmn_mcc = subscr->mcc;
- subscr->plmn_mnc = subscr->mnc;
- }
-
- LOGP(DSUM, LOGL_INFO, "Location update accepted\n");
- LOGP(DMM, LOGL_INFO, "LOCATION UPDATING ACCEPT (mcc %s mnc %s "
- "lac 0x%04x)\n", gsm_print_mcc(subscr->mcc),
- gsm_print_mnc(subscr->mnc), subscr->lac);
-
- /* remove LA from forbidden list */
- gsm322_del_forbidden_la(ms, subscr->mcc, subscr->mnc, subscr->lac);
-
- /* MI */
- if (TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ID)) {
- const uint8_t *mi;
- uint8_t mi_type;
- uint32_t tmsi;
-
- mi = TLVP_VAL(&tp, GSM48_IE_MOBILE_ID)-1;
- if (mi[0] < 1)
- goto short_read;
- mi_type = mi[1] & GSM_MI_TYPE_MASK;
- switch (mi_type) {
- case GSM_MI_TYPE_TMSI:
- if (payload_len + sizeof(struct gsm48_loc_area_id) < 6
- || mi[0] < 5)
- goto short_read;
- memcpy(&tmsi, mi+2, 4);
- subscr->tmsi = ntohl(tmsi);
- LOGP(DMM, LOGL_INFO, "got TMSI 0x%08x (%u)\n",
- subscr->tmsi, subscr->tmsi);
-
- /* store LOCI on sim */
- gsm_subscr_write_loci(ms);
-
- /* send TMSI REALLOCATION COMPLETE */
- gsm48_mm_tx_tmsi_reall_cpl(ms);
- break;
- case GSM_MI_TYPE_IMSI:
- LOGP(DMM, LOGL_INFO, "TMSI removed\n");
- subscr->tmsi = 0xffffffff;
-
- /* store LOCI on sim */
- gsm_subscr_write_loci(ms);
-
- /* send TMSI REALLOCATION COMPLETE */
- gsm48_mm_tx_tmsi_reall_cpl(ms);
- break;
- default:
- LOGP(DMM, LOGL_NOTICE, "TMSI reallocation with unknown "
- "MI type %d.\n", mi_type);
- }
- }
-
- /* send message to PLMN search process */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_SUCCESS);
- if (!nmsg)
- return -ENOMEM;
- gsm322_plmn_sendmsg(ms, nmsg);
-
- /* follow on proceed */
- if (TLVP_PRESENT(&tp, GSM48_IE_MOBILE_ID))
- LOGP(DMM, LOGL_NOTICE, "follow-on proceed not supported.\n");
-
- /* start RR release timer */
- start_mm_t3240(mm);
-
- new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
-
- return 0;
-}
-
-/* 4.4.4.7 LOCATION UPDATING REJECT is received */
-static int gsm48_mm_rx_loc_upd_rej(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
-
- if (payload_len < 1) {
- LOGP(DMM, LOGL_NOTICE, "Short read of LOCATION UPDATING REJECT "
- "message error.\n");
- return -EINVAL;
- }
-
- /* RA was successfull */
- mm->lupd_ra_failure = 0;
-
- /* stop periodic location updating timer */
- stop_mm_t3212(mm); /* 4.4.2 */
-
- /* stop location update timer */
- stop_mm_t3210(mm);
-
- /* store until RR is released */
- mm->lupd_rej_cause = *gh->data;
-
- /* start RR release timer */
- start_mm_t3240(mm);
-
- new_mm_state(mm, GSM48_MM_ST_LOC_UPD_REJ, 0);
-
- return 0;
-}
-
-/* 4.4.4.7 RR is released after location update reject */
-static int gsm48_mm_rel_loc_upd_rej(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct msgb *nmsg;
- struct gsm322_msg *ngm;
-
- LOGP(DMM, LOGL_INFO, "Loc. upd. rejected (cause %d)\n",
- mm->lupd_rej_cause);
-
- /* stop RR release timer */
- stop_mm_t3240(mm);
-
- /* new status */
- switch (mm->lupd_rej_cause) {
- case GSM48_REJECT_IMSI_UNKNOWN_IN_HLR:
- case GSM48_REJECT_ILLEGAL_MS:
- case GSM48_REJECT_ILLEGAL_ME:
- /* reset attempt counter */
- mm->lupd_attempt = 0;
-
- /* SIM invalid */
- subscr->sim_valid = 0;
-
- // fall through
- case GSM48_REJECT_PLMN_NOT_ALLOWED:
- case GSM48_REJECT_LOC_NOT_ALLOWED:
- case GSM48_REJECT_ROAMING_NOT_ALLOWED:
- /* TMSI and LAI invalid */
- subscr->tmsi = 0xffffffff;
- subscr->lac = 0x0000;
-
- /* key is invalid */
- subscr->key_seq = 7;
-
- /* update status */
- new_sim_ustate(subscr, GSM_SIM_U3_ROAMING_NA);
-
- /* store LOCI on sim */
- gsm_subscr_write_loci(ms);
-
- /* update has finished */
- mm->lupd_pending = 0;
- }
-
- /* send event to PLMN search process */
- switch(mm->lupd_rej_cause) {
- case GSM48_REJECT_ROAMING_NOT_ALLOWED:
- case GSM48_REJECT_PLMN_NOT_ALLOWED:
- case GSM48_REJECT_LOC_NOT_ALLOWED:
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_ROAMING_NA);
- break;
- case GSM48_REJECT_IMSI_UNKNOWN_IN_HLR:
- case GSM48_REJECT_ILLEGAL_MS:
- case GSM48_REJECT_ILLEGAL_ME:
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_INVALID_SIM);
- break;
- default:
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_REG_FAILED);
- }
- if (!nmsg)
- return -ENOMEM;
- ngm = (struct gsm322_msg *)nmsg->data;
- ngm->reject = mm->lupd_rej_cause;
- gsm322_plmn_sendmsg(ms, nmsg);
-
- /* forbidden list */
- switch (mm->lupd_rej_cause) {
- case GSM48_REJECT_IMSI_UNKNOWN_IN_HLR:
- LOGP(DSUM, LOGL_INFO, "Location update failed (IMSI unknown "
- "in HLR)\n");
- break;
- case GSM48_REJECT_ILLEGAL_MS:
- LOGP(DSUM, LOGL_INFO, "Location update failed (Illegal MS)\n");
- break;
- case GSM48_REJECT_ILLEGAL_ME:
- LOGP(DSUM, LOGL_INFO, "Location update failed (Illegal ME)\n");
- break;
- case GSM48_REJECT_PLMN_NOT_ALLOWED:
- gsm_subscr_add_forbidden_plmn(subscr, mm->lupd_mcc,
- mm->lupd_mnc, mm->lupd_rej_cause);
- LOGP(DSUM, LOGL_INFO, "Location update failed (PLMN not "
- "allowed)\n");
- break;
- case GSM48_REJECT_LOC_NOT_ALLOWED:
- case GSM48_REJECT_ROAMING_NOT_ALLOWED:
- gsm322_add_forbidden_la(ms, mm->lupd_mcc, mm->lupd_mnc,
- mm->lupd_lac, mm->lupd_rej_cause);
- LOGP(DSUM, LOGL_INFO, "Location update failed (LAI not "
- "allowed)\n");
- break;
- default:
- /* 4.4.4.9 continue with failure handling */
- return gsm48_mm_loc_upd_failed(ms, NULL);
- }
-
- /* return to MM IDLE */
- return gsm48_mm_return_idle(ms, NULL);
-}
-
-/* 4.2.2 delay a location update */
-static int gsm48_mm_loc_upd_delay_per(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
-
- LOGP(DMM, LOGL_INFO, "Schedule a pending periodic loc. upd.\n");
- mm->lupd_periodic = 1;
-
- return 0;
-}
-
-/* delay a location update retry */
-static int gsm48_mm_loc_upd_delay_retry(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
-
- LOGP(DMM, LOGL_INFO, "Schedule a pending periodic loc. upd.\n");
- mm->lupd_retry = 1;
-
- return 0;
-}
-
-/* process failues as described in the lower part of 4.4.4.9 */
-static int gsm48_mm_loc_upd_failed(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm_subscriber *subscr = &ms->subscr;
-
- LOGP(DSUM, LOGL_INFO, "Location update failed\n");
-
- /* stop location update timer, if running */
- stop_mm_t3210(mm);
-
- if (subscr->ustate == GSM_SIM_U1_UPDATED
- && mm->lupd_mcc == subscr->mcc
- && mm->lupd_mnc == subscr->mnc
- && mm->lupd_lac == subscr->lac) {
- if (mm->lupd_attempt < 4) {
- LOGP(DSUM, LOGL_INFO, "Try location update later\n");
- LOGP(DMM, LOGL_INFO, "Loc. upd. failed, retry #%d\n",
- mm->lupd_attempt);
-
- /* start update retry timer */
- start_mm_t3211(mm);
-
- /* return to MM IDLE */
- return gsm48_mm_return_idle(ms, NULL);
- } else
- LOGP(DMM, LOGL_INFO, "Loc. upd. failed too often.\n");
- }
-
- /* TMSI and LAI invalid */
- subscr->tmsi = 0xffffffff;
- subscr->lac = 0x0000;
-
- /* key is invalid */
- subscr->key_seq = 7;
-
- /* update status */
- new_sim_ustate(subscr, GSM_SIM_U2_NOT_UPDATED);
-
- /* store LOCI on sim */
- gsm_subscr_write_loci(ms);
-
- /* start update retry timer (RR connection is released) */
- if (mm->lupd_attempt < 4) {
- mm->start_t3211 = 1;
- LOGP(DSUM, LOGL_INFO, "Try location update later\n");
- }
-
- /* return to MM IDLE */
- return gsm48_mm_return_idle(ms, NULL);
-}
-
-/* abort a location update due to radio failure or release */
-static int gsm48_mm_rel_loc_upd_abort(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *)msg->data;
-
- /* stop RR release timer */
- stop_mm_t3240(mm);
-
- if (rrh->msg_type == GSM48_RR_REL_IND) {
- LOGP(DMM, LOGL_INFO, "RR link released after loc. upd.\n");
-
- /* continue with failure handling */
- return gsm48_mm_loc_upd_failed(ms, NULL);
- }
-
- LOGP(DMM, LOGL_INFO, "Loc. upd. aborted by radio (cause #%d)\n",
- rrh->cause);
-
- /* random access failure, but not two successive failures */
- if (rrh->cause == RR_REL_CAUSE_RA_FAILURE && !mm->lupd_ra_failure) {
- mm->lupd_ra_failure = 1;
-
- /* start RA failure timer */
- start_mm_t3213(mm);
-
- return 0;
- }
-
- /* RA was successfull or sent twice */
- mm->lupd_ra_failure = 0;
-
- /* continue with failure handling */
- return gsm48_mm_loc_upd_failed(ms, NULL);
-}
-
-/* location update has timed out */
-static int gsm48_mm_loc_upd_timeout(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct msgb *nmsg;
- struct gsm48_rr_hdr *nrrh;
-
- /* abort RR connection */
- nmsg = gsm48_rr_msgb_alloc(GSM48_RR_ABORT_REQ);
- if (!nmsg)
- return -ENOMEM;
- nrrh = (struct gsm48_rr_hdr *) nmsg->data;
- nrrh->cause = GSM48_RR_CAUSE_ABNORMAL_TIMER;
- gsm48_rr_downmsg(ms, nmsg);
-
- /* continue with failure handling */
- return gsm48_mm_loc_upd_failed(ms, NULL);
-}
-
-/*
- * process handlers for MM connections
- */
-
-/* cm reestablish request message from upper layer */
-static int gsm48_mm_tx_cm_serv_req(struct osmocom_ms *ms, int rr_prim,
- uint8_t cm_serv)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm_settings *set = &ms->settings;
- struct msgb *nmsg;
- struct gsm48_hdr *ngh;
- struct gsm48_service_request *nsr; /* NOTE: includes MI length */
- uint8_t *cm2lv;
- uint8_t buf[11];
-
- LOGP(DMM, LOGL_INFO, "CM SERVICE REQUEST (cause %d)\n", mm->est_cause);
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
- nsr = (struct gsm48_service_request *)msgb_put(nmsg, sizeof(*nsr));
- cm2lv = (uint8_t *)&nsr->classmark;
-
- ngh->proto_discr = GSM48_PDISC_MM;
- ngh->msg_type = GSM48_MT_MM_CM_SERV_REQ;
-
- /* type and key */
- nsr->cm_service_type = cm_serv;
- nsr->cipher_key_seq = subscr->key_seq;
- /* classmark 2 */
- cm2lv[0] = sizeof(struct gsm48_classmark2);
- gsm48_rr_enc_cm2(ms, (struct gsm48_classmark2 *)(cm2lv + 1),
- (rr_prim == GSM48_RR_EST_REQ) ? cs->sel_arfcn
- : rr->cd_now.arfcn);
- /* MI */
- if (mm->est_cause == RR_EST_CAUSE_EMERGENCY && set->emergency_imsi[0]) {
- LOGP(DMM, LOGL_INFO, "-> Using IMSI %s for emergency\n",
- set->emergency_imsi);
- gsm48_generate_mid_from_imsi(buf, set->emergency_imsi);
- } else
- if (!subscr->sim_valid) { /* have no SIM ? */
- LOGP(DMM, LOGL_INFO, "-> Using IMEI %s\n",
- set->imei);
- gsm48_encode_mi(buf, NULL, ms, GSM_MI_TYPE_IMEI);
- } else
- if (subscr->tmsi != 0xffffffff) { /* have TMSI ? */
- gsm48_encode_mi(buf, NULL, ms, GSM_MI_TYPE_TMSI);
- LOGP(DMM, LOGL_INFO, "-> Using TMSI\n");
- } else {
- gsm48_encode_mi(buf, NULL, ms, GSM_MI_TYPE_IMSI);
- LOGP(DMM, LOGL_INFO, "-> Using IMSI %s\n",
- subscr->imsi);
- }
- msgb_put(nmsg, buf[1]); /* length is part of nsr */
- memcpy(&nsr->mi_len, buf + 1, 1 + buf[1]);
- /* prio is optional for eMLPP */
-
- /* push RR header and send down */
- return gsm48_mm_to_rr(ms, nmsg, rr_prim, mm->est_cause);
-}
-
-/* cm service abort message from upper layer
- * NOTE: T3240 is started by the calling function
- */
-static int gsm48_mm_tx_cm_service_abort(struct osmocom_ms *ms)
-{
- struct msgb *nmsg;
- struct gsm48_hdr *ngh;
-
- LOGP(DMM, LOGL_INFO, "CM SERVICE ABORT\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- ngh = (struct gsm48_hdr *)msgb_put(nmsg, sizeof(*ngh));
-
- ngh->proto_discr = GSM48_PDISC_MM;
- ngh->msg_type = GSM48_MT_MM_CM_SERV_ABORT;
-
- /* push RR header and send down */
- return gsm48_mm_to_rr(ms, nmsg, GSM48_RR_DATA_REQ, 0);
-}
-
-/* cm service acknowledge is received from lower layer */
-static int gsm48_mm_rx_cm_service_acc(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
-
- /* stop MM connection timer */
- stop_mm_t3230(mm);
-
- new_mm_state(mm, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
-
- return gsm48_mm_conn_go_dedic(ms);
-}
-
-/* 9.2.6 CM SERVICE REJECT message received */
-static int gsm48_mm_rx_cm_service_rej(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm48_hdr *gh = msgb_l3(msg);
- unsigned int payload_len = msgb_l3len(msg) - sizeof(*gh);
- uint8_t abort_any = 0;
- uint8_t reject_cause;
-
- if (payload_len < 1) {
- LOGP(DMM, LOGL_NOTICE, "Short read of cm service reject "
- "message error.\n");
- return -EINVAL;
- }
-
- /* reject cause */
- reject_cause = *gh->data;
-
- LOGP(DMM, LOGL_INFO, "CM SERVICE REJECT (cause %d)\n", reject_cause);
-
- /* stop MM connection timer */
- stop_mm_t3230(mm);
-
- /* selection action on cause value */
- switch (reject_cause) {
- case GSM48_REJECT_IMSI_UNKNOWN_IN_VLR:
- case GSM48_REJECT_ILLEGAL_ME:
- abort_any = 1;
-
- /* TMSI and LAI invalid */
- subscr->tmsi = 0xffffffff;
- subscr->lac = 0x0000;
-
- /* key is invalid */
- subscr->key_seq = 7;
-
- /* update status */
- new_sim_ustate(subscr, GSM_SIM_U2_NOT_UPDATED);
-
- /* store LOCI on sim */
- gsm_subscr_write_loci(ms);
-
- /* change to WAIT_NETWORK_CMD state impied by abort_any == 1 */
-
- if (reject_cause == GSM48_REJECT_ILLEGAL_ME)
- subscr->sim_valid = 0;
-
- break;
- default:
- /* state implied by the number of remaining connections */
- ;
- }
-
- /* release MM connection(s) */
- gsm48_mm_release_mm_conn(ms, abort_any, 16, 0);
-
- /* state depends on the existance of remaining MM connections */
- if (llist_empty(&mm->mm_conn))
- new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
- else
- new_mm_state(mm, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
-
- return 0;
-}
-
-/* initiate an MM connection 4.5.1.1
- *
- * this function is called when:
- * - no RR connection exists
- * - an RR connection exists, but this is the first MM connection
- * - an RR connection exists, and there are already MM connection(s)
- */
-static int gsm48_mm_init_mm(struct osmocom_ms *ms, struct msgb *msg,
- int rr_prim)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
- int msg_type = mmh->msg_type;
- int emergency = 0;
- uint8_t cause = 0, cm_serv = 0, proto = 0;
- struct msgb *nmsg;
- struct gsm48_mmxx_hdr *nmmh;
- struct gsm48_mm_conn *conn, *conn_found = NULL;
-
- /* reset loc. upd. counter on CM service request */
- mm->lupd_attempt = 0;
-
- /* find if there is already a pending connection */
- llist_for_each_entry(conn, &mm->mm_conn, list) {
- if (conn->state == GSM48_MMXX_ST_CONN_PEND) {
- conn_found = conn;
- break;
- }
- }
-
- /* if pending connection */
- if (conn_found) {
- LOGP(DMM, LOGL_INFO, "Init MM Connection, but already have "
- "pending MM Connection.\n");
- cause = 17;
- reject:
- nmsg = NULL;
- switch(msg_type) {
- case GSM48_MMCC_EST_REQ:
- nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_REL_IND,
- mmh->ref, mmh->transaction_id);
- break;
- case GSM48_MMSS_EST_REQ:
- nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSS_REL_IND,
- mmh->ref, mmh->transaction_id);
- break;
- case GSM48_MMSMS_EST_REQ:
- nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSMS_REL_IND,
- mmh->ref, mmh->transaction_id);
- break;
- }
- if (!nmsg)
- return -ENOMEM;
- nmmh = (struct gsm48_mmxx_hdr *)nmsg->data;
- nmmh->cause = cause;
- gsm48_mmxx_upmsg(ms, nmsg);
-
- return -EBUSY;
- }
- /* in case of an emergency setup */
- if (msg_type == GSM48_MMCC_EST_REQ && mmh->emergency)
- emergency = 1;
-
- /* if sim is not updated */
- if (!emergency && subscr->ustate != GSM_SIM_U1_UPDATED) {
- LOGP(DMM, LOGL_INFO, "Init MM Connection, but SIM not "
- "updated.\n");
- cause = 21;
- goto reject;
- }
-
- if (mm->state == GSM48_MM_ST_MM_IDLE) {
- /* current MM idle state */
- switch (mm->substate) {
- case GSM48_MM_SST_NORMAL_SERVICE:
- case GSM48_MM_SST_PLMN_SEARCH_NORMAL:
- LOGP(DMM, LOGL_INFO, "Init MM Connection.\n");
- break; /* allow when normal */
- case GSM48_MM_SST_LOC_UPD_NEEDED:
- case GSM48_MM_SST_ATTEMPT_UPDATE:
- /* store mm request if attempting to update */
- if (!emergency) {
- LOGP(DMM, LOGL_INFO, "Init MM Connection, but "
- "attempting to update.\n");
- cause = 21;
- goto reject;
- /* TODO: implement delay and start loc upd. */
- }
- break;
- default:
- /* reject if not emergency */
- if (!emergency) {
- LOGP(DMM, LOGL_INFO, "Init MM Connection, not "
- "in normal state.\n");
- cause = 21;
- goto reject;
- }
- break;
- }
- } else
- LOGP(DMM, LOGL_INFO, "Init another MM Connection.\n");
-
- /* set cause, service, proto */
- switch(msg_type) {
- case GSM48_MMCC_EST_REQ:
- if (emergency) {
- cause = RR_EST_CAUSE_EMERGENCY;
- cm_serv = GSM48_CMSERV_EMERGENCY;
- } else {
- cause = RR_EST_CAUSE_ORIG_TCHF;
- cm_serv = GSM48_CMSERV_MO_CALL_PACKET;
- }
- proto = GSM48_PDISC_CC;
- break;
- case GSM48_MMSS_EST_REQ:
- cause = RR_EST_CAUSE_OTHER_SDCCH;
- cm_serv = GSM48_CMSERV_SUP_SERV;
- proto = GSM48_PDISC_NC_SS;
- break;
- case GSM48_MMSMS_EST_REQ:
- cause = RR_EST_CAUSE_OTHER_SDCCH;
- cm_serv = GSM48_CMSERV_SMS;
- proto = GSM48_PDISC_SMS;
- break;
- }
-
- /* create MM connection instance */
- conn = mm_conn_new(mm, proto, mmh->transaction_id, mmh->ref);
- if (!conn)
- return -ENOMEM;
-
- new_conn_state(conn, GSM48_MMXX_ST_CONN_PEND);
-
- /* send CM SERVICE REQUEST */
- if (rr_prim) {
- mm->est_cause = cause;
- return gsm48_mm_tx_cm_serv_req(ms, rr_prim, cm_serv);
- } else
- return 0;
-}
-
-/* 4.5.1.1 a) MM connection request triggers RR connection */
-static int gsm48_mm_init_mm_no_rr(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- int rc;
-
- /* start MM connection by requesting RR connection */
- rc = gsm48_mm_init_mm(ms, msg, GSM48_RR_EST_REQ);
- if (rc)
- return rc;
-
- new_mm_state(mm, GSM48_MM_ST_WAIT_RR_CONN_MM_CON, 0);
-
- return 0;
-}
-
-/* 4.5.1.1 a) RR is esablised during mm connection, wait for CM accepted */
-static int gsm48_mm_est_mm_con(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
-
- /* 4.5.1.7 if there is no more MM connection */
- if (llist_empty(&mm->mm_conn)) {
- LOGP(DMM, LOGL_INFO, "MM Connection, are already gone.\n");
-
- /* start RR release timer */
- start_mm_t3240(mm);
-
- new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
-
- /* send abort */
- return gsm48_mm_tx_cm_service_abort(ms);
- }
-
- /* start MM connection timer */
- start_mm_t3230(mm);
-
- new_mm_state(mm, GSM48_MM_ST_WAIT_OUT_MM_CONN, 0);
-
- return 0;
-}
-
-/* 4.5.1.1 b) MM connection request on existing RR connection */
-static int gsm48_mm_init_mm_first(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- int rc;
-
- /* start MM connection by sending data */
- rc = gsm48_mm_init_mm(ms, msg, GSM48_RR_DATA_REQ);
- if (rc)
- return rc;
-
- /* stop "RR connection release not allowed" timer */
- stop_mm_t3241(mm);
-
- /* start MM connection timer */
- start_mm_t3230(mm);
-
- new_mm_state(mm, GSM48_MM_ST_WAIT_OUT_MM_CONN, 0);
-
- return 0;
-}
-
-/* 4.5.1.1 b) another MM connection request on existing RR connection */
-static int gsm48_mm_init_mm_more(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- int rc;
-
- /* start MM connection by sending data */
- rc = gsm48_mm_init_mm(ms, msg, GSM48_RR_DATA_REQ);
- if (rc)
- return rc;
-
- /* start MM connection timer */
- start_mm_t3230(mm);
-
- new_mm_state(mm, GSM48_MM_ST_WAIT_ADD_OUT_MM_CON, 0);
-
- return 0;
-}
-
-/* 4.5.1.1 b) delay on WAIT FOR NETWORK COMMAND state */
-static int gsm48_mm_init_mm_wait(struct osmocom_ms *ms, struct msgb *msg)
-{
- /* reject */
- gsm48_mm_init_mm_reject(ms, msg);
-#if 0
- this requires handling when leaving this state...
-
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- int rc;
-
- /* just create the MM connection in pending state */
- rc = gsm48_mm_init_mm(ms, msg, 0);
- if (rc)
- return rc;
-
- /* start MM connection timer */
- start_mm_t3230(mm);
-
- new_mm_state(mm, GSM48_MM_ST_WAIT_ADD_OUT_MM_CON, 0);
-#endif
-
- return 0;
-}
-
-/* initiate an mm connection other cases */
-static int gsm48_mm_init_mm_reject(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
- int msg_type = mmh->msg_type;
- struct msgb *nmsg;
- struct gsm48_mmxx_hdr *nmmh;
-
- /* reject */
- nmsg = NULL;
- switch(msg_type) {
- case GSM48_MMCC_EST_REQ:
- nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_REL_IND, mmh->ref,
- mmh->transaction_id);
- break;
- case GSM48_MMSS_EST_REQ:
- nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSS_REL_IND, mmh->ref,
- mmh->transaction_id);
- break;
- case GSM48_MMSMS_EST_REQ:
- nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSMS_REL_IND, mmh->ref,
- mmh->transaction_id);
- break;
- }
- if (!nmsg)
- return -ENOMEM;
- nmmh = (struct gsm48_mmxx_hdr *)nmsg->data;
- nmmh->cause = 17;
- gsm48_mmxx_upmsg(ms, nmsg);
-
- return 0;
-}
-
-/* accepting pending connection, got dedicated mode
- *
- * this function is called:
- * - when ciphering command is received
- * - when cm service is accepted
- */
-static int gsm48_mm_conn_go_dedic(struct osmocom_ms *ms)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm48_mm_conn *conn, *conn_found = NULL;
- struct msgb *nmsg;
- struct gsm48_mmxx_hdr *nmmh;
-
- /* the first and only pending connection is the recent requested */
- llist_for_each_entry(conn, &mm->mm_conn, list) {
- if (conn->state == GSM48_MMXX_ST_CONN_PEND) {
- conn_found = conn;
- break;
- }
- }
-
- /* if no pending connection (anymore) */
- if (!conn_found) {
- LOGP(DMM, LOGL_INFO, "No pending MM Connection.\n");
-
- return 0;
- }
-
- new_conn_state(conn, GSM48_MMXX_ST_DEDICATED);
-
- /* send establishment confirm */
- nmsg = NULL;
- switch(conn_found->protocol) {
- case GSM48_PDISC_CC:
- nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_EST_CNF, conn->ref,
- conn->transaction_id);
- break;
- case GSM48_PDISC_NC_SS:
- nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSS_EST_CNF, conn->ref,
- conn->transaction_id);
- break;
- case GSM48_PDISC_SMS:
- nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMSMS_EST_CNF, conn->ref,
- conn->transaction_id);
- break;
- }
- if (!nmsg)
- return -ENOMEM;
- nmmh = (struct gsm48_mmxx_hdr *)nmsg->data;
- nmmh->cause = 17;
- gsm48_mmxx_upmsg(ms, nmsg);
-
- return 0;
-}
-
-/* a RR-SYNC-IND is received during MM connection establishment */
-static int gsm48_mm_sync_ind_wait(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *)msg->data;
-
- if (rrh->cause != RR_SYNC_CAUSE_CIPHERING) {
- LOGP(DMM, LOGL_NOTICE, "Ignore sync indication, not waiting "
- "for CM service\n");
- return -EINVAL;
- }
-
- /* stop MM connection timer */
- stop_mm_t3230(mm);
-
- new_mm_state(mm, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
-
- return gsm48_mm_conn_go_dedic(ms);
-}
-
-/* a RR-SYNC-IND is received during MM connection active */
-static int gsm48_mm_sync_ind_active(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm48_mm_conn *conn;
- struct msgb *nmsg;
- struct gsm48_mmxx_hdr *nmmh;
-
- /* stop MM connection timer */
- stop_mm_t3230(mm);
-
- /* broadcast all MMCC connection(s) */
- llist_for_each_entry(conn, &mm->mm_conn, list) {
- /* send MMCC-SYNC-IND */
- nmsg = NULL;
- switch(conn->protocol) {
- case GSM48_PDISC_CC:
- nmsg = gsm48_mmxx_msgb_alloc(GSM48_MMCC_SYNC_IND,
- conn->ref, conn->transaction_id);
- break;
- }
- if (!nmsg)
- continue; /* skip if not of CC type */
- nmmh = (struct gsm48_mmxx_hdr *)nmsg->data;
- nmmh->cause = 17;
- /* copy L3 message */
- nmsg->l3h = msgb_put(nmsg, msgb_l3len(msg));
- memcpy(nmsg->l3h, msg->l3h, msgb_l3len(msg));
- gsm48_mmxx_upmsg(ms, nmsg);
- }
-
- return 0;
-}
-
-/* 4.5.1.2 RR abort/release is received during MM connection establishment */
-static int gsm48_mm_abort_mm_con(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *)msg->data;
- int cause;
-
- /* stop RR release timer */
- stop_mm_t3240(mm);
-
- /* this conversion is not of any standard */
- switch(rrh->cause) {
- case RR_REL_CAUSE_NOT_AUTHORIZED:
- case RR_REL_CAUSE_EMERGENCY_ONLY:
- case RR_REL_CAUSE_TRY_LATER:
- cause = 21;
- break;
- case RR_REL_CAUSE_NORMAL:
- cause = 16;
- break;
- default:
- cause = 47;
- }
-
- /* stop MM connection timer */
- stop_mm_t3230(mm);
-
- /* release all connections */
- gsm48_mm_release_mm_conn(ms, 1, cause, 1);
-
- /* return to MM IDLE */
- return gsm48_mm_return_idle(ms, NULL);
-}
-
-/* 4.5.1.2 timeout is received during MM connection establishment */
-static int gsm48_mm_timeout_mm_con(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
-
- /* release pending connection */
- gsm48_mm_release_mm_conn(ms, 0, 102, 0);
-
- /* state depends on the existance of remaining MM connections */
- if (llist_empty(&mm->mm_conn)) {
- /* start RR release timer */
- start_mm_t3240(mm);
-
- new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
- } else
- new_mm_state(mm, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
-
- return 0;
-}
-
-/* respond to paging */
-static int gsm48_mm_est(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
-
- mm->est_cause = RR_EST_CAUSE_ANS_PAG_ANY;
- new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
-
- return 0;
-}
-
-/* send CM data */
-static int gsm48_mm_data(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
- struct gsm48_mm_conn *conn;
- int msg_type = mmh->msg_type;
-
- /* get connection, if not exist (anymore), release */
- conn = mm_conn_by_ref(mm, mmh->ref);
- if (!conn) {
- LOGP(DMM, LOGL_INFO, "MMXX_DATA_REQ with unknown (already "
- "released) ref=%x, sending MMXX_REL_IND\n", mmh->ref);
- switch(msg_type & GSM48_MMXX_MASK) {
- case GSM48_MMCC_CLASS:
- mmh->msg_type = GSM48_MMCC_REL_IND;
- break;
- case GSM48_MMSS_CLASS:
- mmh->msg_type = GSM48_MMSS_REL_IND;
- break;
- case GSM48_MMSMS_CLASS:
- mmh->msg_type = GSM48_MMSMS_REL_IND;
- break;
- }
- mmh->cause = 31;
-
- /* mirror message with REL_IND + cause */
- return gsm48_mmxx_upmsg(ms, msg);
- }
-
- /* pull MM header */
- msgb_pull(msg, sizeof(struct gsm48_mmxx_hdr));
-
- /* push RR header and send down */
- return gsm48_mm_to_rr(ms, msg, GSM48_RR_DATA_REQ, 0);
-}
-
-/* release of MM connection (active state) */
-static int gsm48_mm_release_active(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
- struct gsm48_mm_conn *conn;
-
- /* get connection, if not exist (anymore), release */
- conn = mm_conn_by_ref(mm, mmh->ref);
- if (conn)
- mm_conn_free(conn);
-
- /* state depends on the existance of remaining MM connections */
- if (llist_empty(&mm->mm_conn)) {
- /* start RR release timer */
- start_mm_t3240(mm);
-
- new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
- } else
- new_mm_state(mm, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
-
- return 0;
-}
-
-/* release of MM connection (wait for additional state) */
-static int gsm48_mm_release_wait_add(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
- struct gsm48_mm_conn *conn;
-
- /* get connection, if not exist (anymore), release */
- conn = mm_conn_by_ref(mm, mmh->ref);
- if (conn)
- mm_conn_free(conn);
-
- return 0;
-}
-
-/* release of MM connection (wait for active state) */
-static int gsm48_mm_release_wait_active(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
- struct gsm48_mm_conn *conn;
-
- /* get connection, if not exist (anymore), release */
- conn = mm_conn_by_ref(mm, mmh->ref);
- if (conn)
- mm_conn_free(conn);
-
- /* 4.5.1.7 if there is no MM connection during wait for active state */
- if (llist_empty(&mm->mm_conn)) {
- LOGP(DMM, LOGL_INFO, "No MM Connection during 'wait for "
- "active' state.\n");
-
- /* start RR release timer */
- start_mm_t3240(mm);
-
- new_mm_state(mm, GSM48_MM_ST_WAIT_NETWORK_CMD, 0);
-
- /* send abort */
- return gsm48_mm_tx_cm_service_abort(ms);
- }
-
- return 0;
-}
-
-/* release of MM connection (wait for RR state) */
-static int gsm48_mm_release_wait_rr(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
- struct gsm48_mm_conn *conn;
-
- /* get connection, if not exist (anymore), release */
- conn = mm_conn_by_ref(mm, mmh->ref);
- if (conn)
- mm_conn_free(conn);
-
- /* later, if RR connection is established, the CM SERIVE ABORT
- * message will be sent
- */
- return 0;
-}
-
-/* abort RR connection (due to T3240) */
-static int gsm48_mm_abort_rr(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct msgb *nmsg;
- struct gsm48_rr_hdr *nrrh;
-
- /* send abort to RR */
- nmsg = gsm48_rr_msgb_alloc(GSM48_RR_ABORT_REQ);
- if (!nmsg)
- return -ENOMEM;
- nrrh = (struct gsm48_rr_hdr *) nmsg->data;
- nrrh->cause = GSM48_RR_CAUSE_ABNORMAL_TIMER;
- gsm48_rr_downmsg(ms, nmsg);
-
- /* return to MM IDLE */
- return gsm48_mm_return_idle(ms, NULL);
-}
-
-/*
- * other processes
- */
-
-/* RR is released in other states */
-static int gsm48_mm_rel_other(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
-
- /* stop RR release timer (if running) */
- stop_mm_t3240(mm);
-
- /* return to MM IDLE */
- return gsm48_mm_return_idle(ms, NULL);
-}
-
-/*
- * state machines
- */
-
-/* state trasitions for MMxx-SAP messages from upper layers */
-static struct downstate {
- uint32_t states;
- uint32_t substates;
- int type;
- int (*rout) (struct osmocom_ms *ms, struct msgb *msg);
-} downstatelist[] = {
- /* 4.2.2.1 Normal service */
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
- GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
- GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_no_rr},
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
- GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_no_rr},
-
- /* 4.2.2.2 Attempt to update / Loc. Upd. needed */
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE) |
- SBIT(GSM48_MM_SST_LOC_UPD_NEEDED),
- GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr}, /* emergency only */
-
- /* 4.2.2.3 Limited service */
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
- GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
-
- /* 4.2.2.4 No IMSI */
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NO_IMSI),
- GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
-
- /* 4.2.2.5 PLMN search, normal service */
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
- GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
- GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_no_rr},
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
- GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_no_rr},
-
- /* 4.2.2.6 PLMN search */
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH),
- GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_no_rr},
-
- /* 4.5.1.1 MM Connection (EST) */
- {SBIT(GSM48_MM_ST_RR_CONN_RELEASE_NA), ALL_STATES,
- GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_first},
-
- {SBIT(GSM48_MM_ST_RR_CONN_RELEASE_NA), ALL_STATES,
- GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_first},
-
- {SBIT(GSM48_MM_ST_RR_CONN_RELEASE_NA), ALL_STATES,
- GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_first},
-
- {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
- GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_more},
-
- {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
- GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_more},
-
- {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
- GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_more},
-
- {SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD), ALL_STATES,
- GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_wait},
-
- {SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD), ALL_STATES,
- GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_wait},
-
- {SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD), ALL_STATES,
- GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_wait},
-
- {ALL_STATES, ALL_STATES,
- GSM48_MMCC_EST_REQ, gsm48_mm_init_mm_reject},
-
- {ALL_STATES, ALL_STATES,
- GSM48_MMSS_EST_REQ, gsm48_mm_init_mm_reject},
-
- {ALL_STATES, ALL_STATES,
- GSM48_MMSMS_EST_REQ, gsm48_mm_init_mm_reject},
-
- /* 4.5.2.1 MM Connection (DATA) */
- {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
- SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
- GSM48_MMCC_DATA_REQ, gsm48_mm_data},
-
- {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
- SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
- GSM48_MMSS_DATA_REQ, gsm48_mm_data},
-
- {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
- SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
- GSM48_MMSMS_DATA_REQ, gsm48_mm_data},
-
- /* 4.5.2.1 MM Connection (REL) */
- {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
- GSM48_MMCC_REL_REQ, gsm48_mm_release_active},
-
- {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
- GSM48_MMSS_REL_REQ, gsm48_mm_release_active},
-
- {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), ALL_STATES,
- GSM48_MMSMS_REL_REQ, gsm48_mm_release_active},
-
- {SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
- GSM48_MMCC_REL_REQ, gsm48_mm_release_wait_add},
-
- {SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
- GSM48_MMSS_REL_REQ, gsm48_mm_release_wait_add},
-
- {SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), ALL_STATES,
- GSM48_MMSMS_REL_REQ, gsm48_mm_release_wait_add},
-
- {SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN), ALL_STATES,
- GSM48_MMCC_REL_REQ, gsm48_mm_release_wait_active},
-
- {SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN), ALL_STATES,
- GSM48_MMSS_REL_REQ, gsm48_mm_release_wait_active},
-
- {SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN), ALL_STATES,
- GSM48_MMSMS_REL_REQ, gsm48_mm_release_wait_active},
-
- {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON), ALL_STATES,
- GSM48_MMCC_REL_REQ, gsm48_mm_release_wait_rr},
-
- {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON), ALL_STATES,
- GSM48_MMSS_REL_REQ, gsm48_mm_release_wait_rr},
-
- {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON), ALL_STATES,
- GSM48_MMSMS_REL_REQ, gsm48_mm_release_wait_rr},
-};
-
-#define DOWNSLLEN \
- (sizeof(downstatelist) / sizeof(struct downstate))
-
-int gsm48_mmxx_downmsg(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm48_mmxx_hdr *mmh = (struct gsm48_mmxx_hdr *)msg->data;
- int msg_type = mmh->msg_type;
- struct gsm48_mm_conn *conn;
- int i, rc;
-
- /* keep up to date with the transaction ID */
- conn = mm_conn_by_ref(mm, mmh->ref);
- if (conn)
- conn->transaction_id = mmh->transaction_id;
-
- LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' event in state %s\n",
- ms->name, get_mmxx_name(msg_type),
- gsm48_mm_state_names[mm->state]);
- if (mm->state == GSM48_MM_ST_MM_IDLE)
- LOGP(DMM, LOGL_INFO, "-> substate %s\n",
- gsm48_mm_substate_names[mm->substate]);
- LOGP(DMM, LOGL_INFO, "-> callref %x, transaction_id %d\n",
- mmh->ref, mmh->transaction_id);
-
- /* Find function for current state and message */
- for (i = 0; i < DOWNSLLEN; i++)
- if ((msg_type == downstatelist[i].type)
- && ((1 << mm->state) & downstatelist[i].states)
- && ((1 << mm->substate) & downstatelist[i].substates))
- break;
- if (i == DOWNSLLEN) {
- LOGP(DMM, LOGL_NOTICE, "Message unhandled at this state.\n");
- msgb_free(msg);
- return 0;
- }
-
- rc = downstatelist[i].rout(ms, msg);
-
- if (downstatelist[i].rout != gsm48_mm_data)
- msgb_free(msg);
-
- return rc;
-}
-
-/* state trasitions for radio ressource messages (lower layer) */
-static struct rrdatastate {
- uint32_t states;
- int type;
- int (*rout) (struct osmocom_ms *ms, struct msgb *msg);
-} rrdatastatelist[] = {
- /* paging */
- {SBIT(GSM48_MM_ST_MM_IDLE),
- GSM48_RR_EST_IND, gsm48_mm_est},
-
- /* imsi detach */
- {SBIT(GSM48_MM_ST_WAIT_RR_CONN_IMSI_D), /* 4.3.4.4 */
- GSM48_RR_EST_CNF, gsm48_mm_imsi_detach_sent},
-
- {SBIT(GSM48_MM_ST_WAIT_RR_CONN_IMSI_D), /* 4.3.4.4 (unsuc.) */
- GSM48_RR_REL_IND, gsm48_mm_imsi_detach_end},
- /* also this may happen if SABM is ackwnowledged with DISC */
-
- {SBIT(GSM48_MM_ST_WAIT_RR_CONN_IMSI_D), /* 4.3.4.4 (lost) */
- GSM48_RR_ABORT_IND, gsm48_mm_imsi_detach_end},
-
- {SBIT(GSM48_MM_ST_IMSI_DETACH_INIT), /* 4.3.4.4 (unsuc.) */
- GSM48_RR_REL_IND, gsm48_mm_imsi_detach_end},
-
- {SBIT(GSM48_MM_ST_IMSI_DETACH_INIT), /* 4.3.4.4 (lost) */
- GSM48_RR_ABORT_IND, gsm48_mm_imsi_detach_end},
-
- /* location update */
- {SBIT(GSM48_MM_ST_WAIT_RR_CONN_LUPD), /* 4.4.4.1 */
- GSM48_RR_EST_CNF, gsm48_mm_est_loc_upd},
-
- {SBIT(GSM48_MM_ST_LOC_UPD_INIT) |
- SBIT(GSM48_MM_ST_WAIT_RR_CONN_LUPD), /* 4.4.4.9 */
- GSM48_RR_REL_IND, gsm48_mm_rel_loc_upd_abort},
-
- {SBIT(GSM48_MM_ST_LOC_UPD_INIT) |
- SBIT(GSM48_MM_ST_WAIT_RR_CONN_LUPD), /* 4.4.4.9 */
- GSM48_RR_ABORT_IND, gsm48_mm_rel_loc_upd_abort},
-
- {SBIT(GSM48_MM_ST_LOC_UPD_REJ), /* 4.4.4.7 */
- GSM48_RR_REL_IND, gsm48_mm_rel_loc_upd_rej},
-
- {SBIT(GSM48_MM_ST_LOC_UPD_REJ), /* 4.4.4.7 */
- GSM48_RR_ABORT_IND, gsm48_mm_rel_loc_upd_rej},
-
- /* MM connection (EST) */
- {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON), /* 4.5.1.1 */
- GSM48_RR_EST_CNF, gsm48_mm_est_mm_con},
-
- /* MM connection (DATA) */
- {ALL_STATES,
- GSM48_RR_DATA_IND, gsm48_mm_data_ind},
-
- /* MM connection (SYNC) */
- {SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN) |
- SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), /* 4.5.1.1 */
- GSM48_RR_SYNC_IND, gsm48_mm_sync_ind_wait},
-
- {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE),
- GSM48_RR_SYNC_IND, gsm48_mm_sync_ind_active},
-
- /* MM connection (REL/ABORT) */
- {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON) |
- SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN) |
- SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), /* 4.5.1.2 */
- GSM48_RR_REL_IND, gsm48_mm_abort_mm_con},
-
- {SBIT(GSM48_MM_ST_WAIT_RR_CONN_MM_CON) |
- SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN) |
- SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), /* 4.5.1.2 */
- GSM48_RR_ABORT_IND, gsm48_mm_abort_mm_con},
-
- /* MM connection (REL/ABORT with re-establishment possibility) */
- {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE), /* not supported */
- GSM48_RR_REL_IND, gsm48_mm_abort_mm_con},
-
- {SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
- SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON), /* not supported */
- GSM48_RR_ABORT_IND, gsm48_mm_abort_mm_con},
-
- /* other (also wait for network command) */
- {ALL_STATES,
- GSM48_RR_REL_IND, gsm48_mm_rel_other},
-
- {ALL_STATES,
- GSM48_RR_ABORT_IND, gsm48_mm_rel_other},
-};
-
-#define RRDATASLLEN \
- (sizeof(rrdatastatelist) / sizeof(struct rrdatastate))
-
-static int gsm48_rcv_rr(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *)msg->data;
- int msg_type = rrh->msg_type;
- int i, rc;
-
- LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' from RR in state %s\n",
- ms->name, get_rr_name(msg_type),
- gsm48_mm_state_names[mm->state]);
-
- /* find function for current state and message */
- for (i = 0; i < RRDATASLLEN; i++)
- if ((msg_type == rrdatastatelist[i].type)
- && ((1 << mm->state) & rrdatastatelist[i].states))
- break;
- if (i == RRDATASLLEN) {
- LOGP(DMM, LOGL_NOTICE, "Message unhandled at this state.\n");
- msgb_free(msg);
- return 0;
- }
-
- rc = rrdatastatelist[i].rout(ms, msg);
-
- if (rrdatastatelist[i].rout != gsm48_mm_data_ind)
- msgb_free(msg);
-
- return rc;
-}
-
-/* state trasitions for mobile managemnt messages (lower layer) */
-static struct mmdatastate {
- uint32_t states;
- int type;
- int (*rout) (struct osmocom_ms *ms, struct msgb *msg);
-} mmdatastatelist[] = {
- {ALL_STATES, /* 4.3.1.2 */
- GSM48_MT_MM_TMSI_REALL_CMD, gsm48_mm_rx_tmsi_realloc_cmd},
-
- {ALL_STATES, /* 4.3.2.2 */
- GSM48_MT_MM_AUTH_REQ, gsm48_mm_rx_auth_req},
-
- {ALL_STATES, /* 4.3.2.5 */
- GSM48_MT_MM_AUTH_REJ, gsm48_mm_rx_auth_rej},
-
- {ALL_STATES, /* 4.3.3.2 */
- GSM48_MT_MM_ID_REQ, gsm48_mm_rx_id_req},
-
- {ALL_STATES, /* 4.3.5.2 */
- GSM48_MT_MM_ABORT, gsm48_mm_rx_abort},
-
- {ALL_STATES, /* 4.3.6.2 */
- GSM48_MT_MM_INFO, gsm48_mm_rx_info},
-
- {SBIT(GSM48_MM_ST_LOC_UPD_INIT), /* 4.4.4.6 */
- GSM48_MT_MM_LOC_UPD_ACCEPT, gsm48_mm_rx_loc_upd_acc},
-
- {SBIT(GSM48_MM_ST_LOC_UPD_INIT), /* 4.4.4.7 */
- GSM48_MT_MM_LOC_UPD_REJECT, gsm48_mm_rx_loc_upd_rej},
-
- {ALL_STATES, /* 4.5.1.1 */
- GSM48_MT_MM_CM_SERV_ACC, gsm48_mm_rx_cm_service_acc},
-
- {ALL_STATES, /* 4.5.1.1 */
- GSM48_MT_MM_CM_SERV_REJ, gsm48_mm_rx_cm_service_rej},
-};
-
-#define MMDATASLLEN \
- (sizeof(mmdatastatelist) / sizeof(struct mmdatastate))
-
-static int gsm48_mm_data_ind(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct gsm48_hdr *gh = msgb_l3(msg);
- uint8_t pdisc = gh->proto_discr & 0x0f;
- uint8_t msg_type = gh->msg_type & 0xbf;
- struct gsm48_mmxx_hdr *mmh;
- int msg_supported = 0; /* determine, if message is supported at all */
- int rr_prim = -1, rr_est = -1; /* no prim set */
- uint8_t skip_ind;
- int i, rc;
-
- /* 9.2.19 */
- if (msg_type == GSM48_MT_MM_NULL)
- return 0;
-
- if (mm->state == GSM48_MM_ST_IMSI_DETACH_INIT) {
- LOGP(DMM, LOGL_NOTICE, "DATA IND ignored during IMSI "
- "detach.\n");
- return 0;
- }
- /* pull the RR header */
- msgb_pull(msg, sizeof(struct gsm48_rr_hdr));
-
- /* create transaction (if not exists) and push message */
- switch (pdisc) {
- case GSM48_PDISC_CC:
- rr_prim = GSM48_MMCC_DATA_IND;
- rr_est = GSM48_MMCC_EST_IND;
- break;
-#if 0
- case GSM48_PDISC_NC_SS:
- rr_prim = GSM48_MMSS_DATA_IND;
- rr_est = GSM48_MMSS_EST_IND;
- break;
- case GSM48_PDISC_SMS:
- rr_prim = GSM48_MMSMS_DATA_IND;
- rr_est = GSM48_MMSMS_EST_IND;
- break;
-#endif
- }
- if (rr_prim != -1) {
- uint8_t transaction_id = ((gh->proto_discr & 0xf0) ^ 0x80) >> 4;
- /* flip */
- struct gsm48_mm_conn *conn;
-
- /* find transaction, if any */
- conn = mm_conn_by_id(mm, pdisc, transaction_id);
-
- /* create MM connection instance */
- if (!conn) {
- conn = mm_conn_new(mm, pdisc, transaction_id,
- mm_conn_new_ref++);
- rr_prim = rr_est;
- }
- if (!conn)
- return -ENOMEM;
-
- /* push new header */
- msgb_push(msg, sizeof(struct gsm48_mmxx_hdr));
- mmh = (struct gsm48_mmxx_hdr *)msg->data;
- mmh->msg_type = rr_prim;
- mmh->ref = conn->ref;
-
- /* go MM CONN ACTIVE state */
- if (mm->state == GSM48_MM_ST_WAIT_NETWORK_CMD
- || mm->state == GSM48_MM_ST_RR_CONN_RELEASE_NA) {
- /* stop RR release timer */
- stop_mm_t3240(mm);
-
- /* stop "RR connection release not allowed" timer */
- stop_mm_t3241(mm);
-
- new_mm_state(mm, GSM48_MM_ST_MM_CONN_ACTIVE, 0);
- }
- }
-
- /* forward message */
- switch (pdisc) {
- case GSM48_PDISC_MM:
- skip_ind = (gh->proto_discr & 0xf0) >> 4;
-
- /* ignore if skip indicator is not B'0000' */
- if (skip_ind)
- return 0;
- break; /* follow the selection proceedure below */
-
- case GSM48_PDISC_CC:
- return gsm48_rcv_cc(ms, msg);
-
-#if 0
- case GSM48_PDISC_NC_SS:
- return gsm48_rcv_ss(ms, msg);
-
- case GSM48_PDISC_SMS:
- return gsm48_rcv_sms(ms, msg);
-#endif
-
- default:
- LOGP(DMM, LOGL_NOTICE, "Protocol type 0x%02x unsupported.\n",
- pdisc);
- msgb_free(msg);
- return gsm48_mm_tx_mm_status(ms,
- GSM48_REJECT_MSG_TYPE_NOT_IMPLEMENTED);
- }
-
- LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' in MM state %s\n", ms->name,
- get_mm_name(msg_type), gsm48_mm_state_names[mm->state]);
-
- stop_mm_t3212(mm); /* 4.4.2 */
-
- /* 11.2 re-start pending RR release timer */
- if (osmo_timer_pending(&mm->t3240)) {
- stop_mm_t3240(mm);
- start_mm_t3240(mm);
- }
-
- /* find function for current state and message */
- for (i = 0; i < MMDATASLLEN; i++) {
- if (msg_type == mmdatastatelist[i].type)
- msg_supported = 1;
- if ((msg_type == mmdatastatelist[i].type)
- && ((1 << mm->state) & mmdatastatelist[i].states))
- break;
- }
- if (i == MMDATASLLEN) {
- msgb_free(msg);
- if (msg_supported) {
- LOGP(DMM, LOGL_NOTICE, "Message unhandled at this "
- "state.\n");
- return gsm48_mm_tx_mm_status(ms,
- GSM48_REJECT_MSG_TYPE_NOT_COMPATIBLE);
- } else {
- LOGP(DMM, LOGL_NOTICE, "Message not supported.\n");
- return gsm48_mm_tx_mm_status(ms,
- GSM48_REJECT_MSG_TYPE_NOT_IMPLEMENTED);
- }
- }
-
- rc = mmdatastatelist[i].rout(ms, msg);
-
- msgb_free(msg);
-
- return rc;
-}
-
-/* state trasitions for mobile management events */
-static struct eventstate {
- uint32_t states;
- uint32_t substates;
- int type;
- int (*rout) (struct osmocom_ms *ms, struct msgb *msg);
-} eventstatelist[] = {
- /* 4.2.3 return to MM IDLE */
- {ALL_STATES - SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
- GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_no_cell_found},
-
- {ALL_STATES - SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
- GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_return_idle},
-
- /* 4.2.2.1 Normal service */
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
- GSM48_MM_EVENT_USER_PLMN_SEL, gsm48_mm_plmn_search}, /* 4.2.1.2 */
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
- GSM48_MM_EVENT_LOST_COVERAGE, gsm48_mm_plmn_search}, /* 4.2.1.2 */
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
- GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_loc_upd_normal}, /* change */
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
- GSM48_MM_EVENT_TIMEOUT_T3211, gsm48_mm_loc_upd},
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
- GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_upd},
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
- GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_periodic},
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
- GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_start},
-
- /* 4.2.2.2 Attempt to update / Loc. upd. needed */
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE) |
- SBIT(GSM48_MM_SST_LOC_UPD_NEEDED),
- GSM48_MM_EVENT_USER_PLMN_SEL, gsm48_mm_plmn_search}, /* 4.2.1.2 */
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE) |
- SBIT(GSM48_MM_SST_LOC_UPD_NEEDED),
- GSM48_MM_EVENT_LOST_COVERAGE, gsm48_mm_plmn_search}, /* 4.2.1.2 */
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE) |
- SBIT(GSM48_MM_SST_LOC_UPD_NEEDED),
- GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_loc_upd_normal}, /* change */
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE),
- GSM48_MM_EVENT_TIMEOUT_T3211, gsm48_mm_loc_upd},
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE),
- GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_upd},
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_ATTEMPT_UPDATE),
- GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_periodic},
-
- /* 4.2.2.3 Limited service */
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
- GSM48_MM_EVENT_USER_PLMN_SEL, gsm48_mm_plmn_search}, /* 4.2.1.2 */
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
- GSM48_MM_EVENT_LOST_COVERAGE, gsm48_mm_plmn_search}, /* 4.2.1.2 */
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
- GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_loc_upd_normal}, /* if allow. */
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_LIMITED_SERVICE),
- GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay_per}, /* 4.4.2 */
-
- /* 4.2.2.4 No IMSI */
- /* 4.2.2.5 PLMN search, normal service */
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
- GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_no_cell_found}, /* 4.2.1.1 */
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
- GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_cell_selected}, /* 4.2.1.1 */
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
- GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay_per}, /* 4.4.2 */
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH_NORMAL),
- GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_start},
-
- /* 4.2.2.6 PLMN search */
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH),
- GSM48_MM_EVENT_NO_CELL_FOUND, gsm48_mm_no_cell_found}, /* 4.2.1.1 */
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH),
- GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_cell_selected}, /* 4.2.1.1 */
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_PLMN_SEARCH),
- GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay_per}, /* 4.4.2 */
-
- /* No cell available */
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NO_CELL_AVAIL),
- GSM48_MM_EVENT_CELL_SELECTED, gsm48_mm_cell_selected}, /* 4.2.1.1 */
-
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NO_CELL_AVAIL),
- GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_delay_per}, /* 4.4.2 */
-
- /* IMSI detach in other cases */
- {SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES, /* silently detach */
- GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_end},
-
- {SBIT(GSM48_MM_ST_WAIT_OUT_MM_CONN) |
- SBIT(GSM48_MM_ST_MM_CONN_ACTIVE) |
- SBIT(GSM48_MM_ST_PROCESS_CM_SERV_P) |
- SBIT(GSM48_MM_ST_WAIT_REEST) |
- SBIT(GSM48_MM_ST_WAIT_ADD_OUT_MM_CON) |
- SBIT(GSM48_MM_ST_MM_CONN_ACTIVE_VGCS) |
- SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD), ALL_STATES, /* we can release */
- GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_release},
-
- {SBIT(GSM48_MM_ST_WAIT_RR_CONN_IMSI_D) |
- SBIT(GSM48_MM_ST_IMSI_DETACH_INIT) |
- SBIT(GSM48_MM_ST_IMSI_DETACH_PEND), ALL_STATES, /* ignore */
- GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_ignore},
-
- {ALL_STATES, ALL_STATES,
- GSM48_MM_EVENT_IMSI_DETACH, gsm48_mm_imsi_detach_delay},
-
- {GSM48_MM_ST_IMSI_DETACH_INIT, ALL_STATES,
- GSM48_MM_EVENT_TIMEOUT_T3220, gsm48_mm_imsi_detach_end},
-
- /* location update in other cases */
- {SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
- GSM48_MM_EVENT_TIMEOUT_T3211, gsm48_mm_loc_upd_delay_retry},
-
- {SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
- GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_upd_delay_retry},
-
- {ALL_STATES, ALL_STATES,
- GSM48_MM_EVENT_TIMEOUT_T3212, gsm48_mm_loc_upd_ignore},
-
- {ALL_STATES - SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
- GSM48_MM_EVENT_TIMEOUT_T3210, gsm48_mm_loc_upd_timeout},
-
- {ALL_STATES - SBIT(GSM48_MM_ST_MM_IDLE), ALL_STATES,
- GSM48_MM_EVENT_TIMEOUT_T3213, gsm48_mm_loc_upd_failed},
- /* 4.4.4.9 c) (but without retry) */
-
- /* SYSINFO event */
- {ALL_STATES, ALL_STATES,
- GSM48_MM_EVENT_SYSINFO, gsm48_mm_sysinfo},
-
- /* T3240 timed out */
- {SBIT(GSM48_MM_ST_WAIT_NETWORK_CMD) |
- SBIT(GSM48_MM_ST_LOC_UPD_REJ), ALL_STATES, /* 4.4.4.8 */
- GSM48_MM_EVENT_TIMEOUT_T3240, gsm48_mm_abort_rr},
-
- /* T3230 timed out */
- {SBIT(GSM48_MM_ST_MM_IDLE), SBIT(GSM48_MM_SST_NORMAL_SERVICE),
- GSM48_MM_EVENT_TIMEOUT_T3230, gsm48_mm_timeout_mm_con},
-
- /* SIM reports SRES */
- {ALL_STATES, ALL_STATES, /* 4.3.2.2 */
- GSM48_MM_EVENT_AUTH_RESPONSE, gsm48_mm_tx_auth_rsp},
-
-#if 0
- /* change in classmark is reported */
- {ALL_STATES, ALL_STATES,
- GSM48_MM_EVENT_CLASSMARK_CHG, gsm48_mm_classm_chg},
-#endif
-};
-
-#define EVENTSLLEN \
- (sizeof(eventstatelist) / sizeof(struct eventstate))
-
-static int gsm48_mm_ev(struct osmocom_ms *ms, int msg_type, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- int i, rc;
-
- if (mm->state == GSM48_MM_ST_MM_IDLE) {
- if (msg_type != GSM48_MM_EVENT_SYSINFO)
- LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' event in "
- "state MM IDLE, %s\n", ms->name,
- get_mmevent_name(msg_type),
- gsm48_mm_substate_names[mm->substate]);
- } else
- LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' event in state "
- "%s\n", ms->name, get_mmevent_name(msg_type),
- gsm48_mm_state_names[mm->state]);
-
- /* Find function for current state and message */
- for (i = 0; i < EVENTSLLEN; i++)
- if ((msg_type == eventstatelist[i].type)
- && ((1 << mm->state) & eventstatelist[i].states)
- && ((1 << mm->substate) & eventstatelist[i].substates))
- break;
- if (i == EVENTSLLEN) {
- LOGP(DMM, LOGL_NOTICE, "Message unhandled at this state.\n");
- return 0;
- }
-
- rc = eventstatelist[i].rout(ms, msg);
-
- return rc;
-}
-
-/*
- * MM Register (SIM insert and remove)
- */
-
-/* register new SIM card and trigger attach */
-static int gsm48_mmr_reg_req(struct osmocom_ms *ms)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct msgb *nmsg;
-
- /* schedule insertion of SIM */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_SIM_INSERT);
- if (!nmsg)
- return -ENOMEM;
- gsm322_plmn_sendmsg(ms, nmsg);
-
- /* 4.2.1.2 SIM is inserted in state NO IMSI */
- if (mm->state == GSM48_MM_ST_MM_IDLE
- && mm->substate == GSM48_MM_SST_NO_IMSI)
- new_mm_state(mm, GSM48_MM_ST_MM_IDLE,
- gsm48_mm_set_plmn_search(ms));
-
- return 0;
-}
-
-/* trigger detach of sim card */
-static int gsm48_mmr_nreg_req(struct osmocom_ms *ms)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
- struct msgb *nmsg;
-
- nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_IMSI_DETACH);
- if (!nmsg)
- return -ENOMEM;
- gsm48_mmevent_msg(mm->ms, nmsg);
-
- return 0;
-}
-
-static int gsm48_rcv_mmr(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmr *mmr = (struct gsm48_mmr *)msg->data;
- int msg_type = mmr->msg_type;
- int rc = 0;
-
- LOGP(DMM, LOGL_INFO, "(ms %s) Received '%s' event\n", ms->name,
- get_mmr_name(msg_type));
- switch(msg_type) {
- case GSM48_MMR_REG_REQ:
- rc = gsm48_mmr_reg_req(ms);
- break;
- case GSM48_MMR_NREG_REQ:
- rc = gsm48_mmr_nreg_req(ms);
- break;
- default:
- LOGP(DMM, LOGL_NOTICE, "Message unhandled.\n");
- }
-
- return rc;
-}
-
-
diff --git a/Src/osmoconbb/src/host/layer23/src/mobile/gsm48_rr.c b/Src/osmoconbb/src/host/layer23/src/mobile/gsm48_rr.c
deleted file mode 100644
index c1e386a..0000000
--- a/Src/osmoconbb/src/host/layer23/src/mobile/gsm48_rr.c
+++ /dev/null
@@ -1,5265 +0,0 @@
-/*
- * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-/* Very short description of some of the procedures:
- *
- * A radio ressource request causes sendig a channel request on RACH.
- * After receiving of an immediate assignment the link will be establised.
- * After the link is established, the dedicated mode is entered and confirmed.
- *
- * A Paging request also triggers the channel request as above...
- * After the link is established, the dedicated mode is entered and indicated.
- *
- * During dedicated mode, messages are transferred.
- *
- * When an assignment command or a handover command is received, the current
- * link is released. After release, the new channel is activated and the
- * link is established again. After link is establised, pending messages from
- * radio ressource are sent.
- *
- * When the assignment or handover fails, the old channel is activate and the
- * link is established again. Also pending messages are sent.
- *
- */
-
-/* Testing delayed (immediate) assigment / handover
- *
- * When enabled, the starting time will be set by given frames in the future.
- * If a starting time is given by the network, this time is ignored.
- */
-//#define TEST_STARTING_TIMER 140
-
-/* Testing if frequency modification works correctly "after time".
- *
- * When enabled, the starting time will be set in the future.
- * A wrong channel is defined "before time", so noise is received until
- * starting time elapses.
- * If a starting time is given by the network, this time is ignored.
- * Also channel definitions "before time" are ignored.
- *
- * NOTE: TEST_STARTING_TIMER MUST be defined also.
- */
-//#define TEST_FREQUENCY_MOD
-
-#include <stdint.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <arpa/inet.h>
-
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/utils.h>
-#include <osmocom/gsm/rsl.h>
-#include <osmocom/gsm/gsm48.h>
-#include <osmocom/core/bitvec.h>
-
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/l1l2_interface.h>
-#include <osmocom/bb/common/l23_app.h>
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/networks.h>
-#include <osmocom/bb/common/l1ctl.h>
-#include <osmocom/bb/mobile/vty.h>
-
-#include <l1ctl_proto.h>
-
-static void start_rr_t_meas(struct gsm48_rrlayer *rr, int sec, int micro);
-static void stop_rr_t_starting(struct gsm48_rrlayer *rr);
-static void stop_rr_t3124(struct gsm48_rrlayer *rr);
-static int gsm48_rcv_rsl(struct osmocom_ms *ms, struct msgb *msg);
-static int gsm48_rr_dl_est(struct osmocom_ms *ms);
-static int gsm48_rr_tx_meas_rep(struct osmocom_ms *ms);
-static int gsm48_rr_set_mode(struct osmocom_ms *ms, uint8_t chan_nr,
- uint8_t mode);
-static int gsm48_rr_rel_cnf(struct osmocom_ms *ms, struct msgb *msg);
-
-/*
- * support
- */
-
-#define MIN(a, b) ((a < b) ? a : b)
-
-int gsm48_encode_lai(struct gsm48_loc_area_id *lai, uint16_t mcc,
- uint16_t mnc, uint16_t lac)
-{
- lai->digits[0] = (mcc >> 8) | (mcc & 0xf0);
- lai->digits[1] = (mcc & 0x0f) | (mnc << 4);
- lai->digits[2] = (mnc >> 8) | (mnc & 0xf0);
- lai->lac = htons(lac);
-
- return 0;
-}
-
-/* decode "Power Command" (10.5.2.28) and (10.5.2.28a) */
-static int gsm48_decode_power_cmd_acc(struct gsm48_power_cmd *pc,
- uint8_t *power_level, uint8_t *atc)
-{
- *power_level = pc->power_level;
- if (atc) /* only in case of 10.5.2.28a */
- *atc = pc->atc;
-
- return 0;
-}
-
-/* 10.5.2.38 decode Starting time IE */
-static int gsm48_decode_start_time(struct gsm48_rr_cd *cd,
- struct gsm48_start_time *st)
-{
- cd->start = 1;
- cd->start_tm.t1 = st->t1;
- cd->start_tm.t2 = st->t2;
- cd->start_tm.t3 = (st->t3_high << 3) | st->t3_low;
- cd->start_tm.fn = gsm_gsmtime2fn(&cd->start_tm);
-
- return 0;
-}
-
-/* decode "BA Range" (10.5.2.1a) */
-static int gsm48_decode_ba_range(const uint8_t *ba, uint8_t ba_len,
- uint32_t *range, uint8_t *ranges, int max_ranges)
-{
- /* ba = pointer to IE without IE type and length octets
- * ba_len = number of octets
- * range = pointer to store decoded range
- * ranges = number of ranges decoded
- * max_ranges = maximum number of decoded ranges that can be stored
- */
- uint16_t lower, higher;
- int i, n, required_octets;
-
- /* find out how much ba ranges will be decoded */
- n = *ba++;
- ba_len --;
- required_octets = 5 * (n >> 1) + 3 * (n & 1);
- if (required_octets > ba_len) {
- LOGP(DRR, LOGL_NOTICE, "BA range IE too short: %d ranges "
- "require %d octets, but only %d octets remain.\n",
- n, required_octets, ba_len);
- *ranges = 0;
- return -EINVAL;
- }
- if (max_ranges > n)
- LOGP(DRR, LOGL_NOTICE, "BA range %d exceed the maximum number "
- "of ranges supported by this mobile (%d).\n",
- n, max_ranges);
- n = max_ranges;
-
- /* decode ranges */
- for (i = 0; i < n; i++) {
- if (!(i & 1)) {
- /* decode even range number */
- lower = *ba++ << 2;
- lower |= (*ba >> 6);
- higher = (*ba++ & 0x3f) << 4;
- higher |= *ba >> 4;
- } else {
- lower = (*ba++ & 0x0f) << 6;
- lower |= *ba >> 2;
- higher = (*ba++ & 0x03) << 8;
- higher |= *ba++;
- /* decode odd range number */
- }
- *range++ = (higher << 16) | lower;
- }
- *ranges = n;
-
- return 0;
-}
-
-/* decode "Cell Description" (10.5.2.2) */
-static int gsm48_decode_cell_desc(struct gsm48_cell_desc *cd, uint16_t *arfcn,
- uint8_t *ncc, uint8_t *bcc)
-{
- *arfcn = (cd->arfcn_hi << 8) + cd->arfcn_lo;
- *ncc = cd->ncc;
- *bcc = cd->bcc;
-
- return 0;
-}
-
-/* decode "Synchronization Indication" (10.5.2.39) */
-static int gsm48_decode_sync_ind(struct gsm48_rrlayer *rr,
- struct gsm48_sync_ind *si)
-{
- rr->hando_sync_ind = si->si;
- rr->hando_rot = si->rot;
- rr->hando_nci = si->nci;
-
- return 0;
-}
-
-/* 3.1.4.3 set sequence number and increment */
-static int gsm48_apply_v_sd(struct gsm48_rrlayer *rr, struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- uint8_t pdisc = gh->proto_discr & 0x0f;
- uint8_t v_sd;
-
- switch (pdisc) {
- case GSM48_PDISC_MM:
- case GSM48_PDISC_CC:
- case GSM48_PDISC_NC_SS:
- /* all thre pdiscs share the same V(SD) */
- pdisc = GSM48_PDISC_MM;
- // fall through
- case GSM48_PDISC_GROUP_CC:
- case GSM48_PDISC_BCAST_CC:
- case GSM48_PDISC_PDSS1:
- case GSM48_PDISC_PDSS2:
- /* extract v_sd(pdisc) */
- v_sd = (rr->v_sd >> pdisc) & 1;
-
- /* replace bit 7 vy v_sd */
- gh->msg_type &= 0xbf;
- gh->msg_type |= (v_sd << 6);
-
- /* increment V(SD) */
- rr->v_sd ^= (1 << pdisc);
- LOGP(DRR, LOGL_INFO, "Using and incrementing V(SD) = %d "
- "(pdisc %x)\n", v_sd, pdisc);
- break;
- case GSM48_PDISC_RR:
- case GSM48_PDISC_SMS:
- /* no V(VSD) is required */
- break;
- default:
- LOGP(DRR, LOGL_ERROR, "Error, V(SD) of pdisc %x not handled\n",
- pdisc);
- return -ENOTSUP;
- }
-
- return 0;
-}
-
-/* set channel mode if supported, or return error cause */
-static uint8_t gsm48_rr_check_mode(struct osmocom_ms *ms, uint8_t chan_nr,
- uint8_t mode)
-{
- struct gsm_settings *set = &ms->settings;
- uint8_t ch_type, ch_subch, ch_ts;
-
- /* only complain if we use TCH/F or TCH/H */
- rsl_dec_chan_nr(chan_nr, &ch_type, &ch_subch, &ch_ts);
- if (ch_type != RSL_CHAN_Bm_ACCHs
- && ch_type != RSL_CHAN_Lm_ACCHs)
- return 0;
-
- switch (mode) {
- case GSM48_CMODE_SIGN:
- LOGP(DRR, LOGL_INFO, "Mode: signalling\n");
- break;
- case GSM48_CMODE_SPEECH_V1:
- if (ch_type == RSL_CHAN_Bm_ACCHs) {
- if (!set->full_v1) {
- LOGP(DRR, LOGL_NOTICE, "Not supporting "
- "full-rate speech V1\n");
- return GSM48_RR_CAUSE_CHAN_MODE_UNACCT;
- }
- LOGP(DRR, LOGL_INFO, "Mode: full-rate speech V1\n");
- } else {
- if (!set->half_v1) {
- LOGP(DRR, LOGL_NOTICE, "Not supporting "
- "half-rate speech V1\n");
- return GSM48_RR_CAUSE_CHAN_MODE_UNACCT;
- }
- LOGP(DRR, LOGL_INFO, "Mode: half-rate speech V1\n");
- }
- break;
- case GSM48_CMODE_SPEECH_EFR:
- if (ch_type == RSL_CHAN_Bm_ACCHs) {
- if (!set->full_v2) {
- LOGP(DRR, LOGL_NOTICE, "Not supporting "
- "full-rate speech V2\n");
- return GSM48_RR_CAUSE_CHAN_MODE_UNACCT;
- }
- LOGP(DRR, LOGL_INFO, "Mode: full-rate speech V2\n");
- } else {
- LOGP(DRR, LOGL_NOTICE, "Not supporting "
- "half-rate speech V2\n");
- return GSM48_RR_CAUSE_CHAN_MODE_UNACCT;
- }
- break;
- case GSM48_CMODE_SPEECH_AMR:
- if (ch_type == RSL_CHAN_Bm_ACCHs) {
- if (!set->full_v3) {
- LOGP(DRR, LOGL_NOTICE, "Not supporting "
- "full-rate speech V3\n");
- return GSM48_RR_CAUSE_CHAN_MODE_UNACCT;
- }
- LOGP(DRR, LOGL_INFO, "Mode: full-rate speech V3\n");
- } else {
- if (!set->half_v3) {
- LOGP(DRR, LOGL_NOTICE, "Not supporting "
- "half-rate speech V3\n");
- return GSM48_RR_CAUSE_CHAN_MODE_UNACCT;
- }
- LOGP(DRR, LOGL_INFO, "Mode: half-rate speech V3\n");
- }
- break;
- default:
- LOGP(DRR, LOGL_ERROR, "Mode 0x%02x not supported!\n", mode);
- return GSM48_RR_CAUSE_CHAN_MODE_UNACCT;
- }
-
- return 0;
-}
-
-/* apply new "alter_delay" in dedicated mode */
-int gsm48_rr_alter_delay(struct osmocom_ms *ms)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm_settings *set = &rr->ms->settings;
-
- if (rr->state != GSM48_RR_ST_DEDICATED)
- return -EINVAL;
- l1ctl_tx_param_req(ms, rr->cd_now.ind_ta - set->alter_delay,
- (set->alter_tx_power) ? set->alter_tx_power_value
- : rr->cd_now.ind_tx_power);
-
- return 0;
-}
-
-/*
- * state transition
- */
-
-const char *gsm48_rr_state_names[] = {
- "idle",
- "connection pending",
- "dedicated",
- "release pending",
-};
-
-static void new_rr_state(struct gsm48_rrlayer *rr, int state)
-{
- if (state < 0 || state >=
- (sizeof(gsm48_rr_state_names) / sizeof(char *)))
- return;
-
- /* must check against equal state */
- if (rr->state == state) {
- LOGP(DRR, LOGL_INFO, "equal state ? %s\n",
- gsm48_rr_state_names[rr->state]);
- return;
- }
-
- LOGP(DRR, LOGL_INFO, "new state %s -> %s\n",
- gsm48_rr_state_names[rr->state], gsm48_rr_state_names[state]);
-
- /* abort handover, in case of release of dedicated mode */
- if (rr->state == GSM48_RR_ST_DEDICATED) {
- /* disable handover / assign state */
- rr->modify_state = GSM48_RR_MOD_NONE;
- /* stop start_time_timer */
- stop_rr_t_starting(rr);
- /* stop handover timer */
- stop_rr_t3124(rr);
- }
-
- rr->state = state;
-
- if (state == GSM48_RR_ST_IDLE) {
- struct msgb *msg, *nmsg;
- struct gsm322_msg *em;
-
- /* release dedicated mode, if any */
- l1ctl_tx_dm_rel_req(rr->ms);
- rr->ms->meas.rl_fail = 0;
- rr->dm_est = 0;
- l1ctl_tx_reset_req(rr->ms, L1CTL_RES_T_FULL);
- /* free establish message, if any */
- rr->rr_est_req = 0;
- if (rr->rr_est_msg) {
- msgb_free(rr->rr_est_msg);
- rr->rr_est_msg = NULL;
- }
- /* free all pending messages */
- while((msg = msgb_dequeue(&rr->downqueue)))
- msgb_free(msg);
- /* clear all descriptions of last channel */
- memset(&rr->cd_now, 0, sizeof(rr->cd_now));
- /* reset ciphering */
- rr->cipher_on = 0;
- /* reset audio mode */
- /* tell cell selection process to return to idle mode
- * NOTE: this must be sent unbuffered, because it will
- * leave camping state, so it locks against subsequent
- * establishment of dedicated channel, before the
- * cell selection process returned to camping state
- * again. (after cell reselection)
- */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_RET_IDLE);
- if (!nmsg)
- return;
- /* return to same cell after LOC.UPD. */
- if (rr->est_cause == RR_EST_CAUSE_LOC_UPD) {
- em = (struct gsm322_msg *) nmsg->data;
- em->same_cell = 1;
- }
- gsm322_c_event(rr->ms, nmsg);
- msgb_free(nmsg);
- /* reset any BA range */
- rr->ba_ranges = 0;
- }
-}
-
-/*
- * messages
- */
-
-/* names of RR-SAP */
-static const struct value_string gsm48_rr_msg_names[] = {
- { GSM48_RR_EST_REQ, "RR_EST_REQ" },
- { GSM48_RR_EST_IND, "RR_EST_IND" },
- { GSM48_RR_EST_CNF, "RR_EST_CNF" },
- { GSM48_RR_REL_IND, "RR_REL_IND" },
- { GSM48_RR_SYNC_IND, "RR_SYNC_IND" },
- { GSM48_RR_DATA_REQ, "RR_DATA_REQ" },
- { GSM48_RR_DATA_IND, "RR_DATA_IND" },
- { GSM48_RR_UNIT_DATA_IND, "RR_UNIT_DATA_IND" },
- { GSM48_RR_ABORT_REQ, "RR_ABORT_REQ" },
- { GSM48_RR_ABORT_IND, "RR_ABORT_IND" },
- { GSM48_RR_ACT_REQ, "RR_ACT_REQ" },
- { 0, NULL }
-};
-
-const char *get_rr_name(int value)
-{
- return get_value_string(gsm48_rr_msg_names, value);
-}
-
-/* allocate GSM 04.08 layer 3 message */
-struct msgb *gsm48_l3_msgb_alloc(void)
-{
- struct msgb *msg;
-
- msg = msgb_alloc_headroom(L3_ALLOC_SIZE+L3_ALLOC_HEADROOM,
- L3_ALLOC_HEADROOM, "GSM 04.08 L3");
- if (!msg)
- return NULL;
- msg->l3h = msg->data;
-
- return msg;
-}
-
-/* allocate GSM 04.06 layer 2 RSL message */
-struct msgb *gsm48_rsl_msgb_alloc(void)
-{
- struct msgb *msg;
-
- msg = msgb_alloc_headroom(RSL_ALLOC_SIZE+RSL_ALLOC_HEADROOM,
- RSL_ALLOC_HEADROOM, "GSM 04.06 RSL");
- if (!msg)
- return NULL;
- msg->l2h = msg->data;
-
- return msg;
-}
-
-/* allocate GSM 04.08 message (RR-SAP) */
-struct msgb *gsm48_rr_msgb_alloc(int msg_type)
-{
- struct msgb *msg;
- struct gsm48_rr_hdr *rrh;
-
- msg = msgb_alloc_headroom(RR_ALLOC_SIZE+RR_ALLOC_HEADROOM,
- RR_ALLOC_HEADROOM, "GSM 04.08 RR");
- if (!msg)
- return NULL;
-
- rrh = (struct gsm48_rr_hdr *) msgb_put(msg, sizeof(*rrh));
- rrh->msg_type = msg_type;
-
- return msg;
-}
-
-/* queue message (RR-SAP) */
-int gsm48_rr_upmsg(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_mmlayer *mm = &ms->mmlayer;
-
- msgb_enqueue(&mm->rr_upqueue, msg);
-
- return 0;
-}
-
-/* push rsl header and send (RSL-SAP) */
-static int gsm48_send_rsl(struct osmocom_ms *ms, uint8_t msg_type,
- struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
-
- if (!msg->l3h) {
- LOGP(DRR, LOGL_ERROR, "FIX l3h\n");
- return -EINVAL;
- }
- rsl_rll_push_l3(msg, msg_type, rr->cd_now.chan_nr,
- rr->cd_now.link_id, 1);
-
- return lapdm_rslms_recvmsg(msg, &ms->lapdm_channel);
-}
-
-/* push rsl header + release mode and send (RSL-SAP) */
-static int gsm48_send_rsl_rel(struct osmocom_ms *ms, uint8_t msg_type,
- struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
-
- rsl_rll_push_hdr(msg, msg_type, rr->cd_now.chan_nr,
- rr->cd_now.link_id, 1);
-
- return lapdm_rslms_recvmsg(msg, &ms->lapdm_channel);
-}
-
-/* enqueue messages (RSL-SAP) */
-static int rcv_rsl(struct msgb *msg, struct lapdm_entity *le, void *l3ctx)
-{
- struct osmocom_ms *ms = l3ctx;
- struct gsm48_rrlayer *rr = &ms->rrlayer;
-
- msgb_enqueue(&rr->rsl_upqueue, msg);
-
- return 0;
-}
-
-/* dequeue messages (RSL-SAP) */
-int gsm48_rsl_dequeue(struct osmocom_ms *ms)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct msgb *msg;
- int work = 0;
-
- while ((msg = msgb_dequeue(&rr->rsl_upqueue))) {
- /* msg is freed there */
- gsm48_rcv_rsl(ms, msg);
- work = 1; /* work done */
- }
-
- return work;
-}
-
-int gsm48_rr_start_monitor(struct osmocom_ms *ms)
-{
- ms->rrlayer.monitor = 1;
-
- return 0;
-}
-
-int gsm48_rr_stop_monitor(struct osmocom_ms *ms)
-{
- ms->rrlayer.monitor = 0;
-
- return 0;
-}
-
-/*
- * timers handling
- */
-
-/* special timer to monitor measurements */
-static void timeout_rr_meas(void *arg)
-{
- struct gsm48_rrlayer *rr = arg;
- struct gsm322_cellsel *cs = &rr->ms->cellsel;
- struct rx_meas_stat *meas = &rr->ms->meas;
- struct gsm_settings *set = &rr->ms->settings;
- int rxlev, berr, snr;
- uint8_t ch_type, ch_subch, ch_ts;
- char text[256];
-
- /* don't monitor if no cell is selcted or if we scan neighbour cells */
- if (!cs->selected || cs->neighbour) {
- sprintf(text, "MON: not camping on serving cell");
- goto restart;
- } else if (!meas->frames) {
- sprintf(text, "MON: no cell info");
- } else {
- rxlev = (meas->rxlev + meas->frames / 2) / meas->frames;
- berr = (meas->berr + meas->frames / 2) / meas->frames;
- snr = (meas->snr + meas->frames / 2) / meas->frames;
- sprintf(text, "MON: f=%d lev=%s snr=%2d ber=%3d "
- "LAI=%s %s %04x ID=%04x", cs->sel_arfcn,
- gsm_print_rxlev(rxlev), berr, snr,
- gsm_print_mcc(cs->sel_mcc),
- gsm_print_mnc(cs->sel_mnc), cs->sel_lac, cs->sel_id);
- if (rr->state == GSM48_RR_ST_DEDICATED) {
- rsl_dec_chan_nr(rr->cd_now.chan_nr, &ch_type,
- &ch_subch, &ch_ts);
- sprintf(text + strlen(text), " TA=%d pwr=%d TS=%d",
- rr->cd_now.ind_ta - set->alter_delay,
- (set->alter_tx_power) ? set->alter_tx_power_value
- : rr->cd_now.ind_tx_power, ch_ts);
- if (ch_type == RSL_CHAN_SDCCH8_ACCH
- || ch_type == RSL_CHAN_SDCCH4_ACCH)
- sprintf(text + strlen(text), "/%d", ch_subch);
- } else
- gsm322_meas(rr->ms, rxlev);
- }
- LOGP(DRR, LOGL_INFO, "%s\n", text);
- if (rr->monitor)
- vty_notify(rr->ms, "%s\n", text);
-
- if (rr->dm_est)
- gsm48_rr_tx_meas_rep(rr->ms);
-
-restart:
- meas->frames = meas->snr = meas->berr = meas->rxlev = 0;
- start_rr_t_meas(rr, 1, 0);
-}
-
-/* special timer to assign / handover when starting time is reached */
-static void timeout_rr_t_starting(void *arg)
-{
- struct gsm48_rrlayer *rr = arg;
- struct msgb *nmsg;
-
- LOGP(DRR, LOGL_INFO, "starting timer has fired\n");
-
- /* open channel when starting timer of IMM.ASS has fired */
- if (rr->modify_state == GSM48_RR_MOD_IMM_ASS) {
- rr->modify_state = GSM48_RR_MOD_NONE;
- gsm48_rr_dl_est(rr->ms);
- return;
- }
-
- /* start suspension of current link */
- LOGP(DRR, LOGL_INFO, "request suspension of data link\n");
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return;
- gsm48_send_rsl(rr->ms, RSL_MT_SUSP_REQ, nmsg);
-}
-
-/* special timer to ensure that UA is sent before disconnecting channel */
-static void timeout_rr_t_rel_wait(void *arg)
-{
- struct gsm48_rrlayer *rr = arg;
-
- LOGP(DRR, LOGL_INFO, "L2 release timer has fired, done waiting\n");
-
- /* return to idle now */
- new_rr_state(rr, GSM48_RR_ST_IDLE);
-}
-
-/* 3.4.13.1.1: Timeout of T3110 */
-static void timeout_rr_t3110(void *arg)
-{
- struct gsm48_rrlayer *rr = arg;
- struct osmocom_ms *ms = rr->ms;
- struct msgb *nmsg;
- uint8_t *mode;
-
- LOGP(DRR, LOGL_INFO, "timer T3110 has fired, release locally\n");
-
- new_rr_state(rr, GSM48_RR_ST_REL_PEND);
-
- /* disconnect the main signalling link */
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return;
- mode = msgb_put(nmsg, 2);
- mode[0] = RSL_IE_RELEASE_MODE;
- mode[1] = 1; /* local release */
- gsm48_send_rsl_rel(ms, RSL_MT_REL_REQ, nmsg);
-
- return;
-}
-
-static void timeout_rr_t3122(void *arg)
-{
- LOGP(DRR, LOGL_INFO, "timer T3122 has fired\n");
-}
-
-static void timeout_rr_t3124(void *arg)
-{
- LOGP(DRR, LOGL_INFO, "timer T3124 has fired\n");
-}
-
-static void timeout_rr_t3126(void *arg)
-{
- struct gsm48_rrlayer *rr = arg;
- struct osmocom_ms *ms = rr->ms;
-
- LOGP(DRR, LOGL_INFO, "timer T3126 has fired\n");
- if (rr->rr_est_req) {
- struct msgb *msg = gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
- struct gsm48_rr_hdr *rrh;
-
- LOGP(DSUM, LOGL_INFO, "Requesting channel failed\n");
- if (!msg)
- return;
- rrh = (struct gsm48_rr_hdr *)msg->data;
- rrh->cause = RR_REL_CAUSE_RA_FAILURE;
- gsm48_rr_upmsg(ms, msg);
- }
-
- new_rr_state(rr, GSM48_RR_ST_IDLE);
-}
-
-static void start_rr_t_meas(struct gsm48_rrlayer *rr, int sec, int micro)
-{
- rr->t_meas.cb = timeout_rr_meas;
- rr->t_meas.data = rr;
- osmo_timer_schedule(&rr->t_meas, sec, micro);
-}
-
-static void start_rr_t_rel_wait(struct gsm48_rrlayer *rr, int sec, int micro)
-{
- LOGP(DRR, LOGL_INFO, "starting T_rel_wait with %d.%03d seconds\n", sec,
- micro / 1000);
- rr->t_rel_wait.cb = timeout_rr_t_rel_wait;
- rr->t_rel_wait.data = rr;
- osmo_timer_schedule(&rr->t_rel_wait, sec, micro);
-}
-
-static void start_rr_t_starting(struct gsm48_rrlayer *rr, int sec, int micro)
-{
- LOGP(DRR, LOGL_INFO, "starting T_starting with %d.%03d seconds\n", sec,
- micro / 1000);
- rr->t_starting.cb = timeout_rr_t_starting;
- rr->t_starting.data = rr;
- osmo_timer_schedule(&rr->t_starting, sec, micro);
-}
-
-static void start_rr_t3110(struct gsm48_rrlayer *rr, int sec, int micro)
-{
- LOGP(DRR, LOGL_INFO, "starting T3110 with %d.%03d seconds\n", sec,
- micro / 1000);
- rr->t3110.cb = timeout_rr_t3110;
- rr->t3110.data = rr;
- osmo_timer_schedule(&rr->t3110, sec, micro);
-}
-
-static void start_rr_t3122(struct gsm48_rrlayer *rr, int sec, int micro)
-{
- LOGP(DRR, LOGL_INFO, "starting T3122 with %d.%03d seconds\n", sec,
- micro / 1000);
- rr->t3122.cb = timeout_rr_t3122;
- rr->t3122.data = rr;
- osmo_timer_schedule(&rr->t3122, sec, micro);
-}
-
-static void start_rr_t3124(struct gsm48_rrlayer *rr, int sec, int micro)
-{
- LOGP(DRR, LOGL_INFO, "starting T3124 with %d.%03d seconds\n", sec,
- micro / 1000);
- rr->t3124.cb = timeout_rr_t3124;
- rr->t3124.data = rr;
- osmo_timer_schedule(&rr->t3124, sec, micro);
-}
-
-static void start_rr_t3126(struct gsm48_rrlayer *rr, int sec, int micro)
-{
- LOGP(DRR, LOGL_INFO, "starting T3126 with %d.%03d seconds\n", sec,
- micro / 1000);
- rr->t3126.cb = timeout_rr_t3126;
- rr->t3126.data = rr;
- osmo_timer_schedule(&rr->t3126, sec, micro);
-}
-
-static void stop_rr_t_meas(struct gsm48_rrlayer *rr)
-{
- if (osmo_timer_pending(&rr->t_meas)) {
- LOGP(DRR, LOGL_INFO, "stopping pending timer T_meas\n");
- osmo_timer_del(&rr->t_meas);
- }
-}
-
-static void stop_rr_t_starting(struct gsm48_rrlayer *rr)
-{
- if (osmo_timer_pending(&rr->t_starting)) {
- LOGP(DRR, LOGL_INFO, "stopping pending timer T_starting\n");
- osmo_timer_del(&rr->t_starting);
- }
-}
-
-static void stop_rr_t_rel_wait(struct gsm48_rrlayer *rr)
-{
- if (osmo_timer_pending(&rr->t_rel_wait)) {
- LOGP(DRR, LOGL_INFO, "stopping pending timer T_rel_wait\n");
- osmo_timer_del(&rr->t_rel_wait);
- }
-}
-
-static void stop_rr_t3110(struct gsm48_rrlayer *rr)
-{
- if (osmo_timer_pending(&rr->t3110)) {
- LOGP(DRR, LOGL_INFO, "stopping pending timer T3110\n");
- osmo_timer_del(&rr->t3110);
- }
-}
-
-static void stop_rr_t3122(struct gsm48_rrlayer *rr)
-{
- if (osmo_timer_pending(&rr->t3122)) {
- LOGP(DRR, LOGL_INFO, "stopping pending timer T3122\n");
- osmo_timer_del(&rr->t3122);
- }
-}
-
-static void stop_rr_t3124(struct gsm48_rrlayer *rr)
-{
- if (osmo_timer_pending(&rr->t3124)) {
- LOGP(DRR, LOGL_INFO, "stopping pending timer T3124\n");
- osmo_timer_del(&rr->t3124);
- }
-}
-
-static void stop_rr_t3126(struct gsm48_rrlayer *rr)
-{
- if (osmo_timer_pending(&rr->t3126)) {
- LOGP(DRR, LOGL_INFO, "stopping pending timer T3126\n");
- osmo_timer_del(&rr->t3126);
- }
-}
-
-/*
- * status
- */
-
-/* send rr status request */
-static int gsm48_rr_tx_rr_status(struct osmocom_ms *ms, uint8_t cause)
-{
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
- struct gsm48_rr_status *st;
-
- LOGP(DRR, LOGL_INFO, "RR STATUS (cause #%d)\n", cause);
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
- st = (struct gsm48_rr_status *) msgb_put(nmsg, sizeof(*st));
-
- gh->proto_discr = GSM48_PDISC_RR;
- gh->msg_type = GSM48_MT_RR_CIPH_M_COMPL;
-
- /* rr cause */
- st->rr_cause = cause;
-
- return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg);
-}
-
-/*
- * ciphering
- */
-
-/* send chiperhing mode complete */
-static int gsm48_rr_tx_cip_mode_cpl(struct osmocom_ms *ms, uint8_t cr)
-{
- struct gsm_settings *set = &ms->settings;
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
- struct gsm48_rr_hdr *nrrh;
- uint8_t buf[11], *tlv;
-
- LOGP(DRR, LOGL_INFO, "CIPHERING MODE COMPLETE (cr %d)\n", cr);
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
-
- gh->proto_discr = GSM48_PDISC_RR;
- gh->msg_type = GSM48_MT_RR_CIPH_M_COMPL;
-
- /* MI */
- if (cr) {
- gsm48_generate_mid_from_imsi(buf, set->imeisv);
- /* alter MI type */
- buf[2] = (buf[2] & ~GSM_MI_TYPE_MASK) | GSM_MI_TYPE_IMEISV;
- tlv = msgb_put(nmsg, 2 + buf[1]);
- memcpy(tlv, buf, 2 + buf[1]);
- }
-
- gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg);
-
- /* send RR_SYNC_IND(ciphering) */
- nmsg = gsm48_rr_msgb_alloc(GSM48_RR_SYNC_IND);
- if (!nmsg)
- return -ENOMEM;
- nrrh = (struct gsm48_rr_hdr *)nmsg->data;
- nrrh->cause = RR_SYNC_CAUSE_CIPHERING;
- return gsm48_rr_upmsg(ms, nmsg);
-}
-
-/* receive ciphering mode command */
-static int gsm48_rr_rx_cip_mode_cmd(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm_settings *set = &ms->settings;
- struct gsm48_hdr *gh = msgb_l3(msg);
- struct gsm48_cip_mode_cmd *cm = (struct gsm48_cip_mode_cmd *)gh->data;
- int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*cm);
- uint8_t sc, alg_id, cr;
-
- if (payload_len < 0) {
- LOGP(DRR, LOGL_NOTICE, "Short read of CIPHERING MODE COMMAND "
- "message.\n");
- return gsm48_rr_tx_rr_status(ms,
- GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
- }
-
- /* cipher mode setting */
- sc = cm->sc;
- alg_id = cm->alg_id;
- /* cipher mode response */
- cr = cm->cr;
-
- if (!sc)
- LOGP(DRR, LOGL_INFO, "CIPHERING MODE COMMAND (sc=%u, cr=%u)\n",
- sc, cr);
- else
- LOGP(DRR, LOGL_INFO, "CIPHERING MODE COMMAND (sc=%u, "
- "algo=A5/%d cr=%u)\n", sc, alg_id + 1, cr);
-
- /* 3.4.7.2 */
- if (rr->cipher_on && sc) {
- LOGP(DRR, LOGL_NOTICE, "chiphering already applied\n");
- return gsm48_rr_tx_rr_status(ms,
- GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
- }
-
- /* check if we actually support this cipher */
- if (sc && ((alg_id == GSM_CIPHER_A5_1 && !set->a5_1)
- || (alg_id == GSM_CIPHER_A5_2 && !set->a5_2)
- || (alg_id == GSM_CIPHER_A5_3 && !set->a5_3)
- || (alg_id == GSM_CIPHER_A5_4 && !set->a5_4)
- || (alg_id == GSM_CIPHER_A5_5 && !set->a5_5)
- || (alg_id == GSM_CIPHER_A5_6 && !set->a5_6)
- || (alg_id == GSM_CIPHER_A5_7 && !set->a5_7))) {
- LOGP(DRR, LOGL_NOTICE, "algo not supported\n");
- return gsm48_rr_tx_rr_status(ms,
- GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
- }
-
- /* check if we have no key */
- if (sc && subscr->key_seq == 7) {
- LOGP(DRR, LOGL_NOTICE, "no key available\n");
- return gsm48_rr_tx_rr_status(ms,
- GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
- }
-
- /* change to ciphering */
- rr->cipher_on = sc;
- rr->cipher_type = alg_id;
- if (rr->cipher_on)
- l1ctl_tx_crypto_req(ms, rr->cipher_type + 1, subscr->key, 8);
- else
- l1ctl_tx_crypto_req(ms, 0, NULL, 0);
-
- /* response (using the new mode) */
- return gsm48_rr_tx_cip_mode_cpl(ms, cr);
-}
-
-/*
- * classmark
- */
-
-/* Encode "Classmark 3" (10.5.1.7) */
-static int gsm48_rr_enc_cm3(struct osmocom_ms *ms, uint8_t *buf, uint8_t *len)
-{
- struct gsm_support *sup = &ms->support;
- struct gsm_settings *set = &ms->settings;
- struct bitvec bv;
-
- memset(&bv, 0, sizeof(bv));
- bv.data = buf;
- bv.data_len = 12;
-
- /* spare bit */
- bitvec_set_bit(&bv, 0);
- /* band 3 supported */
- if (set->dcs)
- bitvec_set_bit(&bv, ONE);
- else
- bitvec_set_bit(&bv, ZERO);
- /* band 2 supported */
- if (set->e_gsm || set->r_gsm)
- bitvec_set_bit(&bv, ONE);
- else
- bitvec_set_bit(&bv, ZERO);
- /* band 1 supported */
- if (set->p_gsm && !(set->e_gsm || set->r_gsm))
- bitvec_set_bit(&bv, ONE);
- else
- bitvec_set_bit(&bv, ZERO);
- /* a5 bits */
- if (set->a5_7)
- bitvec_set_bit(&bv, ONE);
- else
- bitvec_set_bit(&bv, ZERO);
- if (set->a5_6)
- bitvec_set_bit(&bv, ONE);
- else
- bitvec_set_bit(&bv, ZERO);
- if (set->a5_5)
- bitvec_set_bit(&bv, ONE);
- else
- bitvec_set_bit(&bv, ZERO);
- if (set->a5_4)
- bitvec_set_bit(&bv, ONE);
- else
- bitvec_set_bit(&bv, ZERO);
- /* radio capability */
- if (!set->dcs && !set->p_gsm && !(set->e_gsm || set->r_gsm)) {
- /* Fig. 10.5.7 / TS 24.0008: none of dcs, p, e, r */
- } else
- if (set->dcs && !set->p_gsm && !(set->e_gsm || set->r_gsm)) {
- /* dcs only */
- bitvec_set_uint(&bv, 0, 4);
- bitvec_set_uint(&bv, set->class_dcs, 4);
- } else
- if (set->dcs && (set->p_gsm || (set->e_gsm || set->r_gsm))) {
- /* dcs */
- bitvec_set_uint(&bv, set->class_dcs, 4);
- /* low band */
- bitvec_set_uint(&bv, set->class_900, 4);
- } else {
- /* low band only */
- bitvec_set_uint(&bv, 0, 4);
- bitvec_set_uint(&bv, set->class_900, 4);
- }
- /* r support */
- if (set->r_gsm) {
- bitvec_set_bit(&bv, ONE);
- bitvec_set_uint(&bv, set->class_900, 3);
- } else {
- bitvec_set_bit(&bv, ZERO);
- }
- /* multi slot support */
- if (sup->ms_sup) {
- bitvec_set_bit(&bv, ONE);
- bitvec_set_uint(&bv, sup->ms_sup, 5);
- } else {
- bitvec_set_bit(&bv, ZERO);
- }
- /* ucs2 treatment */
- if (sup->ucs2_treat) {
- bitvec_set_bit(&bv, ONE);
- } else {
- bitvec_set_bit(&bv, ZERO);
- }
- /* support extended measurements */
- if (sup->ext_meas) {
- bitvec_set_bit(&bv, ONE);
- } else {
- bitvec_set_bit(&bv, ZERO);
- }
- /* support measurement capability */
- if (sup->meas_cap) {
- bitvec_set_bit(&bv, ONE);
- bitvec_set_uint(&bv, sup->sms_val, 4);
- bitvec_set_uint(&bv, sup->sm_val, 4);
- } else {
- bitvec_set_bit(&bv, ZERO);
- }
- /* positioning method capability */
- if (sup->loc_serv) {
- bitvec_set_bit(&bv, ONE);
- bitvec_set_bit(&bv, sup->e_otd_ass == 1);
- bitvec_set_bit(&bv, sup->e_otd_based == 1);
- bitvec_set_bit(&bv, sup->gps_ass == 1);
- bitvec_set_bit(&bv, sup->gps_based == 1);
- bitvec_set_bit(&bv, sup->gps_conv == 1);
- } else {
- bitvec_set_bit(&bv, ZERO);
- }
- /* The following bits are described in TS 24.008 */
- /* EDGE multi slot support */
- if (set->edge_ms_sup) {
- bitvec_set_bit(&bv, ONE);
- bitvec_set_uint(&bv, set->edge_ms_sup, 5);
- } else {
- bitvec_set_bit(&bv, ZERO);
- }
- /* EDGE support */
- if (set->edge_psk_sup) {
- bitvec_set_bit(&bv, ONE);
- bitvec_set_bit(&bv, set->edge_psk_uplink == 1);
- if (set->p_gsm || (set->e_gsm || set->r_gsm)) {
- bitvec_set_bit(&bv, ONE);
- bitvec_set_uint(&bv, set->class_900_edge, 2);
- } else {
- bitvec_set_bit(&bv, ZERO);
- }
- if (set->dcs || set->pcs) {
- bitvec_set_bit(&bv, ONE);
- bitvec_set_uint(&bv, set->class_dcs_pcs_edge, 2);
- } else {
- bitvec_set_bit(&bv, ZERO);
- }
- } else {
- bitvec_set_bit(&bv, ZERO);
- }
- /* GSM 400 Bands */
- if (set->gsm_480 || set->gsm_450) {
- bitvec_set_bit(&bv, ONE);
- bitvec_set_bit(&bv, set->gsm_480 == 1);
- bitvec_set_bit(&bv, set->gsm_450 == 1);
- bitvec_set_uint(&bv, set->class_400, 4);
- } else {
- bitvec_set_bit(&bv, ZERO);
- }
- /* GSM 850 Band */
- if (set->gsm_850) {
- bitvec_set_bit(&bv, ONE);
- bitvec_set_uint(&bv, set->class_850, 4);
- } else {
- bitvec_set_bit(&bv, ZERO);
- }
- /* PCS Band */
- if (set->pcs) {
- bitvec_set_bit(&bv, ONE);
- bitvec_set_uint(&bv, set->class_pcs, 4);
- } else {
- bitvec_set_bit(&bv, ZERO);
- }
- /* RAT Capability */
- bitvec_set_bit(&bv, set->umts_fdd == 1);
- bitvec_set_bit(&bv, set->umts_tdd == 1);
- bitvec_set_bit(&bv, set->cdma_2000 == 1);
- /* DTM */
- if (set->dtm) {
- bitvec_set_bit(&bv, ONE);
- bitvec_set_uint(&bv, set->class_dtm, 2);
- bitvec_set_bit(&bv, set->dtm_mac == 1);
- bitvec_set_bit(&bv, set->dtm_egprs == 1);
- } else {
- bitvec_set_bit(&bv, ZERO);
- }
- /* info: The max number of bits are about 80. */
-
- /* partitial bytes will be completed */
- *len = (bv.cur_bit + 7) >> 3;
- bitvec_spare_padding(&bv, (*len * 8) - 1);
-
- return 0;
-}
-
-/* encode classmark 2 */
-int gsm48_rr_enc_cm2(struct osmocom_ms *ms, struct gsm48_classmark2 *cm,
- uint16_t arfcn)
-{
- struct gsm_support *sup = &ms->support;
- struct gsm_settings *set = &ms->settings;
-
- cm->pwr_lev = gsm48_current_pwr_lev(set, arfcn);
- cm->a5_1 = !set->a5_1;
- cm->es_ind = sup->es_ind;
- cm->rev_lev = sup->rev_lev;
- cm->fc = (set->r_gsm || set->e_gsm);
- cm->vgcs = sup->vgcs;
- cm->vbs = sup->vbs;
- cm->sm_cap = set->sms_ptp;
- cm->ss_scr = sup->ss_ind;
- cm->ps_cap = sup->ps_cap;
- cm->a5_2 = set->a5_2;
- cm->a5_3 = set->a5_3;
- cm->cmsp = sup->cmsp;
- cm->solsa = sup->solsa;
- cm->lcsva_cap = sup->lcsva;
-
- return 0;
-}
-
-/* send classmark change */
-static int gsm48_rr_tx_cm_change(struct osmocom_ms *ms)
-{
- struct gsm_support *sup = &ms->support;
- struct gsm_settings *set = &ms->settings;
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
- struct gsm48_cm_change *cc;
- uint8_t cm3[14], *tlv;
-
- LOGP(DRR, LOGL_INFO, "CLASSMARK CHANGE\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
- cc = (struct gsm48_cm_change *) msgb_put(nmsg, sizeof(*cc));
-
- gh->proto_discr = GSM48_PDISC_RR;
- gh->msg_type = GSM48_MT_RR_CLSM_CHG;
-
- /* classmark 2 */
- cc->cm2_len = sizeof(cc->cm2);
- gsm48_rr_enc_cm2(ms, &cc->cm2, rr->cd_now.arfcn);
-
- /* classmark 3 */
- if (set->dcs || set->pcs || set->e_gsm || set->r_gsm || set->gsm_850
- || set->a5_7 || set->a5_6 || set->a5_5 || set->a5_4
- || sup->ms_sup
- || sup->ucs2_treat
- || sup->ext_meas || sup->meas_cap
- || sup->loc_serv) {
- cc->cm2.cm3 = 1;
- cm3[0] = GSM48_IE_CLASSMARK3;
- gsm48_rr_enc_cm3(ms, cm3 + 2, &cm3[1]);
- tlv = msgb_put(nmsg, 2 + cm3[1]);
- memcpy(tlv, cm3, 2 + cm3[1]);
- }
-
- return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg);
-}
-
-/* receiving classmark enquiry */
-static int gsm48_rr_rx_cm_enq(struct osmocom_ms *ms, struct msgb *msg)
-{
- /* send classmark */
- return gsm48_rr_tx_cm_change(ms);
-}
-
-/*
- * random access
- */
-
-/* start random access */
-static int gsm48_rr_chan_req(struct osmocom_ms *ms, int cause, int paging)
-{
- struct gsm_settings *set = &ms->settings;
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = cs->si;
- struct msgb *nmsg;
- struct gsm48_rr_hdr *nrrh;
- uint8_t chan_req_val, chan_req_mask;
- int rc;
-
- LOGP(DSUM, LOGL_INFO, "Establish radio link due to %s request\n",
- (paging) ? "paging" : "mobility management");
-
- /* ignore paging, if not camping */
- if (paging
- && (!cs->selected || (cs->state != GSM322_C3_CAMPED_NORMALLY
- && cs->state != GSM322_C7_CAMPED_ANY_CELL))) {
- LOGP(DRR, LOGL_INFO, "Paging, but not camping, ignore.\n");
- return -EINVAL;
- }
-
- /* ignore channel request while not camping on a cell */
- if (!cs->selected) {
- LOGP(DRR, LOGL_INFO, "Channel request rejected, we did not "
- "properly select the serving cell.\n");
-
- goto rel_ind;
- }
-
- /* tell cell selection process to leave idle mode
- * NOTE: this must be sent unbuffered, because the state may not
- * change until idle mode is left
- */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_LEAVE_IDLE);
- if (!nmsg)
- return -ENOMEM;
- rc = gsm322_c_event(ms, nmsg);
- msgb_free(nmsg);
- if (rc) {
- if (paging)
- return rc;
- LOGP(DRR, LOGL_INFO, "Failed to leave IDLE mode.\n");
- goto undefined;
- }
-
- /* 3.3.1.1.2 */
- new_rr_state(rr, GSM48_RR_ST_CONN_PEND);
-
- /* set assignment state */
- rr->wait_assign = 0;
-
- /* number of retransmissions (with first transmission) */
- rr->n_chan_req = s->max_retrans + 1;
-
- /* generate CHAN REQ (9.1.8) */
- switch (cause) {
- case RR_EST_CAUSE_EMERGENCY:
- /* 101xxxxx */
- chan_req_mask = 0x1f;
- chan_req_val = 0xa0;
- LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (Emergency call)\n",
- chan_req_val);
- break;
- case RR_EST_CAUSE_REESTAB_TCH_F:
- chan_req_mask = 0x1f;
- chan_req_val = 0xc0;
- LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (re-establish "
- "TCH/F)\n", chan_req_val);
- break;
- case RR_EST_CAUSE_REESTAB_TCH_H:
- if (s->neci) {
- chan_req_mask = 0x03;
- chan_req_val = 0x68;
- LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x "
- "(re-establish TCH/H with NECI)\n",
- chan_req_val);
- } else {
- chan_req_mask = 0x1f;
- chan_req_val = 0xc0;
- LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x "
- "(re-establish TCH/H no NECI)\n", chan_req_val);
- }
- break;
- case RR_EST_CAUSE_REESTAB_2_TCH_H:
- if (s->neci) {
- chan_req_mask = 0x03;
- chan_req_val = 0x6c;
- LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x "
- "(re-establish TCH/H+TCH/H with NECI)\n",
- chan_req_val);
- } else {
- chan_req_mask = 0x1f;
- chan_req_val = 0xc0;
- LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x "
- "(re-establish TCH/H+TCH/H no NECI)\n",
- chan_req_val);
- }
- break;
- case RR_EST_CAUSE_ANS_PAG_ANY:
- chan_req_mask = 0x1f;
- chan_req_val = 0x80;
- LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (PAGING "
- "Any channel)\n", chan_req_val);
- break;
- case RR_EST_CAUSE_ANS_PAG_SDCCH:
- chan_req_mask = 0x0f;
- chan_req_val = 0x10;
- LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (PAGING SDCCH)\n",
- chan_req_val);
- break;
- case RR_EST_CAUSE_ANS_PAG_TCH_F:
- switch (set->ch_cap) {
- case GSM_CAP_SDCCH:
- chan_req_mask = 0x0f;
- chan_req_val = 0x10;
- break;
- case GSM_CAP_SDCCH_TCHF:
- chan_req_mask = 0x1f;
- chan_req_val = 0x80;
- break;
- default:
- chan_req_mask = 0x0f;
- chan_req_val = 0x20;
- break;
- }
- LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (PAGING TCH/F)\n",
- chan_req_val);
- break;
- case RR_EST_CAUSE_ANS_PAG_TCH_ANY:
- switch (set->ch_cap) {
- case GSM_CAP_SDCCH:
- chan_req_mask = 0x0f;
- chan_req_val = 0x10;
- break;
- case GSM_CAP_SDCCH_TCHF:
- chan_req_mask = 0x1f;
- chan_req_val = 0x80;
- break;
- default:
- chan_req_mask = 0x0f;
- chan_req_val = 0x30;
- break;
- }
- LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (PAGING TCH/H or "
- "TCH/F)\n", chan_req_val);
- break;
- case RR_EST_CAUSE_ORIG_TCHF:
- /* ms supports no dual rate */
- chan_req_mask = 0x1f;
- chan_req_val = 0xe0;
- LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (Orig TCH/F)\n",
- chan_req_val);
- break;
- case RR_EST_CAUSE_LOC_UPD:
- if (s->neci) {
- chan_req_mask = 0x0f;
- chan_req_val = 0x00;
- LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (Location "
- "Update with NECI)\n", chan_req_val);
- } else {
- chan_req_mask = 0x1f;
- chan_req_val = 0x00;
- LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (Location "
- "Update no NECI)\n", chan_req_val);
- }
- break;
- case RR_EST_CAUSE_OTHER_SDCCH:
- if (s->neci) {
- chan_req_mask = 0x0f;
- chan_req_val = 0x10;
- LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (OHTER "
- "with NECI)\n", chan_req_val);
- } else {
- chan_req_mask = 0x1f;
- chan_req_val = 0xe0;
- LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: %02x (OTHER "
- "no NECI)\n", chan_req_val);
- }
- break;
- default:
- if (!rr->rr_est_req) /* no request from MM */
- return -EINVAL;
-
- LOGP(DRR, LOGL_INFO, "CHANNEL REQUEST: with unknown "
- "establishment cause: %d\n", cause);
- undefined:
- LOGP(DSUM, LOGL_INFO, "Requesting channel failed\n");
-
-rel_ind:
- nmsg = gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
- if (!nmsg)
- return -ENOMEM;
- nrrh = (struct gsm48_rr_hdr *)nmsg->data;
- nrrh->cause = RR_REL_CAUSE_UNDEFINED;
- gsm48_rr_upmsg(ms, nmsg);
- new_rr_state(rr, GSM48_RR_ST_IDLE);
- return -EINVAL;
- }
-
- /* store value, mask and history */
- rr->chan_req_val = chan_req_val;
- rr->chan_req_mask = chan_req_mask;
- rr->cr_hist[2].valid = 0;
- rr->cr_hist[1].valid = 0;
- rr->cr_hist[0].valid = 0;
-
- /* store establishment cause, so 'choose cell' selects the last cell
- * after location updating */
- rr->est_cause = cause;
-
- /* if channel is already active somehow */
- if (cs->ccch_state == GSM322_CCCH_ST_DATA)
- return gsm48_rr_tx_rand_acc(ms, NULL);
-
- return 0;
-}
-
-/* send first/next channel request in conn pend state */
-int gsm48_rr_tx_rand_acc(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = &ms->cellsel.sel_si;
- struct gsm_settings *set = &ms->settings;
- struct msgb *nmsg;
- struct abis_rsl_cchan_hdr *ncch;
- int slots;
- uint8_t chan_req;
- uint8_t tx_power;
-
- /* already assigned */
- if (rr->wait_assign == 2)
- return 0;
-
- /* store frame number */
- if (msg) {
- struct abis_rsl_cchan_hdr *ch = msgb_l2(msg);
- struct gsm48_req_ref *ref =
- (struct gsm48_req_ref *) (ch->data + 1);
-
- if (msgb_l2len(msg) < sizeof(*ch) + sizeof(*ref)) {
- LOGP(DRR, LOGL_ERROR, "CHAN_CNF too slort\n");
- return -EINVAL;
- }
-
- /* shift history and store */
- memcpy(&(rr->cr_hist[2]), &(rr->cr_hist[1]),
- sizeof(struct gsm48_cr_hist));
- memcpy(&(rr->cr_hist[1]), &(rr->cr_hist[0]),
- sizeof(struct gsm48_cr_hist));
- rr->cr_hist[0].valid = 1;
- rr->cr_hist[0].ref.ra = rr->cr_ra;
- rr->cr_hist[0].ref.t1 = ref->t1;
- rr->cr_hist[0].ref.t2 = ref->t2;
- rr->cr_hist[0].ref.t3_low = ref->t3_low;
- rr->cr_hist[0].ref.t3_high = ref->t3_high;
- }
-
- if (cs->ccch_state != GSM322_CCCH_ST_DATA) {
- LOGP(DRR, LOGL_INFO, "CCCH channel activation failed.\n");
-fail:
- if (rr->rr_est_req) {
- struct msgb *msg =
- gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
- struct gsm48_rr_hdr *rrh;
-
- LOGP(DSUM, LOGL_INFO, "Requesting channel failed\n");
- if (!msg)
- return -ENOMEM;
- rrh = (struct gsm48_rr_hdr *)msg->data;
- rrh->cause = RR_REL_CAUSE_RA_FAILURE;
- gsm48_rr_upmsg(ms, msg);
- }
-
- new_rr_state(rr, GSM48_RR_ST_IDLE);
-
- return 0;
- }
-
- if (!s || !s->si3 || !s->tx_integer) {
- LOGP(DRR, LOGL_NOTICE, "Not enough SYSINFO\n");
- goto fail;
- }
-
- if (rr->state == GSM48_RR_ST_IDLE) {
- LOGP(DRR, LOGL_INFO, "MM already released RR.\n");
-
- return 0;
- }
-
- LOGP(DRR, LOGL_INFO, "RANDOM ACCESS (requests left %d)\n",
- rr->n_chan_req);
-
- if (!rr->n_chan_req) {
- LOGP(DRR, LOGL_INFO, "Done with sending RANDOM ACCESS "
- "bursts\n");
- if (!osmo_timer_pending(&rr->t3126))
- start_rr_t3126(rr, 5, 0); /* TODO improve! */
- return 0;
- }
- rr->n_chan_req--;
-
- if (rr->wait_assign == 0) {
- /* first random acces, without delay of slots */
- slots = 0;
- rr->wait_assign = 1;
- } else {
- /* subsequent random acces, with slots from table 3.1 */
- switch(s->tx_integer) {
- case 3: case 8: case 14: case 50:
- if (s->ccch_conf != 1) /* not combined CCCH */
- slots = 55;
- else
- slots = 41;
- break;
- case 4: case 9: case 16:
- if (s->ccch_conf != 1)
- slots = 76;
- else
- slots = 52;
- break;
- case 5: case 10: case 20:
- if (s->ccch_conf != 1)
- slots = 109;
- else
- slots = 58;
- break;
- case 6: case 11: case 25:
- if (s->ccch_conf != 1)
- slots = 163;
- else
- slots = 86;
- break;
- default:
- if (s->ccch_conf != 1)
- slots = 217;
- else
- slots = 115;
- break;
- }
- }
-
- chan_req = random();
- chan_req &= rr->chan_req_mask;
- chan_req |= rr->chan_req_val;
-
- LOGP(DRR, LOGL_INFO, "RANDOM ACCESS (Tx-integer %d combined %s "
- "S(lots) %d ra 0x%02x)\n", s->tx_integer,
- (s->ccch_conf == 1) ? "yes": "no", slots, chan_req);
-
- slots = (random() % s->tx_integer) + slots;
-
- /* (re)send CHANNEL RQD with new randiom */
- nmsg = gsm48_rsl_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- ncch = (struct abis_rsl_cchan_hdr *) msgb_put(nmsg, sizeof(*ncch)
- + 4 + 2 + 2);
- rsl_init_cchan_hdr(ncch, RSL_MT_CHAN_RQD);
- ncch->chan_nr = RSL_CHAN_RACH;
- ncch->data[0] = RSL_IE_REQ_REFERENCE;
- ncch->data[1] = chan_req;
- ncch->data[2] = (slots >> 8) | ((s->ccch_conf == 1) << 7);
- ncch->data[3] = slots;
- ncch->data[4] = RSL_IE_ACCESS_DELAY;
- ncch->data[5] = set->alter_delay; /* (-)=earlier (+)=later */
- ncch->data[6] = RSL_IE_MS_POWER;
- if (set->alter_tx_power) {
- tx_power = set->alter_tx_power_value;
- LOGP(DRR, LOGL_INFO, "Use alternative tx-power %d (%d dBm)\n",
- tx_power,
- ms_pwr_dbm(gsm_arfcn2band(cs->arfcn), tx_power));
- } else {
- tx_power = s->ms_txpwr_max_cch;
- /* power offset in case of DCS1800 */
- if (s->po && (cs->arfcn & 1023) >= 512
- && (cs->arfcn & 1023) <= 885) {
- LOGP(DRR, LOGL_INFO, "Use MS-TXPWR-MAX-CCH power value "
- "%d (%d dBm) with offset %d dBm\n", tx_power,
- ms_pwr_dbm(gsm_arfcn2band(cs->arfcn), tx_power),
- s->po_value * 2);
- /* use reserved bits 7,8 for offset (+ X * 2dB) */
- tx_power |= s->po_value << 6;
- } else
- LOGP(DRR, LOGL_INFO, "Use MS-TXPWR-MAX-CCH power value "
- "%d (%d dBm)\n", tx_power,
- ms_pwr_dbm(gsm_arfcn2band(cs->arfcn),
- tx_power));
- }
- ncch->data[7] = tx_power;
-
- /* set initial indications */
- rr->cd_now.ind_tx_power = s->ms_txpwr_max_cch;
- rr->cd_now.ind_ta = set->alter_delay;
-
- /* store ra until confirmed, then copy it with time into cr_hist */
- rr->cr_ra = chan_req;
-
- return lapdm_rslms_recvmsg(nmsg, &ms->lapdm_channel);
-}
-
-/*
- * system information
- */
-
-/* send sysinfo event to other layers */
-static int gsm48_new_sysinfo(struct osmocom_ms *ms, uint8_t type)
-{
- struct gsm48_sysinfo *s = ms->cellsel.si;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct msgb *nmsg;
- struct gsm322_msg *em;
-
- /* update list of measurements, if BA(SACCH) is complete and new */
- if (s
- && (type == GSM48_MT_RR_SYSINFO_5
- || type == GSM48_MT_RR_SYSINFO_5bis
- || type == GSM48_MT_RR_SYSINFO_5ter)
- && s->si5
- && (!s->nb_ext_ind_si5 || s->si5bis)) {
- struct gsm48_rr_meas *rrmeas = &ms->rrlayer.meas;
- int n = 0, i, refer_pcs;
-
- LOGP(DRR, LOGL_NOTICE, "Complete set of SI5* for BA(%d)\n",
- s->nb_ba_ind_si5);
- rrmeas->nc_num = 0;
- refer_pcs = gsm_refer_pcs(cs->arfcn, s);
-
- /* collect channels from freq list (1..1023,0) */
- for (i = 1; i <= 1024; i++) {
- if ((s->freq[i & 1023].mask & FREQ_TYPE_REP)) {
- if (n == 32) {
- LOGP(DRR, LOGL_NOTICE, "SI5* report "
- "exceeds 32 BCCHs\n");
- break;
- }
- if (refer_pcs && i >= 512 && i <= 810)
- rrmeas->nc_arfcn[n] = i | ARFCN_PCS;
- else
- rrmeas->nc_arfcn[n] = i & 1023;
- rrmeas->nc_rxlev[n] = -128;
- LOGP(DRR, LOGL_NOTICE, "SI5* report arfcn %s\n",
- gsm_print_arfcn(rrmeas->nc_arfcn[n]));
- n++;
- }
- }
- rrmeas->nc_num = n;
- }
-
- /* send sysinfo event to other layers */
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_SYSINFO);
- if (!nmsg)
- return -ENOMEM;
- em = (struct gsm322_msg *) nmsg->data;
- em->sysinfo = type;
- gsm322_cs_sendmsg(ms, nmsg);
-
- /* if not camping, we don't care about SI */
- if (ms->cellsel.neighbour
- || (ms->cellsel.state != GSM322_C3_CAMPED_NORMALLY
- && ms->cellsel.state != GSM322_C7_CAMPED_ANY_CELL))
- return 0;
-
- /* send timer info to location update process */
- nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_SYSINFO);
- if (!nmsg)
- return -ENOMEM;
- gsm48_mmevent_msg(ms, nmsg);
-
- return 0;
-}
-
-/* receive "SYSTEM INFORMATION 1" message (9.1.31) */
-static int gsm48_rr_rx_sysinfo1(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_system_information_type_1 *si = msgb_l3(msg);
- struct gsm48_sysinfo *s = ms->cellsel.si;
- int payload_len = msgb_l3len(msg) - sizeof(*si);
-
- if (!s) {
- LOGP(DRR, LOGL_INFO, "No cell selected, SYSTEM INFORMATION 1 "
- "ignored\n");
- return -EINVAL;
- }
-
- if (payload_len < 0) {
- LOGP(DRR, LOGL_NOTICE, "Short read of SYSTEM INFORMATION 1 "
- "message.\n");
- return -EINVAL;
- }
-
- if (!memcmp(si, s->si1_msg, MIN(msgb_l3len(msg), sizeof(s->si1_msg))))
- return 0;
-
- gsm48_decode_sysinfo1(s, si, msgb_l3len(msg));
-
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 1\n");
-
- return gsm48_new_sysinfo(ms, si->header.system_information);
-}
-
-/* receive "SYSTEM INFORMATION 2" message (9.1.32) */
-static int gsm48_rr_rx_sysinfo2(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_system_information_type_2 *si = msgb_l3(msg);
- struct gsm48_sysinfo *s = ms->cellsel.si;
- int payload_len = msgb_l3len(msg) - sizeof(*si);
-
- if (!s) {
- LOGP(DRR, LOGL_INFO, "No cell selected, SYSTEM INFORMATION 2 "
- "ignored\n");
- return -EINVAL;
- }
-
- if (payload_len < 0) {
- LOGP(DRR, LOGL_NOTICE, "Short read of SYSTEM INFORMATION 2 "
- "message.\n");
- return -EINVAL;
- }
-
- if (!memcmp(si, s->si2_msg, MIN(msgb_l3len(msg), sizeof(s->si2_msg))))
- return 0;
-
- gsm48_decode_sysinfo2(s, si, msgb_l3len(msg));
-
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2\n");
-
- return gsm48_new_sysinfo(ms, si->header.system_information);
-}
-
-/* receive "SYSTEM INFORMATION 2bis" message (9.1.33) */
-static int gsm48_rr_rx_sysinfo2bis(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_system_information_type_2bis *si = msgb_l3(msg);
- struct gsm48_sysinfo *s = ms->cellsel.si;
- int payload_len = msgb_l3len(msg) - sizeof(*si);
-
- if (!s) {
- LOGP(DRR, LOGL_INFO, "No cell selected, SYSTEM INFORMATION 2bis"
- " ignored\n");
- return -EINVAL;
- }
-
- if (payload_len < 0) {
- LOGP(DRR, LOGL_NOTICE, "Short read of SYSTEM INFORMATION 2bis "
- "message.\n");
- return -EINVAL;
- }
-
- if (!memcmp(si, s->si2b_msg, MIN(msgb_l3len(msg), sizeof(s->si2b_msg))))
- return 0;
-
- gsm48_decode_sysinfo2bis(s, si, msgb_l3len(msg));
-
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2bis\n");
-
- return gsm48_new_sysinfo(ms, si->header.system_information);
-}
-
-/* receive "SYSTEM INFORMATION 2ter" message (9.1.34) */
-static int gsm48_rr_rx_sysinfo2ter(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_system_information_type_2ter *si = msgb_l3(msg);
- struct gsm48_sysinfo *s = ms->cellsel.si;
- int payload_len = msgb_l3len(msg) - sizeof(*si);
-
- if (!s) {
- LOGP(DRR, LOGL_INFO, "No cell selected, SYSTEM INFORMATION 2ter"
- " ignored\n");
- return -EINVAL;
- }
-
- if (payload_len < 0) {
- LOGP(DRR, LOGL_NOTICE, "Short read of SYSTEM INFORMATION 2ter "
- "message.\n");
- return -EINVAL;
- }
-
- if (!memcmp(si, s->si2t_msg, MIN(msgb_l3len(msg), sizeof(s->si2t_msg))))
- return 0;
-
- gsm48_decode_sysinfo2ter(s, si, msgb_l3len(msg));
-
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 2ter\n");
-
- return gsm48_new_sysinfo(ms, si->header.system_information);
-}
-
-/* receive "SYSTEM INFORMATION 3" message (9.1.35) */
-static int gsm48_rr_rx_sysinfo3(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_system_information_type_3 *si = msgb_l3(msg);
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = cs->si;
- int payload_len = msgb_l3len(msg) - sizeof(*si);
-
- if (!s) {
- LOGP(DRR, LOGL_INFO, "No cell selected, SYSTEM INFORMATION 3 "
- "ignored\n");
- return -EINVAL;
- }
-
- if (payload_len < 0) {
- LOGP(DRR, LOGL_NOTICE, "Short read of SYSTEM INFORMATION 3 "
- "message.\n");
- return -EINVAL;
- }
-
- if (!memcmp(si, s->si3_msg, MIN(msgb_l3len(msg), sizeof(s->si3_msg))))
- return 0;
-
- gsm48_decode_sysinfo3(s, si, msgb_l3len(msg));
-
- if (cs->ccch_mode == CCCH_MODE_NONE) {
- cs->ccch_mode = (s->ccch_conf == 1) ? CCCH_MODE_COMBINED :
- CCCH_MODE_NON_COMBINED;
- LOGP(DRR, LOGL_NOTICE, "Changing CCCH_MODE to %d\n",
- cs->ccch_mode);
- l1ctl_tx_ccch_mode_req(ms, cs->ccch_mode);
- }
-
- return gsm48_new_sysinfo(ms, si->header.system_information);
-}
-
-/* receive "SYSTEM INFORMATION 4" message (9.1.36) */
-static int gsm48_rr_rx_sysinfo4(struct osmocom_ms *ms, struct msgb *msg)
-{
- /* NOTE: pseudo length is not in this structure, so we skip */
- struct gsm48_system_information_type_4 *si = msgb_l3(msg);
- struct gsm48_sysinfo *s = ms->cellsel.si;
- int payload_len = msgb_l3len(msg) - sizeof(*si);
-
- if (!s) {
- LOGP(DRR, LOGL_INFO, "No cell selected, SYSTEM INFORMATION 4 "
- "ignored\n");
- return -EINVAL;
- }
-
- if (payload_len < 0) {
- LOGP(DRR, LOGL_NOTICE, "Short read of SYSTEM INFORMATION 4 "
- "message.\n");
- return -EINVAL;
- }
-
- if (!memcmp(si, s->si4_msg, MIN(msgb_l3len(msg), sizeof(s->si4_msg))))
- return 0;
-
- gsm48_decode_sysinfo4(s, si, msgb_l3len(msg));
-
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 4 (mcc %s mnc %s "
- "lac 0x%04x)\n", gsm_print_mcc(s->mcc),
- gsm_print_mnc(s->mnc), s->lac);
-
- return gsm48_new_sysinfo(ms, si->header.system_information);
-}
-
-/* receive "SYSTEM INFORMATION 5" message (9.1.37) */
-static int gsm48_rr_rx_sysinfo5(struct osmocom_ms *ms, struct msgb *msg)
-{
- /* NOTE: pseudo length is not in this structure, so we skip */
- struct gsm48_system_information_type_5 *si = msgb_l3(msg) + 1;
- struct gsm48_sysinfo *s = ms->cellsel.si;
- int payload_len = msgb_l3len(msg) - sizeof(*si) - 1;
-
- if (!s) {
- LOGP(DRR, LOGL_INFO, "No cell selected, SYSTEM INFORMATION 5 "
- "ignored\n");
- return -EINVAL;
- }
-
- if (payload_len < 0) {
- LOGP(DRR, LOGL_NOTICE, "Short read of SYSTEM INFORMATION 5 "
- "message.\n");
- return -EINVAL;
- }
-
- if (!memcmp(si, s->si5_msg, MIN(msgb_l3len(msg), sizeof(s->si5_msg))))
- return 0;
-
- gsm48_decode_sysinfo5(s, si, msgb_l3len(msg));
-
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 5\n");
-
- return gsm48_new_sysinfo(ms, si->system_information);
-}
-
-/* receive "SYSTEM INFORMATION 5bis" message (9.1.38) */
-static int gsm48_rr_rx_sysinfo5bis(struct osmocom_ms *ms, struct msgb *msg)
-{
- /* NOTE: pseudo length is not in this structure, so we skip */
- struct gsm48_system_information_type_5bis *si = msgb_l3(msg) + 1;
- struct gsm48_sysinfo *s = ms->cellsel.si;
- int payload_len = msgb_l3len(msg) - sizeof(*si) - 1;
-
- if (!s) {
- LOGP(DRR, LOGL_INFO, "No cell selected, SYSTEM INFORMATION 5bis"
- " ignored\n");
- return -EINVAL;
- }
-
- if (payload_len < 0) {
- LOGP(DRR, LOGL_NOTICE, "Short read of SYSTEM INFORMATION 5bis "
- "message.\n");
- return -EINVAL;
- }
-
- if (!memcmp(si, s->si5b_msg, MIN(msgb_l3len(msg),
- sizeof(s->si5b_msg))))
- return 0;
-
- gsm48_decode_sysinfo5bis(s, si, msgb_l3len(msg));
-
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 5bis\n");
-
- return gsm48_new_sysinfo(ms, si->system_information);
-}
-
-/* receive "SYSTEM INFORMATION 5ter" message (9.1.39) */
-static int gsm48_rr_rx_sysinfo5ter(struct osmocom_ms *ms, struct msgb *msg)
-{
- /* NOTE: pseudo length is not in this structure, so we skip */
- struct gsm48_system_information_type_5ter *si = msgb_l3(msg) + 1;
- struct gsm48_sysinfo *s = ms->cellsel.si;
- int payload_len = msgb_l3len(msg) - sizeof(*si) - 1;
-
- if (!s) {
- LOGP(DRR, LOGL_INFO, "No cell selected, SYSTEM INFORMATION 5ter"
- " ignored\n");
- return -EINVAL;
- }
-
- if (payload_len < 0) {
- LOGP(DRR, LOGL_NOTICE, "Short read of SYSTEM INFORMATION 5ter "
- "message.\n");
- return -EINVAL;
- }
-
- if (!memcmp(si, s->si5t_msg, MIN(msgb_l3len(msg),
- sizeof(s->si5t_msg))))
- return 0;
-
- gsm48_decode_sysinfo5ter(s, si, msgb_l3len(msg));
-
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 5ter\n");
-
- return gsm48_new_sysinfo(ms, si->system_information);
-}
-
-/* receive "SYSTEM INFORMATION 6" message (9.1.39) */
-static int gsm48_rr_rx_sysinfo6(struct osmocom_ms *ms, struct msgb *msg)
-{
- /* NOTE: pseudo length is not in this structure, so we skip */
- struct gsm48_system_information_type_6 *si = msgb_l3(msg) + 1;
- struct gsm48_sysinfo *s = ms->cellsel.si;
- struct rx_meas_stat *meas = &ms->meas;
- int payload_len = msgb_l3len(msg) - sizeof(*si) - 1;
-
- if (!s) {
- LOGP(DRR, LOGL_INFO, "No cell selected, SYSTEM INFORMATION 6 "
- "ignored\n");
- return -EINVAL;
- }
-
- if (payload_len < 0) {
- LOGP(DRR, LOGL_NOTICE, "Short read of SYSTEM INFORMATION 6 "
- "message.\n");
- return -EINVAL;
- }
-
- if (!memcmp(si, s->si6_msg, MIN(msgb_l3len(msg), sizeof(s->si6_msg))))
- return 0;
-
- gsm48_decode_sysinfo6(s, si, msgb_l3len(msg));
-
- LOGP(DRR, LOGL_INFO, "New SYSTEM INFORMATION 6 (mcc %s mnc %s "
- "lac 0x%04x SACCH-timeout %d)\n", gsm_print_mcc(s->mcc),
- gsm_print_mnc(s->mnc), s->lac, s->sacch_radio_link_timeout);
-
- meas->rl_fail = meas->s = s->sacch_radio_link_timeout;
- LOGP(DRR, LOGL_INFO, "using (new) SACCH timeout %d\n", meas->rl_fail);
-
- return gsm48_new_sysinfo(ms, si->system_information);
-}
-
-/*
- * paging
- */
-
-/* paging channel request */
-static int gsm48_rr_chan2cause[4] = {
- RR_EST_CAUSE_ANS_PAG_ANY,
- RR_EST_CAUSE_ANS_PAG_SDCCH,
- RR_EST_CAUSE_ANS_PAG_TCH_F,
- RR_EST_CAUSE_ANS_PAG_TCH_ANY
-};
-
-/* given LV of mobile identity is checked agains ms */
-static int gsm_match_mi(struct osmocom_ms *ms, uint8_t *mi)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- char imsi[16];
- uint32_t tmsi;
- uint8_t mi_type;
-
- if (mi[0] < 1)
- return 0;
- mi_type = mi[1] & GSM_MI_TYPE_MASK;
- switch (mi_type) {
- case GSM_MI_TYPE_TMSI:
- if (mi[0] < 5)
- return 0;
- memcpy(&tmsi, mi+2, 4);
- if (ms->subscr.tmsi == ntohl(tmsi)
- && ms->subscr.mcc == cs->sel_mcc
- && ms->subscr.mnc == cs->sel_mnc
- && ms->subscr.lac == cs->sel_lac) {
- LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n",
- ntohl(tmsi));
-
- return 1;
- } else
- LOGP(DPAG, LOGL_INFO, " TMSI %08x (not for us)\n",
- ntohl(tmsi));
- break;
- case GSM_MI_TYPE_IMSI:
- gsm48_mi_to_string(imsi, sizeof(imsi), mi + 1, mi[0]);
- if (!strcmp(imsi, ms->subscr.imsi)) {
- LOGP(DPAG, LOGL_INFO, " IMSI %s matches\n", imsi);
-
- return 1;
- } else
- LOGP(DPAG, LOGL_INFO, " IMSI %s (not for us)\n", imsi);
- break;
- default:
- LOGP(DPAG, LOGL_NOTICE, "Paging with unsupported MI type %d.\n",
- mi_type);
- }
-
- return 0;
-}
-
-/* 9.1.22 PAGING REQUEST 1 message received */
-static int gsm48_rr_rx_pag_req_1(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_paging1 *pa = msgb_l3(msg);
- int payload_len = msgb_l3len(msg) - sizeof(*pa);
- int chan_1, chan_2;
- uint8_t *mi;
-
- /* empty paging request */
- if (payload_len >= 2 && (pa->data[1] & GSM_MI_TYPE_MASK) == 0)
- return 0;
-
- /* 3.3.1.1.2: ignore paging while not camping on a cell */
- if (rr->state != GSM48_RR_ST_IDLE || !cs->selected
- || (cs->state != GSM322_C3_CAMPED_NORMALLY
- && cs->state != GSM322_C7_CAMPED_ANY_CELL)
- || cs->neighbour) {
- LOGP(DRR, LOGL_INFO, "PAGING ignored, we are not camping.\n");
-
- return 0;
- }
- LOGP(DPAG, LOGL_INFO, "PAGING REQUEST 1\n");
-
- if (payload_len < 2) {
- short_read:
- LOGP(DRR, LOGL_NOTICE, "Short read of PAGING REQUEST 1 "
- "message.\n");
-
- return -EINVAL;
- }
-
- /* channel needed */
- chan_1 = pa->cneed1;
- chan_2 = pa->cneed2;
- /* first MI */
- mi = pa->data;
- if (payload_len < mi[0] + 1)
- goto short_read;
- if (gsm_match_mi(ms, mi) > 0)
- return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_1], 1);
- /* second MI */
- payload_len -= mi[0] + 1;
- mi = pa->data + mi[0] + 1;
- if (payload_len < 2)
- return 0;
- if (mi[0] != GSM48_IE_MOBILE_ID)
- return 0;
- if (payload_len < mi[1] + 2)
- goto short_read;
- if (gsm_match_mi(ms, mi + 1) > 0)
- return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_2], 1);
-
- return 0;
-}
-
-/* 9.1.23 PAGING REQUEST 2 message received */
-static int gsm48_rr_rx_pag_req_2(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_paging2 *pa = msgb_l3(msg);
- int payload_len = msgb_l3len(msg) - sizeof(*pa);
- uint8_t *mi;
- int chan_1, chan_2, chan_3;
-
- /* 3.3.1.1.2: ignore paging while not camping on a cell */
- if (rr->state != GSM48_RR_ST_IDLE || !cs->selected
- || (cs->state != GSM322_C3_CAMPED_NORMALLY
- && cs->state != GSM322_C7_CAMPED_ANY_CELL)
- || cs->neighbour) {
- LOGP(DRR, LOGL_INFO, "PAGING ignored, we are not camping.\n");
-
- return 0;
- }
- LOGP(DPAG, LOGL_INFO, "PAGING REQUEST 2\n");
-
- if (payload_len < 0) {
- short_read:
- LOGP(DRR, LOGL_NOTICE, "Short read of PAGING REQUEST 2 "
- "message .\n");
-
- return -EINVAL;
- }
-
- /* channel needed */
- chan_1 = pa->cneed1;
- chan_2 = pa->cneed2;
- /* first MI */
- if (ms->subscr.tmsi == ntohl(pa->tmsi1)
- && ms->subscr.mcc == cs->sel_mcc
- && ms->subscr.mnc == cs->sel_mnc
- && ms->subscr.lac == cs->sel_lac) {
- LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi1));
- return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_1], 1);
- } else
- LOGP(DPAG, LOGL_INFO, " TMSI %08x (not for us)\n",
- ntohl(pa->tmsi1));
- /* second MI */
- if (ms->subscr.tmsi == ntohl(pa->tmsi2)
- && ms->subscr.mcc == cs->sel_mcc
- && ms->subscr.mnc == cs->sel_mnc
- && ms->subscr.lac == cs->sel_lac) {
- LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi2));
- return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_2], 1);
- } else
- LOGP(DPAG, LOGL_INFO, " TMSI %08x (not for us)\n",
- ntohl(pa->tmsi2));
- /* third MI */
- mi = pa->data;
- if (payload_len < 2)
- return 0;
- if (mi[0] != GSM48_IE_MOBILE_ID)
- return 0;
- if (payload_len < mi[1] + 2 + 1) /* must include "channel needed" */
- goto short_read;
- chan_3 = mi[mi[1] + 2] & 0x03; /* channel needed */
- if (gsm_match_mi(ms, mi + 1) > 0)
- return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_3], 1);
-
- return 0;
-}
-
-/* 9.1.24 PAGING REQUEST 3 message received */
-static int gsm48_rr_rx_pag_req_3(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_paging3 *pa = msgb_l3(msg);
- int payload_len = msgb_l3len(msg) - sizeof(*pa);
- int chan_1, chan_2, chan_3, chan_4;
-
- /* 3.3.1.1.2: ignore paging while not camping on a cell */
- if (rr->state != GSM48_RR_ST_IDLE || !cs->selected
- || (cs->state != GSM322_C3_CAMPED_NORMALLY
- && cs->state != GSM322_C7_CAMPED_ANY_CELL)
- || cs->neighbour) {
- LOGP(DRR, LOGL_INFO, "PAGING ignored, we are not camping.\n");
-
- return 0;
- }
- LOGP(DPAG, LOGL_INFO, "PAGING REQUEST 3\n");
-
- if (payload_len < 0) { /* must include "channel needed", part of *pa */
- LOGP(DRR, LOGL_NOTICE, "Short read of PAGING REQUEST 3 "
- "message .\n");
-
- return -EINVAL;
- }
-
- /* channel needed */
- chan_1 = pa->cneed1;
- chan_2 = pa->cneed2;
- chan_3 = pa->cneed3;
- chan_4 = pa->cneed4;
- /* first MI */
- if (ms->subscr.tmsi == ntohl(pa->tmsi1)
- && ms->subscr.mcc == cs->sel_mcc
- && ms->subscr.mnc == cs->sel_mnc
- && ms->subscr.lac == cs->sel_lac) {
- LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi1));
- return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_1], 1);
- } else
- LOGP(DPAG, LOGL_INFO, " TMSI %08x (not for us)\n",
- ntohl(pa->tmsi1));
- /* second MI */
- if (ms->subscr.tmsi == ntohl(pa->tmsi2)
- && ms->subscr.mcc == cs->sel_mcc
- && ms->subscr.mnc == cs->sel_mnc
- && ms->subscr.lac == cs->sel_lac) {
- LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi2));
- return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_2], 1);
- } else
- LOGP(DPAG, LOGL_INFO, " TMSI %08x (not for us)\n",
- ntohl(pa->tmsi2));
- /* thrid MI */
- if (ms->subscr.tmsi == ntohl(pa->tmsi3)
- && ms->subscr.mcc == cs->sel_mcc
- && ms->subscr.mnc == cs->sel_mnc
- && ms->subscr.lac == cs->sel_lac) {
- LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi3));
- return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_3], 1);
- } else
- LOGP(DPAG, LOGL_INFO, " TMSI %08x (not for us)\n",
- ntohl(pa->tmsi3));
- /* fourth MI */
- if (ms->subscr.tmsi == ntohl(pa->tmsi4)
- && ms->subscr.mcc == cs->sel_mcc
- && ms->subscr.mnc == cs->sel_mnc
- && ms->subscr.lac == cs->sel_lac) {
- LOGP(DPAG, LOGL_INFO, " TMSI %08x matches\n", ntohl(pa->tmsi4));
- return gsm48_rr_chan_req(ms, gsm48_rr_chan2cause[chan_4], 1);
- } else
- LOGP(DPAG, LOGL_INFO, " TMSI %08x (not for us)\n",
- ntohl(pa->tmsi4));
-
- return 0;
-}
-
-/*
- * (immediate) assignment
- */
-
-/* match request reference agains request history */
-static int gsm48_match_ra(struct osmocom_ms *ms, struct gsm48_req_ref *ref)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- int i;
- uint8_t ia_t1, ia_t2, ia_t3;
- uint8_t cr_t1, cr_t2, cr_t3;
-
- for (i = 0; i < 3; i++) {
- /* filter confirmed RACH requests only */
- if (rr->cr_hist[i].valid && ref->ra == rr->cr_hist[i].ref.ra) {
- ia_t1 = ref->t1;
- ia_t2 = ref->t2;
- ia_t3 = (ref->t3_high << 3) | ref->t3_low;
- ref = &rr->cr_hist[i].ref;
- cr_t1 = ref->t1;
- cr_t2 = ref->t2;
- cr_t3 = (ref->t3_high << 3) | ref->t3_low;
- if (ia_t1 == cr_t1 && ia_t2 == cr_t2
- && ia_t3 == cr_t3) {
- LOGP(DRR, LOGL_INFO, "request %02x matches "
- "(fn=%d,%d,%d)\n", ref->ra, ia_t1,
- ia_t2, ia_t3);
- return 1;
- } else
- LOGP(DRR, LOGL_INFO, "request %02x matches "
- "but not frame number (IMM.ASS "
- "fn=%d,%d,%d != RACH fn=%d,%d,%d)\n",
- ref->ra, ia_t1, ia_t2, ia_t3,
- cr_t1, cr_t2, cr_t3);
- }
- }
-
- return 0;
-}
-
-/* 9.1.18 IMMEDIATE ASSIGNMENT is received */
-static int gsm48_rr_rx_imm_ass(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm48_imm_ass *ia = msgb_l3(msg);
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = cs->si;
- int ma_len = msgb_l3len(msg) - sizeof(*ia);
- uint8_t ch_type, ch_subch, ch_ts;
- struct gsm48_rr_cd cd;
-#ifndef TEST_STARTING_TIMER
- uint8_t *st, st_len;
-#endif
-
- /* ignore imm.ass. while not camping on a cell */
- if (!cs->selected || cs->neighbour || !s) {
- LOGP(DRR, LOGL_INFO, "IMMEDIATED ASSGINMENT ignored, we are "
- "have not proper selected the serving cell.\n");
-
- return 0;
- }
-
- memset(&cd, 0, sizeof(cd));
- cd.ind_tx_power = rr->cd_now.ind_tx_power;
-
- if (ma_len < 0 /* mobile allocation IE must be included */
- || ia->mob_alloc_len > ma_len) { /* short read of IE */
- LOGP(DRR, LOGL_NOTICE, "Short read of IMMEDIATE ASSIGNMENT "
- "message.\n");
- return -EINVAL;
- }
- if (ia->mob_alloc_len > 8) {
- LOGP(DRR, LOGL_NOTICE, "Moble allocation in IMMEDIATE "
- "ASSIGNMENT too large.\n");
- return -EINVAL;
- }
-
- /* starting time */
-#ifdef TEST_STARTING_TIMER
- cd.start = 1;
- cd.start_tm.fn = (ms->meas.last_fn + TEST_STARTING_TIMER) % 42432;
- LOGP(DRR, LOGL_INFO, " TESTING: starting time ahead\n");
-#else
- st_len = ma_len - ia->mob_alloc_len;
- st = ia->mob_alloc + ia->mob_alloc_len;
- if (st_len >= 3 && st[0] == GSM48_IE_START_TIME)
- gsm48_decode_start_time(&cd, (struct gsm48_start_time *)(st+1));
-#endif
-
- /* decode channel description */
- LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT:\n");
- cd.chan_nr = ia->chan_desc.chan_nr;
- rsl_dec_chan_nr(cd.chan_nr, &ch_type, &ch_subch, &ch_ts);
- if (ia->chan_desc.h0.h) {
- cd.h = 1;
- gsm48_decode_chan_h1(&ia->chan_desc, &cd.tsc, &cd.maio,
- &cd.hsn);
- LOGP(DRR, LOGL_INFO, " (ta %d/%dm ra 0x%02x chan_nr 0x%02x "
- "MAIO %u HSN %u TS %u SS %u TSC %u)\n",
- ia->timing_advance,
- ia->timing_advance * GSM_TA_CM / 100,
- ia->req_ref.ra, ia->chan_desc.chan_nr, cd.maio,
- cd.hsn, ch_ts, ch_subch, cd.tsc);
- } else {
- cd.h = 0;
- gsm48_decode_chan_h0(&ia->chan_desc, &cd.tsc, &cd.arfcn);
- if (gsm_refer_pcs(cs->arfcn, s))
- cd.arfcn |= ARFCN_PCS;
- LOGP(DRR, LOGL_INFO, " (ta %d/%dm ra 0x%02x chan_nr 0x%02x "
- "ARFCN %s TS %u SS %u TSC %u)\n",
- ia->timing_advance,
- ia->timing_advance * GSM_TA_CM / 100,
- ia->req_ref.ra, ia->chan_desc.chan_nr,
- gsm_print_arfcn(cd.arfcn), ch_ts, ch_subch, cd.tsc);
- }
-
- /* 3.3.1.1.2: ignore assignment while idle */
- if (rr->state != GSM48_RR_ST_CONN_PEND || rr->wait_assign == 0) {
- LOGP(DRR, LOGL_INFO, "Not for us, no request.\n");
- return 0;
- }
-
- if (rr->wait_assign == 2) {
- LOGP(DRR, LOGL_INFO, "Ignoring, channel already assigned.\n");
- return 0;
- }
-
- /* request ref */
- if (gsm48_match_ra(ms, &ia->req_ref)) {
- /* channel description */
- memcpy(&rr->cd_now, &cd, sizeof(rr->cd_now));
- /* timing advance */
- rr->cd_now.ind_ta = ia->timing_advance;
- /* mobile allocation */
- memcpy(&rr->cd_now.mob_alloc_lv, &ia->mob_alloc_len,
- ia->mob_alloc_len + 1);
- rr->wait_assign = 2;
- /* reset scheduler */
- LOGP(DRR, LOGL_INFO, "resetting scheduler\n");
- l1ctl_tx_reset_req(ms, L1CTL_RES_T_SCHED);
-
- return gsm48_rr_dl_est(ms);
- }
- LOGP(DRR, LOGL_INFO, "Request, but not for us.\n");
-
- return 0;
-}
-
-/* 9.1.19 IMMEDIATE ASSIGNMENT EXTENDED is received */
-static int gsm48_rr_rx_imm_ass_ext(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = cs->si;
- struct gsm48_imm_ass_ext *ia = msgb_l3(msg);
- int ma_len = msgb_l3len(msg) - sizeof(*ia);
- uint8_t ch_type, ch_subch, ch_ts;
- struct gsm48_rr_cd cd1, cd2;
-#ifndef TEST_STARTING_TIMER
- uint8_t *st, st_len;
-#endif
-
- /* ignore imm.ass.ext while not camping on a cell */
- if (!cs->selected || cs->neighbour || !s) {
- LOGP(DRR, LOGL_INFO, "IMMEDIATED ASSGINMENT ignored, we are "
- "have not proper selected the serving cell.\n");
-
- return 0;
- }
-
- memset(&cd1, 0, sizeof(cd1));
- cd1.ind_tx_power = rr->cd_now.ind_tx_power;
- memset(&cd2, 0, sizeof(cd2));
- cd2.ind_tx_power = rr->cd_now.ind_tx_power;
-
- if (ma_len < 0 /* mobile allocation IE must be included */
- || ia->mob_alloc_len > ma_len) { /* short read of IE */
- LOGP(DRR, LOGL_NOTICE, "Short read of IMMEDIATE ASSIGNMENT "
- "EXTENDED message.\n");
- return -EINVAL;
- }
- if (ia->mob_alloc_len > 4) {
- LOGP(DRR, LOGL_NOTICE, "Moble allocation in IMMEDIATE "
- "ASSIGNMENT EXTENDED too large.\n");
- return -EINVAL;
- }
-
-#ifdef TEST_STARTING_TIMER
- cd1.start = 1;
- cd2.start_tm.fn = (ms->meas.last_fn + TEST_STARTING_TIMER) % 42432;
- memcpy(&cd2, &cd1, sizeof(cd2));
- LOGP(DRR, LOGL_INFO, " TESTING: starting time ahead\n");
-#else
- /* starting time */
- st_len = ma_len - ia->mob_alloc_len;
- st = ia->mob_alloc + ia->mob_alloc_len;
- if (st_len >= 3 && st[0] == GSM48_IE_START_TIME) {
- gsm48_decode_start_time(&cd1,
- (struct gsm48_start_time *)(st+1));
- memcpy(&cd2, &cd1, sizeof(cd2));
- }
-#endif
-
- /* decode channel description */
- LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT EXTENDED:\n");
- cd1.chan_nr = ia->chan_desc1.chan_nr;
- rsl_dec_chan_nr(cd1.chan_nr, &ch_type, &ch_subch, &ch_ts);
- if (ia->chan_desc1.h0.h) {
- cd1.h = 1;
- gsm48_decode_chan_h1(&ia->chan_desc1, &cd1.tsc, &cd1.maio,
- &cd1.hsn);
- LOGP(DRR, LOGL_INFO, " assignment 1 (ta %d/%dm ra 0x%02x "
- "chan_nr 0x%02x MAIO %u HSN %u TS %u SS %u TSC %u)\n",
- ia->timing_advance1,
- ia->timing_advance1 * GSM_TA_CM / 100,
- ia->req_ref1.ra, ia->chan_desc1.chan_nr, cd1.maio,
- cd1.hsn, ch_ts, ch_subch, cd1.tsc);
- } else {
- cd1.h = 0;
- gsm48_decode_chan_h0(&ia->chan_desc1, &cd1.tsc, &cd1.arfcn);
- if (gsm_refer_pcs(cs->arfcn, s))
- cd1.arfcn |= ARFCN_PCS;
- LOGP(DRR, LOGL_INFO, " assignment 1 (ta %d/%dm ra 0x%02x "
- "chan_nr 0x%02x ARFCN %s TS %u SS %u TSC %u)\n",
- ia->timing_advance1,
- ia->timing_advance1 * GSM_TA_CM / 100,
- ia->req_ref1.ra, ia->chan_desc1.chan_nr,
- gsm_print_arfcn(cd1.arfcn), ch_ts, ch_subch, cd1.tsc);
- }
- cd2.chan_nr = ia->chan_desc2.chan_nr;
- rsl_dec_chan_nr(cd2.chan_nr, &ch_type, &ch_subch, &ch_ts);
- if (ia->chan_desc2.h0.h) {
- cd2.h = 1;
- gsm48_decode_chan_h1(&ia->chan_desc2, &cd2.tsc, &cd2.maio,
- &cd2.hsn);
- LOGP(DRR, LOGL_INFO, " assignment 2 (ta %d/%dm ra 0x%02x "
- "chan_nr 0x%02x MAIO %u HSN %u TS %u SS %u TSC %u)\n",
- ia->timing_advance2,
- ia->timing_advance2 * GSM_TA_CM / 100,
- ia->req_ref2.ra, ia->chan_desc2.chan_nr, cd2.maio,
- cd2.hsn, ch_ts, ch_subch, cd2.tsc);
- } else {
- cd2.h = 0;
- gsm48_decode_chan_h0(&ia->chan_desc2, &cd2.tsc, &cd2.arfcn);
- if (gsm_refer_pcs(cs->arfcn, s))
- cd2.arfcn |= ARFCN_PCS;
- LOGP(DRR, LOGL_INFO, " assignment 2 (ta %d/%dm ra 0x%02x "
- "chan_nr 0x%02x ARFCN %s TS %u SS %u TSC %u)\n",
- ia->timing_advance2,
- ia->timing_advance2 * GSM_TA_CM / 100,
- ia->req_ref2.ra, ia->chan_desc2.chan_nr,
- gsm_print_arfcn(cd2.arfcn), ch_ts, ch_subch, cd2.tsc);
- }
-
- /* 3.3.1.1.2: ignore assignment while idle */
- if (rr->state != GSM48_RR_ST_CONN_PEND || rr->wait_assign == 0) {
- LOGP(DRR, LOGL_INFO, "Not for us, no request.\n");
- return 0;
- }
-
- if (rr->wait_assign == 2) {
- LOGP(DRR, LOGL_INFO, "Ignoring, channel already assigned.\n");
- return 0;
- }
-
- /* request ref 1 */
- if (gsm48_match_ra(ms, &ia->req_ref1)) {
- /* channel description */
- memcpy(&rr->cd_now, &cd1, sizeof(rr->cd_now));
- /* timing advance */
- rr->cd_now.ind_ta = ia->timing_advance1;
- /* mobile allocation */
- memcpy(&rr->cd_now.mob_alloc_lv, &ia->mob_alloc_len,
- ia->mob_alloc_len + 1);
- rr->wait_assign = 2;
- /* reset scheduler */
- LOGP(DRR, LOGL_INFO, "resetting scheduler\n");
- l1ctl_tx_reset_req(ms, L1CTL_RES_T_SCHED);
-
- return gsm48_rr_dl_est(ms);
- }
- /* request ref 2 */
- if (gsm48_match_ra(ms, &ia->req_ref2)) {
- /* channel description */
- memcpy(&rr->cd_now, &cd2, sizeof(rr->cd_now));
- /* timing advance */
- rr->cd_now.ind_ta = ia->timing_advance2;
- /* mobile allocation */
- memcpy(&rr->cd_now.mob_alloc_lv, &ia->mob_alloc_len,
- ia->mob_alloc_len + 1);
- rr->wait_assign = 2;
- /* reset scheduler */
- LOGP(DRR, LOGL_INFO, "resetting scheduler\n");
- l1ctl_tx_reset_req(ms, L1CTL_RES_T_SCHED);
-
- return gsm48_rr_dl_est(ms);
- }
- LOGP(DRR, LOGL_INFO, "Request, but not for us.\n");
-
- return 0;
-}
-
-/* 9.1.20 IMMEDIATE ASSIGNMENT REJECT is received */
-static int gsm48_rr_rx_imm_ass_rej(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm48_imm_ass_rej *ia = msgb_l3(msg);
- int payload_len = msgb_l3len(msg) - sizeof(*ia);
- int i;
- struct gsm48_req_ref *req_ref;
- uint8_t t3122_value;
-
- /* 3.3.1.1.2: ignore assignment while idle */
- if (rr->state != GSM48_RR_ST_CONN_PEND || rr->wait_assign == 0)
- return 0;
-
- if (rr->wait_assign == 2) {
- return 0;
- }
-
- if (payload_len < 0) {
- LOGP(DRR, LOGL_NOTICE, "Short read of IMMEDIATE ASSIGNMENT "
- "REJECT message.\n");
- return -EINVAL;
- }
-
- for (i = 0; i < 4; i++) {
- /* request reference */
- req_ref = (struct gsm48_req_ref *)
- (((uint8_t *)&ia->req_ref1) + i * 4);
- LOGP(DRR, LOGL_INFO, "IMMEDIATE ASSIGNMENT REJECT "
- "(ref 0x%02x)\n", req_ref->ra);
- if (gsm48_match_ra(ms, req_ref)) {
- /* wait indication */
- t3122_value = *(((uint8_t *)&ia->wait_ind1) + i * 4);
- if (t3122_value)
- start_rr_t3122(rr, t3122_value, 0);
- /* start timer 3126 if not already */
- if (!osmo_timer_pending(&rr->t3126))
- start_rr_t3126(rr, 5, 0); /* TODO improve! */
- /* stop assignmnet requests */
- rr->n_chan_req = 0;
-
- /* wait until timer 3126 expires, then release
- * or wait for channel assignment */
- return 0;
- }
- }
-
- return 0;
-}
-
-/* 9.1.1 ADDITIONAL ASSIGMENT is received */
-static int gsm48_rr_rx_add_ass(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- struct gsm48_add_ass *aa = (struct gsm48_add_ass *)gh->data;
- int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*aa);
- struct tlv_parsed tp;
-
- if (payload_len < 0) {
- LOGP(DRR, LOGL_NOTICE, "Short read of ADDITIONAL ASSIGNMENT "
- "message.\n");
- return gsm48_rr_tx_rr_status(ms,
- GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
- }
- tlv_parse(&tp, &gsm48_rr_att_tlvdef, aa->data, payload_len, 0, 0);
-
- return gsm48_rr_tx_rr_status(ms, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
-}
-
-/*
- * measturement reports
- */
-
-static int gsm48_rr_tx_meas_rep(struct osmocom_ms *ms)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm48_sysinfo *s = ms->cellsel.si;
- struct rx_meas_stat *meas = &rr->ms->meas;
- struct gsm48_rr_meas *rrmeas = &rr->meas;
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
- struct gsm48_meas_res *mr;
- uint8_t serv_rxlev_full = 0, serv_rxlev_sub = 0, serv_rxqual_full = 0,
- serv_rxqual_sub = 0;
- uint8_t ta, tx_power;
- uint8_t rep_ba = 0, rep_valid = 0, meas_valid = 0, multi_rep = 0;
- uint8_t n = 0, rxlev_nc[6], bsic_nc[6], bcch_f_nc[6];
-
- /* just in case! */
- if (!s)
- return -EINVAL;
-
- /* check if SI5* is completely received, check BA-IND */
- if (s->si5
- && (!s->nb_ext_ind_si5 || s->si5bis)) {
- rep_ba = s->nb_ba_ind_si5;
- if ((s->si5bis && s->nb_ext_ind_si5
- && s->nb_ba_ind_si5bis != rep_ba)
- || (s->si5ter && s->nb_ba_ind_si5ter != rep_ba)) {
- LOGP(DRR, LOGL_NOTICE, "BA-IND missmatch on SI5*");
- } else
- rep_valid = 1;
- }
-
- /* check for valid measurements, any frame must exist */
- if (meas->frames) {
- meas_valid = 1;
- serv_rxlev_full = serv_rxlev_sub =
- (meas->rxlev + (meas->frames / 2)) / meas->frames;
- serv_rxqual_full = serv_rxqual_sub = 0; // FIXME
- }
-
- memset(&rxlev_nc, 0, sizeof(rxlev_nc));
- memset(&bsic_nc, 0, sizeof(bsic_nc));
- memset(&bcch_f_nc, 0, sizeof(bcch_f_nc));
- if (rep_valid) {
- int8_t strongest, current;
- uint8_t ncc;
- int i, index;
-
- /* multiband reporting, if not: 0 = normal reporting */
- if (s->si5ter)
- multi_rep = s->nb_multi_rep_si5ter;
-
- /* get 6 strongest measurements */
- // FIXME: multiband report
- strongest = 127; /* infinite */
- for (n = 0; n < 6; n++) {
- current = -128; /* -infinite */
- index = 0;
- for (i = 0; i < rrmeas->nc_num; i++) {
- /* only check if NCC is permitted */
- ncc = rrmeas->nc_bsic[i] >> 3;
- if ((s->nb_ncc_permitted_si6 & (1 << ncc))
- && rrmeas->nc_rxlev[i] > current
- && rrmeas->nc_rxlev[i] < strongest) {
- current = rrmeas->nc_rxlev[i];
- index = i;
- }
- }
- if (current == -128) /* no more found */
- break;
- rxlev_nc[n] = rrmeas->nc_rxlev[index] + 110;
- bsic_nc[n] = rrmeas->nc_bsic[index];
- bcch_f_nc[n] = index;
- }
- }
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
-
- /* use indicated tx-power and TA (not the altered ones) */
- tx_power = rr->cd_now.ind_tx_power;
- // FIXME: degrade power to the max supported level
- ta = rr->cd_now.ind_ta;
-
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
- mr = (struct gsm48_meas_res *) msgb_put(nmsg, sizeof(*mr));
-
- gh->proto_discr = GSM48_PDISC_RR;
- gh->msg_type = GSM48_MT_RR_MEAS_REP;
-
- /* measurement results */
- mr->rxlev_full = serv_rxlev_full;
- mr->rxlev_sub = serv_rxlev_sub;
- mr->rxqual_full = serv_rxqual_full;
- mr->rxqual_sub = serv_rxqual_sub;
- mr->dtx_used = 0; // FIXME: no DTX yet
- mr->ba_used = rep_ba;
- mr->meas_valid = !meas_valid; /* 0 = valid */
- if (rep_valid) {
- mr->no_nc_n_hi = n >> 2;
- mr->no_nc_n_lo = n & 3;
- } else {
- /* no results for serving cells */
- mr->no_nc_n_hi = 1;
- mr->no_nc_n_lo = 3;
- }
- mr->rxlev_nc1 = rxlev_nc[0];
- mr->rxlev_nc2_hi = rxlev_nc[1] >> 1;
- mr->rxlev_nc2_lo = rxlev_nc[1] & 1;
- mr->rxlev_nc3_hi = rxlev_nc[2] >> 2;
- mr->rxlev_nc3_lo = rxlev_nc[2] & 3;
- mr->rxlev_nc4_hi = rxlev_nc[3] >> 3;
- mr->rxlev_nc4_lo = rxlev_nc[3] & 7;
- mr->rxlev_nc5_hi = rxlev_nc[4] >> 4;
- mr->rxlev_nc5_lo = rxlev_nc[4] & 15;
- mr->rxlev_nc6_hi = rxlev_nc[5] >> 5;
- mr->rxlev_nc6_lo = rxlev_nc[5] & 31;
- mr->bsic_nc1_hi = bsic_nc[0] >> 3;
- mr->bsic_nc1_lo = bsic_nc[0] & 7;
- mr->bsic_nc2_hi = bsic_nc[1] >> 4;
- mr->bsic_nc2_lo = bsic_nc[1] & 15;
- mr->bsic_nc3_hi = bsic_nc[2] >> 5;
- mr->bsic_nc3_lo = bsic_nc[2] & 31;
- mr->bsic_nc4 = bsic_nc[3];
- mr->bsic_nc5 = bsic_nc[4];
- mr->bsic_nc6 = bsic_nc[5];
- mr->bcch_f_nc1 = bcch_f_nc[0];
- mr->bcch_f_nc2 = bcch_f_nc[1];
- mr->bcch_f_nc3 = bcch_f_nc[2];
- mr->bcch_f_nc4 = bcch_f_nc[3];
- mr->bcch_f_nc5_hi = bcch_f_nc[4] >> 1;
- mr->bcch_f_nc5_lo = bcch_f_nc[4] & 1;
- mr->bcch_f_nc6_hi = bcch_f_nc[5] >> 2;
- mr->bcch_f_nc6_lo = bcch_f_nc[5] & 3;
-
- LOGP(DRR, LOGL_INFO, "MEAS REP: pwr=%d TA=%d meas-invalid=%d "
- "rxlev-full=%d rxlev-sub=%d rxqual-full=%d rxqual-sub=%d "
- "dtx %d ba %d no-ncell-n %d\n", tx_power, ta, mr->meas_valid,
- mr->rxlev_full - 110, mr->rxlev_sub - 110,
- mr->rxqual_full, mr->rxqual_sub, mr->dtx_used, mr->ba_used,
- (mr->no_nc_n_hi << 2) | mr->no_nc_n_lo);
-
- msgb_tv16_push(nmsg, RSL_IE_L3_INFO,
- nmsg->tail - (uint8_t *)msgb_l3(nmsg));
- msgb_push(nmsg, 2 + 2);
- nmsg->data[0] = RSL_IE_TIMING_ADVANCE;
- nmsg->data[1] = ta;
- nmsg->data[2] = RSL_IE_MS_POWER;
- nmsg->data[3] = tx_power;
- rsl_rll_push_hdr(nmsg, RSL_MT_UNIT_DATA_REQ, rr->cd_now.chan_nr,
- 0x40, 1);
-
- return lapdm_rslms_recvmsg(nmsg, &ms->lapdm_channel);
-}
-
-/*
- * link establishment and release
- */
-
-/* process "Loss Of Signal" */
-int gsm48_rr_los(struct osmocom_ms *ms)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- uint8_t *mode;
- struct msgb *nmsg;
- struct gsm48_rr_hdr *nrrh;
-
- LOGP(DSUM, LOGL_INFO, "Radio link lost signal\n");
-
- /* stop T3211 if running */
- stop_rr_t3110(rr);
-
- switch(rr->state) {
- case GSM48_RR_ST_CONN_PEND:
- LOGP(DRR, LOGL_INFO, "LOS during RACH request\n");
-
- /* stop pending RACH timer */
- stop_rr_t3126(rr);
- break;
- case GSM48_RR_ST_DEDICATED:
- LOGP(DRR, LOGL_INFO, "LOS during dedicated mode, release "
- "locally\n");
-
- new_rr_state(rr, GSM48_RR_ST_REL_PEND);
-
- /* release message */
- rel_local:
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- mode = msgb_put(nmsg, 2);
- mode[0] = RSL_IE_RELEASE_MODE;
- mode[1] = 1; /* local release */
- /* start release */
- return gsm48_send_rsl_rel(ms, RSL_MT_REL_REQ, nmsg);
- case GSM48_RR_ST_REL_PEND:
- LOGP(DRR, LOGL_INFO, "LOS during RR release procedure, release "
- "locally\n");
-
- /* stop pending RACH timer */
- stop_rr_t3110(rr);
-
- /* release locally */
- goto rel_local;
- default:
- /* this should not happen */
- LOGP(DRR, LOGL_ERROR, "LOS in IDLE state, ignoring\n");
- return -EINVAL;
- }
-
- /* send inication to upper layer */
- nmsg = gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
- if (!nmsg)
- return -ENOMEM;
- nrrh = (struct gsm48_rr_hdr *)nmsg->data;
- nrrh->cause = RR_REL_CAUSE_LOST_SIGNAL;
- gsm48_rr_upmsg(ms, nmsg);
-
- /* return idle */
- new_rr_state(rr, GSM48_RR_ST_IDLE);
- return 0;
-}
-
-/* activation of channel in dedicated mode */
-static int gsm48_rr_activate_channel(struct osmocom_ms *ms,
- struct gsm48_rr_cd *cd, uint16_t *ma, uint8_t ma_len)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm_settings *set = &ms->settings;
- struct gsm48_sysinfo *s = ms->cellsel.si;
- struct rx_meas_stat *meas = &ms->meas;
- uint8_t ch_type, ch_subch, ch_ts;
- uint8_t timeout = 64;
-
- /* setting (new) timing advance */
- LOGP(DRR, LOGL_INFO, "setting indicated TA %d (actual TA %d)\n",
- cd->ind_ta, cd->ind_ta - set->alter_delay);
- l1ctl_tx_param_req(ms, cd->ind_ta - set->alter_delay,
- (set->alter_tx_power) ? set->alter_tx_power_value
- : cd->ind_tx_power);
-
- /* reset measurement and link timeout */
- meas->ds_fail = 0;
- if (s) {
- if (s->sacch_radio_link_timeout) {
- timeout = s->sacch_radio_link_timeout;
- LOGP(DRR, LOGL_INFO, "using last SACCH timeout %d\n",
- timeout);
- } else if (s->bcch_radio_link_timeout) {
- timeout = s->bcch_radio_link_timeout;
- LOGP(DRR, LOGL_INFO, "using last BCCH timeout %d\n",
- timeout);
- }
- }
- meas->rl_fail = meas->s = timeout;
-
- /* setting initial (invalid) measurement report, resetting SI5* */
- if (s) {
- memset(s->si5_msg, 0, sizeof(s->si5_msg));
- memset(s->si5b_msg, 0, sizeof(s->si5b_msg));
- memset(s->si5t_msg, 0, sizeof(s->si5t_msg));
- }
- meas->frames = meas->snr = meas->berr = meas->rxlev = 0;
- rr->meas.nc_num = 0;
- stop_rr_t_meas(rr);
- start_rr_t_meas(rr, 1, 0);
- gsm48_rr_tx_meas_rep(ms);
-
- /* establish */
- LOGP(DRR, LOGL_INFO, "establishing channel in dedicated mode\n");
- rsl_dec_chan_nr(cd->chan_nr, &ch_type, &ch_subch, &ch_ts);
- LOGP(DRR, LOGL_INFO, " Channel type %d, subch %d, ts %d, mode %d, "
- "audio-mode %d, cipher %d\n", ch_type, ch_subch, ch_ts,
- cd->mode, rr->audio_mode, rr->cipher_type + 1);
- if (cd->h)
- l1ctl_tx_dm_est_req_h1(ms, cd->maio, cd->hsn,
- ma, ma_len, cd->chan_nr, cd->tsc, cd->mode,
- rr->audio_mode);
- else
- l1ctl_tx_dm_est_req_h0(ms, cd->arfcn, cd->chan_nr, cd->tsc,
- cd->mode, rr->audio_mode);
- rr->dm_est = 1;
-
- /* old SI 5/6 are not valid on a new dedicated channel */
- s->si5 = s->si5bis = s->si5ter = s->si6 = 0;
-
- if (rr->cipher_on)
- l1ctl_tx_crypto_req(ms, rr->cipher_type + 1, subscr->key, 8);
-
- return 0;
-}
-
-/* frequency change of channel "after time" */
-static int gsm48_rr_channel_after_time(struct osmocom_ms *ms,
- struct gsm48_rr_cd *cd, uint16_t *ma, uint8_t ma_len, uint16_t fn)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm48_rrlayer *rr = &ms->rrlayer;
-
- if (cd->h)
- l1ctl_tx_dm_freq_req_h1(ms, cd->maio, cd->hsn,
- ma, ma_len, cd->tsc, fn);
- else
- l1ctl_tx_dm_freq_req_h0(ms, cd->arfcn, cd->tsc, fn);
-
- if (rr->cipher_on)
- l1ctl_tx_crypto_req(ms, rr->cipher_type + 1, subscr->key, 8);
-
- gsm48_rr_set_mode(ms, cd->chan_nr, cd->mode);
-
- return 0;
-}
-
-/* render list of hopping channels from channel description elements */
-static int gsm48_rr_render_ma(struct osmocom_ms *ms, struct gsm48_rr_cd *cd,
- uint16_t *ma, uint8_t *ma_len)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = cs->si;
- struct gsm_settings *set = &ms->settings;
- int i, pcs, index;
- uint16_t arfcn;
-
- pcs = gsm_refer_pcs(cs->arfcn, s) ? ARFCN_PCS : 0;
-
- /* no hopping (no MA), channel description is valid */
- if (!cd->h) {
- *ma_len = 0;
- return 0;
- }
-
- /* decode mobile allocation */
- if (cd->mob_alloc_lv[0]) {
- struct gsm_sysinfo_freq *freq = s->freq;
-
- LOGP(DRR, LOGL_INFO, "decoding mobile allocation\n");
-
- if (cd->cell_desc_lv[0]) {
- LOGP(DRR, LOGL_INFO, "using cell channel descr.\n");
- if (cd->cell_desc_lv[0] != 16) {
- LOGP(DRR, LOGL_ERROR, "cell channel descr. "
- "has invalid lenght\n");
- return GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
- }
- gsm48_decode_freq_list(freq, cd->cell_desc_lv + 1, 16,
- 0xce, FREQ_TYPE_SERV);
- }
-
- gsm48_decode_mobile_alloc(freq, cd->mob_alloc_lv + 1,
- cd->mob_alloc_lv[0], ma, ma_len, 0);
- if (*ma_len < 1) {
- LOGP(DRR, LOGL_NOTICE, "mobile allocation with no "
- "frequency available\n");
- return GSM48_RR_CAUSE_NO_CELL_ALLOC_A;
-
- }
- } else
- /* decode frequency list */
- if (cd->freq_list_lv[0]) {
- struct gsm_sysinfo_freq f[1024];
- int j = 0;
-
- LOGP(DRR, LOGL_INFO, "decoding frequency list\n");
-
- /* get bitmap */
- if (gsm48_decode_freq_list(f, cd->freq_list_lv + 1,
- cd->freq_list_lv[0], 0xce, FREQ_TYPE_SERV)) {
- LOGP(DRR, LOGL_NOTICE, "frequency list invalid\n");
- return GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
- }
-
- /* collect channels from bitmap (1..1023,0) */
- for (i = 1; i <= 1024; i++) {
- if ((f[i & 1023].mask & FREQ_TYPE_SERV)) {
- LOGP(DRR, LOGL_INFO, "Listed ARFCN #%d: %s\n",
- j, gsm_print_arfcn((i & 1023) | pcs));
- if (j == 64) {
- LOGP(DRR, LOGL_NOTICE, "frequency list "
- "exceeds 64 entries!\n");
- return GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
- }
- ma[j++] = i & 1023;
- }
- }
- *ma_len = j;
- } else
- /* decode frequency channel sequence */
- if (cd->freq_seq_lv[0]) {
- int j = 0, inc;
-
- LOGP(DRR, LOGL_INFO, "decoding frequency channel sequence\n");
-
- if (cd->freq_seq_lv[0] != 9) {
- LOGP(DRR, LOGL_NOTICE, "invalid frequency channel "
- "sequence\n");
- return GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
- }
- arfcn = cd->freq_seq_lv[1] & 0x7f;
- LOGP(DRR, LOGL_INFO, "Listed Sequence ARFCN #%d: %s\n", j,
- gsm_print_arfcn(arfcn | pcs));
- ma[j++] = arfcn;
- for (i = 0; i < 16; i++) {
- if ((i & 1))
- inc = cd->freq_seq_lv[2 + (i >> 1)] & 0x0f;
- else
- inc = cd->freq_seq_lv[2 + (i >> 1)] >> 4;
- if (inc) {
- arfcn += inc;
- LOGP(DRR, LOGL_INFO, "Listed Sequence ARFCN "
- "#%d: %s\n", j,
- gsm_print_arfcn(i | pcs));
- ma[j++] = arfcn;
- } else
- arfcn += 15;
- }
- *ma_len = j;
- } else {
- LOGP(DRR, LOGL_NOTICE, "hopping, but nothing that tells us "
- "a sequence\n");
- return GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
- }
-
- /* convert to band_arfcn and check for unsported frequency */
- for (i = 0; i < *ma_len; i++) {
- arfcn = ma[i] | pcs;
- ma[i] = arfcn;
- index = arfcn2index(arfcn);
- if (!(set->freq_map[index >> 3] & (1 << (index & 7)))) {
- LOGP(DRR, LOGL_NOTICE, "Hopping ARFCN %s not "
- "supported\n", gsm_print_arfcn(arfcn));
- return GSM48_RR_CAUSE_FREQ_NOT_IMPL;
- }
- }
-
- return 0;
-}
-
-/* activate link and send establish request */
-static int gsm48_rr_dl_est(struct osmocom_ms *ms)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
- struct gsm48_pag_rsp *pr;
- uint8_t mi[11];
- uint16_t ma[64];
- uint8_t ma_len;
-
- /* 3.3.1.1.3.1 */
- stop_rr_t3126(rr);
-
- /* check if we have to change channel at starting time (we delay) */
- if (rr->cd_now.start) {
- int32_t now, start, diff;
- uint32_t start_mili = 0;
-
- /* how much time do we have left? */
- now = ms->meas.last_fn % 42432;
- start = rr->cd_now.start_tm.fn % 42432;
- diff = start - now;
- if (diff < 0)
- diff += 42432;
- LOGP(DRR, LOGL_INFO, " (Tnow %d Tstart %d diff %d)\n",
- now, start, diff);
- start_mili = (uint32_t)diff * 19580 / 42432 * 10;
- if (diff >= 32024 || !start_mili) {
- LOGP(DRR, LOGL_INFO, " -> Start time already "
- "elapsed\n");
- rr->cd_now.start = 0;
- } else {
- LOGP(DRR, LOGL_INFO, " -> Start time is %d ms in the "
- "future\n", start_mili);
- }
-
-#ifndef TEST_FREQUENCY_MOD
- /* schedule start of IMM.ASS */
- rr->modify_state = GSM48_RR_MOD_IMM_ASS;
- start_rr_t_starting(rr, start_mili / 1000,
- (start_mili % 1000) * 1000);
- /* when timer fires, start time is already elapsed */
- rr->cd_now.start = 0;
-
- return 0;
-#endif
- }
-
- /* get hopping sequence, if required */
- if (gsm48_rr_render_ma(ms, &rr->cd_now, ma, &ma_len))
- return -EINVAL;
-
- /* clear all sequence numbers for all possible PDs */
- rr->v_sd = 0;
-
- /* send DL_EST_REQ */
- if (rr->rr_est_msg) {
- LOGP(DRR, LOGL_INFO, "sending establish message\n");
-
- /* use queued message */
- nmsg = rr->rr_est_msg;
- rr->rr_est_msg = 0;
-
- /* set sequence number and increment */
- gsm48_apply_v_sd(rr, nmsg);
- } else {
- /* create paging response */
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
- gh->proto_discr = GSM48_PDISC_RR;
- gh->msg_type = GSM48_MT_RR_PAG_RESP;
- pr = (struct gsm48_pag_rsp *) msgb_put(nmsg, sizeof(*pr));
- /* key sequence */
- pr->key_seq = subscr->key_seq;
- /* classmark 2 */
- pr->cm2_len = sizeof(pr->cm2);
- gsm48_rr_enc_cm2(ms, &pr->cm2, rr->cd_now.arfcn);
- /* mobile identity */
- if (ms->subscr.tmsi != 0xffffffff
- && ms->subscr.mcc == cs->sel_mcc
- && ms->subscr.mnc == cs->sel_mnc
- && ms->subscr.lac == cs->sel_lac) {
- gsm48_generate_mid_from_tmsi(mi, subscr->tmsi);
- LOGP(DRR, LOGL_INFO, "sending paging response with "
- "TMSI\n");
- } else if (subscr->imsi[0]) {
- gsm48_generate_mid_from_imsi(mi, subscr->imsi);
- LOGP(DRR, LOGL_INFO, "sending paging response with "
- "IMSI\n");
- } else {
- mi[1] = 1;
- mi[2] = 0xf0 | GSM_MI_TYPE_NONE;
- LOGP(DRR, LOGL_INFO, "sending paging response without "
- "TMSI/IMSI\n");
- }
- msgb_put(nmsg, 1 + mi[1]);
- memcpy(pr->data, mi + 1, 1 + mi[1]);
- }
-
-#ifdef TEST_FREQUENCY_MOD
- LOGP(DRR, LOGL_INFO, " TESTING: frequency modify IMM.ASS\n");
- memcpy(&rr->cd_before, &rr->cd_now, sizeof(rr->cd_before));
- rr->cd_before.h = 0;
- rr->cd_before.arfcn = 0;
- /* activate channel */
- gsm48_rr_activate_channel(ms, &rr->cd_before, ma, ma_len);
- /* render channel "after time" */
- gsm48_rr_render_ma(ms, &rr->cd_now, ma, &ma_len);
- /* schedule change of channel */
- gsm48_rr_channel_after_time(ms, &rr->cd_now, ma, ma_len,
- rr->cd_now.start_tm.fn);
-#else
- /* activate channel */
- gsm48_rr_activate_channel(ms, &rr->cd_now, ma, ma_len);
-#endif
-
- /* start establishmnet */
- return gsm48_send_rsl(ms, RSL_MT_EST_REQ, nmsg);
-}
-
-/* the link is established */
-static int gsm48_rr_estab_cnf(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- uint8_t *mode;
- struct msgb *nmsg;
-
- /* if MM has releases before confirm, we start release */
- if (rr->state == GSM48_RR_ST_REL_PEND) {
- LOGP(DRR, LOGL_INFO, "MM already released RR.\n");
- /* release message */
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- mode = msgb_put(nmsg, 2);
- mode[0] = RSL_IE_RELEASE_MODE;
- mode[1] = 0; /* normal release */
- /* start release */
- return gsm48_send_rsl_rel(ms, RSL_MT_REL_REQ, nmsg);
- }
-
- /* 3.3.1.1.4 */
- new_rr_state(rr, GSM48_RR_ST_DEDICATED);
-
- /* send confirm to upper layer */
- nmsg = gsm48_rr_msgb_alloc(
- (rr->rr_est_req) ? GSM48_RR_EST_CNF : GSM48_RR_EST_IND);
- if (!nmsg)
- return -ENOMEM;
- return gsm48_rr_upmsg(ms, nmsg);
-}
-
-/* the link is released in pending state (by l2) */
-static int gsm48_rr_rel_ind(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct msgb *nmsg;
- struct gsm48_rr_hdr *nrrh;
-
- /* switch back to old channel, if modify/ho failed */
- switch (rr->modify_state) {
- case GSM48_RR_MOD_ASSIGN:
- case GSM48_RR_MOD_HANDO:
- /* channel is deactivate there */
- return gsm48_rr_rel_cnf(ms, msg);
- case GSM48_RR_MOD_ASSIGN_RESUME:
- case GSM48_RR_MOD_HANDO_RESUME:
- rr->modify_state = GSM48_RR_MOD_NONE;
- break;
- }
-
- LOGP(DSUM, LOGL_INFO, "Radio link is released\n");
-
- /* send inication to upper layer */
- nmsg = gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
- if (!nmsg)
- return -ENOMEM;
- nrrh = (struct gsm48_rr_hdr *)nmsg->data;
- nrrh->cause = RR_REL_CAUSE_NORMAL;
- gsm48_rr_upmsg(ms, nmsg);
-
- /* start release timer, so UA will be transmitted */
- start_rr_t_rel_wait(rr, 1, 500000);
-
- /* pending release */
- new_rr_state(rr, GSM48_RR_ST_REL_PEND);
-
- return 0;
-}
-
-/* 9.1.7 CHANNEL RELEASE is received */
-static int gsm48_rr_rx_chan_rel(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm48_hdr *gh = msgb_l3(msg);
- struct gsm48_chan_rel *cr = (struct gsm48_chan_rel *)gh->data;
- int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*cr);
- struct tlv_parsed tp;
- struct msgb *nmsg;
- uint8_t *mode;
-
- if (payload_len < 0) {
- LOGP(DRR, LOGL_NOTICE, "Short read of CHANNEL RELEASE "
- "message.\n");
- return gsm48_rr_tx_rr_status(ms,
- GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
- }
- tlv_parse(&tp, &gsm48_rr_att_tlvdef, cr->data, payload_len, 0, 0);
-
- LOGP(DRR, LOGL_INFO, "channel release request with cause 0x%02x)\n",
- cr->rr_cause);
-
- /* BA range */
- if (TLVP_PRESENT(&tp, GSM48_IE_BA_RANGE)) {
- gsm48_decode_ba_range(TLVP_VAL(&tp, GSM48_IE_BA_RANGE),
- *(TLVP_VAL(&tp, GSM48_IE_BA_RANGE) - 1), rr->ba_range,
- &rr->ba_ranges,
- sizeof(rr->ba_range) / sizeof(rr->ba_range[0]));
- /* NOTE: the ranges are kept until IDLE state is returned
- * (see new_rr_state)
- */
- }
-
- new_rr_state(rr, GSM48_RR_ST_REL_PEND);
-
- /* start T3110, so that two DISCs can be sent due to T200 timeout */
- start_rr_t3110(rr, 1, 500000);
-
- /* disconnect the main signalling link */
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- mode = msgb_put(nmsg, 2);
- mode[0] = RSL_IE_RELEASE_MODE;
- mode[1] = 0; /* normal release */
- return gsm48_send_rsl_rel(ms, RSL_MT_REL_REQ, nmsg);
-}
-
-/*
- * frequency redefition, chanel mode modify, assignment, and handover
- */
-
-/* set channel mode in case of TCH */
-static int gsm48_rr_set_mode(struct osmocom_ms *ms, uint8_t chan_nr,
- uint8_t mode)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- uint8_t ch_type, ch_subch, ch_ts;
-
- /* only apply mode to TCH/F or TCH/H */
- rsl_dec_chan_nr(chan_nr, &ch_type, &ch_subch, &ch_ts);
- if (ch_type != RSL_CHAN_Bm_ACCHs
- && ch_type != RSL_CHAN_Lm_ACCHs)
- return -ENOTSUP;
-
- /* setting (new) timing advance */
- LOGP(DRR, LOGL_INFO, "setting TCH mode to %d, audio mode to %d\n",
- mode, rr->audio_mode);
- l1ctl_tx_tch_mode_req(ms, mode, rr->audio_mode);
-
- return 0;
-}
-
-/* 9.1.13 FREQUENCY REDEFINITION is received */
-static int gsm48_rr_rx_frq_redef(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = cs->si;
- struct gsm48_frq_redef *fr = msgb_l3(msg);
- int mob_al_len = msgb_l3len(msg) - sizeof(*fr);
- uint8_t ch_type, ch_subch, ch_ts;
- struct gsm48_rr_cd cd;
- uint8_t cause;
- uint8_t *st;
- uint16_t ma[64];
- uint8_t ma_len;
-
- memcpy(&cd, &rr->cd_now, sizeof(cd));
-
- if (mob_al_len < 0 /* mobile allocation IE must be included */
- || fr->mob_alloc_len + 2 > mob_al_len) { /* short read of IE */
- LOGP(DRR, LOGL_NOTICE, "Short read of FREQUENCY REDEFINITION "
- "message.\n");
- return -EINVAL;
- }
- if (fr->mob_alloc_len > 8) {
- LOGP(DRR, LOGL_NOTICE, "Moble allocation in FREQUENCY "
- "REDEFINITION too large.\n");
- return -EINVAL;
- }
-
- /* decode channel description */
- LOGP(DRR, LOGL_INFO, "FREQUENCY REDEFINITION:\n");
- cd.chan_nr = fr->chan_desc.chan_nr;
- rsl_dec_chan_nr(cd.chan_nr, &ch_type, &ch_subch, &ch_ts);
- if (fr->chan_desc.h0.h) {
- cd.h = 1;
- gsm48_decode_chan_h1(&fr->chan_desc, &cd.tsc, &cd.maio,
- &cd.hsn);
- LOGP(DRR, LOGL_INFO, " (MAIO %u HSN %u TS %u SS %u TSC %u)\n",
- cd.maio, cd.hsn, ch_ts, ch_subch, cd.tsc);
- } else {
- cd.h = 0;
- gsm48_decode_chan_h0(&fr->chan_desc, &cd.tsc, &cd.arfcn);
- if (gsm_refer_pcs(cs->arfcn, s))
- cd.arfcn |= ARFCN_PCS;
- LOGP(DRR, LOGL_INFO, " (ARFCN %s TS %u SS %u TSC %u)\n",
- gsm_print_arfcn(cd.arfcn), ch_ts, ch_subch, cd.tsc);
- }
-
- /* mobile allocation */
- memcpy(rr->cd_now.mob_alloc_lv, &fr->mob_alloc_len,
- fr->mob_alloc_len + 1);
-
- /* starting time */
- st = fr->mob_alloc + fr->mob_alloc_len;
- gsm48_decode_start_time(&cd, (struct gsm48_start_time *)(st+1));
-
- /* cell channel description */
- if (mob_al_len >= fr->mob_alloc_len + 2 + 17
- && fr->mob_alloc[fr->mob_alloc_len + 2] == GSM48_IE_CELL_CH_DESC) {
- const uint8_t *v = fr->mob_alloc + fr->mob_alloc_len + 2 + 1;
-
- LOGP(DRR, LOGL_INFO, " using cell channel description)\n");
- cd.cell_desc_lv[0] = 16;
- memcpy(cd.cell_desc_lv + 1, v, 17);
- }
-
- /* render channel "after time" */
- cause = gsm48_rr_render_ma(ms, &rr->cd_now, ma, &ma_len);
- if (cause)
- return gsm48_rr_tx_rr_status(ms, cause);
-
- /* update to new channel data */
- memcpy(&rr->cd_now, &cd, sizeof(rr->cd_now));
-
- /* schedule change of channel */
- gsm48_rr_channel_after_time(ms, &rr->cd_now, ma, ma_len,
- rr->cd_now.start_tm.fn);
-
- rr->cd_now.start = 0;
-
- return 0;
-}
-
-/* 9.1.6 sending CHANNEL MODE MODIFY ACKNOWLEDGE */
-static int gsm48_rr_tx_chan_modify_ack(struct osmocom_ms *ms,
- struct gsm48_chan_desc *cd, uint8_t mode)
-{
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
- struct gsm48_chan_mode_modify *cm;
-
- LOGP(DRR, LOGL_INFO, "CHAN.MODE.MOD ACKNOWLEDGE\n");
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
- cm = (struct gsm48_chan_mode_modify *) msgb_put(nmsg, sizeof(*cm));
-
- gh->proto_discr = GSM48_PDISC_RR;
- gh->msg_type = GSM48_MT_RR_CHAN_MODE_MODIF_ACK;
-
- /* CD */
- memcpy(&cm->chan_desc, cd, sizeof(struct gsm48_chan_desc));
- /* mode */
- cm->mode = mode;
-
- return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, nmsg);
-}
-
-/* 9.1.5 CHANNEL MODE MODIFY is received */
-static int gsm48_rr_rx_chan_modify(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = cs->si;
- struct gsm48_hdr *gh = msgb_l3(msg);
- struct gsm48_chan_mode_modify *cm =
- (struct gsm48_chan_mode_modify *)gh->data;
- int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*cm);
- struct gsm48_rr_cd *cd = &rr->cd_now;
- uint8_t ch_type, ch_subch, ch_ts;
- uint8_t cause;
-
- LOGP(DRR, LOGL_INFO, "CHANNEL MODE MODIFY\n");
-
-
- if (payload_len < 0) {
- LOGP(DRR, LOGL_NOTICE, "Short read of CHANNEL MODE MODIFY "
- "message.\n");
- return gsm48_rr_tx_rr_status(ms,
- GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
- }
-
- /* decode channel description */
- cd->chan_nr = cm->chan_desc.chan_nr;
- rsl_dec_chan_nr(cd->chan_nr, &ch_type, &ch_subch, &ch_ts);
- if (cm->chan_desc.h0.h) {
- cd->h = 1;
- gsm48_decode_chan_h1(&cm->chan_desc, &cd->tsc, &cd->maio,
- &cd->hsn);
- LOGP(DRR, LOGL_INFO, " (chan_nr 0x%02x MAIO %u HSN %u TS %u "
- "SS %u TSC %u mode %u)\n", cm->chan_desc.chan_nr,
- cd->maio, cd->hsn, ch_ts, ch_subch, cd->tsc, cm->mode);
- } else {
- cd->h = 0;
- gsm48_decode_chan_h0(&cm->chan_desc, &cd->tsc, &cd->arfcn);
- if (gsm_refer_pcs(cs->arfcn, s))
- cd->arfcn |= ARFCN_PCS;
- LOGP(DRR, LOGL_INFO, " (chan_nr 0x%02x ARFCN %s TS %u SS %u "
- "TSC %u mode %u)\n", cm->chan_desc.chan_nr,
- gsm_print_arfcn(cd->arfcn), ch_ts, ch_subch, cd->tsc,
- cm->mode);
- }
- /* mode */
- cause = gsm48_rr_check_mode(ms, cd->chan_nr, cm->mode);
- if (cause)
- return gsm48_rr_tx_rr_status(ms, cause);
- cd->mode = cm->mode;
- gsm48_rr_set_mode(ms, cd->chan_nr, cd->mode);
-
- return gsm48_rr_tx_chan_modify_ack(ms, &cm->chan_desc, cm->mode);
-}
-
-/* 9.1.3 sending ASSIGNMENT COMPLETE */
-static int gsm48_rr_tx_ass_cpl(struct osmocom_ms *ms, uint8_t cause)
-{
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
- struct gsm48_ass_cpl *ac;
-
- LOGP(DRR, LOGL_INFO, "ASSIGNMENT COMPLETE (cause #%d)\n", cause);
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
- ac = (struct gsm48_ass_cpl *) msgb_put(nmsg, sizeof(*ac));
-
- gh->proto_discr = GSM48_PDISC_RR;
- gh->msg_type = GSM48_MT_RR_ASS_COMPL;
-
- /* RR_CAUSE */
- ac->rr_cause = cause;
-
- return gsm48_send_rsl(ms, RSL_MT_RES_REQ, nmsg);
-}
-
-/* 9.1.4 sending ASSIGNMENT FAILURE */
-static int gsm48_rr_tx_ass_fail(struct osmocom_ms *ms, uint8_t cause,
- uint8_t rsl_prim)
-{
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
- struct gsm48_ass_fail *af;
-
- LOGP(DRR, LOGL_INFO, "ASSIGNMENT FAILURE (cause #%d)\n", cause);
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
- af = (struct gsm48_ass_fail *) msgb_put(nmsg, sizeof(*af));
-
- gh->proto_discr = GSM48_PDISC_RR;
- gh->msg_type = GSM48_MT_RR_ASS_COMPL;
-
- /* RR_CAUSE */
- af->rr_cause = cause;
-
- return gsm48_send_rsl(ms, rsl_prim, nmsg);
-}
-
-/* 9.1.2 ASSIGNMENT COMMAND is received */
-static int gsm48_rr_rx_ass_cmd(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = cs->si;
- struct gsm48_hdr *gh = msgb_l3(msg);
- struct gsm48_ass_cmd *ac = (struct gsm48_ass_cmd *)gh->data;
- int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*ac);
- struct tlv_parsed tp;
- struct gsm48_rr_cd *cda = &rr->cd_after;
- struct gsm48_rr_cd *cdb = &rr->cd_before;
- uint8_t ch_type, ch_subch, ch_ts;
- uint8_t before_time = 0;
- uint16_t ma[64];
- uint8_t ma_len;
- uint32_t start_mili = 0;
- uint8_t cause;
- struct msgb *nmsg;
-
-
- LOGP(DRR, LOGL_INFO, "ASSIGNMENT COMMAND\n");
-
- memset(cda, 0, sizeof(*cda));
- cda->ind_tx_power = rr->cd_now.ind_tx_power;
- memset(cdb, 0, sizeof(*cdb));
- cdb->ind_tx_power = rr->cd_now.ind_tx_power;
-
- if (payload_len < 0) {
- LOGP(DRR, LOGL_NOTICE, "Short read of ASSIGNMENT COMMAND "
- "message.\n");
- return gsm48_rr_tx_rr_status(ms,
- GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
- }
- tlv_parse(&tp, &gsm48_rr_att_tlvdef, ac->data, payload_len, 0, 0);
-
- /* decode channel description (before time) */
- if (TLVP_PRESENT(&tp, GSM48_IE_CH_DESC_1_BEFORE)) {
- struct gsm48_chan_desc *ccd = (struct gsm48_chan_desc *)
- TLVP_VAL(&tp, GSM48_IE_CH_DESC_1_BEFORE);
- cdb->chan_nr = ccd->chan_nr;
- rsl_dec_chan_nr(cdb->chan_nr, &ch_type, &ch_subch, &ch_ts);
- if (ccd->h0.h) {
- cdb->h = 1;
- gsm48_decode_chan_h1(ccd, &cdb->tsc, &cdb->maio,
- &cdb->hsn);
- LOGP(DRR, LOGL_INFO, " before: (chan_nr 0x%02x MAIO %u "
- "HSN %u TS %u SS %u TSC %u)\n", ccd->chan_nr,
- cdb->maio, cdb->hsn, ch_ts, ch_subch, cdb->tsc);
- } else {
- cdb->h = 0;
- gsm48_decode_chan_h0(ccd, &cdb->tsc, &cdb->arfcn);
- if (gsm_refer_pcs(cs->arfcn, s))
- cdb->arfcn |= ARFCN_PCS;
- LOGP(DRR, LOGL_INFO, " before: (chan_nr 0x%02x "
- "ARFCN %s TS %u SS %u TSC %u)\n", ccd->chan_nr,
- gsm_print_arfcn(cdb->arfcn),
- ch_ts, ch_subch, cdb->tsc);
- }
- before_time = 1;
- }
-
- /* decode channel description (after time) */
- cda->chan_nr = ac->chan_desc.chan_nr;
- rsl_dec_chan_nr(cda->chan_nr, &ch_type, &ch_subch, &ch_ts);
- if (ac->chan_desc.h0.h) {
- cda->h = 1;
- gsm48_decode_chan_h1(&ac->chan_desc, &cda->tsc, &cda->maio,
- &cda->hsn);
- LOGP(DRR, LOGL_INFO, " after: (chan_nr 0x%02x MAIO %u HSN %u "
- "TS %u SS %u TSC %u)\n", ac->chan_desc.chan_nr,
- cda->maio, cda->hsn, ch_ts, ch_subch, cda->tsc);
- } else {
- cda->h = 0;
- gsm48_decode_chan_h0(&ac->chan_desc, &cda->tsc, &cda->arfcn);
- if (gsm_refer_pcs(cs->arfcn, s))
- cda->arfcn |= ARFCN_PCS;
- LOGP(DRR, LOGL_INFO, " after: (chan_nr 0x%02x ARFCN %s TS %u "
- "SS %u TSC %u)\n", ac->chan_desc.chan_nr,
- gsm_print_arfcn(cda->arfcn), ch_ts, ch_subch, cda->tsc);
- }
-
- /* starting time */
-#ifdef TEST_STARTING_TIMER
- cda->start = 1;
- cda->start_tm.fn = (ms->meas.last_fn + TEST_STARTING_TIMER) % 42432;
- LOGP(DRR, LOGL_INFO, " TESTING: starting time ahead\n");
-#else
- if (TLVP_PRESENT(&tp, GSM48_IE_START_TIME)) {
- gsm48_decode_start_time(cda, (struct gsm48_start_time *)
- TLVP_VAL(&tp, GSM48_IE_START_TIME));
- /* 9.1.2.5 "... before time IE is not present..." */
- if (!before_time) {
- LOGP(DRR, LOGL_INFO, " -> channel description after "
- "time only, but starting time\n");
- } else
- LOGP(DRR, LOGL_INFO, " -> channel description before "
- "and after time\n");
- } else {
- /* 9.1.2.5 "... IEs unnecessary in this message." */
- if (before_time) {
- before_time = 0;
- LOGP(DRR, LOGL_INFO, " -> channel description before "
- "time, but no starting time, ignoring!\n");
- }
- }
-#endif
-
- /* mobile allocation / frequency list after time */
- if (cda->h) {
- if (TLVP_PRESENT(&tp, GSM48_IE_MA_AFTER)) {
- const uint8_t *lv =
- TLVP_VAL(&tp, GSM48_IE_MA_AFTER) - 1;
-
- LOGP(DRR, LOGL_INFO, " after: hopping required and "
- "mobile allocation available\n");
- if (*lv + 1 > sizeof(cda->mob_alloc_lv)) {
- LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
- return -ENOMEM;
- }
- memcpy(cda->mob_alloc_lv, lv, *lv + 1);
- } else
- if (TLVP_PRESENT(&tp, GSM48_IE_FREQ_L_AFTER)) {
- const uint8_t *lv =
- TLVP_VAL(&tp, GSM48_IE_FREQ_L_AFTER) - 1;
-
- LOGP(DRR, LOGL_INFO, " after: hopping required and "
- "frequency list available\n");
- if (*lv + 1 > sizeof(cda->freq_list_lv)) {
- LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
- return -ENOMEM;
- }
- memcpy(cda->freq_list_lv, lv, *lv + 1);
- } else {
- LOGP(DRR, LOGL_NOTICE, " after: hopping required, but "
- "no mobile allocation / frequency list\n");
- }
- }
-
- /* mobile allocation / frequency list before time */
- if (cdb->h) {
- if (TLVP_PRESENT(&tp, GSM48_IE_MA_BEFORE)) {
- const uint8_t *lv =
- TLVP_VAL(&tp, GSM48_IE_MA_BEFORE) - 1;
-
- LOGP(DRR, LOGL_INFO, " before: hopping required and "
- "mobile allocation available\n");
- if (*lv + 1 > sizeof(cdb->mob_alloc_lv)) {
- LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
- return -ENOMEM;
- }
- memcpy(cdb->mob_alloc_lv, lv, *lv + 1);
- } else
- if (TLVP_PRESENT(&tp, GSM48_IE_FREQ_L_BEFORE)) {
- const uint8_t *lv =
- TLVP_VAL(&tp, GSM48_IE_FREQ_L_BEFORE) - 1;
-
- LOGP(DRR, LOGL_INFO, " before: hopping required and "
- "frequency list available\n");
- if (*lv + 1 > sizeof(cdb->freq_list_lv)) {
- LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
- return -ENOMEM;
- }
- memcpy(cdb->freq_list_lv, lv, *lv + 1);
- } else
- if (TLVP_PRESENT(&tp, GSM48_IE_F_CH_SEQ_BEFORE)) {
- const uint8_t *v =
- TLVP_VAL(&tp, GSM48_IE_F_CH_SEQ_BEFORE);
- uint8_t len = TLVP_LEN(&tp, GSM48_IE_F_CH_SEQ_BEFORE);
-
- LOGP(DRR, LOGL_INFO, " before: hopping required and "
- "frequency channel sequence available\n");
- if (len + 1 > sizeof(cdb->freq_seq_lv)) {
- LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
- return -ENOMEM;
- }
- cdb->freq_seq_lv[0] = len;
- memcpy(cdb->freq_seq_lv + 1, v, len);
- } else
- if (cda->mob_alloc_lv[0]) {
- LOGP(DRR, LOGL_INFO, " before: hopping required and "
- "mobile allocation not available, using "
- "mobile allocation after time\n");
- memcpy(cdb->mob_alloc_lv, cda->mob_alloc_lv,
- sizeof(cdb->mob_alloc_lv));
- } else
- if (cda->freq_list_lv[0]) {
- LOGP(DRR, LOGL_INFO, " before: hopping required and "
- "frequency list not available, using "
- "frequency list after time\n");
- memcpy(cdb->freq_list_lv, cda->freq_list_lv,
- sizeof(cdb->freq_list_lv));
- } else {
- LOGP(DRR, LOGL_NOTICE, " before: hopping required, but "
- "no mobile allocation / frequency list\n");
- }
- }
-
- /* cell channel description */
- if (TLVP_PRESENT(&tp, GSM48_IE_CELL_CH_DESC)) {
- const uint8_t *v = TLVP_VAL(&tp, GSM48_IE_CELL_CH_DESC);
- uint8_t len = TLVP_LEN(&tp, GSM48_IE_CELL_CH_DESC);
-
- LOGP(DRR, LOGL_INFO, " both: using cell channel description "
- "in case of mobile allocation\n");
- if (len + 1 > sizeof(cdb->cell_desc_lv)) {
- LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
- return -ENOMEM;
- }
- cdb->cell_desc_lv[0] = len;
- memcpy(cdb->cell_desc_lv + 1, v, len);
- cda->cell_desc_lv[0] = len;
- memcpy(cda->cell_desc_lv + 1, v, len);
- } else {
- /* keep old */
- memcpy(cdb->cell_desc_lv, rr->cd_now.cell_desc_lv,
- sizeof(cdb->cell_desc_lv));
- memcpy(cda->cell_desc_lv, rr->cd_now.cell_desc_lv,
- sizeof(cda->cell_desc_lv));
- }
-
- /* channel mode */
- if (TLVP_PRESENT(&tp, GSM48_IE_CHANMODE_1)) {
- cda->mode = cdb->mode = *TLVP_VAL(&tp, GSM48_IE_CHANMODE_1);
- LOGP(DRR, LOGL_INFO, " both: changing channel mode 0x%02x\n",
- cda->mode);
- } else
- cda->mode = cdb->mode = rr->cd_now.mode;
-
- /* cipher mode setting */
- if (TLVP_PRESENT(&tp, GSM48_IE_CIP_MODE_SET)) {
- cda->cipher = cdb->cipher =
- *TLVP_VAL(&tp, GSM48_IE_CIP_MODE_SET);
- LOGP(DRR, LOGL_INFO, " both: changing cipher mode 0x%02x\n",
- cda->cipher);
- } else
- cda->cipher = cdb->cipher = rr->cd_now.cipher;
-
- /* power command and TA (before and after time) */
- gsm48_decode_power_cmd_acc(
- (struct gsm48_power_cmd *) &ac->power_command,
- &cda->ind_tx_power, NULL);
- cdb->ind_tx_power = cda->ind_tx_power;
- cda->ind_ta = cdb->ind_ta = rr->cd_now.ind_ta; /* same cell */
- LOGP(DRR, LOGL_INFO, " both: (tx_power %d TA %d)\n", cda->ind_tx_power,
- cda->ind_ta);
-
- /* check if we have to change channel at starting time */
- if (cda->start) {
- int32_t now, start, diff;
-
- /* how much time do we have left? */
- now = ms->meas.last_fn % 42432;
- start = cda->start_tm.fn % 42432;
- diff = start - now;
- if (diff < 0)
- diff += 42432;
- LOGP(DRR, LOGL_INFO, " after: (Tnow %d Tstart %d diff %d)\n",
- now, start, diff);
- start_mili = (uint32_t)diff * 19580 / 42432 * 10;
- if (diff >= 32024 || !start_mili) {
- LOGP(DRR, LOGL_INFO, " -> Start time already "
- "elapsed\n");
- before_time = 0;
- cda->start = 0;
- } else {
- LOGP(DRR, LOGL_INFO, " -> Start time is %d ms in the "
- "future\n", start_mili);
- }
- }
-
- /* check if channels are valid */
- cause = gsm48_rr_check_mode(ms, cda->chan_nr, cda->mode);
- if (cause)
- return gsm48_rr_tx_ass_fail(ms, cause, RSL_MT_DATA_REQ);
- if (before_time) {
- cause = gsm48_rr_render_ma(ms, cdb, ma, &ma_len);
- if (cause)
- return gsm48_rr_tx_ass_fail(ms, cause, RSL_MT_DATA_REQ);
- }
- cause = gsm48_rr_render_ma(ms, cda, ma, &ma_len);
- if (cause)
- return gsm48_rr_tx_ass_fail(ms, cause, RSL_MT_DATA_REQ);
-
-#ifdef TEST_FREQUENCY_MOD
- LOGP(DRR, LOGL_INFO, " TESTING: frequency modify ASS.CMD\n");
- before_time = 1;
- memcpy(cdb, cda, sizeof(*cdb));
- cdb->h = 0;
- cdb->arfcn = 0;
-#endif
-
- /* schedule start of assignment */
- rr->modify_state = GSM48_RR_MOD_ASSIGN;
- if (!before_time && cda->start) {
- start_rr_t_starting(rr, start_mili / 1000, start_mili % 1000);
- /* when timer fires, start time is already elapsed */
- cda->start = 0;
-
- return 0;
- }
-
- /* if no starting time, start suspension of current link directly */
- LOGP(DRR, LOGL_INFO, "request suspension of data link\n");
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gsm48_send_rsl(ms, RSL_MT_SUSP_REQ, nmsg);
-
- return 0;
-}
-
-/* 9.1.16 sending HANDOVER COMPLETE */
-static int gsm48_rr_tx_hando_cpl(struct osmocom_ms *ms, uint8_t cause)
-{
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
- struct gsm48_ho_cpl *hc;
-
- LOGP(DRR, LOGL_INFO, "HANDOVER COMPLETE (cause #%d)\n", cause);
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
- hc = (struct gsm48_ho_cpl *) msgb_put(nmsg, sizeof(*hc));
-
- gh->proto_discr = GSM48_PDISC_RR;
- gh->msg_type = GSM48_MT_RR_HANDO_COMPL;
-
- /* RR_CAUSE */
- hc->rr_cause = cause;
-
- // FIXME: mobile observed time
-
- return gsm48_send_rsl(ms, RSL_MT_RES_REQ, nmsg);
-}
-
-/* 9.1.4 sending HANDOVER FAILURE */
-static int gsm48_rr_tx_hando_fail(struct osmocom_ms *ms, uint8_t cause,
- uint8_t rsl_prim)
-{
- struct msgb *nmsg;
- struct gsm48_hdr *gh;
- struct gsm48_ho_fail *hf;
-
- LOGP(DRR, LOGL_INFO, "HANDOVER FAILURE (cause #%d)\n", cause);
-
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gh = (struct gsm48_hdr *) msgb_put(nmsg, sizeof(*gh));
- hf = (struct gsm48_ho_fail *) msgb_put(nmsg, sizeof(*hf));
-
- gh->proto_discr = GSM48_PDISC_RR;
- gh->msg_type = GSM48_MT_RR_ASS_COMPL;
-
- /* RR_CAUSE */
- hf->rr_cause = cause;
-
- return gsm48_send_rsl(ms, rsl_prim, nmsg);
-}
-
-/* receiving HANDOVER COMMAND message (9.1.15) */
-static int gsm48_rr_rx_hando_cmd(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = cs->si;
- struct gsm48_hdr *gh = msgb_l3(msg);
- struct gsm48_ho_cmd *ho = (struct gsm48_ho_cmd *)gh->data;
- int payload_len = msgb_l3len(msg) - sizeof(*gh) - sizeof(*ho);
- struct tlv_parsed tp;
- struct gsm48_rr_cd *cda = &rr->cd_after;
- struct gsm48_rr_cd *cdb = &rr->cd_before;
- uint16_t arfcn;
- uint8_t bcc, ncc;
- uint8_t ch_type, ch_subch, ch_ts;
- uint8_t before_time = 0;
- uint16_t ma[64];
- uint8_t ma_len;
- uint32_t start_mili = 0;
- uint8_t cause;
- struct msgb *nmsg;
-
- LOGP(DRR, LOGL_INFO, "HANDOVER COMMAND\n");
-
- memset(cda, 0, sizeof(*cda));
- cda->ind_tx_power = rr->cd_now.ind_tx_power;
- memset(cdb, 0, sizeof(*cdb));
- cdb->ind_tx_power = rr->cd_now.ind_tx_power;
-
- if (payload_len < 0) {
- LOGP(DRR, LOGL_NOTICE, "Short read of HANDOVER COMMAND "
- "message.\n");
- return gsm48_rr_tx_rr_status(ms,
- GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
- }
-
- /* cell description */
- gsm48_decode_cell_desc(&ho->cell_desc, &arfcn, &ncc, &bcc);
-
- /* handover reference */
- rr->chan_req_val = ho->ho_ref;
- rr->chan_req_mask = 0x00;
-
- tlv_parse(&tp, &gsm48_rr_att_tlvdef, ho->data, payload_len, 0, 0);
-
- /* sync ind */
- if (TLVP_PRESENT(&tp, GSM48_IE_SYNC_IND)) {
- gsm48_decode_sync_ind(rr, (struct gsm48_sync_ind *)
- TLVP_VAL(&tp, GSM48_IE_SYNC_IND));
- LOGP(DRR, LOGL_INFO, " (sync_ind=%d rot=%d nci=%d)\n",
- rr->hando_sync_ind, rr->hando_rot, rr->hando_nci);
- }
-
- /* decode channel description (before time) */
- if (TLVP_PRESENT(&tp, GSM48_IE_CH_DESC_1_BEFORE)) {
- struct gsm48_chan_desc *ccd = (struct gsm48_chan_desc *)
- TLVP_VAL(&tp, GSM48_IE_CH_DESC_1_BEFORE);
- cdb->chan_nr = ccd->chan_nr;
- rsl_dec_chan_nr(cdb->chan_nr, &ch_type, &ch_subch, &ch_ts);
- if (ccd->h0.h) {
- cdb->h = 1;
- gsm48_decode_chan_h1(ccd, &cdb->tsc, &cdb->maio,
- &cdb->hsn);
- LOGP(DRR, LOGL_INFO, " before: (chan_nr 0x%02x MAIO %u "
- "HSN %u TS %u SS %u TSC %u)\n", ccd->chan_nr,
- cdb->maio, cdb->hsn, ch_ts, ch_subch, cdb->tsc);
- } else {
- cdb->h = 0;
- gsm48_decode_chan_h0(ccd, &cdb->tsc, &cdb->arfcn);
- if (gsm_refer_pcs(cs->arfcn, s))
- cdb->arfcn |= ARFCN_PCS;
- LOGP(DRR, LOGL_INFO, " before: (chan_nr 0x%02x "
- "ARFCN %s TS %u SS %u TSC %u)\n", ccd->chan_nr,
- gsm_print_arfcn(cdb->arfcn),
- ch_ts, ch_subch, cdb->tsc);
- }
- before_time = 1;
- }
-
- /* decode channel description (after time) */
- cda->chan_nr = ho->chan_desc.chan_nr;
- rsl_dec_chan_nr(cda->chan_nr, &ch_type, &ch_subch, &ch_ts);
- if (ho->chan_desc.h0.h) {
- cda->h = 1;
- gsm48_decode_chan_h1(&ho->chan_desc, &cda->tsc, &cda->maio,
- &cda->hsn);
- LOGP(DRR, LOGL_INFO, " after: (chan_nr 0x%02x MAIO %u HSN %u "
- "TS %u SS %u TSC %u)\n", ho->chan_desc.chan_nr,
- cda->maio, cda->hsn, ch_ts, ch_subch, cda->tsc);
- } else {
- cda->h = 0;
- gsm48_decode_chan_h0(&ho->chan_desc, &cda->tsc, &cda->arfcn);
- if (gsm_refer_pcs(cs->arfcn, s))
- cda->arfcn |= ARFCN_PCS;
- LOGP(DRR, LOGL_INFO, " after: (chan_nr 0x%02x ARFCN %s TS %u "
- "SS %u TSC %u)\n", ho->chan_desc.chan_nr,
- gsm_print_arfcn(cda->arfcn), ch_ts, ch_subch, cda->tsc);
- }
-
- /* starting time */
-#ifdef TEST_STARTING_TIMER
- cda->start = 1;
- cda->start_tm.fn = (ms->meas.last_fn + TEST_STARTING_TIMER) % 42432;
- LOGP(DRR, LOGL_INFO, " TESTING: starting time ahead\n");
-#else
- if (TLVP_PRESENT(&tp, GSM48_IE_START_TIME)) {
- gsm48_decode_start_time(cda, (struct gsm48_start_time *)
- TLVP_VAL(&tp, GSM48_IE_START_TIME));
- /* 9.1.2.5 "... before time IE is not present..." */
- if (!before_time) {
- LOGP(DRR, LOGL_INFO, " -> channel description after "
- "time only, but starting time\n");
- } else
- LOGP(DRR, LOGL_INFO, " -> channel description before "
- "and after time\n");
- } else {
- /* 9.1.2.5 "... IEs unnecessary in this message." */
- if (before_time) {
- before_time = 0;
- LOGP(DRR, LOGL_INFO, " -> channel description before "
- "time, but no starting time, ignoring!\n");
- }
- }
-#endif
-
- /* mobile allocation / frequency list after time */
- if (cda->h) {
- if (TLVP_PRESENT(&tp, GSM48_IE_MA_AFTER)) {
- const uint8_t *lv =
- TLVP_VAL(&tp, GSM48_IE_MA_AFTER) - 1;
-
- LOGP(DRR, LOGL_INFO, " after: hopping required and "
- "mobile allocation available\n");
- if (*lv + 1 > sizeof(cda->mob_alloc_lv)) {
- LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
- return -ENOMEM;
- }
- memcpy(cda->mob_alloc_lv, lv, *lv + 1);
- } else
- if (TLVP_PRESENT(&tp, GSM48_IE_FREQ_L_AFTER)) {
- const uint8_t *lv =
- TLVP_VAL(&tp, GSM48_IE_FREQ_L_AFTER) - 1;
-
- LOGP(DRR, LOGL_INFO, " after: hopping required and "
- "frequency list available\n");
- if (*lv + 1 > sizeof(cda->freq_list_lv)) {
- LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
- return -ENOMEM;
- }
- memcpy(cda->freq_list_lv, lv, *lv + 1);
- } else {
- LOGP(DRR, LOGL_NOTICE, " after: hopping required, but "
- "no mobile allocation / frequency list\n");
- }
- }
-
- /* mobile allocation / frequency list before time */
- if (cdb->h) {
- if (TLVP_PRESENT(&tp, GSM48_IE_MA_BEFORE)) {
- const uint8_t *lv =
- TLVP_VAL(&tp, GSM48_IE_MA_BEFORE) - 1;
-
- LOGP(DRR, LOGL_INFO, " before: hopping required and "
- "mobile allocation available\n");
- if (*lv + 1 > sizeof(cdb->mob_alloc_lv)) {
- LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
- return -ENOMEM;
- }
- memcpy(cdb->mob_alloc_lv, lv, *lv + 1);
- } else
- if (TLVP_PRESENT(&tp, GSM48_IE_FREQ_L_BEFORE)) {
- const uint8_t *lv =
- TLVP_VAL(&tp, GSM48_IE_FREQ_L_BEFORE) - 1;
-
- LOGP(DRR, LOGL_INFO, " before: hopping required and "
- "frequency list available\n");
- if (*lv + 1 > sizeof(cdb->freq_list_lv)) {
- LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
- return -ENOMEM;
- }
- memcpy(cdb->freq_list_lv, lv, *lv + 1);
- } else
- if (TLVP_PRESENT(&tp, GSM48_IE_F_CH_SEQ_BEFORE)) {
- const uint8_t *v =
- TLVP_VAL(&tp, GSM48_IE_F_CH_SEQ_BEFORE);
- uint8_t len = TLVP_LEN(&tp, GSM48_IE_F_CH_SEQ_BEFORE);
-
- LOGP(DRR, LOGL_INFO, " before: hopping required and "
- "frequency channel sequence available\n");
- if (len + 1 > sizeof(cdb->freq_seq_lv)) {
- LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
- return -ENOMEM;
- }
- cdb->freq_seq_lv[0] = len;
- memcpy(cdb->freq_seq_lv, v + 1, *v);
- } else
- if (cda->mob_alloc_lv[0]) {
- LOGP(DRR, LOGL_INFO, " before: hopping required and "
- "mobile allocation not available, using "
- "mobile allocation after time\n");
- memcpy(cdb->mob_alloc_lv, cda->mob_alloc_lv,
- sizeof(cdb->mob_alloc_lv));
- } else
- if (cda->freq_list_lv[0]) {
- LOGP(DRR, LOGL_INFO, " before: hopping required and "
- "frequency list not available, using "
- "frequency list after time\n");
- memcpy(cdb->freq_list_lv, cda->freq_list_lv,
- sizeof(cdb->freq_list_lv));
- } else {
- LOGP(DRR, LOGL_NOTICE, " before: hopping required, but "
- "no mobile allocation / frequency list\n");
- }
- }
-
- /* cell channel description */
- if (TLVP_PRESENT(&tp, GSM48_IE_CELL_CH_DESC)) {
- const uint8_t *v = TLVP_VAL(&tp, GSM48_IE_CELL_CH_DESC);
- uint8_t len = TLVP_LEN(&tp, GSM48_IE_CELL_CH_DESC);
-
- LOGP(DRR, LOGL_INFO, " both: using cell channel description "
- "in case of mobile allocation\n");
- if (len + 1 > sizeof(cdb->cell_desc_lv)) {
- LOGP(DRR, LOGL_ERROR, "Error: no LV space!\n");
- return -ENOMEM;
- }
- cdb->cell_desc_lv[0] = len;
- memcpy(cdb->cell_desc_lv + 1, v, len);
- cda->cell_desc_lv[0] = len;
- memcpy(cda->cell_desc_lv + 1, v, len);
- } else {
- /* keep old */
- memcpy(cdb->cell_desc_lv, rr->cd_now.cell_desc_lv,
- sizeof(cdb->cell_desc_lv));
- memcpy(cda->cell_desc_lv, rr->cd_now.cell_desc_lv,
- sizeof(cda->cell_desc_lv));
- }
-
- /* channel mode */
- if (TLVP_PRESENT(&tp, GSM48_IE_CHANMODE_1)) {
- cda->mode = cdb->mode = *TLVP_VAL(&tp, GSM48_IE_CHANMODE_1);
- LOGP(DRR, LOGL_INFO, " both: changing channel mode 0x%02x\n",
- cda->mode);
- } else
- cda->mode = cdb->mode = rr->cd_now.mode;
-
- /* cipher mode setting */
- if (TLVP_PRESENT(&tp, GSM48_IE_CIP_MODE_SET)) {
- cda->cipher = cdb->cipher =
- *TLVP_VAL(&tp, GSM48_IE_CIP_MODE_SET);
- LOGP(DRR, LOGL_INFO, " both: changing cipher mode 0x%02x\n",
- cda->cipher);
- } else
- cda->cipher = cdb->cipher = rr->cd_now.cipher;
-
- /* power command and TA (before and after time) */
- gsm48_decode_power_cmd_acc(
- (struct gsm48_power_cmd *) &ho->power_command,
- &cda->ind_tx_power, &rr->hando_act);
- cdb->ind_tx_power = cda->ind_tx_power;
- cda->ind_ta = cdb->ind_ta = rr->cd_now.ind_ta; /* same cell */
- LOGP(DRR, LOGL_INFO, " both: (tx_power %d TA %d access=%s)\n",
- cda->ind_tx_power, cda->ind_ta,
- (rr->hando_act) ? "optional" : "mandatory");
-
- /* check if we have to change channel at starting time */
- if (cda->start) {
- int32_t now, start, diff;
-
- /* how much time do we have left? */
- now = ms->meas.last_fn % 42432;
- start = cda->start_tm.fn % 42432;
- diff = start - now;
- if (diff < 0)
- diff += 42432;
- LOGP(DRR, LOGL_INFO, " after: (Tnow %d Tstart %d diff %d)\n",
- now, start, diff);
- start_mili = (uint32_t)diff * 19580 / 42432 * 10;
- if (diff >= 32024 || !start_mili) {
- LOGP(DRR, LOGL_INFO, " -> Start time already "
- "elapsed\n");
- before_time = 0;
- cda->start = 0;
- } else {
- LOGP(DRR, LOGL_INFO, " -> Start time is %d ms in the "
- "future\n", start_mili);
- }
- }
-
- /* check if channels are valid */
- if (before_time) {
- cause = gsm48_rr_render_ma(ms, cdb, ma, &ma_len);
- if (cause)
- return gsm48_rr_tx_hando_fail(ms, cause, RSL_MT_DATA_REQ);
- }
- cause = gsm48_rr_render_ma(ms, cda, ma, &ma_len);
- if (cause)
- return gsm48_rr_tx_hando_fail(ms, cause, RSL_MT_DATA_REQ);
-
-
-#if 0
- if (not supported) {
- LOGP(DRR, LOGL_NOTICE, "New channel is not supported.\n");
- return GSM48_RR_CAUSE_CHAN_MODE_UNACCEPT;
- }
-#endif
-
-#ifdef TEST_FREQUENCY_MOD
- LOGP(DRR, LOGL_INFO, " TESTING: frequency modify HANDO.CMD\n");
- before_time = 1;
- memcpy(cdb, cda, sizeof(*cdb));
- cdb->h = 0;
- cdb->arfcn = 0;
-#endif
-
- /* schedule start of handover */
- rr->modify_state = GSM48_RR_MOD_HANDO;
- if (!before_time && cda->start) {
- start_rr_t_starting(rr, start_mili / 1000, start_mili % 1000);
- /* when timer fires, start time is already elapsed */
- cda->start = 0;
-
- return 0;
- }
-
- /* if no starting time, start suspension of current link directly */
- LOGP(DRR, LOGL_INFO, "request suspension of data link\n");
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- gsm48_send_rsl(ms, RSL_MT_SUSP_REQ, nmsg);
-
- return 0;
-}
-
-/* send all queued messages down to layer 2 */
-static int gsm48_rr_dequeue_down(struct osmocom_ms *ms)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct msgb *msg;
-
- while((msg = msgb_dequeue(&rr->downqueue))) {
- LOGP(DRR, LOGL_INFO, "Sending queued message.\n");
- gsm48_send_rsl(ms, RSL_MT_DATA_REQ, msg);
- }
-
- return 0;
-}
-
-/* channel is resumed in dedicated mode */
-static int gsm48_rr_estab_cnf_dedicated(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
-
- LOGP(DRR, LOGL_INFO, "data link is resumed\n");
-
- /* transmit queued frames during ho / ass transition */
- gsm48_rr_dequeue_down(ms);
-
- rr->modify_state = GSM48_RR_MOD_NONE;
-
- return 0;
-}
-
-/* suspend confirm in dedicated mode */
-static int gsm48_rr_susp_cnf_dedicated(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
-
- if (rr->modify_state) {
- uint16_t ma[64];
- uint8_t ma_len;
-
- /* deactivating dedicated mode */
- LOGP(DRR, LOGL_INFO, "suspension coplete, leaving dedicated "
- "mode\n");
- l1ctl_tx_dm_rel_req(ms);
- ms->meas.rl_fail = 0;
- rr->dm_est = 0;
- l1ctl_tx_reset_req(ms, L1CTL_RES_T_SCHED);
-
- /* store current channel descriptions */
- memcpy(&rr->cd_last, &rr->cd_now, sizeof(rr->cd_last));
-
- /* copy channel description "after time" */
- memcpy(&rr->cd_now, &rr->cd_after, sizeof(rr->cd_now));
-
- if (rr->cd_after.start) {
- /* render channel "before time" */
- gsm48_rr_render_ma(ms, &rr->cd_before, ma, &ma_len);
-
- /* activate channel */
- gsm48_rr_activate_channel(ms, &rr->cd_before, ma,
- ma_len);
-
- /* render channel "after time" */
- gsm48_rr_render_ma(ms, &rr->cd_now, ma, &ma_len);
-
- /* schedule change of channel */
- gsm48_rr_channel_after_time(ms, &rr->cd_now, ma, ma_len,
- rr->cd_now.start_tm.fn);
- } else {
- /* render channel "after time" */
- gsm48_rr_render_ma(ms, &rr->cd_now, ma, &ma_len);
-
- /* activate channel */
- gsm48_rr_activate_channel(ms, &rr->cd_now, ma, ma_len);
- }
-
- /* send DL-RESUME REQUEST */
- LOGP(DRR, LOGL_INFO, "request resume of data link\n");
- switch (rr->modify_state) {
- case GSM48_RR_MOD_ASSIGN:
- gsm48_rr_tx_ass_cpl(ms, GSM48_RR_CAUSE_NORMAL);
- break;
- case GSM48_RR_MOD_HANDO:
- gsm48_rr_tx_hando_cpl(ms, GSM48_RR_CAUSE_NORMAL);
- break;
- }
-
-#ifdef TODO
- /* trigger RACH */
- if (rr->modify_state == GSM48_RR_MOD_HANDO) {
- gsm48_rr_tx_hando_access(ms);
- rr->hando_acc_left = 3;
- }
-#endif
- }
- return 0;
-}
-
-/*
- * radio ressource requests
- */
-
-/* establish request for dedicated mode */
-static int gsm48_rr_est_req(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct gsm48_sysinfo *s = &cs->sel_si;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *) msg->data;
- struct gsm48_hdr *gh = msgb_l3(msg);
- uint8_t cause;
- struct msgb *nmsg;
- struct gsm48_rr_hdr *nrrh;
- uint16_t acc_class;
-
- /* 3.3.1.1.3.2 */
- if (osmo_timer_pending(&rr->t3122)) {
- if (rrh->cause != RR_EST_CAUSE_EMERGENCY) {
- LOGP(DRR, LOGL_INFO, "T3122 running, rejecting!\n");
- cause = RR_REL_CAUSE_T3122;
- reject:
- LOGP(DSUM, LOGL_INFO, "Establishing radio link not "
- "possible\n");
- nmsg = gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
- if (!nmsg)
- return -ENOMEM;
- nrrh = (struct gsm48_rr_hdr *)nmsg->data;
- nrrh->cause = cause;
- return gsm48_rr_upmsg(ms, nmsg);
- }
- LOGP(DRR, LOGL_INFO, "T3122 running, but emergency call\n");
- stop_rr_t3122(rr);
- }
-
- /* if state is not idle */
- if (rr->state != GSM48_RR_ST_IDLE) {
- LOGP(DRR, LOGL_INFO, "We are not IDLE yet, rejecting!\n");
- cause = RR_REL_CAUSE_TRY_LATER;
- goto reject;
- }
-
- /* cell selected */
- if (!cs->selected) {
- LOGP(DRR, LOGL_INFO, "No cell selected, rejecting!\n");
- cause = RR_REL_CAUSE_TRY_LATER;
- goto reject;
- }
-
- /* check if camping */
- if (cs->state != GSM322_C3_CAMPED_NORMALLY
- && rrh->cause != RR_EST_CAUSE_EMERGENCY) {
- LOGP(DRR, LOGL_INFO, "Not camping normally, rejecting! "
- "(cs->state = %d)\n", cs->state);
- cause = RR_REL_CAUSE_EMERGENCY_ONLY;
- goto reject;
- }
- if (cs->state != GSM322_C3_CAMPED_NORMALLY
- && cs->state != GSM322_C7_CAMPED_ANY_CELL) {
- LOGP(DRR, LOGL_INFO, "Not camping, rejecting! "
- "(cs->state = %d)\n", cs->state);
- cause = RR_REL_CAUSE_TRY_LATER;
- goto reject;
- }
-
- /* check for relevant informations */
- if (!s->si3) {
- LOGP(DRR, LOGL_INFO, "Not enough SI, rejecting!\n");
- cause = RR_REL_CAUSE_TRY_LATER;
- goto reject;
- }
-
- /* 3.3.1.1.1 */
- if (!subscr->acc_barr && s->cell_barr) {
- LOGP(DRR, LOGL_INFO, "Cell barred, rejecting!\n");
- cause = RR_REL_CAUSE_NOT_AUTHORIZED;
- goto reject;
- }
- if (rrh->cause == RR_EST_CAUSE_EMERGENCY)
- acc_class = subscr->acc_class | 0x0400;
- else
- acc_class = subscr->acc_class & 0xfbff;
- if (!subscr->acc_barr && !(acc_class & (s->class_barr ^ 0xffff))) {
- LOGP(DRR, LOGL_INFO, "Cell barred for our access class (access "
- "%04x barred %04x)!\n", acc_class, s->class_barr);
- cause = RR_REL_CAUSE_NOT_AUTHORIZED;
- goto reject;
- }
-
- /* requested by RR */
- rr->rr_est_req = 1;
-
- /* clone and store REQUEST message */
- if (!gh) {
- LOGP(DRR, LOGL_ERROR, "Error, missing l3 message\n");
- return -EINVAL;
- }
- rr->rr_est_msg = gsm48_l3_msgb_alloc();
- if (!rr->rr_est_msg)
- return -ENOMEM;
- memcpy(msgb_put(rr->rr_est_msg, msgb_l3len(msg)),
- msgb_l3(msg), msgb_l3len(msg));
-
- /* request channel */
- return gsm48_rr_chan_req(ms, rrh->cause, 0);
-}
-
-/* 3.4.2 transfer data in dedicated mode */
-static int gsm48_rr_data_req(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
-
- if (rr->state != GSM48_RR_ST_DEDICATED) {
- msgb_free(msg);
- return -EINVAL;
- }
-
- /* pull RR header */
- msgb_pull(msg, sizeof(struct gsm48_rr_hdr));
-
- /* set sequence number and increment */
- gsm48_apply_v_sd(rr, msg);
-
- /* queue message, during handover or assignment procedure */
- if (rr->modify_state == GSM48_RR_MOD_ASSIGN
- || rr->modify_state == GSM48_RR_MOD_HANDO) {
- LOGP(DRR, LOGL_INFO, "Queueing message during suspend.\n");
- msgb_enqueue(&rr->downqueue, msg);
- return 0;
- }
-
- /* forward message */
- return gsm48_send_rsl(ms, RSL_MT_DATA_REQ, msg);
-}
-
-/*
- * data indications from data link
- */
-
-/* 3.4.2 data from layer 2 to RR and upper layer*/
-static int gsm48_rr_data_ind(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_hdr *gh = msgb_l3(msg);
- struct gsm48_rr_hdr *rrh;
- uint8_t pdisc = gh->proto_discr & 0x0f;
-
- if (pdisc == GSM48_PDISC_RR) {
- int rc = -EINVAL;
- uint8_t skip_ind = (gh->proto_discr & 0xf0) >> 4;
-
- /* ignore if skip indicator is not B'0000' */
- if (skip_ind)
- return 0;
-
- switch(gh->msg_type) {
- case GSM48_MT_RR_ADD_ASS:
- rc = gsm48_rr_rx_add_ass(ms, msg);
- break;
- case GSM48_MT_RR_ASS_CMD:
- rc = gsm48_rr_rx_ass_cmd(ms, msg);
- break;
- case GSM48_MT_RR_CIPH_M_CMD:
- rc = gsm48_rr_rx_cip_mode_cmd(ms, msg);
- break;
- case GSM48_MT_RR_CLSM_ENQ:
- rc = gsm48_rr_rx_cm_enq(ms, msg);
- break;
- case GSM48_MT_RR_CHAN_MODE_MODIF:
- rc = gsm48_rr_rx_chan_modify(ms, msg);
- break;
- case GSM48_MT_RR_HANDO_CMD:
- rc = gsm48_rr_rx_hando_cmd(ms, msg);
- break;
- case GSM48_MT_RR_FREQ_REDEF:
- rc = gsm48_rr_rx_frq_redef(ms, msg);
- break;
- case GSM48_MT_RR_CHAN_REL:
- rc = gsm48_rr_rx_chan_rel(ms, msg);
- break;
- case GSM48_MT_RR_APP_INFO:
- LOGP(DRR, LOGL_NOTICE, "APP INFO not supported!\n");
- break;
- default:
- LOGP(DRR, LOGL_NOTICE, "Message type 0x%02x unknown.\n",
- gh->msg_type);
-
- /* status message */
- gsm48_rr_tx_rr_status(ms, GSM48_RR_CAUSE_MSG_TYPE_N);
- }
-
- msgb_free(msg);
- return rc;
- }
-
- /* pull off RSL header up to L3 message */
- msgb_pull(msg, (long)msgb_l3(msg) - (long)msg->data);
-
- /* push RR header */
- msgb_push(msg, sizeof(struct gsm48_rr_hdr));
- rrh = (struct gsm48_rr_hdr *)msg->data;
- rrh->msg_type = GSM48_RR_DATA_IND;
-
- return gsm48_rr_upmsg(ms, msg);
-}
-
-/* receive BCCH at RR layer */
-static int gsm48_rr_rx_bcch(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_system_information_type_header *sih = msgb_l3(msg);
-
- switch (sih->system_information) {
- case GSM48_MT_RR_SYSINFO_1:
- return gsm48_rr_rx_sysinfo1(ms, msg);
- case GSM48_MT_RR_SYSINFO_2:
- return gsm48_rr_rx_sysinfo2(ms, msg);
- case GSM48_MT_RR_SYSINFO_2bis:
- return gsm48_rr_rx_sysinfo2bis(ms, msg);
- case GSM48_MT_RR_SYSINFO_2ter:
- return gsm48_rr_rx_sysinfo2ter(ms, msg);
- case GSM48_MT_RR_SYSINFO_3:
- return gsm48_rr_rx_sysinfo3(ms, msg);
- case GSM48_MT_RR_SYSINFO_4:
- return gsm48_rr_rx_sysinfo4(ms, msg);
- default:
-#if 0
- LOGP(DRR, LOGL_NOTICE, "BCCH message type 0x%02x not sup.\n",
- sih->system_information);
-#endif
- return -EINVAL;
- }
-}
-
-/* receive CCCH at RR layer */
-static int gsm48_rr_rx_pch_agch(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_system_information_type_header *sih = msgb_l3(msg);
-
- switch (sih->system_information) {
- case GSM48_MT_RR_PAG_REQ_1:
- return gsm48_rr_rx_pag_req_1(ms, msg);
- case GSM48_MT_RR_PAG_REQ_2:
- return gsm48_rr_rx_pag_req_2(ms, msg);
- case GSM48_MT_RR_PAG_REQ_3:
- return gsm48_rr_rx_pag_req_3(ms, msg);
-
- case GSM48_MT_RR_IMM_ASS:
- return gsm48_rr_rx_imm_ass(ms, msg);
- case GSM48_MT_RR_IMM_ASS_EXT:
- return gsm48_rr_rx_imm_ass_ext(ms, msg);
- case GSM48_MT_RR_IMM_ASS_REJ:
- return gsm48_rr_rx_imm_ass_rej(ms, msg);
- default:
-#if 0
- LOGP(DRR, LOGL_NOTICE, "CCCH message type 0x%02x unknown.\n",
- sih->system_information);
-#endif
- return -EINVAL;
- }
-}
-
-/* receive ACCH at RR layer */
-static int gsm48_rr_rx_acch(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm_settings *set = &ms->settings;
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- struct gsm48_system_information_type_header *sih = msgb_l3(msg);
- uint8_t ind_ta, ind_tx_power;
-
- if (msgb_l2len(msg) < sizeof(*rllh) + 2 + 2) {
- LOGP(DRR, LOGL_ERROR, "Missing TA and TX_POWER IEs\n");
- return -EINVAL;
- }
-
- ind_ta = rllh->data[1];
- ind_tx_power = rllh->data[3];
- LOGP(DRR, LOGL_INFO, "Indicated ta %d (actual ta %d)\n",
- ind_ta, ind_ta - set->alter_delay);
- LOGP(DRR, LOGL_INFO, "Indicated tx_power %d\n",
- ind_tx_power);
- if (ind_ta != rr->cd_now.ind_ta
- || ind_tx_power != rr->cd_now.ind_tx_power) {
- LOGP(DRR, LOGL_INFO, "setting new ta and tx_power\n");
- l1ctl_tx_param_req(ms, ind_ta - set->alter_delay,
- (set->alter_tx_power) ? set->alter_tx_power_value
- : ind_tx_power);
- rr->cd_now.ind_ta = ind_ta;
- rr->cd_now.ind_tx_power = ind_tx_power;
- }
-
- switch (sih->system_information) {
- case GSM48_MT_RR_SYSINFO_5:
- return gsm48_rr_rx_sysinfo5(ms, msg);
- case GSM48_MT_RR_SYSINFO_5bis:
- return gsm48_rr_rx_sysinfo5bis(ms, msg);
- case GSM48_MT_RR_SYSINFO_5ter:
- return gsm48_rr_rx_sysinfo5ter(ms, msg);
- case GSM48_MT_RR_SYSINFO_6:
- return gsm48_rr_rx_sysinfo6(ms, msg);
- default:
- LOGP(DRR, LOGL_NOTICE, "ACCH message type 0x%02x unknown.\n",
- sih->system_information);
- return -EINVAL;
- }
-}
-
-/* unit data from layer 2 to RR layer */
-static int gsm48_rr_unit_data_ind(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm322_cellsel *cs = &ms->cellsel;
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- struct tlv_parsed tv;
- uint8_t ch_type, ch_subch, ch_ts;
-
- DEBUGP(DRSL, "RSLms UNIT DATA IND chan_nr=0x%02x link_id=0x%02x\n",
- rllh->chan_nr, rllh->link_id);
-
- rsl_tlv_parse(&tv, rllh->data, msgb_l2len(msg)-sizeof(*rllh));
- if (!TLVP_PRESENT(&tv, RSL_IE_L3_INFO)) {
- DEBUGP(DRSL, "UNIT_DATA_IND without L3 INFO ?!?\n");
- return -EIO;
- }
- msg->l3h = (uint8_t *) TLVP_VAL(&tv, RSL_IE_L3_INFO);
-
- if (cs->ccch_state != GSM322_CCCH_ST_SYNC
- && cs->ccch_state != GSM322_CCCH_ST_DATA)
- return -EINVAL;
-
- /* temporary moved here until confirm is fixed */
- if (cs->ccch_state != GSM322_CCCH_ST_DATA) {
- LOGP(DCS, LOGL_INFO, "Channel provides data.\n");
- cs->ccch_state = GSM322_CCCH_ST_DATA;
-
- /* in dedicated mode */
- if (ms->rrlayer.state == GSM48_RR_ST_CONN_PEND)
- return gsm48_rr_tx_rand_acc(ms, NULL);
-
- /* set timer for reading BCCH */
- if (cs->state == GSM322_C2_STORED_CELL_SEL
- || cs->state == GSM322_C1_NORMAL_CELL_SEL
- || cs->state == GSM322_C6_ANY_CELL_SEL
- || cs->state == GSM322_C4_NORMAL_CELL_RESEL
- || cs->state == GSM322_C8_ANY_CELL_RESEL
- || cs->state == GSM322_C5_CHOOSE_CELL
- || cs->state == GSM322_C9_CHOOSE_ANY_CELL
- || cs->state == GSM322_PLMN_SEARCH
- || cs->state == GSM322_HPLMN_SEARCH)
- start_cs_timer(cs, ms->support.scan_to, 0);
- // TODO: timer depends on BCCH config
- }
-
- rsl_dec_chan_nr(rllh->chan_nr, &ch_type, &ch_subch, &ch_ts);
- switch (ch_type) {
- case RSL_CHAN_PCH_AGCH:
- return gsm48_rr_rx_pch_agch(ms, msg);
- case RSL_CHAN_BCCH:
- return gsm48_rr_rx_bcch(ms, msg);
- case RSL_CHAN_Bm_ACCHs:
- case RSL_CHAN_Lm_ACCHs:
- case RSL_CHAN_SDCCH4_ACCH:
- case RSL_CHAN_SDCCH8_ACCH:
- return gsm48_rr_rx_acch(ms, msg);
- default:
- LOGP(DRSL, LOGL_NOTICE, "RSL with chan_nr 0x%02x unknown.\n",
- rllh->chan_nr);
- return -EINVAL;
- }
-}
-
-/* 3.4.13.3 RR abort in dedicated mode (also in conn. pending mode) */
-static int gsm48_rr_abort_req(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- uint8_t *mode;
-
- /* stop pending RACH timer */
- stop_rr_t3126(rr);
-
- /* release "normally" if we are in dedicated mode */
- if (rr->state == GSM48_RR_ST_DEDICATED) {
- struct msgb *nmsg;
-
- LOGP(DRR, LOGL_INFO, "Abort in dedicated state, send release "
- "to layer 2.\n");
-
- new_rr_state(rr, GSM48_RR_ST_REL_PEND);
-
- /* release message */
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- mode = msgb_put(nmsg, 2);
- mode[0] = RSL_IE_RELEASE_MODE;
- mode[1] = 0; /* normal release */
- return gsm48_send_rsl_rel(ms, RSL_MT_REL_REQ, nmsg);
- }
-
- LOGP(DRR, LOGL_INFO, "Abort in connection pending state, return to "
- "idle state.\n");
- /* return idle */
- new_rr_state(rr, GSM48_RR_ST_IDLE);
-
- return 0;
-}
-
-/* release confirm */
-static int gsm48_rr_rel_cnf(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct msgb *nmsg;
- struct gsm48_rr_hdr *nrrh;
- uint8_t cause = RR_REL_CAUSE_NORMAL;
- uint16_t ma[64];
- uint8_t ma_len;
-
- /* switch back to old channel, if modify/ho failed */
- switch (rr->modify_state) {
- case GSM48_RR_MOD_ASSIGN:
- case GSM48_RR_MOD_HANDO:
- /* deactivate channel */
- l1ctl_tx_dm_rel_req(ms);
- ms->meas.rl_fail = 0;
- rr->dm_est = 0;
- l1ctl_tx_reset_req(ms, L1CTL_RES_T_SCHED);
-
- /* get old channel description */
- memcpy(&rr->cd_now, &rr->cd_last, sizeof(rr->cd_now));
-
- /* render and change radio to old channel */
- gsm48_rr_render_ma(ms, &rr->cd_now, ma, &ma_len);
- gsm48_rr_activate_channel(ms, &rr->cd_now, ma, ma_len);
-
- /* re-establish old link */
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- if (rr->modify_state == GSM48_RR_MOD_ASSIGN) {
- rr->modify_state = GSM48_RR_MOD_ASSIGN_RESUME;
- return gsm48_rr_tx_ass_fail(ms,
- GSM48_RR_CAUSE_ABNORMAL_UNSPEC,
- RSL_MT_RECON_REQ);
- } else {
- rr->modify_state = GSM48_RR_MOD_HANDO_RESUME;
- return gsm48_rr_tx_hando_fail(ms,
- GSM48_RR_CAUSE_ABNORMAL_UNSPEC,
- RSL_MT_RECON_REQ);
- }
- /* returns above */
- case GSM48_RR_MOD_ASSIGN_RESUME:
- case GSM48_RR_MOD_HANDO_RESUME:
- rr->modify_state = GSM48_RR_MOD_NONE;
- cause = RR_REL_CAUSE_LINK_FAILURE;
- break;
- }
-
- LOGP(DSUM, LOGL_INFO, "Requested channel aborted\n");
-
- /* stop T3211 if running */
- stop_rr_t3110(rr);
-
- /* send release indication */
- nmsg = gsm48_rr_msgb_alloc(GSM48_RR_REL_IND);
- if (!nmsg)
- return -ENOMEM;
- nrrh = (struct gsm48_rr_hdr *)nmsg->data;
- nrrh->cause = cause;
- gsm48_rr_upmsg(ms, nmsg);
-
- /* return idle */
- new_rr_state(rr, GSM48_RR_ST_IDLE);
- return 0;
-}
-
-/* MDL-ERROR */
-static int gsm48_rr_mdl_error_ind(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- struct msgb *nmsg;
- struct gsm48_rr_hdr *nrrh;
- uint8_t *mode;
- uint8_t cause = rllh->data[2];
-
- switch (cause) {
- case RLL_CAUSE_SEQ_ERR:
- case RLL_CAUSE_UNSOL_DM_RESP_MF:
- break;
- default:
- LOGP(DRR, LOGL_NOTICE, "MDL-Error (cause %d) ignoring\n",
- cause);
- }
-
- LOGP(DRR, LOGL_NOTICE, "MDL-Error (cause %d) aborting\n", cause);
-
- /* disconnect the main signalling link */
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- mode = msgb_put(nmsg, 2);
- mode[0] = RSL_IE_RELEASE_MODE;
- mode[1] = 1; /* local release */
- gsm48_send_rsl_rel(ms, RSL_MT_REL_REQ, nmsg);
-
- /* in case of modify/hando: wait for confirm */
- if (rr->modify_state)
- return 0;
-
- /* send abort ind to upper layer */
- nmsg = gsm48_rr_msgb_alloc(GSM48_RR_ABORT_IND);
- if (!nmsg)
- return -ENOMEM;
- nrrh = (struct gsm48_rr_hdr *)nmsg->data;
- nrrh->cause = RR_REL_CAUSE_LINK_FAILURE;
- gsm48_rr_upmsg(ms, nmsg);
-
- /* return idle */
- new_rr_state(rr, GSM48_RR_ST_IDLE);
- return 0;
-}
-
-/*
- * state machines
- */
-
-/* state trasitions for link layer messages (lower layer) */
-static struct dldatastate {
- uint32_t states;
- int type;
- int (*rout) (struct osmocom_ms *ms, struct msgb *msg);
-} dldatastatelist[] = {
- /* data transfer */
- {SBIT(GSM48_RR_ST_IDLE) |
- SBIT(GSM48_RR_ST_CONN_PEND) |
- SBIT(GSM48_RR_ST_DEDICATED) |
- SBIT(GSM48_RR_ST_REL_PEND),
- RSL_MT_UNIT_DATA_IND, gsm48_rr_unit_data_ind},
-
- {SBIT(GSM48_RR_ST_DEDICATED), /* 3.4.2 */
- RSL_MT_DATA_IND, gsm48_rr_data_ind},
-
- /* esablish */
- {SBIT(GSM48_RR_ST_IDLE) |
- SBIT(GSM48_RR_ST_CONN_PEND) |
- SBIT(GSM48_RR_ST_REL_PEND),
- RSL_MT_EST_CONF, gsm48_rr_estab_cnf},
-
- /* resume */
- {SBIT(GSM48_RR_ST_DEDICATED),
- RSL_MT_EST_CONF, gsm48_rr_estab_cnf_dedicated},
-
- /* release */
- {SBIT(GSM48_RR_ST_CONN_PEND) |
- SBIT(GSM48_RR_ST_DEDICATED),
- RSL_MT_REL_IND, gsm48_rr_rel_ind},
-
- {SBIT(GSM48_RR_ST_REL_PEND),
- RSL_MT_REL_CONF, gsm48_rr_rel_cnf},
-
- /* reconnect */
- {SBIT(GSM48_RR_ST_CONN_PEND) |
- SBIT(GSM48_RR_ST_DEDICATED),
- RSL_MT_REL_CONF, gsm48_rr_rel_cnf},
-
- /* suspenion */
- {SBIT(GSM48_RR_ST_DEDICATED),
- RSL_MT_SUSP_CONF, gsm48_rr_susp_cnf_dedicated},
-
-#if 0
- {SBIT(GSM48_RR_ST_DEDICATED),
- RSL_MT_CHAN_CNF, gsm48_rr_rand_acc_cnf_dedicated},
-#endif
-
- {SBIT(GSM48_RR_ST_DEDICATED),
- RSL_MT_ERROR_IND, gsm48_rr_mdl_error_ind},
-};
-
-#define DLDATASLLEN \
- (sizeof(dldatastatelist) / sizeof(struct dldatastate))
-
-static int gsm48_rcv_rll(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct abis_rsl_rll_hdr *rllh = msgb_l2(msg);
- int msg_type = rllh->c.msg_type;
- int i;
- int rc;
-
- if (msg_type != RSL_MT_UNIT_DATA_IND) {
- LOGP(DRSL, LOGL_INFO, "(ms %s) Received '%s' from L2 in state "
- "%s\n", ms->name, rsl_msg_name(msg_type),
- gsm48_rr_state_names[rr->state]);
- }
-
- /* find function for current state and message */
- for (i = 0; i < DLDATASLLEN; i++)
- if ((msg_type == dldatastatelist[i].type)
- && ((1 << rr->state) & dldatastatelist[i].states))
- break;
- if (i == DLDATASLLEN) {
- LOGP(DRSL, LOGL_NOTICE, "RSLms message unhandled\n");
- msgb_free(msg);
- return 0;
- }
-
- rc = dldatastatelist[i].rout(ms, msg);
-
- /* free msgb unless it is forwarded */
- if (dldatastatelist[i].rout != gsm48_rr_data_ind)
- msgb_free(msg);
-
- return rc;
-}
-
-static int gsm48_rcv_cch(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct abis_rsl_cchan_hdr *ch = msgb_l2(msg);
- int msg_type = ch->c.msg_type;
- int rc;
-
- LOGP(DRSL, LOGL_INFO, "(ms %s) Received '%s' from L2 in state "
- "%s\n", ms->name, rsl_msg_name(msg_type),
- gsm48_rr_state_names[rr->state]);
-
- if (rr->state == GSM48_RR_ST_CONN_PEND
- && msg_type == RSL_MT_CHAN_CONF) {
- rc = gsm48_rr_tx_rand_acc(ms, msg);
- msgb_free(msg);
- return rc;
- }
-
- LOGP(DRSL, LOGL_NOTICE, "RSLms message unhandled\n");
- msgb_free(msg);
- return 0;
-}
-
-
-/* input function for L2 messags up to L3 */
-static int gsm48_rcv_rsl(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct abis_rsl_common_hdr *rslh = msgb_l2(msg);
- int rc = 0;
-
- switch (rslh->msg_discr & 0xfe) {
- case ABIS_RSL_MDISC_RLL:
- rc = gsm48_rcv_rll(ms, msg);
- break;
- case ABIS_RSL_MDISC_COM_CHAN:
- rc = gsm48_rcv_cch(ms, msg);
- break;
- default:
- /* FIXME: implement this */
- LOGP(DRSL, LOGL_NOTICE, "unknown RSLms msg_discr 0x%02x\n",
- rslh->msg_discr);
- msgb_free(msg);
- rc = -EINVAL;
- break;
- }
-
- return rc;
-}
-
-/* state trasitions for RR-SAP messages from up */
-static struct rrdownstate {
- uint32_t states;
- int type;
- int (*rout) (struct osmocom_ms *ms, struct msgb *msg);
-} rrdownstatelist[] = {
- /* NOTE: If not IDLE, it is rejected there. */
- {ALL_STATES, /* 3.3.1.1 */
- GSM48_RR_EST_REQ, gsm48_rr_est_req},
-
- {SBIT(GSM48_RR_ST_DEDICATED), /* 3.4.2 */
- GSM48_RR_DATA_REQ, gsm48_rr_data_req},
-
- {SBIT(GSM48_RR_ST_CONN_PEND) |
- SBIT(GSM48_RR_ST_DEDICATED), /* 3.4.13.3 */
- GSM48_RR_ABORT_REQ, gsm48_rr_abort_req},
-};
-
-#define RRDOWNSLLEN \
- (sizeof(rrdownstatelist) / sizeof(struct rrdownstate))
-
-int gsm48_rr_downmsg(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct gsm48_rr_hdr *rrh = (struct gsm48_rr_hdr *) msg->data;
- int msg_type = rrh->msg_type;
- int i;
- int rc;
-
- LOGP(DRR, LOGL_INFO, "(ms %s) Message '%s' received in state %s\n",
- ms->name, get_rr_name(msg_type),
- gsm48_rr_state_names[rr->state]);
-
- /* find function for current state and message */
- for (i = 0; i < RRDOWNSLLEN; i++)
- if ((msg_type == rrdownstatelist[i].type)
- && ((1 << rr->state) & rrdownstatelist[i].states))
- break;
- if (i == RRDOWNSLLEN) {
- LOGP(DRR, LOGL_NOTICE, "Message unhandled at this state.\n");
- msgb_free(msg);
- return 0;
- }
-
- rc = rrdownstatelist[i].rout(ms, msg);
-
- /* free msgb uless it is forwarded */
- if (rrdownstatelist[i].rout != gsm48_rr_data_req)
- msgb_free(msg);
-
- return rc;
-}
-
-/*
- * init/exit
- */
-
-int gsm48_rr_init(struct osmocom_ms *ms)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
-
- memset(rr, 0, sizeof(*rr));
- rr->ms = ms;
-
- LOGP(DRR, LOGL_INFO, "init Radio Ressource process\n");
-
- INIT_LLIST_HEAD(&rr->rsl_upqueue);
- INIT_LLIST_HEAD(&rr->downqueue);
- /* downqueue is handled here, so don't add_work */
-
- lapdm_channel_set_l3(&ms->lapdm_channel, &rcv_rsl, ms);
-
- start_rr_t_meas(rr, 1, 0);
-
- rr->audio_mode = AUDIO_TX_MICROPHONE | AUDIO_RX_SPEAKER;
-
- return 0;
-}
-
-int gsm48_rr_exit(struct osmocom_ms *ms)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct msgb *msg;
-
- LOGP(DRR, LOGL_INFO, "exit Radio Ressource process\n");
-
- /* flush queues */
- while ((msg = msgb_dequeue(&rr->rsl_upqueue)))
- msgb_free(msg);
- while ((msg = msgb_dequeue(&rr->downqueue)))
- msgb_free(msg);
-
- if (rr->rr_est_msg) {
- msgb_free(rr->rr_est_msg);
- rr->rr_est_msg = NULL;
- }
-
- stop_rr_t_meas(rr);
- stop_rr_t_starting(rr);
- stop_rr_t_rel_wait(rr);
- stop_rr_t3110(rr);
- stop_rr_t3122(rr);
- stop_rr_t3124(rr);
- stop_rr_t3126(rr);
-
- return 0;
-}
-
-#if 0
-
-todo rr_sync_ind when receiving ciph, re ass, channel mode modify
-
-
-static void timeout_rr_t3124(void *arg)
-{
- struct gsm48_rrlayer *rr = arg;
- struct msgb *nmsg;
-
- /* stop sending more access bursts when timer expired */
- hando_acc_left = 0;
-
- /* get old channel description */
- memcpy(&rr->chan_desc, &rr->chan_last, sizeof(rr->chan_desc));
-
- /* change radio to old channel */
- tx_ph_dm_est_req(ms, rr->cd_now.arfcn, rr->cd_now.chan_nr,
- rr->cd_now.tsc);
- rr->dm_est = 1;
-
- /* re-establish old link */
- nmsg = gsm48_l3_msgb_alloc();
- if (!nmsg)
- return -ENOMEM;
- return gsm48_send_rsl(ms, RSL_MT_REEST_REQ, nmsg);
-
- todo
-}
-
-/* send HANDOVER ACCESS burst (9.1.14) */
-static int gsm48_rr_tx_hando_access(struct osmocom_ms *ms)
-{
- nmsg = msgb_alloc_headroom(20, 16, "HAND_ACCESS");
- if (!nmsg)
- return -ENOMEM;
- *msgb_put(nmsg, 1) = rr->hando_ref;
- todo burst
- return gsm48_send_rsl(ms, RSL_MT_RAND_ACC_REQ, nmsg);
-}
-
-/* send next channel request in dedicated state */
-static int gsm48_rr_rand_acc_cnf_dedicated(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- struct msgb *nmsg;
- int s;
-
- if (rr->modify_state != GSM48_RR_MOD_HANDO) {
- LOGP(DRR, LOGL_NOTICE, "Random acces confirm, but not in handover state.\n");
- return 0;
- }
-
- /* send up to four handover access bursts */
- if (rr->hando_acc_left) {
- rr->hando_acc_left--;
- gsm48_rr_tx_hando_access(ms);
- return;
- }
-
- /* start timer for sending next HANDOVER ACCESS bursts afterwards */
- if (!osmo_timer_pending(&rr->t3124)) {
- if (allocated channel is SDCCH)
- start_rr_t3124(rr, GSM_T3124_675);
- else
- start_rr_t3124(rr, GSM_T3124_320);
- }
- if (!rr->n_chan_req) {
- start_rr_t3126(rr, 5, 0); /* TODO improve! */
- return 0;
- }
- rr->n_chan_req--;
-
- /* wait for PHYSICAL INFORMATION message or T3124 timeout */
- return 0;
-
-}
-
-#endif
-
-int gsm48_rr_tx_voice(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- uint8_t ch_type, ch_subch, ch_ts;
-
- if (!rr->dm_est) {
- LOGP(DRR, LOGL_INFO, "Current channel is not active\n");
- msgb_free(msg);
- return -ENOTSUP;
- }
-
- rsl_dec_chan_nr(rr->cd_now.chan_nr, &ch_type, &ch_subch, &ch_ts);
- if (ch_type != RSL_CHAN_Bm_ACCHs) {
- LOGP(DRR, LOGL_INFO, "Current channel is not (yet) TCH/F\n");
- msgb_free(msg);
- return -ENOTSUP;
- }
-
- return l1ctl_tx_traffic_req(ms, msg, rr->cd_now.chan_nr,
- rr->cd_now.link_id);
-}
-
-int gsm48_rr_audio_mode(struct osmocom_ms *ms, uint8_t mode)
-{
- struct gsm48_rrlayer *rr = &ms->rrlayer;
- uint8_t ch_type, ch_subch, ch_ts;
-
- LOGP(DRR, LOGL_INFO, "setting audio mode to %d\n", mode);
-
- rr->audio_mode = mode;
-
- if (!rr->dm_est)
- return 0;
-
- rsl_dec_chan_nr(rr->cd_now.chan_nr, &ch_type, &ch_subch, &ch_ts);
- if (ch_type != RSL_CHAN_Bm_ACCHs
- && ch_type != RSL_CHAN_Lm_ACCHs)
- return 0;
-
- return l1ctl_tx_tch_mode_req(ms, rr->cd_now.mode, mode);
-}
-
diff --git a/Src/osmoconbb/src/host/layer23/src/mobile/main.c b/Src/osmoconbb/src/host/layer23/src/mobile/main.c
deleted file mode 100644
index ed961c5..0000000
--- a/Src/osmoconbb/src/host/layer23/src/mobile/main.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/* Main method of the layer2/3 stack */
-
-/* (C) 2010 by Holger Hans Peter Freyther
- * (C) 2010 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/mobile/app_mobile.h>
-
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/linuxlist.h>
-#include <osmocom/core/gsmtap_util.h>
-#include <osmocom/core/gsmtap.h>
-#include <osmocom/core/signal.h>
-
-#include <arpa/inet.h>
-
-#define _GNU_SOURCE
-#include <getopt.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <time.h>
-#include <libgen.h>
-
-struct log_target *stderr_target;
-
-void *l23_ctx = NULL;
-struct llist_head ms_list;
-static char *gsmtap_ip = 0;
-struct gsmtap_inst *gsmtap_inst = NULL;
-unsigned short vty_port = 4247;
-int debug_set = 0;
-char *config_dir = NULL;
-
-int mobile_delete(struct osmocom_ms *ms, int force);
-int mobile_signal_cb(unsigned int subsys, unsigned int signal,
- void *handler_data, void *signal_data);
-int mobile_work(struct osmocom_ms *ms);
-int mobile_exit(struct osmocom_ms *ms, int force);
-
-
-const char *openbsc_copyright =
- "Copyright (C) 2008-2010 ...\n"
- "Contributions by ...\n\n"
- "License GPLv2+: GNU GPL version 2 or later "
- "<http://gnu.org/licenses/gpl.html>\n"
- "This is free software: you are free to change and redistribute it.\n"
- "There is NO WARRANTY, to the extent permitted by law.\n";
-
-static void print_usage(const char *app)
-{
- printf("Usage: %s\n", app);
-}
-
-static void print_help()
-{
- printf(" Some help...\n");
- printf(" -h --help this text\n");
- printf(" -i --gsmtap-ip The destination IP used for GSMTAP.\n");
- printf(" -v --vty-port The VTY port number to telnet to. "
- "(default %u)\n", vty_port);
- printf(" -d --debug Change debug flags.\n");
-}
-
-static void handle_options(int argc, char **argv)
-{
- while (1) {
- int option_index = 0, c;
- static struct option long_options[] = {
- {"help", 0, 0, 'h'},
- {"gsmtap-ip", 1, 0, 'i'},
- {"vty-port", 1, 0, 'v'},
- {"debug", 1, 0, 'd'},
- {0, 0, 0, 0},
- };
-
- c = getopt_long(argc, argv, "hi:v:d:",
- long_options, &option_index);
- if (c == -1)
- break;
-
- switch (c) {
- case 'h':
- print_usage(argv[0]);
- print_help();
- exit(0);
- break;
- case 'i':
- gsmtap_ip = optarg;
- break;
- case 'v':
- vty_port = atoi(optarg);
- break;
- case 'd':
- log_parse_category_mask(stderr_target, optarg);
- debug_set = 1;
- break;
- default:
- break;
- }
- }
-}
-
-void sighandler(int sigset)
-{
- if (sigset == SIGHUP || sigset == SIGPIPE)
- return;
-
- fprintf(stderr, "Signal %d received.\n", sigset);
-
- /* in case there is a lockup during exit */
- signal(SIGINT, SIG_DFL);
- signal(SIGHUP, SIG_DFL);
- signal(SIGTERM, SIG_DFL);
- signal(SIGPIPE, SIG_DFL);
-
- osmo_signal_dispatch(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL);
-}
-
-int main(int argc, char **argv)
-{
- int quit = 0;
- int rc;
- char const * home;
- size_t len;
- const char osmocomcfg[] = ".osmocom/bb/mobile.cfg";
- char *config_file = NULL;
-
- printf("%s\n", openbsc_copyright);
-
- srand(time(NULL));
-
- INIT_LLIST_HEAD(&ms_list);
- log_init(&log_info, NULL);
- stderr_target = log_target_create_stderr();
- log_add_target(stderr_target);
- log_set_all_filter(stderr_target, 1);
-
- l23_ctx = talloc_named_const(NULL, 1, "layer2 context");
-
- handle_options(argc, argv);
-
- if (!debug_set)
- log_parse_category_mask(stderr_target, "DCS:DNB:DPLMN:DRR:DMM:DSIM:DCC:DMNCC:DPAG:DSUM");
- log_set_log_level(stderr_target, LOGL_DEBUG);
-
- if (gsmtap_ip) {
- gsmtap_inst = gsmtap_source_init(gsmtap_ip, GSMTAP_UDP_PORT, 1);
- if (!gsmtap_inst) {
- fprintf(stderr, "Failed during gsmtap_init()\n");
- exit(1);
- }
- gsmtap_source_add_sink(gsmtap_inst);
- }
-
- home = getenv("HOME");
- if (home != NULL) {
- len = strlen(home) + 1 + sizeof(osmocomcfg);
- config_file = talloc_size(l23_ctx, len);
- if (config_file != NULL)
- snprintf(config_file, len, "%s/%s", home, osmocomcfg);
- }
- /* save the config file directory name */
- config_dir = talloc_strdup(l23_ctx, config_file);
- config_dir = dirname(config_dir);
-
- rc = l23_app_init(NULL, config_file, vty_port);
- if (rc)
- exit(rc);
-
- signal(SIGINT, sighandler);
- signal(SIGHUP, sighandler);
- signal(SIGTERM, sighandler);
- signal(SIGPIPE, sighandler);
-
- while (1) {
- l23_app_work(&quit);
- if (quit && llist_empty(&ms_list))
- break;
- osmo_select_main(0);
- }
-
- l23_app_exit();
-
- return 0;
-}
diff --git a/Src/osmoconbb/src/host/layer23/src/mobile/mnccms.c b/Src/osmoconbb/src/host/layer23/src/mobile/mnccms.c
deleted file mode 100644
index 8d3abe6..0000000
--- a/Src/osmoconbb/src/host/layer23/src/mobile/mnccms.c
+++ /dev/null
@@ -1,777 +0,0 @@
-/*
- * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdint.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <osmocom/core/talloc.h>
-
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/mobile/mncc.h>
-#include <osmocom/bb/mobile/vty.h>
-
-void *l23_ctx;
-static uint32_t new_callref = 1;
-static LLIST_HEAD(call_list);
-
-void mncc_set_cause(struct gsm_mncc *data, int loc, int val);
-static int dtmf_statemachine(struct gsm_call *call, struct gsm_mncc *mncc);
-static void timeout_dtmf(void *arg);
-int mncc_answer(struct osmocom_ms *ms);
-
-/*
- * support functions
- */
-
-/* DTMF timer */
-static void start_dtmf_timer(struct gsm_call *call, uint16_t ms)
-{
- LOGP(DCC, LOGL_INFO, "starting DTMF timer %d ms\n", ms);
- call->dtmf_timer.cb = timeout_dtmf;
- call->dtmf_timer.data = call;
- osmo_timer_schedule(&call->dtmf_timer, 0, ms * 1000);
-}
-
-static void stop_dtmf_timer(struct gsm_call *call)
-{
- if (osmo_timer_pending(&call->dtmf_timer)) {
- LOGP(DCC, LOGL_INFO, "stopping pending DTMF timer\n");
- osmo_timer_del(&call->dtmf_timer);
- }
-}
-
-/* free call instance */
-static void free_call(struct gsm_call *call)
-{
- stop_dtmf_timer(call);
-
- llist_del(&call->entry);
- DEBUGP(DMNCC, "(call %x) Call removed.\n", call->callref);
- talloc_free(call);
-}
-
-
-struct gsm_call *get_call_ref(uint32_t callref)
-{
- struct gsm_call *callt;
-
- llist_for_each_entry(callt, &call_list, entry) {
- if (callt->callref == callref)
- return callt;
- }
- return NULL;
-}
-
-static int8_t mncc_get_bearer(struct gsm_settings *set, uint8_t speech_ver)
-{
- switch (speech_ver) {
- case 4:
- if (set->full_v3)
- LOGP(DMNCC, LOGL_INFO, " net suggests full rate v3\n");
- else {
- LOGP(DMNCC, LOGL_INFO, " full rate v3 not supported\n");
- speech_ver = -1;
- }
- break;
- case 2:
- if (set->full_v2)
- LOGP(DMNCC, LOGL_INFO, " net suggests full rate v2\n");
- else {
- LOGP(DMNCC, LOGL_INFO, " full rate v2 not supported\n");
- speech_ver = -1;
- }
- break;
- case 0: /* mandatory */
- if (set->full_v1)
- LOGP(DMNCC, LOGL_INFO, " net suggests full rate v1\n");
- else {
- LOGP(DMNCC, LOGL_INFO, " full rate v1 not supported\n");
- speech_ver = -1;
- }
- break;
- case 5:
- if (set->half_v3)
- LOGP(DMNCC, LOGL_INFO, " net suggests half rate v3\n");
- else {
- LOGP(DMNCC, LOGL_INFO, " half rate v3 not supported\n");
- speech_ver = -1;
- }
- break;
- case 1:
- if (set->half_v1)
- LOGP(DMNCC, LOGL_INFO, " net suggests half rate v1\n");
- else {
- LOGP(DMNCC, LOGL_INFO, " half rate v1 not supported\n");
- speech_ver = -1;
- }
- break;
- default:
- LOGP(DMNCC, LOGL_INFO, " net suggests unknown speech version "
- "%d\n", speech_ver);
- speech_ver = -1;
- }
-
- return speech_ver;
-}
-
-static void mncc_set_bearer(struct osmocom_ms *ms, int8_t speech_ver,
- struct gsm_mncc *mncc)
-{
- struct gsm_settings *set = &ms->settings;
- int i = 0;
-
- mncc->fields |= MNCC_F_BEARER_CAP;
- mncc->bearer_cap.coding = 0;
- if (set->ch_cap == GSM_CAP_SDCCH_TCHF_TCHH
- && (set->half_v1 || set->half_v3)) {
- mncc->bearer_cap.radio = 3;
- LOGP(DMNCC, LOGL_INFO, " support TCH/H also\n");
- } else {
- mncc->bearer_cap.radio = 1;
- LOGP(DMNCC, LOGL_INFO, " support TCH/F only\n");
- }
- mncc->bearer_cap.speech_ctm = 0;
- /* if no specific speech_ver is given */
- if (speech_ver < 0) {
- /* if half rate is supported and prefered */
- if (set->half_v3 && set->half && set->half_prefer) {
- mncc->bearer_cap.speech_ver[i++] = 5;
- LOGP(DMNCC, LOGL_INFO, " support half rate v3\n");
- }
- if (set->half_v1 && set->half && set->half_prefer) {
- mncc->bearer_cap.speech_ver[i++] = 1;
- LOGP(DMNCC, LOGL_INFO, " support half rate v1\n");
- }
- /* if full rate is supported */
- if (set->full_v3) {
- mncc->bearer_cap.speech_ver[i++] = 4;
- LOGP(DMNCC, LOGL_INFO, " support full rate v3\n");
- }
- if (set->full_v2) {
- mncc->bearer_cap.speech_ver[i++] = 2;
- LOGP(DMNCC, LOGL_INFO, " support full rate v2\n");
- }
- if (set->full_v1) { /* mandatory, so it's always true */
- mncc->bearer_cap.speech_ver[i++] = 0;
- LOGP(DMNCC, LOGL_INFO, " support full rate v1\n");
- }
- /* if half rate is supported and not prefered */
- if (set->half_v3 && set->half && !set->half_prefer) {
- mncc->bearer_cap.speech_ver[i++] = 5;
- LOGP(DMNCC, LOGL_INFO, " support half rate v3\n");
- }
- if (set->half_v1 && set->half && !set->half_prefer) {
- mncc->bearer_cap.speech_ver[i++] = 1;
- LOGP(DMNCC, LOGL_INFO, " support half rate v1\n");
- }
- /* if specific speech_ver is given (it must be supported) */
- } else
- mncc->bearer_cap.speech_ver[i++] = speech_ver;
- mncc->bearer_cap.speech_ver[i] = -1; /* end of list */
- mncc->bearer_cap.transfer = 0;
- mncc->bearer_cap.mode = 0;
-}
-
-/*
- * MNCCms dummy application
- */
-
-/* this is a minimal implementation as required by GSM 04.08 */
-int mncc_recv_dummy(struct osmocom_ms *ms, int msg_type, void *arg)
-{
- struct gsm_mncc *data = arg;
- uint32_t callref = data->callref;
- struct gsm_mncc rel;
-
- if (msg_type == MNCC_REL_IND || msg_type == MNCC_REL_CNF)
- return 0;
-
- LOGP(DMNCC, LOGL_INFO, "Rejecting incoming call\n");
-
- /* reject, as we don't support Calls */
- memset(&rel, 0, sizeof(struct gsm_mncc));
- rel.callref = callref;
- mncc_set_cause(&rel, GSM48_CAUSE_LOC_USER,
- GSM48_CC_CAUSE_INCOMPAT_DEST);
-
- return mncc_send(ms, MNCC_REL_REQ, &rel);
-}
-
-/*
- * MNCCms basic call application
- */
-
-int mncc_recv_mobile(struct osmocom_ms *ms, int msg_type, void *arg)
-{
- struct gsm_settings *set = &ms->settings;
- struct gsm_mncc *data = arg;
- struct gsm_call *call = get_call_ref(data->callref);
- struct gsm_mncc mncc;
- uint8_t cause;
- int8_t speech_ver = -1, speech_ver_half = -1, temp;
- int first_call = 0;
-
- /* call does not exist */
- if (!call && msg_type != MNCC_SETUP_IND) {
- LOGP(DMNCC, LOGL_INFO, "Rejecting incoming call "
- "(callref %x)\n", data->callref);
- if (msg_type == MNCC_REL_IND || msg_type == MNCC_REL_CNF)
- return 0;
- cause = GSM48_CC_CAUSE_INCOMPAT_DEST;
- release:
- memset(&mncc, 0, sizeof(struct gsm_mncc));
- mncc.callref = data->callref;
- mncc_set_cause(&mncc, GSM48_CAUSE_LOC_USER, cause);
- return mncc_send(ms, MNCC_REL_REQ, &mncc);
- }
-
- /* setup without call */
- if (!call) {
- if (llist_empty(&call_list))
- first_call = 1;
- call = talloc_zero(l23_ctx, struct gsm_call);
- if (!call)
- return -ENOMEM;
- call->ms = ms;
- call->callref = data->callref;
- llist_add_tail(&call->entry, &call_list);
- }
-
- /* not in initiated state anymore */
- call->init = 0;
-
- switch (msg_type) {
- case MNCC_DISC_IND:
- vty_notify(ms, NULL);
- switch (data->cause.value) {
- case GSM48_CC_CAUSE_UNASSIGNED_NR:
- vty_notify(ms, "Call: Number not assigned\n");
- break;
- case GSM48_CC_CAUSE_NO_ROUTE:
- vty_notify(ms, "Call: Destination unreachable\n");
- break;
- case GSM48_CC_CAUSE_NORM_CALL_CLEAR:
- vty_notify(ms, "Call: Remote hangs up\n");
- break;
- case GSM48_CC_CAUSE_USER_BUSY:
- vty_notify(ms, "Call: Remote busy\n");
- break;
- case GSM48_CC_CAUSE_USER_NOTRESPOND:
- vty_notify(ms, "Call: Remote not responding\n");
- break;
- case GSM48_CC_CAUSE_USER_ALERTING_NA:
- vty_notify(ms, "Call: Remote not answering\n");
- break;
- case GSM48_CC_CAUSE_CALL_REJECTED:
- vty_notify(ms, "Call has been rejected\n");
- break;
- case GSM48_CC_CAUSE_NUMBER_CHANGED:
- vty_notify(ms, "Call: Number changed\n");
- break;
- case GSM48_CC_CAUSE_PRE_EMPTION:
- vty_notify(ms, "Call: Cleared due to pre-emption\n");
- break;
- case GSM48_CC_CAUSE_DEST_OOO:
- vty_notify(ms, "Call: Remote out of order\n");
- break;
- case GSM48_CC_CAUSE_INV_NR_FORMAT:
- vty_notify(ms, "Call: Number invalid or imcomplete\n");
- break;
- case GSM48_CC_CAUSE_NO_CIRCUIT_CHAN:
- vty_notify(ms, "Call: No channel available\n");
- break;
- case GSM48_CC_CAUSE_NETWORK_OOO:
- vty_notify(ms, "Call: Network out of order\n");
- break;
- case GSM48_CC_CAUSE_TEMP_FAILURE:
- vty_notify(ms, "Call: Temporary failure\n");
- break;
- case GSM48_CC_CAUSE_SWITCH_CONG:
- vty_notify(ms, "Congestion\n");
- break;
- default:
- vty_notify(ms, "Call has been disconnected "
- "(clear cause %d)\n", data->cause.value);
- }
- LOGP(DMNCC, LOGL_INFO, "Call has been disconnected "
- "(cause %d)\n", data->cause.value);
- if ((data->fields & MNCC_F_PROGRESS)
- && data->progress.descr == 8) {
- vty_notify(ms, "Please hang up!\n");
- break;
- }
- free_call(call);
- cause = GSM48_CC_CAUSE_NORM_CALL_CLEAR;
- goto release;
- case MNCC_REL_IND:
- case MNCC_REL_CNF:
- vty_notify(ms, NULL);
- if (data->cause.value == GSM48_CC_CAUSE_CALL_REJECTED)
- vty_notify(ms, "Call has been rejected\n");
- else
- vty_notify(ms, "Call has been released\n");
- LOGP(DMNCC, LOGL_INFO, "Call has been released (cause %d)\n",
- data->cause.value);
- free_call(call);
- break;
- case MNCC_CALL_PROC_IND:
- vty_notify(ms, NULL);
- vty_notify(ms, "Call is proceeding\n");
- LOGP(DMNCC, LOGL_INFO, "Call is proceeding\n");
- if ((data->fields & MNCC_F_BEARER_CAP)
- && data->bearer_cap.speech_ver[0] >= 0) {
- mncc_get_bearer(set, data->bearer_cap.speech_ver[0]);
- }
- break;
- case MNCC_ALERT_IND:
- vty_notify(ms, NULL);
- vty_notify(ms, "Call is alerting\n");
- LOGP(DMNCC, LOGL_INFO, "Call is alerting\n");
- break;
- case MNCC_SETUP_CNF:
- vty_notify(ms, NULL);
- vty_notify(ms, "Call is answered\n");
- LOGP(DMNCC, LOGL_INFO, "Call is answered\n");
- break;
- case MNCC_SETUP_IND:
- vty_notify(ms, NULL);
- if (!first_call && !ms->settings.cw) {
- vty_notify(ms, "Incoming call rejected while busy\n");
- LOGP(DMNCC, LOGL_INFO, "Incoming call but busy\n");
- cause = GSM48_CC_CAUSE_USER_BUSY;
- goto release;
- }
- /* select first supported speech_ver */
- if ((data->fields & MNCC_F_BEARER_CAP)) {
- int i;
-
- for (i = 0; data->bearer_cap.speech_ver[i] >= 0; i++) {
-
- temp = mncc_get_bearer(set,
- data->bearer_cap.speech_ver[i]);
- if (temp < 0)
- continue;
- if (temp == 5 || temp == 1) { /* half */
- /* only the first half rate */
- if (speech_ver_half < 0)
- speech_ver_half = temp;
- } else {
- /* only the first full rate */
- if (speech_ver < 0)
- speech_ver = temp;
- }
- }
- /* half and full given */
- if (speech_ver_half >= 0 && speech_ver >= 0) {
- if (set->half_prefer) {
- LOGP(DMNCC, LOGL_INFO, " both supported"
- " codec rates are given, using "
- "preferred half rate\n");
- speech_ver = speech_ver_half;
- } else
- LOGP(DMNCC, LOGL_INFO, " both supported"
- " codec rates are given, using "
- "preferred full rate\n");
- } else if (speech_ver_half < 0 && speech_ver < 0) {
- LOGP(DMNCC, LOGL_INFO, " no supported codec "
- "rate is given\n");
- /* only half rate is given, use it */
- } else if (speech_ver_half >= 0) {
- LOGP(DMNCC, LOGL_INFO, " only supported half "
- "rate codec is given, using it\n");
- speech_ver = speech_ver_half;
- /* only full rate is given, use it */
- } else {
- LOGP(DMNCC, LOGL_INFO, " only supported full "
- "rate codec is given, using it\n");
- }
- }
- /* presentation allowed if present == 0 */
- if (data->calling.present || !data->calling.number[0])
- vty_notify(ms, "Incoming call (anonymous)\n");
- else if (data->calling.type == 1)
- vty_notify(ms, "Incoming call (from +%s)\n",
- data->calling.number);
- else if (data->calling.type == 2)
- vty_notify(ms, "Incoming call (from 0-%s)\n",
- data->calling.number);
- else
- vty_notify(ms, "Incoming call (from %s)\n",
- data->calling.number);
- LOGP(DMNCC, LOGL_INFO, "Incoming call (from %s callref %x)\n",
- data->calling.number, call->callref);
- memset(&mncc, 0, sizeof(struct gsm_mncc));
- mncc.callref = call->callref;
- /* only include bearer cap, if not given in setup
- * or if multiple codecs are given
- * or if not only full rate
- * or if given codec is unimplemented
- */
- if (!(data->fields & MNCC_F_BEARER_CAP) || speech_ver < 0)
- mncc_set_bearer(ms, -1, &mncc);
- else if (data->bearer_cap.speech_ver[1] >= 0
- || speech_ver != 0)
- mncc_set_bearer(ms, speech_ver, &mncc);
- /* CC capabilities (optional) */
- if (ms->settings.cc_dtmf) {
- mncc.fields |= MNCC_F_CCCAP;
- mncc.cccap.dtmf = 1;
- }
- mncc_send(ms, MNCC_CALL_CONF_REQ, &mncc);
- if (first_call)
- LOGP(DMNCC, LOGL_INFO, "Ring!\n");
- else {
- LOGP(DMNCC, LOGL_INFO, "Knock!\n");
- call->hold = 1;
- }
- call->ring = 1;
- memset(&mncc, 0, sizeof(struct gsm_mncc));
- mncc.callref = call->callref;
- mncc_send(ms, MNCC_ALERT_REQ, &mncc);
- if (ms->settings.auto_answer) {
- LOGP(DMNCC, LOGL_INFO, "Auto-answering call\n");
- mncc_answer(ms);
- }
- break;
- case MNCC_SETUP_COMPL_IND:
- vty_notify(ms, NULL);
- vty_notify(ms, "Call is connected\n");
- LOGP(DMNCC, LOGL_INFO, "Call is connected\n");
- break;
- case MNCC_HOLD_CNF:
- vty_notify(ms, NULL);
- vty_notify(ms, "Call is on hold\n");
- LOGP(DMNCC, LOGL_INFO, "Call is on hold\n");
- call->hold = 1;
- break;
- case MNCC_HOLD_REJ:
- vty_notify(ms, NULL);
- vty_notify(ms, "Call hold was rejected\n");
- LOGP(DMNCC, LOGL_INFO, "Call hold was rejected\n");
- break;
- case MNCC_RETRIEVE_CNF:
- vty_notify(ms, NULL);
- vty_notify(ms, "Call is retrieved\n");
- LOGP(DMNCC, LOGL_INFO, "Call is retrieved\n");
- call->hold = 0;
- break;
- case MNCC_RETRIEVE_REJ:
- vty_notify(ms, NULL);
- vty_notify(ms, "Call retrieve was rejected\n");
- LOGP(DMNCC, LOGL_INFO, "Call retrieve was rejected\n");
- break;
- case MNCC_FACILITY_IND:
- LOGP(DMNCC, LOGL_INFO, "Facility info not displayed, "
- "unsupported\n");
- break;
- case MNCC_START_DTMF_RSP:
- case MNCC_START_DTMF_REJ:
- case MNCC_STOP_DTMF_RSP:
- dtmf_statemachine(call, data);
- break;
- default:
- LOGP(DMNCC, LOGL_INFO, "Message 0x%02x unsupported\n",
- msg_type);
- return -EINVAL;
- }
-
- return 0;
-}
-
-int mncc_call(struct osmocom_ms *ms, char *number)
-{
- struct gsm_call *call;
- struct gsm_mncc setup;
-
- llist_for_each_entry(call, &call_list, entry) {
- if (!call->hold) {
- vty_notify(ms, NULL);
- vty_notify(ms, "Please put active call on hold "
- "first!\n");
- LOGP(DMNCC, LOGL_INFO, "Cannot make a call, busy!\n");
- return -EBUSY;
- }
- }
-
- call = talloc_zero(l23_ctx, struct gsm_call);
- if (!call)
- return -ENOMEM;
- call->ms = ms;
- call->callref = new_callref++;
- call->init = 1;
- llist_add_tail(&call->entry, &call_list);
-
- memset(&setup, 0, sizeof(struct gsm_mncc));
- setup.callref = call->callref;
-
- if (!strncasecmp(number, "emerg", 5)) {
- LOGP(DMNCC, LOGL_INFO, "Make emergency call\n");
- /* emergency */
- setup.emergency = 1;
- } else {
- LOGP(DMNCC, LOGL_INFO, "Make call to %s\n", number);
- /* called number */
- setup.fields |= MNCC_F_CALLED;
- if (number[0] == '+') {
- number++;
- setup.called.type = 1; /* international */
- } else
- setup.called.type = 0; /* auto/unknown - prefix must be
- used */
- setup.called.plan = 1; /* ISDN */
- strncpy(setup.called.number, number,
- sizeof(setup.called.number) - 1);
-
- /* bearer capability (mandatory) */
- mncc_set_bearer(ms, -1, &setup);
- if (ms->settings.clir)
- setup.clir.sup = 1;
- else if (ms->settings.clip)
- setup.clir.inv = 1;
-
- /* CC capabilities (optional) */
- if (ms->settings.cc_dtmf) {
- setup.fields |= MNCC_F_CCCAP;
- setup.cccap.dtmf = 1;
- }
- }
-
- return mncc_send(ms, MNCC_SETUP_REQ, &setup);
-}
-
-int mncc_hangup(struct osmocom_ms *ms)
-{
- struct gsm_call *call, *found = NULL;
- struct gsm_mncc disc;
-
- llist_for_each_entry(call, &call_list, entry) {
- if (!call->hold) {
- found = call;
- break;
- }
- }
- if (!found) {
- LOGP(DMNCC, LOGL_INFO, "No active call to hangup\n");
- vty_notify(ms, NULL);
- vty_notify(ms, "No active call\n");
- return -EINVAL;
- }
-
- memset(&disc, 0, sizeof(struct gsm_mncc));
- disc.callref = found->callref;
- mncc_set_cause(&disc, GSM48_CAUSE_LOC_USER,
- GSM48_CC_CAUSE_NORM_CALL_CLEAR);
- return mncc_send(ms, (call->init) ? MNCC_REL_REQ : MNCC_DISC_REQ,
- &disc);
-}
-
-int mncc_answer(struct osmocom_ms *ms)
-{
- struct gsm_call *call, *alerting = NULL;
- struct gsm_mncc rsp;
- int active = 0;
-
- llist_for_each_entry(call, &call_list, entry) {
- if (call->ring)
- alerting = call;
- else if (!call->hold)
- active = 1;
- }
- if (!alerting) {
- LOGP(DMNCC, LOGL_INFO, "No call alerting\n");
- vty_notify(ms, NULL);
- vty_notify(ms, "No alerting call\n");
- return -EBUSY;
- }
- if (active) {
- LOGP(DMNCC, LOGL_INFO, "Answer but we have an active call\n");
- vty_notify(ms, NULL);
- vty_notify(ms, "Please put active call on hold first!\n");
- return -EBUSY;
- }
- alerting->ring = 0;
- alerting->hold = 0;
-
- memset(&rsp, 0, sizeof(struct gsm_mncc));
- rsp.callref = alerting->callref;
- return mncc_send(ms, MNCC_SETUP_RSP, &rsp);
-}
-
-int mncc_hold(struct osmocom_ms *ms)
-{
- struct gsm_call *call, *found = NULL;
- struct gsm_mncc hold;
-
- llist_for_each_entry(call, &call_list, entry) {
- if (!call->hold) {
- found = call;
- break;
- }
- }
- if (!found) {
- LOGP(DMNCC, LOGL_INFO, "No active call to hold\n");
- vty_notify(ms, NULL);
- vty_notify(ms, "No active call\n");
- return -EINVAL;
- }
-
- memset(&hold, 0, sizeof(struct gsm_mncc));
- hold.callref = found->callref;
- return mncc_send(ms, MNCC_HOLD_REQ, &hold);
-}
-
-int mncc_retrieve(struct osmocom_ms *ms, int number)
-{
- struct gsm_call *call;
- struct gsm_mncc retr;
- int holdnum = 0, active = 0, i = 0;
-
- llist_for_each_entry(call, &call_list, entry) {
- if (call->hold)
- holdnum++;
- if (!call->hold)
- active = 1;
- }
- if (active) {
- LOGP(DMNCC, LOGL_INFO, "Cannot retrieve during active call\n");
- vty_notify(ms, NULL);
- vty_notify(ms, "Hold active call first!\n");
- return -EINVAL;
- }
- if (holdnum == 0) {
- vty_notify(ms, NULL);
- vty_notify(ms, "No call on hold!\n");
- return -EINVAL;
- }
- if (holdnum > 1 && number <= 0) {
- vty_notify(ms, NULL);
- vty_notify(ms, "Select call 1..%d\n", holdnum);
- return -EINVAL;
- }
- if (holdnum == 1 && number <= 0)
- number = 1;
- if (number > holdnum) {
- vty_notify(ms, NULL);
- vty_notify(ms, "Given number %d out of range!\n", number);
- vty_notify(ms, "Select call 1..%d\n", holdnum);
- return -EINVAL;
- }
-
- llist_for_each_entry(call, &call_list, entry) {
- i++;
- if (i == number)
- break;
- }
-
- memset(&retr, 0, sizeof(struct gsm_mncc));
- retr.callref = call->callref;
- return mncc_send(ms, MNCC_RETRIEVE_REQ, &retr);
-}
-
-/*
- * DTMF
- */
-
-static int dtmf_statemachine(struct gsm_call *call, struct gsm_mncc *mncc)
-{
- struct osmocom_ms *ms = call->ms;
- struct gsm_mncc dtmf;
-
- switch (call->dtmf_state) {
- case DTMF_ST_SPACE:
- case DTMF_ST_IDLE:
- /* end of string */
- if (!call->dtmf[call->dtmf_index]) {
- LOGP(DMNCC, LOGL_INFO, "done with DTMF\n");
- call->dtmf_state = DTMF_ST_IDLE;
- return -EOF;
- }
- memset(&dtmf, 0, sizeof(struct gsm_mncc));
- dtmf.callref = call->callref;
- dtmf.keypad = call->dtmf[call->dtmf_index++];
- call->dtmf_state = DTMF_ST_START;
- LOGP(DMNCC, LOGL_INFO, "start DTMF (keypad %c)\n",
- dtmf.keypad);
- return mncc_send(ms, MNCC_START_DTMF_REQ, &dtmf);
- case DTMF_ST_START:
- if (mncc->msg_type != MNCC_START_DTMF_RSP) {
- LOGP(DMNCC, LOGL_INFO, "DTMF was rejected\n");
- return -ENOTSUP;
- }
- start_dtmf_timer(call, 70);
- call->dtmf_state = DTMF_ST_MARK;
- LOGP(DMNCC, LOGL_INFO, "DTMF is on\n");
- break;
- case DTMF_ST_MARK:
- memset(&dtmf, 0, sizeof(struct gsm_mncc));
- dtmf.callref = call->callref;
- call->dtmf_state = DTMF_ST_STOP;
- LOGP(DMNCC, LOGL_INFO, "stop DTMF\n");
- return mncc_send(ms, MNCC_STOP_DTMF_REQ, &dtmf);
- case DTMF_ST_STOP:
- start_dtmf_timer(call, 120);
- call->dtmf_state = DTMF_ST_SPACE;
- LOGP(DMNCC, LOGL_INFO, "DTMF is off\n");
- break;
- }
-
- return 0;
-}
-
-static void timeout_dtmf(void *arg)
-{
- struct gsm_call *call = arg;
-
- LOGP(DCC, LOGL_INFO, "DTMF timer has fired\n");
- dtmf_statemachine(call, NULL);
-}
-
-int mncc_dtmf(struct osmocom_ms *ms, char *dtmf)
-{
- struct gsm_call *call, *found = NULL;
-
- llist_for_each_entry(call, &call_list, entry) {
- if (!call->hold) {
- found = call;
- break;
- }
- }
- if (!found) {
- LOGP(DMNCC, LOGL_INFO, "No active call to send DTMF\n");
- vty_notify(ms, NULL);
- vty_notify(ms, "No active call\n");
- return -EINVAL;
- }
-
- if (call->dtmf_state != DTMF_ST_IDLE) {
- LOGP(DMNCC, LOGL_INFO, "sending DTMF already\n");
- return -EINVAL;
- }
-
- call->dtmf_index = 0;
- strncpy(call->dtmf, dtmf, sizeof(call->dtmf) - 1);
- return dtmf_statemachine(call, NULL);
-}
-
diff --git a/Src/osmoconbb/src/host/layer23/src/mobile/settings.c b/Src/osmoconbb/src/host/layer23/src/mobile/settings.c
deleted file mode 100644
index 592f8a8..0000000
--- a/Src/osmoconbb/src/host/layer23/src/mobile/settings.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdint.h>
-#include <errno.h>
-#include <string.h>
-#include <osmocom/core/talloc.h>
-
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/networks.h>
-
-static char *layer2_socket_path = "/tmp/osmocom_l2";
-static char *sap_socket_path = "/tmp/osmocom_sap";
-
-int gsm_settings_init(struct osmocom_ms *ms)
-{
- struct gsm_settings *set = &ms->settings;
- struct gsm_support *sup = &ms->support;
-
- strcpy(set->layer2_socket_path, layer2_socket_path);
- strcpy(set->sap_socket_path, sap_socket_path);
-
- /* network search */
- set->plmn_mode = PLMN_MODE_AUTO;
-
- /* IMEI */
- sprintf(set->imei, "000000000000000");
- sprintf(set->imeisv, "0000000000000000");
-
- /* SIM type */
-#warning TODO: Enable after SIM reader is available in master branch.
-// set->sim_type = SIM_TYPE_READER;
-
- /* test SIM */
- strcpy(set->test_imsi, "001010000000000");
- set->test_rplmn_mcc = set->test_rplmn_mnc = 1;
- set->test_lac = 0x0000;
- set->test_tmsi = 0xffffffff;
-
- /* set all supported features */
- set->sms_ptp = sup->sms_ptp;
- set->a5_1 = sup->a5_1;
- set->a5_2 = sup->a5_2;
- set->a5_3 = sup->a5_3;
- set->a5_4 = sup->a5_4;
- set->a5_5 = sup->a5_5;
- set->a5_6 = sup->a5_6;
- set->a5_7 = sup->a5_7;
- set->p_gsm = sup->p_gsm;
- set->e_gsm = sup->e_gsm;
- set->r_gsm = sup->r_gsm;
- set->dcs = sup->dcs;
- set->class_900 = sup->class_900;
- set->class_dcs = sup->class_dcs;
- set->class_850 = sup->class_850;
- set->class_pcs = sup->class_pcs;
- set->class_400 = sup->class_400;
- set->full_v1 = sup->full_v1;
- set->full_v2 = sup->full_v2;
- set->full_v3 = sup->full_v3;
- set->half_v1 = sup->half_v1;
- set->half_v3 = sup->half_v3;
- set->ch_cap = sup->ch_cap;
- set->min_rxlev_db = sup->min_rxlev_db;
- set->dsc_max = sup->dsc_max;
-
- if (sup->half_v1 || sup->half_v3)
- set->half = 1;
-
-
- /* software features */
- set->cc_dtmf = 1;
-
- INIT_LLIST_HEAD(&set->abbrev);
-
- return 0;
-}
-
-int gsm_settings_arfcn(struct osmocom_ms *ms)
-{
- int i;
- struct gsm_settings *set = &ms->settings;
-
- /* set supported frequencies */
- memset(set->freq_map, 0, sizeof(set->freq_map));
- if (set->p_gsm)
- for(i = 1; i <= 124; i++)
- set->freq_map[i >> 3] |= (1 << (i & 7));
- if (set->gsm_850)
- for(i = 128; i <= 251; i++)
- set->freq_map[i >> 3] |= (1 << (i & 7));
- if (set->gsm_450)
- for(i = 259; i <= 293; i++)
- set->freq_map[i >> 3] |= (1 << (i & 7));
- if (set->gsm_480)
- for(i = 306; i <= 340; i++)
- set->freq_map[i >> 3] |= (1 << (i & 7));
- if (set->dcs)
- for(i = 512; i <= 885; i++)
- set->freq_map[i >> 3] |= (1 << (i & 7));
- if (set->pcs)
- for(i = 1024; i <= 1024-512+810; i++)
- set->freq_map[i >> 3] |= (1 << (i & 7));
- if (set->e_gsm) {
- for(i = 975; i <= 1023; i++)
- set->freq_map[i >> 3] |= (1 << (i & 7));
- set->freq_map[0] |= 1;
- }
- if (set->r_gsm)
- for(i = 955; i <= 974; i++)
- set->freq_map[i >> 3] |= (1 << (i & 7));
-
- return 0;
-}
-
-int gsm_settings_exit(struct osmocom_ms *ms)
-{
- struct gsm_settings *set = &ms->settings;
- struct gsm_settings_abbrev *abbrev;
-
- while (!llist_empty(&set->abbrev)) {
- abbrev = llist_entry(set->abbrev.next,
- struct gsm_settings_abbrev, list);
- llist_del(&abbrev->list);
- talloc_free(abbrev);
- }
-
- return 0;
-}
-
-char *gsm_check_imei(const char *imei, const char *sv)
-{
- int i;
-
- if (!imei || strlen(imei) != 15)
- return "IMEI must have 15 digits!";
-
- for (i = 0; i < strlen(imei); i++) {
- if (imei[i] < '0' || imei[i] > '9')
- return "IMEI must have digits 0 to 9 only!";
- }
-
- if (!sv || strlen(sv) != 1)
- return "Software version must have 1 digit!";
-
- if (sv[0] < '0' || sv[0] > '9')
- return "Software version must have digits 0 to 9 only!";
-
- return NULL;
-}
-
-int gsm_random_imei(struct gsm_settings *set)
-{
- int digits = set->imei_random;
- char rand[16];
-
- if (digits <= 0)
- return 0;
- if (digits > 15)
- digits = 15;
-
- sprintf(rand, "%08ld", random() % 100000000);
- sprintf(rand + 8, "%07ld", random() % 10000000);
-
- strcpy(set->imei + 15 - digits, rand + 15 - digits);
- strncpy(set->imeisv, set->imei, 15);
-
- return 0;
-}
-
diff --git a/Src/osmoconbb/src/host/layer23/src/mobile/subscriber.c b/Src/osmoconbb/src/host/layer23/src/mobile/subscriber.c
deleted file mode 100644
index 6de742a..0000000
--- a/Src/osmoconbb/src/host/layer23/src/mobile/subscriber.c
+++ /dev/null
@@ -1,1207 +0,0 @@
-/*
- * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdint.h>
-#include <errno.h>
-#include <string.h>
-#include <arpa/inet.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/gsm/comp128.h>
-
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/networks.h>
-#include <osmocom/bb/mobile/vty.h>
-
-/* enable to get an empty list of forbidden PLMNs, even if stored on SIM.
- * if list is changed, the result is not written back to SIM */
-//#define TEST_EMPTY_FPLMN
-
-void *l23_ctx;
-
-static void subscr_sim_query_cb(struct osmocom_ms *ms, struct msgb *msg);
-static void subscr_sim_update_cb(struct osmocom_ms *ms, struct msgb *msg);
-static void subscr_sim_key_cb(struct osmocom_ms *ms, struct msgb *msg);
-
-/*
- * support
- */
-
-char *gsm_check_imsi(const char *imsi)
-{
- int i;
-
- if (!imsi || strlen(imsi) != 15)
- return "IMSI must have 15 digits!";
-
- for (i = 0; i < strlen(imsi); i++) {
- if (imsi[i] < '0' || imsi[i] > '9')
- return "IMSI must have digits 0 to 9 only!";
- }
-
- return NULL;
-}
-
-static char *sim_decode_bcd(uint8_t *data, uint8_t length)
-{
- int i, j = 0;
- static char result[32], c;
-
- for (i = 0; i < (length << 1); i++) {
- if ((i & 1))
- c = (data[i >> 1] >> 4);
- else
- c = (data[i >> 1] & 0xf);
- if (c == 0xf)
- break;
- result[j++] = c + '0';
- if (j == sizeof(result) - 1)
- break;
- }
- result[j] = '\0';
-
- return result;
-}
-
-static void xor96(uint8_t *ki, uint8_t *rand, uint8_t *sres, uint8_t *kc)
-{
- int i;
-
- for (i=0; i < 4; i++)
- sres[i] = rand[i] ^ ki[i];
- for (i=0; i < 8; i++)
- kc[i] = rand[i] ^ ki[i+4];
-}
-
-/*
- * init/exit
- */
-
-int gsm_subscr_init(struct osmocom_ms *ms)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
-
- memset(subscr, 0, sizeof(*subscr));
- subscr->ms = ms;
-
- /* set TMSI / LAC invalid */
- subscr->tmsi = 0xffffffff;
- subscr->lac = 0x0000;
-
- /* set key invalid */
- subscr->key_seq = 7;
-
- /* any cell selection timer timeout */
- subscr->any_timeout = 30;
-
- /* init lists */
- INIT_LLIST_HEAD(&subscr->plmn_list);
- INIT_LLIST_HEAD(&subscr->plmn_na);
-
- /* open SIM */
- subscr->sim_handle_query = sim_open(ms, subscr_sim_query_cb);
- subscr->sim_handle_update = sim_open(ms, subscr_sim_update_cb);
- subscr->sim_handle_key = sim_open(ms, subscr_sim_key_cb);
-
- return 0;
-}
-
-int gsm_subscr_exit(struct osmocom_ms *ms)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct llist_head *lh, *lh2;
-
- if (subscr->sim_handle_query) {
- sim_close(ms, subscr->sim_handle_query);
- subscr->sim_handle_query = 0;
- }
- if (subscr->sim_handle_update) {
- sim_close(ms, subscr->sim_handle_update);
- subscr->sim_handle_update = 0;
- }
- if (subscr->sim_handle_key) {
- sim_close(ms, subscr->sim_handle_key);
- subscr->sim_handle_key = 0;
- }
-
- /* flush lists */
- llist_for_each_safe(lh, lh2, &subscr->plmn_list) {
- llist_del(lh);
- talloc_free(lh);
- }
- llist_for_each_safe(lh, lh2, &subscr->plmn_na) {
- llist_del(lh);
- talloc_free(lh);
- }
-
- return 0;
-}
-
-/*
- * test card
- */
-
-/* Attach test card, no SIM must be currently attached */
-int gsm_subscr_testcard(struct osmocom_ms *ms, uint16_t mcc, uint16_t mnc,
- uint16_t lac, uint32_t tmsi)
-{
- struct gsm_settings *set = &ms->settings;
- struct gsm_subscriber *subscr = &ms->subscr;
- struct msgb *nmsg;
- char *error;
-
- if (subscr->sim_valid) {
- LOGP(DMM, LOGL_ERROR, "Cannot insert card, until current card "
- "is detached.\n");
- return -EBUSY;
- }
-
- error = gsm_check_imsi(set->test_imsi);
- if (error) {
- LOGP(DMM, LOGL_ERROR, "%s\n", error);
- return -EINVAL;
- }
-
- /* reset subscriber */
- gsm_subscr_exit(ms);
- gsm_subscr_init(ms);
-
- subscr->sim_type = GSM_SIM_TYPE_TEST;
- sprintf(subscr->sim_name, "test");
- subscr->sim_valid = 1;
- subscr->ustate = GSM_SIM_U2_NOT_UPDATED;
- subscr->acc_barr = set->test_barr; /* we may access barred cell */
- subscr->acc_class = 0xffff; /* we have any access class */
- subscr->plmn_valid = set->test_rplmn_valid;
- subscr->plmn_mcc = mcc;
- subscr->plmn_mnc = mnc;
- subscr->mcc = mcc;
- subscr->mnc = mnc;
- subscr->lac = lac;
- subscr->tmsi = tmsi;
- subscr->always_search_hplmn = set->test_always;
- subscr->t6m_hplmn = 1; /* try to find home network every 6 min */
- strcpy(subscr->imsi, set->test_imsi);
-
- LOGP(DMM, LOGL_INFO, "(ms %s) Inserting test card (IMSI=%s %s, %s)\n",
- ms->name, subscr->imsi, gsm_imsi_mcc(subscr->imsi),
- gsm_imsi_mnc(subscr->imsi));
-
- if (subscr->plmn_valid)
- LOGP(DMM, LOGL_INFO, "-> Test card registered to %s %s 0x%04x"
- "(%s, %s)\n", gsm_print_mcc(mcc),
- gsm_print_mnc(mnc), lac, gsm_get_mcc(mcc),
- gsm_get_mnc(mcc, mnc));
- else
- LOGP(DMM, LOGL_INFO, "-> Test card not registered\n");
-
- /* insert card */
- nmsg = gsm48_mmr_msgb_alloc(GSM48_MMR_REG_REQ);
- if (!nmsg)
- return -ENOMEM;
- gsm48_mmr_downmsg(ms, nmsg);
-
- return 0;
-}
-
-/*
- * sim card
- */
-
-static int subscr_sim_iccid(struct osmocom_ms *ms, uint8_t *data,
- uint8_t length)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
-
- strcpy(subscr->iccid, sim_decode_bcd(data, length));
- sprintf(subscr->sim_name, "sim-%s", subscr->iccid);
- LOGP(DMM, LOGL_INFO, "received ICCID %s from SIM\n", subscr->iccid);
-
- return 0;
-}
-
-static int subscr_sim_imsi(struct osmocom_ms *ms, uint8_t *data,
- uint8_t length)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- char *imsi;
-
- /* get actual length */
- if (length < 1)
- return -EINVAL;
- if (data[0] + 1 < length) {
- LOGP(DMM, LOGL_NOTICE, "invalid length = %d\n", length);
- return -EINVAL;
- }
- length = data[0];
-
- /* decode IMSI, skip first digit (parity) */
- imsi = sim_decode_bcd(data + 1, length);
- if (strlen(imsi) - 1 > GSM_IMSI_LENGTH - 1 || strlen(imsi) - 1 < 6) {
- LOGP(DMM, LOGL_NOTICE, "IMSI invalid length = %d\n",
- strlen(imsi) - 1);
- return -EINVAL;
- }
-
- strncpy(subscr->imsi, imsi + 1, sizeof(subscr->imsi) - 1);
-
- LOGP(DMM, LOGL_INFO, "received IMSI %s from SIM\n", subscr->imsi);
-
- return 0;
-}
-
-static int subscr_sim_loci(struct osmocom_ms *ms, uint8_t *data,
- uint8_t length)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm1111_ef_loci *loci;
-
- if (length < 11)
- return -EINVAL;
- loci = (struct gsm1111_ef_loci *) data;
-
- /* TMSI */
- subscr->tmsi = ntohl(loci->tmsi);
-
- /* LAI */
- gsm48_decode_lai(&loci->lai, &subscr->mcc, &subscr->mnc, &subscr->lac);
-
- /* location update status */
- switch (loci->lupd_status & 0x07) {
- case 0x00:
- subscr->ustate = GSM_SIM_U1_UPDATED;
- break;
- case 0x02:
- case 0x03:
- subscr->ustate = GSM_SIM_U3_ROAMING_NA;
- break;
- default:
- subscr->ustate = GSM_SIM_U2_NOT_UPDATED;
- }
-
- LOGP(DMM, LOGL_INFO, "received LOCI from SIM (mcc=%s mnc=%s lac=0x%04x "
- "U%d)\n", gsm_print_mcc(subscr->mcc),
- gsm_print_mnc(subscr->mnc), subscr->lac, subscr->ustate);
-
- return 0;
-}
-
-static int subscr_sim_msisdn(struct osmocom_ms *ms, uint8_t *data,
- uint8_t length)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm1111_ef_adn *adn;
-
- if (length < sizeof(*adn))
- return -EINVAL;
- adn = (struct gsm1111_ef_adn *) (data + length - sizeof(*adn));
-
- /* empty */
- subscr->msisdn[0] = '\0';
- if (adn->len_bcd <= 1)
- return 0;
-
- /* number */
- if (adn->ton_npi == 1)
- strcpy(subscr->msisdn, "+");
- if (adn->ton_npi == 2)
- strcpy(subscr->msisdn, "0");
- strncat(subscr->msisdn, sim_decode_bcd(adn->number, adn->len_bcd - 1),
- sizeof(subscr->msisdn) - 2);
-
- LOGP(DMM, LOGL_INFO, "received MSISDN %s from SIM\n", subscr->msisdn);
-
- return 0;
-}
-
-static int subscr_sim_kc(struct osmocom_ms *ms, uint8_t *data,
- uint8_t length)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
-
- if (length < 9)
- return -EINVAL;
-
- /* key */
- memcpy(subscr->key, data, 8);
-
- /* key sequence */
- subscr->key_seq = data[8] & 0x07;
-
- LOGP(DMM, LOGL_INFO, "received KEY from SIM\n");
-
- return 0;
-}
-
-static int subscr_sim_plmnsel(struct osmocom_ms *ms, uint8_t *data,
- uint8_t length)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm_sub_plmn_list *plmn;
- struct llist_head *lh, *lh2;
- uint8_t lai[5];
- uint16_t dummy_lac;
-
- /* flush list */
- llist_for_each_safe(lh, lh2, &subscr->plmn_list) {
- llist_del(lh);
- talloc_free(lh);
- }
-
- while(length >= 3) {
- /* end of list inside mandatory fields */
- if (data[0] == 0xff && data[1] == 0xff && data[2] == 0x0ff)
- break;
-
- /* add to list */
- plmn = talloc_zero(l23_ctx, struct gsm_sub_plmn_list);
- if (!plmn)
- return -ENOMEM;
- lai[0] = data[0];
- lai[1] = data[1];
- lai[2] = data[2];
- gsm48_decode_lai((struct gsm48_loc_area_id *)lai, &plmn->mcc,
- &plmn->mnc, &dummy_lac);
- llist_add_tail(&plmn->entry, &subscr->plmn_list);
-
- LOGP(DMM, LOGL_INFO, "received PLMN selector (mcc=%s mnc=%s) "
- "from SIM\n",
- gsm_print_mcc(plmn->mcc), gsm_print_mnc(plmn->mnc));
-
- data += 3;
- length -= 3;
- }
-
- return 0;
-}
-
-static int subscr_sim_hpplmn(struct osmocom_ms *ms, uint8_t *data,
- uint8_t length)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
-
- if (length < 1)
- return -EINVAL;
-
- /* HPLMN search interval */
- subscr->t6m_hplmn = *data; /* multiple of 6 minutes */
-
- LOGP(DMM, LOGL_INFO, "received HPPLMN %d (%d mins) from SIM\n",
- subscr->t6m_hplmn, subscr->t6m_hplmn * 6);
-
- return 0;
-}
-
-static int subscr_sim_spn(struct osmocom_ms *ms, uint8_t *data,
- uint8_t length)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- int i;
-
- /* UCS2 code not supported */
- if (length < 17 || data[1] >= 0x80)
- return -ENOTSUP;
-
- data++;
- for (i = 0; i < 16; i++) {
- if (*data == 0xff)
- break;
- subscr->sim_spn[i] = *data++;
- }
- subscr->sim_spn[i] = '\0';
-
- LOGP(DMM, LOGL_INFO, "received SPN %s from SIM\n", subscr->sim_spn);
-
- return 0;
-}
-
-static int subscr_sim_acc(struct osmocom_ms *ms, uint8_t *data,
- uint8_t length)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- uint16_t ac;
-
- if (length < 2)
- return -EINVAL;
-
- /* cell access */
- memcpy(&ac, data, sizeof(ac));
- subscr->acc_class = ntohs(ac);
-
- LOGP(DMM, LOGL_INFO, "received ACC %04x from SIM\n", subscr->acc_class);
-
- return 0;
-}
-
-static int subscr_sim_fplmn(struct osmocom_ms *ms, uint8_t *data,
- uint8_t length)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm_sub_plmn_na *na;
- struct llist_head *lh, *lh2;
- uint8_t lai[5];
- uint16_t dummy_lac;
-
-#ifdef TEST_EMPTY_FPLMN
- return 0;
-#endif
-
- /* flush list */
- llist_for_each_safe(lh, lh2, &subscr->plmn_na) {
- llist_del(lh);
- talloc_free(lh);
- }
-
- while (length >= 3) {
- /* end of list inside mandatory fields */
- if (data[0] == 0xff && data[1] == 0xff && data[2] == 0x0ff)
- break;
-
- /* add to list */
- na = talloc_zero(l23_ctx, struct gsm_sub_plmn_na);
- if (!na)
- return -ENOMEM;
- lai[0] = data[0];
- lai[1] = data[1];
- lai[2] = data[2];
- gsm48_decode_lai((struct gsm48_loc_area_id *)lai, &na->mcc,
- &na->mnc, &dummy_lac);
- na->cause = -1; /* must have a value, but SIM stores no cause */
- llist_add_tail(&na->entry, &subscr->plmn_na);
-
- data += 3;
- length -= 3;
- }
- return 0;
-}
-
-static struct subscr_sim_file {
- uint8_t mandatory;
- uint16_t path[MAX_SIM_PATH_LENGTH];
- uint16_t file;
- int (*func)(struct osmocom_ms *ms, uint8_t *data,
- uint8_t length);
-} subscr_sim_files[] = {
- { 1, { 0 }, 0x2fe2, subscr_sim_iccid },
- { 1, { 0x7f20, 0 }, 0x6f07, subscr_sim_imsi },
- { 1, { 0x7f20, 0 }, 0x6f7e, subscr_sim_loci },
- { 0, { 0x7f10, 0 }, 0x6f40, subscr_sim_msisdn },
- { 0, { 0x7f20, 0 }, 0x6f20, subscr_sim_kc },
- { 0, { 0x7f20, 0 }, 0x6f30, subscr_sim_plmnsel },
- { 0, { 0x7f20, 0 }, 0x6f31, subscr_sim_hpplmn },
- { 0, { 0x7f20, 0 }, 0x6f46, subscr_sim_spn },
- { 0, { 0x7f20, 0 }, 0x6f78, subscr_sim_acc },
- { 0, { 0x7f20, 0 }, 0x6f7b, subscr_sim_fplmn },
- { 0, { 0 }, 0, NULL }
-};
-
-/* request file from SIM */
-static int subscr_sim_request(struct osmocom_ms *ms)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct subscr_sim_file *sf = &subscr_sim_files[subscr->sim_file_index];
- struct msgb *nmsg;
- struct sim_hdr *nsh;
- int i;
-
- /* we are done, fire up PLMN and cell selection process */
- if (!sf->func) {
- LOGP(DMM, LOGL_INFO, "(ms %s) Done reading SIM card "
- "(IMSI=%s %s, %s)\n", ms->name, subscr->imsi,
- gsm_imsi_mcc(subscr->imsi), gsm_imsi_mnc(subscr->imsi));
-
- /* if LAI is valid, set RPLMN */
- if (subscr->lac > 0x0000 && subscr->lac < 0xfffe) {
- subscr->plmn_valid = 1;
- subscr->plmn_mcc = subscr->mcc;
- subscr->plmn_mnc = subscr->mnc;
- LOGP(DMM, LOGL_INFO, "-> SIM card registered to %s %s "
- "(%s, %s)\n", gsm_print_mcc(subscr->plmn_mcc),
- gsm_print_mnc(subscr->plmn_mnc),
- gsm_get_mcc(subscr->plmn_mcc),
- gsm_get_mnc(subscr->plmn_mcc,
- subscr->plmn_mnc));
- } else
- LOGP(DMM, LOGL_INFO, "-> SIM card not registered\n");
-
- /* insert card */
- nmsg = gsm48_mmr_msgb_alloc(GSM48_MMR_REG_REQ);
- if (!nmsg)
- return -ENOMEM;
- gsm48_mmr_downmsg(ms, nmsg);
-
- return 0;
- }
-
- /* trigger SIM reading */
- nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_query,
- SIM_JOB_READ_BINARY);
- if (!nmsg)
- return -ENOMEM;
- nsh = (struct sim_hdr *) nmsg->data;
- i = 0;
- while (sf->path[i]) {
- nsh->path[i] = sf->path[i];
- i++;
- }
- nsh->path[i] = 0; /* end of path */
- nsh->file = sf->file;
- LOGP(DMM, LOGL_INFO, "Requesting SIM file 0x%04x\n", nsh->file);
- sim_job(ms, nmsg);
-
- return 0;
-}
-
-static void subscr_sim_query_cb(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct sim_hdr *sh = (struct sim_hdr *) msg->data;
- uint8_t *payload = msg->data + sizeof(*sh);
- uint16_t payload_len = msg->len - sizeof(*sh);
- int rc;
- struct subscr_sim_file *sf = &subscr_sim_files[subscr->sim_file_index];
- struct msgb *nmsg;
-
- /* error handling */
- if (sh->job_type == SIM_JOB_ERROR) {
- uint8_t cause = payload[0];
-
- switch (cause) {
- /* unlocking required */
- case SIM_CAUSE_PIN1_REQUIRED:
- LOGP(DMM, LOGL_INFO, "PIN is required, %d tries left\n",
- payload[1]);
-
- vty_notify(ms, NULL);
- vty_notify(ms, "Please give PIN for ICCID %s (you have "
- "%d tries left)\n", subscr->iccid, payload[1]);
- subscr->sim_pin_required = 1;
- break;
- case SIM_CAUSE_PIN1_BLOCKED:
- LOGP(DMM, LOGL_NOTICE, "PIN is blocked\n");
-
- vty_notify(ms, NULL);
- vty_notify(ms, "PIN is blocked\n");
- if (payload[1]) {
- vty_notify(ms, "Please give PUC for ICCID %s "
- "(you have %d tries left)\n",
- subscr->iccid, payload[1]);
- }
- subscr->sim_pin_required = 1;
- break;
- case SIM_CAUSE_PUC_BLOCKED:
- LOGP(DMM, LOGL_NOTICE, "PUC is blocked\n");
-
- vty_notify(ms, NULL);
- vty_notify(ms, "PUC is blocked\n");
- subscr->sim_pin_required = 1;
- break;
- default:
- if (sf->func && !sf->mandatory) {
- LOGP(DMM, LOGL_NOTICE, "SIM reading failed, "
- "ignoring!\n");
- goto ignore;
- }
- LOGP(DMM, LOGL_NOTICE, "SIM reading failed\n");
-
- vty_notify(ms, NULL);
- vty_notify(ms, "SIM failed, replace SIM!\n");
-
- /* detach simcard */
- subscr->sim_valid = 0;
- nmsg = gsm48_mmr_msgb_alloc(GSM48_MMR_NREG_REQ);
- if (!nmsg)
- return;
- gsm48_mmr_downmsg(ms, nmsg);
- }
- msgb_free(msg);
-
- return;
- }
-
- /* if pin was successfully unlocked, then resend request */
- if (subscr->sim_pin_required) {
- subscr->sim_pin_required = 0;
- subscr_sim_request(ms);
- return;
- }
-
- /* done when nothing more to read. this happens on PIN requests */
- if (!sf->func)
- return;
-
- /* call function do decode SIM reply */
- rc = sf->func(ms, payload, payload_len);
- if (rc) {
- LOGP(DMM, LOGL_NOTICE, "SIM reading failed, file invalid\n");
- if (subscr_sim_files[subscr->sim_file_index].mandatory) {
- vty_notify(ms, NULL);
- vty_notify(ms, "SIM failed, data invalid, replace "
- "SIM!\n");
- msgb_free(msg);
-
- return;
- }
- }
-
-ignore:
- msgb_free(msg);
-
- /* trigger next file */
- subscr->sim_file_index++;
- subscr_sim_request(ms);
-}
-
-/* enter PIN */
-void gsm_subscr_sim_pin(struct osmocom_ms *ms, char *pin1, char *pin2,
- int8_t mode)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct msgb *nmsg;
- uint8_t job;
-
- /* skip, if no real valid SIM */
- if (subscr->sim_type != GSM_SIM_TYPE_READER)
- return;
-
- switch (mode) {
- case -1:
- job = SIM_JOB_PIN1_DISABLE;
- LOGP(DMM, LOGL_INFO, "disabling PIN %s\n", pin1);
- break;
- case 1:
- job = SIM_JOB_PIN1_ENABLE;
- LOGP(DMM, LOGL_INFO, "enabling PIN %s\n", pin1);
- break;
- case 2:
- job = SIM_JOB_PIN1_CHANGE;
- LOGP(DMM, LOGL_INFO, "changing PIN %s to %s\n", pin1, pin2);
- break;
- case 99:
- job = SIM_JOB_PIN1_UNBLOCK;
- LOGP(DMM, LOGL_INFO, "unblocking PIN %s with PUC %s\n", pin1,
- pin2);
- break;
- default:
- if (!subscr->sim_pin_required) {
- LOGP(DMM, LOGL_ERROR, "No PIN required now\n");
- return;
- }
- LOGP(DMM, LOGL_INFO, "entering PIN %s\n", pin1);
- job = SIM_JOB_PIN1_UNLOCK;
- }
-
- nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_query, job);
- if (!nmsg)
- return;
- memcpy(msgb_put(nmsg, strlen(pin1) + 1), pin1, strlen(pin1) + 1);
- memcpy(msgb_put(nmsg, strlen(pin2) + 1), pin2, strlen(pin2) + 1);
- sim_job(ms, nmsg);
-}
-
-/* Attach SIM reader, no SIM must be currently attached */
-int gsm_subscr_simcard(struct osmocom_ms *ms)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
-
- if (subscr->sim_valid) {
- LOGP(DMM, LOGL_ERROR, "Cannot attach card, until current card "
- "is detached.\n");
- return -EBUSY;
- }
-
- /* reset subscriber */
- gsm_subscr_exit(ms);
- gsm_subscr_init(ms);
-
- subscr->sim_type = GSM_SIM_TYPE_READER;
- sprintf(subscr->sim_name, "sim");
- subscr->sim_valid = 1;
- subscr->ustate = GSM_SIM_U2_NOT_UPDATED;
-
- /* start with first index */
- subscr->sim_file_index = 0;
- return subscr_sim_request(ms);
-}
-
-/* update plmn not allowed list on SIM */
-static int subscr_write_plmn_na(struct osmocom_ms *ms)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct msgb *nmsg;
- struct sim_hdr *nsh;
- struct gsm_sub_plmn_na *na, *nas[4] = { NULL, NULL, NULL, NULL };
- int count = 0, i;
- uint8_t *data;
- uint8_t lai[5];
-
-#ifdef TEST_EMPTY_FPLMN
- return 0;
-#endif
-
- /* skip, if no real valid SIM */
- if (subscr->sim_type != GSM_SIM_TYPE_READER || !subscr->sim_valid)
- return 0;
-
- /* get tail list from "PLMN not allowed" */
- llist_for_each_entry(na, &subscr->plmn_na, entry) {
- if (count < 4)
- nas[count] = na;
- else {
- nas[0] = nas[1];
- nas[1] = nas[2];
- nas[2] = nas[3];
- nas[3] = na;
- }
- count++;
- }
-
- /* write to SIM */
- LOGP(DMM, LOGL_INFO, "Updating FPLMN on SIM\n");
- nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_update,
- SIM_JOB_UPDATE_BINARY);
- if (!nmsg)
- return -ENOMEM;
- nsh = (struct sim_hdr *) nmsg->data;
- data = msgb_put(nmsg, 12);
- nsh->path[0] = 0x7f20;
- nsh->path[1] = 0;
- nsh->file = 0x6f7b;
- for (i = 0; i < 4; i++) {
- if (nas[i]) {
- gsm48_encode_lai((struct gsm48_loc_area_id *)lai,
- nas[i]->mcc, nas[i]->mnc, 0);
- *data++ = lai[0];
- *data++ = lai[1];
- *data++ = lai[2];
- } else {
- *data++ = 0xff;
- *data++ = 0xff;
- *data++ = 0xff;
- }
- }
- sim_job(ms, nmsg);
-
- return 0;
-}
-
-/* update LOCI on SIM */
-int gsm_subscr_write_loci(struct osmocom_ms *ms)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct msgb *nmsg;
- struct sim_hdr *nsh;
- struct gsm1111_ef_loci *loci;
-
- /* skip, if no real valid SIM */
- if (subscr->sim_type != GSM_SIM_TYPE_READER || !subscr->sim_valid)
- return 0;
-
- LOGP(DMM, LOGL_INFO, "Updating LOCI on SIM\n");
-
- /* write to SIM */
- nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_update,
- SIM_JOB_UPDATE_BINARY);
- if (!nmsg)
- return -ENOMEM;
- nsh = (struct sim_hdr *) nmsg->data;
- nsh->path[0] = 0x7f20;
- nsh->path[1] = 0;
- nsh->file = 0x6f7e;
- loci = (struct gsm1111_ef_loci *)msgb_put(nmsg, sizeof(*loci));
-
- /* TMSI */
- loci->tmsi = htonl(subscr->tmsi);
-
- /* LAI */
- gsm48_encode_lai(&loci->lai, subscr->mcc, subscr->mnc, subscr->lac);
-
- /* TMSI time */
- loci->tmsi_time = 0xff;
-
- /* location update status */
- switch (subscr->ustate) {
- case GSM_SIM_U1_UPDATED:
- loci->lupd_status = 0x00;
- break;
- case GSM_SIM_U3_ROAMING_NA:
- loci->lupd_status = 0x03;
- break;
- default:
- loci->lupd_status = 0x01;
- }
-
- sim_job(ms, nmsg);
-
- return 0;
-}
-
-static void subscr_sim_update_cb(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct sim_hdr *sh = (struct sim_hdr *) msg->data;
- uint8_t *payload = msg->data + sizeof(*sh);
-
- /* error handling */
- if (sh->job_type == SIM_JOB_ERROR)
- LOGP(DMM, LOGL_NOTICE, "SIM update failed (cause %d)\n",
- *payload);
-
- msgb_free(msg);
-}
-
-int gsm_subscr_generate_kc(struct osmocom_ms *ms, uint8_t key_seq,
- uint8_t *rand, uint8_t no_sim)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct msgb *nmsg;
- struct sim_hdr *nsh;
-
- /* not a SIM */
- if ((subscr->sim_type != GSM_SIM_TYPE_READER
- && subscr->sim_type != GSM_SIM_TYPE_TEST)
- || !subscr->sim_valid || no_sim) {
- struct gsm48_mm_event *nmme;
-
- LOGP(DMM, LOGL_INFO, "Sending dummy authentication response\n");
- nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_AUTH_RESPONSE);
- if (!nmsg)
- return -ENOMEM;
- nmme = (struct gsm48_mm_event *) nmsg->data;
- nmme->sres[0] = 0x12;
- nmme->sres[1] = 0x34;
- nmme->sres[2] = 0x56;
- nmme->sres[3] = 0x78;
- gsm48_mmevent_msg(ms, nmsg);
-
- return 0;
- }
-
- /* test SIM */
- if (subscr->sim_type == GSM_SIM_TYPE_TEST) {
- struct gsm48_mm_event *nmme;
- uint8_t sres[4];
- struct gsm_settings *set = &ms->settings;
-
- if (set->test_ki_type == GSM_SIM_KEY_COMP128)
- comp128(set->test_ki, rand, sres, subscr->key);
- else
- xor96(set->test_ki, rand, sres, subscr->key);
- /* store sequence */
- subscr->key_seq = key_seq;
-
- LOGP(DMM, LOGL_INFO, "Sending authentication response\n");
- nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_AUTH_RESPONSE);
- if (!nmsg)
- return -ENOMEM;
- nmme = (struct gsm48_mm_event *) nmsg->data;
- memcpy(nmme->sres, sres, 4);
- gsm48_mmevent_msg(ms, nmsg);
-
- return 0;
- }
-
- LOGP(DMM, LOGL_INFO, "Generating KEY at SIM\n");
-
- /* command to SIM */
- nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_key, SIM_JOB_RUN_GSM_ALGO);
- if (!nmsg)
- return -ENOMEM;
- nsh = (struct sim_hdr *) nmsg->data;
- nsh->path[0] = 0x7f20;
- nsh->path[1] = 0;
-
- /* random */
- memcpy(msgb_put(nmsg, 16), rand, 16);
-
- /* store sequence */
- subscr->key_seq = key_seq;
-
- sim_job(ms, nmsg);
-
- return 0;
-}
-
-static void subscr_sim_key_cb(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct sim_hdr *sh = (struct sim_hdr *) msg->data;
- uint8_t *payload = msg->data + sizeof(*sh);
- uint16_t payload_len = msg->len - sizeof(*sh);
- struct msgb *nmsg;
- struct sim_hdr *nsh;
- struct gsm48_mm_event *nmme;
- uint8_t *data;
-
- /* error handling */
- if (sh->job_type == SIM_JOB_ERROR) {
- LOGP(DMM, LOGL_NOTICE, "key generation on SIM failed "
- "(cause %d)\n", *payload);
-
- msgb_free(msg);
-
- return;
- }
-
- if (payload_len < 12) {
- LOGP(DMM, LOGL_NOTICE, "response from SIM too short\n");
- return;
- }
-
- /* store key */
- memcpy(subscr->key, payload + 4, 8);
-
- /* write to SIM */
- LOGP(DMM, LOGL_INFO, "Updating KC on SIM\n");
- nmsg = gsm_sim_msgb_alloc(subscr->sim_handle_update,
- SIM_JOB_UPDATE_BINARY);
- if (!nmsg)
- return;
- nsh = (struct sim_hdr *) nmsg->data;
- nsh->path[0] = 0x7f20;
- nsh->path[1] = 0;
- nsh->file = 0x6f20;
- data = msgb_put(nmsg, 9);
- memcpy(data, subscr->key, 8);
- data[8] = subscr->key_seq;
- sim_job(ms, nmsg);
-
- /* return signed response */
- nmsg = gsm48_mmevent_msgb_alloc(GSM48_MM_EVENT_AUTH_RESPONSE);
- if (!nmsg)
- return;
- nmme = (struct gsm48_mm_event *) nmsg->data;
- memcpy(nmme->sres, payload, 4);
- gsm48_mmevent_msg(ms, nmsg);
-
- msgb_free(msg);
-}
-
-/*
- * detach
- */
-
-/* Detach card */
-int gsm_subscr_remove(struct osmocom_ms *ms)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct msgb *nmsg;
-
- if (!subscr->sim_valid) {
- LOGP(DMM, LOGL_ERROR, "Cannot remove card, no card present\n");
- return -EINVAL;
- }
-
- /* remove card */
- nmsg = gsm48_mmr_msgb_alloc(GSM48_MMR_NREG_REQ);
- if (!nmsg)
- return -ENOMEM;
- gsm48_mmr_downmsg(ms, nmsg);
-
- return 0;
-}
-
-/*
- * state and lists
- */
-
-static const char *subscr_ustate_names[] = {
- "U0_NULL",
- "U1_UPDATED",
- "U2_NOT_UPDATED",
- "U3_ROAMING_NA"
-};
-
-/* change to new U state */
-void new_sim_ustate(struct gsm_subscriber *subscr, int state)
-{
- LOGP(DMM, LOGL_INFO, "(ms %s) new state %s -> %s\n", subscr->ms->name,
- subscr_ustate_names[subscr->ustate],
- subscr_ustate_names[state]);
-
- subscr->ustate = state;
-}
-
-/* del forbidden PLMN. if MCC==0, flush complete list */
-int gsm_subscr_del_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc,
- uint16_t mnc)
-{
- struct gsm_sub_plmn_na *na, *na2;
- int deleted = 0;
-
- llist_for_each_entry_safe(na, na2, &subscr->plmn_na, entry) {
- if (!mcc || (na->mcc == mcc && na->mnc == mnc)) {
- LOGP(DPLMN, LOGL_INFO, "Delete from list of forbidden "
- "PLMNs (mcc=%s, mnc=%s)\n",
- gsm_print_mcc(mcc), gsm_print_mnc(mnc));
- llist_del(&na->entry);
- talloc_free(na);
- deleted = 1;
- if (mcc)
- break;
- }
- }
-
- if (deleted) {
- /* update plmn not allowed list on SIM */
- subscr_write_plmn_na(subscr->ms);
- }
-
- return -EINVAL;
-}
-
-/* add forbidden PLMN */
-int gsm_subscr_add_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc,
- uint16_t mnc, uint8_t cause)
-{
- struct gsm_sub_plmn_na *na;
-
- /* if already in the list, remove and add to tail */
- gsm_subscr_del_forbidden_plmn(subscr, mcc, mnc);
-
- LOGP(DPLMN, LOGL_INFO, "Add to list of forbidden PLMNs "
- "(mcc=%s, mnc=%s)\n", gsm_print_mcc(mcc), gsm_print_mnc(mnc));
- na = talloc_zero(l23_ctx, struct gsm_sub_plmn_na);
- if (!na)
- return -ENOMEM;
- na->mcc = mcc;
- na->mnc = mnc;
- na->cause = cause ? : -1; /* cause 0 is not allowed */
- llist_add_tail(&na->entry, &subscr->plmn_na);
-
- /* don't add Home PLMN to SIM */
- if (subscr->sim_valid && gsm_match_mnc(mcc, mnc, subscr->imsi))
- return -EINVAL;
-
- /* update plmn not allowed list on SIM */
- subscr_write_plmn_na(subscr->ms);
-
- return 0;
-}
-
-/* search forbidden PLMN */
-int gsm_subscr_is_forbidden_plmn(struct gsm_subscriber *subscr, uint16_t mcc,
- uint16_t mnc)
-{
- struct gsm_sub_plmn_na *na;
-
- llist_for_each_entry(na, &subscr->plmn_na, entry) {
- if (na->mcc == mcc && na->mnc == mnc)
- return 1;
- }
-
- return 0;
-}
-
-int gsm_subscr_dump_forbidden_plmn(struct osmocom_ms *ms,
- void (*print)(void *, const char *, ...), void *priv)
-{
- struct gsm_subscriber *subscr = &ms->subscr;
- struct gsm_sub_plmn_na *temp;
-
- print(priv, "MCC |MNC |cause\n");
- print(priv, "-------+-------+-------\n");
- llist_for_each_entry(temp, &subscr->plmn_na, entry)
- print(priv, "%s |%s%s |#%d\n",
- gsm_print_mcc(temp->mcc), gsm_print_mnc(temp->mnc),
- ((temp->mnc & 0x00f) == 0x00f) ? " ":"", temp->cause);
-
- return 0;
-}
-
-/* dump subscriber */
-void gsm_subscr_dump(struct gsm_subscriber *subscr,
- void (*print)(void *, const char *, ...), void *priv)
-{
- int i;
- struct gsm_sub_plmn_list *plmn_list;
- struct gsm_sub_plmn_na *plmn_na;
-
- print(priv, "Mobile Subscriber of MS '%s':\n", subscr->ms->name);
-
- if (!subscr->sim_valid) {
- print(priv, " No SIM present.\n");
- return;
- }
-
- print(priv, " IMSI: %s\n", subscr->imsi);
- if (subscr->iccid[0])
- print(priv, " ICCID: %s\n", subscr->iccid);
- if (subscr->sim_spn[0])
- print(priv, " Service Provider Name: %s\n", subscr->sim_spn);
- if (subscr->msisdn[0])
- print(priv, " MSISDN: %s\n", subscr->msisdn);
- print(priv, " Status: %s IMSI %s", subscr_ustate_names[subscr->ustate],
- (subscr->imsi_attached) ? "attached" : "detached");
- if (subscr->tmsi != 0xffffffff)
- print(priv, " TSMI 0x%08x", subscr->tmsi);
- if (subscr->lac > 0x0000 && subscr->lac < 0xfffe) {
- print(priv, "\n");
- print(priv, " LAI: MCC %s MNC %s LAC 0x%04x "
- "(%s, %s)\n", gsm_print_mcc(subscr->mcc),
- gsm_print_mnc(subscr->mnc), subscr->lac,
- gsm_get_mcc(subscr->mcc),
- gsm_get_mnc(subscr->mcc, subscr->mnc));
- } else
- print(priv, " LAI: invalid\n");
- if (subscr->key_seq != 7) {
- print(priv, " Key: sequence %d ", subscr->key_seq);
- for (i = 0; i < sizeof(subscr->key); i++)
- print(priv, " %02x", subscr->key[i]);
- print(priv, "\n");
- }
- if (subscr->plmn_valid)
- print(priv, " Registered PLMN: MCC %s MNC %s (%s, %s)\n",
- gsm_print_mcc(subscr->plmn_mcc),
- gsm_print_mnc(subscr->plmn_mnc),
- gsm_get_mcc(subscr->plmn_mcc),
- gsm_get_mnc(subscr->plmn_mcc, subscr->plmn_mnc));
- print(priv, " Access barred cells: %s\n",
- (subscr->acc_barr) ? "yes" : "no");
- print(priv, " Access classes:");
- for (i = 0; i < 16; i++)
- if ((subscr->acc_class & (1 << i)))
- print(priv, " C%d", i);
- print(priv, "\n");
- if (!llist_empty(&subscr->plmn_list)) {
- print(priv, " List of preferred PLMNs:\n");
- print(priv, " MCC |MNC\n");
- print(priv, " -------+-------\n");
- llist_for_each_entry(plmn_list, &subscr->plmn_list, entry)
- print(priv, " %s |%s (%s, %s)\n",
- gsm_print_mcc(plmn_list->mcc),
- gsm_print_mnc(plmn_list->mnc),
- gsm_get_mcc(plmn_list->mcc),
- gsm_get_mnc(plmn_list->mcc, plmn_list->mnc));
- }
- if (!llist_empty(&subscr->plmn_na)) {
- print(priv, " List of forbidden PLMNs:\n");
- print(priv, " MCC |MNC |cause\n");
- print(priv, " -------+-------+-------\n");
- llist_for_each_entry(plmn_na, &subscr->plmn_na, entry)
- print(priv, " %s |%s%s |#%d "
- "(%s, %s)\n", gsm_print_mcc(plmn_na->mcc),
- gsm_print_mnc(plmn_na->mnc),
- ((plmn_na->mnc & 0x00f) == 0x00f) ? " ":"",
- plmn_na->cause, gsm_get_mcc(plmn_na->mcc),
- gsm_get_mnc(plmn_na->mcc, plmn_na->mnc));
- }
-}
-
diff --git a/Src/osmoconbb/src/host/layer23/src/mobile/support.c b/Src/osmoconbb/src/host/layer23/src/mobile/support.c
deleted file mode 100644
index c4269ac..0000000
--- a/Src/osmoconbb/src/host/layer23/src/mobile/support.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-
-#include <osmocom/bb/common/osmocom_data.h>
-
-void gsm_support_init(struct osmocom_ms *ms)
-{
- struct gsm_support *sup = &ms->support;
-
- memset(sup, 0, sizeof(*sup));
- sup->ms = ms;
-
- /* controlled early classmark sending */
- sup->es_ind = 0; /* no */
- /* revision level */
- sup->rev_lev = 1; /* phase 2 mobile station */
- /* support of VGCS */
- sup->vgcs = 0; /* no */
- /* support of VBS */
- sup->vbs = 0; /* no */
- /* support of SMS */
- sup->sms_ptp = 0; /* no */
- /* screening indicator */
- sup->ss_ind = 1; /* phase 2 error handling */
- /* pseudo synchronised capability */
- sup->ps_cap = 0; /* no */
- /* CM service prompt */
- sup->cmsp = 0; /* no */
- /* solsa support */
- sup->solsa = 0; /* no */
- /* location service support */
- sup->lcsva = 0; /* no */
- sup->loc_serv = 0; /* no */
- /* codec supprot */
- sup->a5_1 = 1;
- sup->a5_2 = 1;
- sup->a5_3 = 0;
- sup->a5_4 = 0;
- sup->a5_5 = 0;
- sup->a5_6 = 0;
- sup->a5_7 = 0;
- /* radio support */
- sup->p_gsm = 1; /* P-GSM */
- sup->e_gsm = 1; /* E-GSM */
- sup->r_gsm = 1; /* R-GSM */
- sup->dcs = 1;
- sup->gsm_850 = 1;
- sup->pcs = 1;
- sup->gsm_480 = 0;
- sup->gsm_450 = 0;
- /* rf power capability */
- sup->class_900 = 4; /* CLASS 4: Handheld 2W */
- sup->class_850 = 4;
- sup->class_400 = 4;
- sup->class_dcs = 1; /* CLASS 1: Handheld 1W */
- sup->class_pcs = 1;
- /* multi slot support */
- sup->ms_sup = 0; /* no */
- /* ucs2 treatment */
- sup->ucs2_treat = 0; /* default */
- /* support extended measurements */
- sup->ext_meas = 0; /* no */
- /* support switched measurement capability */
- sup->meas_cap = 0; /* no */
- //sup->sms_val = ;
- //sup->sm_val = ;
-
- /* radio */
- sup->ch_cap = GSM_CAP_SDCCH_TCHF_TCHH;
- sup->min_rxlev_db = -106; // TODO
- sup->sync_to = 6; /* how long to wait sync (0.9 s) */
- sup->scan_to = 4; /* how long to wait for all sysinfos (>=4 s) */
- sup->dsc_max = 90; /* the specs defines 90 */
-
- /* codec */
- sup->full_v1 = 1;
- sup->full_v2 = 1;
- sup->full_v3 = 0;
- sup->half_v1 = 1;
- sup->half_v3 = 0;
-}
-
-/* (3.2.1) maximum channels to scan within each band */
-struct gsm_support_scan_max gsm_sup_smax[] = {
- { 259, 293, 15, 0 }, /* GSM 450 */
- { 306, 340, 15, 0 }, /* GSM 480 */
- { 438, 511, 25, 0 },
- { 128, 251, 30, 0 }, /* GSM 850 */
- { 955, 124, 30, 0 }, /* P,E,R GSM */
- { 512, 885, 40, 0 }, /* DCS 1800 */
- { 1024, 1322, 40, 0 }, /* PCS 1900 */
- { 0, 0, 0, 0 }
-};
-
-#define SUP_SET(item) \
- ((sup->item) ? ((set->item) ? "yes" : "disabled") : "no")
-/* dump support */
-void gsm_support_dump(struct osmocom_ms *ms,
- void (*print)(void *, const char *, ...), void *priv)
-{
- struct gsm_support *sup = &ms->support;
- struct gsm_settings *set = &ms->settings;
-
- print(priv, "Supported features of MS '%s':\n", sup->ms->name);
- print(priv, " Phase %d mobile station\n", sup->rev_lev + 1);
- print(priv, " R-GSM : %s\n", SUP_SET(r_gsm));
- print(priv, " E-GSM : %s\n", SUP_SET(e_gsm));
- print(priv, " P-GSM : %s\n", SUP_SET(p_gsm));
- if (set->r_gsm || set->e_gsm || set->p_gsm)
- print(priv, " GSM900 Class : %d\n", set->class_900);
- print(priv, " DCS 1800 : %s\n", SUP_SET(dcs));
- if (set->dcs)
- print(priv, " DCS Class : %d\n", set->class_dcs);
- print(priv, " GSM 850 : %s\n", SUP_SET(gsm_850));
- if (set->gsm_850)
- print(priv, " GSM 850 Class: %d\n", set->class_850);
- print(priv, " PCS 1900 : %s\n", SUP_SET(pcs));
- if (set->pcs)
- print(priv, " PCS Class : %d\n", set->class_pcs);
- print(priv, " GSM 480 : %s\n", SUP_SET(gsm_480));
- print(priv, " GSM 450 : %s\n", SUP_SET(gsm_450));
- if (set->gsm_480 | set->gsm_450)
- print(priv, " GSM 400 Class: %d\n", set->class_400);
- print(priv, " CECS : %s\n", (sup->es_ind) ? "yes" : "no");
- print(priv, " VGCS : %s\n", (sup->vgcs) ? "yes" : "no");
- print(priv, " VBS : %s\n", (sup->vbs) ? "yes" : "no");
- print(priv, " SMS : %s\n", SUP_SET(sms_ptp));
- print(priv, " SS_IND : %s\n", (sup->ss_ind) ? "yes" : "no");
- print(priv, " PS_CAP : %s\n", (sup->ps_cap) ? "yes" : "no");
- print(priv, " CMSP : %s\n", (sup->cmsp) ? "yes" : "no");
- print(priv, " SoLSA : %s\n", (sup->solsa) ? "yes" : "no");
- print(priv, " LCSVA : %s\n", (sup->lcsva) ? "yes" : "no");
- print(priv, " LOC_SERV : %s\n", (sup->loc_serv) ? "yes" : "no");
- print(priv, " A5/1 : %s\n", SUP_SET(a5_1));
- print(priv, " A5/2 : %s\n", SUP_SET(a5_2));
- print(priv, " A5/3 : %s\n", SUP_SET(a5_3));
- print(priv, " A5/4 : %s\n", SUP_SET(a5_4));
- print(priv, " A5/5 : %s\n", SUP_SET(a5_5));
- print(priv, " A5/6 : %s\n", SUP_SET(a5_6));
- print(priv, " A5/7 : %s\n", SUP_SET(a5_7));
- print(priv, " A5/1 : %s\n", SUP_SET(a5_1));
- switch (set->ch_cap) {
- case GSM_CAP_SDCCH:
- print(priv, " Channels : SDCCH only\n");
- break;
- case GSM_CAP_SDCCH_TCHF:
- print(priv, " Channels : SDCCH + TCH/F\n");
- break;
- case GSM_CAP_SDCCH_TCHF_TCHH:
- print(priv, " Channels : SDCCH + TCH/F + TCH/H\n");
- break;
- }
- print(priv, " Full-Rate V1 : %s\n", SUP_SET(full_v1));
- print(priv, " Full-Rate V2 : %s\n", SUP_SET(full_v2));
- print(priv, " Full-Rate V3 : %s\n", SUP_SET(full_v3));
- print(priv, " Half-Rate V1 : %s\n", SUP_SET(half_v1));
- print(priv, " Half-Rate V3 : %s\n", SUP_SET(half_v3));
- print(priv, " Min RXLEV : %d\n", set->min_rxlev_db);
-}
-
diff --git a/Src/osmoconbb/src/host/layer23/src/mobile/transaction.c b/Src/osmoconbb/src/host/layer23/src/mobile/transaction.c
deleted file mode 100644
index 4b66050..0000000
--- a/Src/osmoconbb/src/host/layer23/src/mobile/transaction.c
+++ /dev/null
@@ -1,143 +0,0 @@
-/* GSM 04.07 Transaction handling */
-
-/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdint.h>
-
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/timer.h>
-#include <osmocom/core/msgb.h>
-
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/logging.h>
-#include <osmocom/bb/mobile/mncc.h>
-#include <osmocom/bb/mobile/transaction.h>
-
-extern void *l23_ctx;
-
-void _gsm48_cc_trans_free(struct gsm_trans *trans);
-
-struct gsm_trans *trans_find_by_id(struct osmocom_ms *ms,
- uint8_t proto, uint8_t trans_id)
-{
- struct gsm_trans *trans;
-
- llist_for_each_entry(trans, &ms->trans_list, entry) {
- if (trans->protocol == proto &&
- trans->transaction_id == trans_id)
- return trans;
- }
- return NULL;
-}
-
-struct gsm_trans *trans_find_by_callref(struct osmocom_ms *ms,
- uint32_t callref)
-{
- struct gsm_trans *trans;
-
- llist_for_each_entry(trans, &ms->trans_list, entry) {
- if (trans->callref == callref)
- return trans;
- }
- return NULL;
-}
-
-struct gsm_trans *trans_alloc(struct osmocom_ms *ms,
- uint8_t protocol, uint8_t trans_id,
- uint32_t callref)
-{
- struct gsm_trans *trans;
-
- trans = talloc_zero(l23_ctx, struct gsm_trans);
- if (!trans)
- return NULL;
-
- DEBUGP(DCC, "ms %s allocates transaction (proto %d trans_id %d "
- "callref %x mem %p)\n", ms->name, protocol, trans_id, callref,
- trans);
-
- trans->ms = ms;
-
- trans->protocol = protocol;
- trans->transaction_id = trans_id;
- trans->callref = callref;
-
- llist_add_tail(&trans->entry, &ms->trans_list);
-
- return trans;
-}
-
-void trans_free(struct gsm_trans *trans)
-{
- switch (trans->protocol) {
- case GSM48_PDISC_CC:
- _gsm48_cc_trans_free(trans);
- break;
-#if 0
- case GSM48_PDISC_SS:
- _gsm411_ss_trans_free(trans);
- break;
- case GSM48_PDISC_SMS:
- _gsm411_sms_trans_free(trans);
- break;
-#endif
- }
-
- DEBUGP(DCC, "ms %s frees transaction (mem %p)\n", trans->ms->name,
- trans);
-
- llist_del(&trans->entry);
-
- talloc_free(trans);
-}
-
-/* allocate an unused transaction ID
- * in the given protocol using the ti_flag specified */
-int trans_assign_trans_id(struct osmocom_ms *ms,
- uint8_t protocol, uint8_t ti_flag)
-{
- struct gsm_trans *trans;
- unsigned int used_tid_bitmask = 0;
- int i, j, h;
-
- if (ti_flag)
- ti_flag = 0x8;
-
- /* generate bitmask of already-used TIDs for this (proto) */
- llist_for_each_entry(trans, &ms->trans_list, entry) {
- if (trans->protocol != protocol ||
- trans->transaction_id == 0xff)
- continue;
- used_tid_bitmask |= (1 << trans->transaction_id);
- }
-
- /* find a new one, trying to go in a 'circular' pattern */
- for (h = 6; h > 0; h--)
- if (used_tid_bitmask & (1 << (h | ti_flag)))
- break;
- for (i = 0; i < 7; i++) {
- j = ((h + i) % 7) | ti_flag;
- if ((used_tid_bitmask & (1 << j)) == 0)
- return j;
- }
-
- return -1;
-}
-
diff --git a/Src/osmoconbb/src/host/layer23/src/mobile/voice.c b/Src/osmoconbb/src/host/layer23/src/mobile/voice.c
deleted file mode 100644
index b767833..0000000
--- a/Src/osmoconbb/src/host/layer23/src/mobile/voice.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdlib.h>
-
-#include <osmocom/core/msgb.h>
-
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/mobile/mncc.h>
-#include <osmocom/bb/mobile/voice.h>
-
-
-/*
- * receive voice
- */
-
-static int gsm_recv_voice(struct osmocom_ms *ms, struct msgb *msg)
-{
- struct gsm_data_frame *mncc;
-
- /* distribute and then free */
- if (ms->mncc_entity.mncc_recv && ms->mncc_entity.ref) {
- /* push mncc header in front of data */
- mncc = (struct gsm_data_frame *)
- msgb_push(msg, sizeof(struct gsm_data_frame));
- mncc->msg_type = GSM_TCHF_FRAME;
- mncc->callref = ms->mncc_entity.ref;
- ms->mncc_entity.mncc_recv(ms, mncc->msg_type, mncc);
- }
-
- msgb_free(msg);
- return 0;
-}
-
-/*
- * send voice
- */
-int gsm_send_voice(struct osmocom_ms *ms, struct gsm_data_frame *data)
-{
- struct msgb *nmsg;
-
- nmsg = msgb_alloc_headroom(33 + 64, 64, "TCH/F");
- if (!nmsg)
- return -ENOMEM;
- nmsg->l2h = msgb_put(nmsg, 33);
- memcpy(nmsg->l2h, data->data, 33);
-
- return gsm48_rr_tx_voice(ms, nmsg);
-}
-
-/*
- * init
- */
-
-int gsm_voice_init(struct osmocom_ms *ms)
-{
- ms->l1_entity.l1_traffic_ind = gsm_recv_voice;
-
- return 0;
-}
diff --git a/Src/osmoconbb/src/host/layer23/src/mobile/vty_interface.c b/Src/osmoconbb/src/host/layer23/src/mobile/vty_interface.c
deleted file mode 100644
index c0a7cef..0000000
--- a/Src/osmoconbb/src/host/layer23/src/mobile/vty_interface.c
+++ /dev/null
@@ -1,2798 +0,0 @@
-/*
- * (C) 2010 by Andreas Eversberg <jolly@eversberg.eu>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-#include <osmocom/core/utils.h>
-#include <osmocom/gsm/gsm48.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/signal.h>
-
-#include <osmocom/bb/common/osmocom_data.h>
-#include <osmocom/bb/common/networks.h>
-#include <osmocom/bb/common/gps.h>
-#include <osmocom/bb/mobile/mncc.h>
-#include <osmocom/bb/mobile/transaction.h>
-#include <osmocom/bb/mobile/vty.h>
-#include <osmocom/bb/mobile/app_mobile.h>
-#include <osmocom/vty/telnet_interface.h>
-
-void *l23_ctx;
-
-int mncc_call(struct osmocom_ms *ms, char *number);
-int mncc_hangup(struct osmocom_ms *ms);
-int mncc_answer(struct osmocom_ms *ms);
-int mncc_hold(struct osmocom_ms *ms);
-int mncc_retrieve(struct osmocom_ms *ms, int number);
-int mncc_dtmf(struct osmocom_ms *ms, char *dtmf);
-
-extern struct llist_head ms_list;
-extern struct llist_head active_connections;
-
-struct cmd_node ms_node = {
- MS_NODE,
- "%s(ms)#",
- 1
-};
-
-struct cmd_node testsim_node = {
- TESTSIM_NODE,
- "%s(test-sim)#",
- 1
-};
-
-struct cmd_node support_node = {
- SUPPORT_NODE,
- "%s(support)#",
- 1
-};
-
-static void print_vty(void *priv, const char *fmt, ...)
-{
- char buffer[1000];
- struct vty *vty = priv;
- va_list args;
-
- va_start(args, fmt);
- vsnprintf(buffer, sizeof(buffer) - 1, fmt, args);
- buffer[sizeof(buffer) - 1] = '\0';
- va_end(args);
-
- if (buffer[0]) {
- if (buffer[strlen(buffer) - 1] == '\n') {
- buffer[strlen(buffer) - 1] = '\0';
- vty_out(vty, "%s%s", buffer, VTY_NEWLINE);
- } else
- vty_out(vty, "%s", buffer);
- }
-}
-
-int vty_check_number(struct vty *vty, const char *number)
-{
- int i;
-
- for (i = 0; i < strlen(number); i++) {
- /* allow international notation with + */
- if (i == 0 && number[i] == '+')
- continue;
- if (!(number[i] >= '0' && number[i] <= '9')
- && number[i] != '*'
- && number[i] != '#'
- && !(number[i] >= 'a' && number[i] <= 'c')) {
- vty_out(vty, "Invalid digit '%c' of number!%s",
- number[i], VTY_NEWLINE);
- return -EINVAL;
- }
- }
- if (number[0] == '\0' || (number[0] == '+' && number[1] == '\0')) {
- vty_out(vty, "Given number has no digits!%s", VTY_NEWLINE);
- return -EINVAL;
- }
-
- return 0;
-}
-
-int vty_reading = 0;
-static int hide_default = 0;
-
-static void vty_restart(struct vty *vty, struct osmocom_ms *ms)
-{
- if (vty_reading)
- return;
- if (ms->shutdown != 0)
- return;
- vty_out(vty, "You must restart MS '%s' ('shutdown / no shutdown') for "
- "change to take effect!%s", ms->name, VTY_NEWLINE);
-}
-
-static void vty_restart_if_started(struct vty *vty, struct osmocom_ms *ms)
-{
- if (!ms->started)
- return;
- vty_restart(vty, ms);
-}
-
-static struct osmocom_ms *get_ms(const char *name, struct vty *vty)
-{
- struct osmocom_ms *ms;
-
- llist_for_each_entry(ms, &ms_list, entity) {
- if (!strcmp(ms->name, name)) {
- if (ms->shutdown) {
- vty_out(vty, "MS '%s' is admin down.%s", name,
- VTY_NEWLINE);
- return NULL;
- }
- return ms;
- }
- }
- vty_out(vty, "MS name '%s' does not exits.%s", name, VTY_NEWLINE);
-
- return NULL;
-}
-
-static void gsm_ms_dump(struct osmocom_ms *ms, struct vty *vty)
-{
- struct gsm_settings *set = &ms->settings;
- struct gsm_trans *trans;
- char *service = "";
-
- if (!ms->started)
- service = ", radio is not started";
- else if (ms->mmlayer.state == GSM48_MM_ST_MM_IDLE) {
- /* current MM idle state */
- switch (ms->mmlayer.substate) {
- case GSM48_MM_SST_NORMAL_SERVICE:
- case GSM48_MM_SST_PLMN_SEARCH_NORMAL:
- service = ", service is normal";
- break;
- case GSM48_MM_SST_LOC_UPD_NEEDED:
- case GSM48_MM_SST_ATTEMPT_UPDATE:
- service = ", service is limited (pending)";
- break;
- case GSM48_MM_SST_NO_CELL_AVAIL:
- service = ", service is unavailable";
- break;
- default:
- if (ms->subscr.sim_valid)
- service = ", service is limited";
- else
- service = ", service is limited "
- "(IMSI detached)";
- break;
- }
- } else
- service = ", MM connection active";
-
- vty_out(vty, "MS '%s' is %s%s%s%s", ms->name,
- (ms->shutdown) ? "administratively " : "",
- (ms->shutdown || !ms->started) ? "down" : "up",
- (!ms->shutdown) ? service : "",
- VTY_NEWLINE);
- vty_out(vty, " IMEI: %s%s", set->imei, VTY_NEWLINE);
- vty_out(vty, " IMEISV: %s%s", set->imeisv, VTY_NEWLINE);
- if (set->imei_random)
- vty_out(vty, " IMEI generation: random (%d trailing "
- "digits)%s", set->imei_random, VTY_NEWLINE);
- else
- vty_out(vty, " IMEI generation: fixed%s", VTY_NEWLINE);
-
- if (ms->shutdown)
- return;
-
- if (set->plmn_mode == PLMN_MODE_AUTO)
- vty_out(vty, " automatic network selection state: %s%s",
- get_a_state_name(ms->plmn.state), VTY_NEWLINE);
- else
- vty_out(vty, " manual network selection state : %s%s",
- get_m_state_name(ms->plmn.state), VTY_NEWLINE);
- if (ms->plmn.mcc)
- vty_out(vty, " MCC=%s "
- "MNC=%s (%s, %s)%s", gsm_print_mcc(ms->plmn.mcc),
- gsm_print_mnc(ms->plmn.mnc), gsm_get_mcc(ms->plmn.mcc),
- gsm_get_mnc(ms->plmn.mcc, ms->plmn.mnc), VTY_NEWLINE);
- vty_out(vty, " cell selection state: %s%s",
- get_cs_state_name(ms->cellsel.state), VTY_NEWLINE);
- if (ms->cellsel.sel_mcc) {
- vty_out(vty, " ARFCN=%s MCC=%s MNC=%s "
- "LAC=0x%04x CELLID=0x%04x%s",
- gsm_print_arfcn(ms->cellsel.sel_arfcn),
- gsm_print_mcc(ms->cellsel.sel_mcc),
- gsm_print_mnc(ms->cellsel.sel_mnc),
- ms->cellsel.sel_lac, ms->cellsel.sel_id, VTY_NEWLINE);
- vty_out(vty, " (%s, %s)%s",
- gsm_get_mcc(ms->cellsel.sel_mcc),
- gsm_get_mnc(ms->cellsel.sel_mcc, ms->cellsel.sel_mnc),
- VTY_NEWLINE);
- }
- vty_out(vty, " radio ressource layer state: %s%s",
- gsm48_rr_state_names[ms->rrlayer.state], VTY_NEWLINE);
- vty_out(vty, " mobility management layer state: %s",
- gsm48_mm_state_names[ms->mmlayer.state]);
- if (ms->mmlayer.state == GSM48_MM_ST_MM_IDLE)
- vty_out(vty, ", %s",
- gsm48_mm_substate_names[ms->mmlayer.substate]);
- vty_out(vty, "%s", VTY_NEWLINE);
- llist_for_each_entry(trans, &ms->trans_list, entry) {
- vty_out(vty, " call control state: %s%s",
- gsm48_cc_state_name(trans->cc.state), VTY_NEWLINE);
- }
-}
-
-
-DEFUN(show_ms, show_ms_cmd, "show ms [MS_NAME]",
- SHOW_STR "Display available MS entities\n")
-{
- struct osmocom_ms *ms;
-
- if (argc) {
- llist_for_each_entry(ms, &ms_list, entity) {
- if (!strcmp(ms->name, argv[0])) {
- gsm_ms_dump(ms, vty);
- return CMD_SUCCESS;
- }
- }
- vty_out(vty, "MS name '%s' does not exits.%s", argv[0],
- VTY_NEWLINE);
- return CMD_WARNING;
- } else {
- llist_for_each_entry(ms, &ms_list, entity) {
- gsm_ms_dump(ms, vty);
- vty_out(vty, "%s", VTY_NEWLINE);
- }
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN(show_support, show_support_cmd, "show support [MS_NAME]",
- SHOW_STR "Display information about MS support\n"
- "Name of MS (see \"show ms\")")
-{
- struct osmocom_ms *ms;
-
- if (argc) {
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
- gsm_support_dump(ms, print_vty, vty);
- } else {
- llist_for_each_entry(ms, &ms_list, entity) {
- gsm_support_dump(ms, print_vty, vty);
- vty_out(vty, "%s", VTY_NEWLINE);
- }
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN(show_subscr, show_subscr_cmd, "show subscriber [MS_NAME]",
- SHOW_STR "Display information about subscriber\n"
- "Name of MS (see \"show ms\")")
-{
- struct osmocom_ms *ms;
-
- if (argc) {
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
- gsm_subscr_dump(&ms->subscr, print_vty, vty);
- } else {
- llist_for_each_entry(ms, &ms_list, entity) {
- if (!ms->shutdown) {
- gsm_subscr_dump(&ms->subscr, print_vty, vty);
- vty_out(vty, "%s", VTY_NEWLINE);
- }
- }
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN(show_cell, show_cell_cmd, "show cell MS_NAME",
- SHOW_STR "Display information about received cells\n"
- "Name of MS (see \"show ms\")")
-{
- struct osmocom_ms *ms;
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
-
- gsm322_dump_cs_list(&ms->cellsel, GSM322_CS_FLAG_SUPPORT, print_vty,
- vty);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(show_cell_si, show_cell_si_cmd, "show cell MS_NAME <0-1023> [pcs]",
- SHOW_STR "Display information about received cell\n"
- "Name of MS (see \"show ms\")\nRadio frequency number\n"
- "Given frequency is PCS band (1900) rather than DCS band.")
-{
- struct osmocom_ms *ms;
- struct gsm48_sysinfo *s;
- uint16_t arfcn = atoi(argv[1]);
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
-
- if (argc > 2) {
- if (arfcn < 512 || arfcn > 810) {
- vty_out(vty, "Given ARFCN not in PCS band%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- arfcn |= ARFCN_PCS;
- }
-
- s = ms->cellsel.list[arfcn2index(arfcn)].sysinfo;
- if (!s) {
- vty_out(vty, "Given ARFCN '%s' has no sysinfo available%s",
- argv[1], VTY_NEWLINE);
- return CMD_SUCCESS;
- }
-
- gsm48_sysinfo_dump(s, arfcn, print_vty, vty, ms->settings.freq_map);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(show_nbcells, show_nbcells_cmd, "show neighbour-cells MS_NAME",
- SHOW_STR "Display information about current neighbour cells\n"
- "Name of MS (see \"show ms\")")
-{
- struct osmocom_ms *ms;
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
-
- gsm322_dump_nb_list(&ms->cellsel, print_vty, vty);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(show_ba, show_ba_cmd, "show ba MS_NAME [MCC] [MNC]",
- SHOW_STR "Display information about band allocations\n"
- "Name of MS (see \"show ms\")\nMobile Country Code\n"
- "Mobile Network Code")
-{
- struct osmocom_ms *ms;
- uint16_t mcc = 0, mnc = 0;
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
-
- if (argc >= 3) {
- mcc = gsm_input_mcc((char *)argv[1]);
- mnc = gsm_input_mnc((char *)argv[2]);
- if (mcc == GSM_INPUT_INVALID) {
- vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- if (mnc == GSM_INPUT_INVALID) {
- vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
- gsm322_dump_ba_list(&ms->cellsel, mcc, mnc, print_vty, vty);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(show_forb_plmn, show_forb_plmn_cmd, "show forbidden plmn MS_NAME",
- SHOW_STR "Display information about forbidden cells / networks\n"
- "Display forbidden PLMNs\nName of MS (see \"show ms\")")
-{
- struct osmocom_ms *ms;
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
-
- gsm_subscr_dump_forbidden_plmn(ms, print_vty, vty);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(show_forb_la, show_forb_la_cmd, "show forbidden location-area MS_NAME",
- SHOW_STR "Display information about forbidden cells / networks\n"
- "Display forbidden location areas\nName of MS (see \"show ms\")")
-{
- struct osmocom_ms *ms;
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
-
- gsm322_dump_forbidden_la(ms, print_vty, vty);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(monitor_network, monitor_network_cmd, "monitor network MS_NAME",
- "Monitor...\nMonitor network information\nName of MS (see \"show ms\")")
-{
- struct osmocom_ms *ms;
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
-
- gsm48_rr_start_monitor(ms);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(no_monitor_network, no_monitor_network_cmd, "no monitor network MS_NAME",
- NO_STR "Monitor...\nDeactivate monitor of network information\n"
- "Name of MS (see \"show ms\")")
-{
- struct osmocom_ms *ms;
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
-
- gsm48_rr_stop_monitor(ms);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(sim_test, sim_test_cmd, "sim testcard MS_NAME [MCC] [MNC] [LAC] [TMSI]",
- "SIM actions\nAttach bulit in test SIM\nName of MS (see \"show ms\")\n"
- "Mobile Country Code of RPLMN\nMobile Network Code of RPLMN\n"
- "Optionally location area code\nOptionally current assigned TMSI")
-{
- struct osmocom_ms *ms;
- uint16_t mcc = 0x001, mnc = 0x01f, lac = 0x0000;
- uint32_t tmsi = 0xffffffff;
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
-
- if (ms->subscr.sim_valid) {
- vty_out(vty, "SIM already attached, remove first!%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (argc >= 3) {
- mcc = gsm_input_mcc((char *)argv[1]);
- mnc = gsm_input_mnc((char *)argv[2]);
- if (mcc == GSM_INPUT_INVALID) {
- vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- if (mnc == GSM_INPUT_INVALID) {
- vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
- if (argc >= 4)
- lac = strtoul(argv[3], NULL, 16);
-
- if (argc >= 5)
- tmsi = strtoul(argv[4], NULL, 16);
-
- gsm_subscr_testcard(ms, mcc, mnc, lac, tmsi);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(sim_reader, sim_reader_cmd, "sim reader MS_NAME",
- "SIM actions\nAttach SIM from reader\nName of MS (see \"show ms\")")
-{
- struct osmocom_ms *ms;
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
-
- if (ms->subscr.sim_valid) {
- vty_out(vty, "SIM already attached, remove first!%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- gsm_subscr_simcard(ms);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(sim_remove, sim_remove_cmd, "sim remove MS_NAME",
- "SIM actions\nDetach SIM card\nName of MS (see \"show ms\")")
-{
- struct osmocom_ms *ms;
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
-
- if (!ms->subscr.sim_valid) {
- vty_out(vty, "No SIM attached!%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- gsm_subscr_remove(ms);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(sim_pin, sim_pin_cmd, "sim pin MS_NAME PIN",
- "SIM actions\nEnter PIN for SIM card\nName of MS (see \"show ms\")\n"
- "PIN number")
-{
- struct osmocom_ms *ms;
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
-
- if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
- vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (!ms->subscr.sim_pin_required) {
- vty_out(vty, "No PIN is required at this time!%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- gsm_subscr_sim_pin(ms, (char *)argv[1], "", 0);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(sim_disable_pin, sim_disable_pin_cmd, "sim disable-pin MS_NAME PIN",
- "SIM actions\nDisable PIN of SIM card\nName of MS (see \"show ms\")\n"
- "PIN number")
-{
- struct osmocom_ms *ms;
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
-
- if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
- vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- gsm_subscr_sim_pin(ms, (char *)argv[1], "", -1);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(sim_enable_pin, sim_enable_pin_cmd, "sim enable-pin MS_NAME PIN",
- "SIM actions\nEnable PIN of SIM card\nName of MS (see \"show ms\")\n"
- "PIN number")
-{
- struct osmocom_ms *ms;
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
-
- if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
- vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- gsm_subscr_sim_pin(ms, (char *)argv[1], "", 1);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(sim_change_pin, sim_change_pin_cmd, "sim change-pin MS_NAME OLD NEW",
- "SIM actions\nChange PIN of SIM card\nName of MS (see \"show ms\")\n"
- "Old PIN number\nNew PIN number")
-{
- struct osmocom_ms *ms;
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
-
- if (strlen(argv[1]) < 4 || strlen(argv[1]) > 8) {
- vty_out(vty, "Old PIN must be in range 4..8!%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- if (strlen(argv[2]) < 4 || strlen(argv[2]) > 8) {
- vty_out(vty, "New PIN must be in range 4..8!%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- gsm_subscr_sim_pin(ms, (char *)argv[1], (char *)argv[2], 2);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(sim_unblock_pin, sim_unblock_pin_cmd, "sim unblock-pin MS_NAME PUC NEW",
- "SIM actions\nChange PIN of SIM card\nName of MS (see \"show ms\")\n"
- "Personal Unblock Key\nNew PIN number")
-{
- struct osmocom_ms *ms;
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
-
- if (strlen(argv[1]) != 8) {
- vty_out(vty, "PUC must be 8 digits!%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- if (strlen(argv[2]) < 4 || strlen(argv[2]) > 8) {
- vty_out(vty, "PIN must be in range 4..8!%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- gsm_subscr_sim_pin(ms, (char *)argv[1], (char *)argv[2], 99);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(sim_lai, sim_lai_cmd, "sim lai MS_NAME MCC MNC LAC",
- "SIM actions\nChange LAI of SIM card\nName of MS (see \"show ms\")\n"
- "Mobile Country Code\nMobile Network Code\nLocation Area Code "
- " (use 0000 to remove LAI)")
-{
- struct osmocom_ms *ms;
- uint16_t mcc = gsm_input_mcc((char *)argv[1]),
- mnc = gsm_input_mnc((char *)argv[2]),
- lac = strtoul(argv[3], NULL, 16);
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
-
- if (mcc == GSM_INPUT_INVALID) {
- vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- if (mnc == GSM_INPUT_INVALID) {
- vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- ms->subscr.mcc = mcc;
- ms->subscr.mnc = mnc;
- ms->subscr.lac = lac;
- ms->subscr.tmsi = 0xffffffff;
-
- gsm_subscr_write_loci(ms);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(network_select, network_select_cmd,
- "network select MS_NAME MCC MNC [force]",
- "Select ...\nSelect Network\nName of MS (see \"show ms\")\n"
- "Mobile Country Code\nMobile Network Code\n"
- "Force selecting a network that is not in the list")
-{
- struct osmocom_ms *ms;
- struct gsm322_plmn *plmn;
- struct msgb *nmsg;
- struct gsm322_msg *ngm;
- struct gsm322_plmn_list *temp;
- uint16_t mcc = gsm_input_mcc((char *)argv[1]),
- mnc = gsm_input_mnc((char *)argv[2]);
- int found = 0;
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
- plmn = &ms->plmn;
-
- if (ms->settings.plmn_mode != PLMN_MODE_MANUAL) {
- vty_out(vty, "Not in manual network selection mode%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (mcc == GSM_INPUT_INVALID) {
- vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- if (mnc == GSM_INPUT_INVALID) {
- vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (argc < 4) {
- llist_for_each_entry(temp, &plmn->sorted_plmn, entry)
- if (temp->mcc == mcc && temp->mnc == mnc)
- found = 1;
- if (!found) {
- vty_out(vty, "Network not in list!%s", VTY_NEWLINE);
- vty_out(vty, "To force selecting this network, use "
- "'force' keyword%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_CHOOSE_PLMN);
- if (!nmsg)
- return CMD_WARNING;
- ngm = (struct gsm322_msg *) nmsg->data;
- ngm->mcc = mcc;
- ngm->mnc = mnc;
- gsm322_plmn_sendmsg(ms, nmsg);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(call, call_cmd, "call MS_NAME (NUMBER|emergency|answer|hangup|hold)",
- "Make a call\nName of MS (see \"show ms\")\nPhone number to call "
- "(Use digits '0123456789*#abc', and '+' to dial international)\n"
- "Make an emergency call\nAnswer an incomming call\nHangup a call\n"
- "Hold current active call\n")
-{
- struct osmocom_ms *ms;
- struct gsm_settings *set;
- struct gsm_settings_abbrev *abbrev;
- char *number;
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
- set = &ms->settings;
-
- if (set->ch_cap == GSM_CAP_SDCCH) {
- vty_out(vty, "Basic call is not supported for SDCCH only "
- "mobile%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- number = (char *)argv[1];
- if (!strcmp(number, "emergency"))
- mncc_call(ms, number);
- else if (!strcmp(number, "answer"))
- mncc_answer(ms);
- else if (!strcmp(number, "hangup"))
- mncc_hangup(ms);
- else if (!strcmp(number, "hold"))
- mncc_hold(ms);
- else {
- llist_for_each_entry(abbrev, &set->abbrev, list) {
- if (!strcmp(number, abbrev->abbrev)) {
- number = abbrev->number;
- vty_out(vty, "Dialing number '%s'%s", number,
- VTY_NEWLINE);
- break;
- }
- }
- if (vty_check_number(vty, number))
- return CMD_WARNING;
- mncc_call(ms, number);
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN(call_retr, call_retr_cmd, "call MS_NAME retrieve [NUMBER]",
- "Make a call\nName of MS (see \"show ms\")\n"
- "Retrieve call on hold\nNumber of call to retrieve")
-{
- struct osmocom_ms *ms;
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
-
- mncc_retrieve(ms, (argc > 1) ? atoi(argv[1]) : 0);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(call_dtmf, call_dtmf_cmd, "call MS_NAME dtmf DIGITS",
- "Make a call\nName of MS (see \"show ms\")\n"
- "One or more DTMF digits to transmit")
-{
- struct osmocom_ms *ms;
- struct gsm_settings *set;
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
- set = &ms->settings;
-
- if (!set->cc_dtmf) {
- vty_out(vty, "DTMF not supported, please enable!%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- mncc_dtmf(ms, (char *)argv[1]);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(test_reselection, test_reselection_cmd, "test re-selection NAME",
- "Manually trigger cell re-selection\nName of MS (see \"show ms\")")
-{
- struct osmocom_ms *ms;
- struct gsm_settings *set;
- struct msgb *nmsg;
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
- set = &ms->settings;
-
- if (set->stick) {
- vty_out(vty, "Cannot trigger cell re-selection, because we "
- "stick to a cell!%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_CELL_RESEL);
- if (!nmsg)
- return CMD_WARNING;
- gsm322_c_event(ms, nmsg);
-
-
- return CMD_SUCCESS;
-}
-
-DEFUN(delete_forbidden_plmn, delete_forbidden_plmn_cmd,
- "delete forbidden plmn NAME MCC MNC",
- "Delete\nForbidden\nplmn\nName of MS (see \"show ms\")\n"
- "Mobile Country Code\nMobile Network Code")
-{
- struct osmocom_ms *ms;
- uint16_t mcc = gsm_input_mcc((char *)argv[1]),
- mnc = gsm_input_mnc((char *)argv[2]);
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
-
- if (mcc == GSM_INPUT_INVALID) {
- vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- if (mnc == GSM_INPUT_INVALID) {
- vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- gsm_subscr_del_forbidden_plmn(&ms->subscr, mcc, mnc);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(network_show, network_show_cmd, "network show MS_NAME",
- "Network ...\nShow results of network search (again)\n"
- "Name of MS (see \"show ms\")")
-{
- struct osmocom_ms *ms;
- struct gsm_settings *set;
- struct gsm322_plmn *plmn;
- struct gsm322_plmn_list *temp;
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
- set = &ms->settings;
- plmn = &ms->plmn;
-
- if (set->plmn_mode != PLMN_MODE_AUTO
- && plmn->state != GSM322_M3_NOT_ON_PLMN) {
- vty_out(vty, "Start network search first!%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- llist_for_each_entry(temp, &plmn->sorted_plmn, entry)
- vty_out(vty, " Network %s, %s (%s, %s)%s",
- gsm_print_mcc(temp->mcc), gsm_print_mnc(temp->mnc),
- gsm_get_mcc(temp->mcc),
- gsm_get_mnc(temp->mcc, temp->mnc), VTY_NEWLINE);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(network_search, network_search_cmd, "network search MS_NAME",
- "Network ...\nTrigger network search\nName of MS (see \"show ms\")")
-{
- struct osmocom_ms *ms;
- struct msgb *nmsg;
-
- ms = get_ms(argv[0], vty);
- if (!ms)
- return CMD_WARNING;
-
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_USER_RESEL);
- if (!nmsg)
- return CMD_WARNING;
- gsm322_plmn_sendmsg(ms, nmsg);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_gps_enable, cfg_gps_enable_cmd, "gps enable",
- "GPS receiver")
-{
- if (osmo_gps_open()) {
- g.enable = 1;
- vty_out(vty, "Failed to open GPS device!%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- g.enable = 1;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_no_gps_enable, cfg_no_gps_enable_cmd, "no gps enable",
- NO_STR "Disable GPS receiver")
-{
- if (g.enable)
- osmo_gps_close();
- g.enable = 0;
-
- return CMD_SUCCESS;
-}
-
-#ifdef _HAVE_GPSD
-DEFUN(cfg_gps_host, cfg_gps_host_cmd, "gps host HOST:PORT",
- "GPS receiver\nSelect gpsd host and port\n"
- "IP and port (optional) of the host running gpsd")
-{
- char* colon = strstr(argv[0], ":");
- if (colon != NULL) {
- memcpy(g.gpsd_host, argv[0], colon - argv[0] - 1);
- g.gpsd_host[colon - argv[0]] = '\0';
- memcpy(g.gpsd_port, colon, strlen(colon));
- g.gpsd_port[strlen(colon)] = '\0';
- } else {
- snprintf(g.gpsd_host, ARRAY_SIZE(g.gpsd_host), "%s", argv[0]);
- g.gpsd_host[ARRAY_SIZE(g.gpsd_host) - 1] = '\0';
- snprintf(g.gpsd_port, ARRAY_SIZE(g.gpsd_port), "2947");
- g.gpsd_port[ARRAY_SIZE(g.gpsd_port) - 1] = '\0';
- }
- g.gps_type = GPS_TYPE_GPSD;
- if (g.enable) {
- osmo_gps_close();
- if (osmo_gps_open()) {
- vty_out(vty, "Failed to connect to gpsd host!%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
- return CMD_SUCCESS;
-}
-#endif
-
-DEFUN(cfg_gps_device, cfg_gps_device_cmd, "gps device DEVICE",
- "GPS receiver\nSelect serial device\n"
- "Full path of serial device including /dev/")
-{
- strncpy(g.device, argv[0], sizeof(g.device));
- g.device[sizeof(g.device) - 1] = '\0';
- g.gps_type = GPS_TYPE_SERIAL;
- if (g.enable) {
- osmo_gps_close();
- if (osmo_gps_open()) {
- vty_out(vty, "Failed to open GPS device!%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_gps_baud, cfg_gps_baud_cmd, "gps baudrate "
- "(default|4800|""9600|19200|38400|57600|115200)",
- "GPS receiver\nSelect baud rate\nDefault, don't modify\n\n\n\n\n\n")
-{
- if (argv[0][0] == 'd')
- g.baud = 0;
- else
- g.baud = atoi(argv[0]);
- if (g.enable) {
- osmo_gps_close();
- if (osmo_gps_open()) {
- g.enable = 0;
- vty_out(vty, "Failed to open GPS device!%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_hide_default, cfg_hide_default_cmd, "hide-default",
- "Hide most default values in config to make it more compact")
-{
- hide_default = 1;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_no_hide_default, cfg_no_hide_default_cmd, "no hide-default",
- NO_STR "Show default values in config")
-{
- hide_default = 0;
-
- return CMD_SUCCESS;
-}
-
-/* per MS config */
-DEFUN(cfg_ms, cfg_ms_cmd, "ms MS_NAME",
- "Select a mobile station to configure\nName of MS (see \"show ms\")")
-{
- struct osmocom_ms *ms;
- int found = 0;
-
- llist_for_each_entry(ms, &ms_list, entity) {
- if (!strcmp(ms->name, argv[0])) {
- found = 1;
- break;
- }
- }
-
- if (!found) {
- if (!vty_reading) {
- vty_out(vty, "MS name '%s' does not exits, try "
- "'ms %s create'%s", argv[0], argv[0],
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- ms = mobile_new((char *)argv[0]);
- if (!ms) {
- vty_out(vty, "Failed to add MS name '%s'%s", argv[0],
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
- vty->index = ms;
- vty->node = MS_NODE;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_create, cfg_ms_create_cmd, "ms MS_NAME create",
- "Select a mobile station to configure\nName of MS (see \"show ms\")\n"
- "Create if MS does not exists")
-{
- struct osmocom_ms *ms;
- int found = 0;
-
- llist_for_each_entry(ms, &ms_list, entity) {
- if (!strcmp(ms->name, argv[0])) {
- found = 1;
- break;
- }
- }
-
- if (!found) {
- ms = mobile_new((char *)argv[0]);
- if (!ms) {
- vty_out(vty, "Failed to add MS name '%s'%s", argv[0],
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
- vty->index = ms;
- vty->node = MS_NODE;
-
- vty_out(vty, "MS '%s' created, after configuration, do 'no shutdown'%s",
- argv[0], VTY_NEWLINE);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_rename, cfg_ms_rename_cmd, "ms MS_NAME rename MS_NAME",
- "Select a mobile station to configure\nName of MS (see \"show ms\")\n"
- "Rename MS\nNew name of MS")
-{
- struct osmocom_ms *ms;
- int found = 0;
-
- llist_for_each_entry(ms, &ms_list, entity) {
- if (!strcmp(ms->name, argv[0])) {
- found = 1;
- break;
- }
- }
-
- if (!found) {
- vty_out(vty, "MS name '%s' does not exist%s", argv[0],
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- strncpy(ms->name, argv[1], sizeof(ms->name) - 1);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_no_ms, cfg_no_ms_cmd, "no ms MS_NAME",
- NO_STR "Select a mobile station to remove\n"
- "Name of MS (see \"show ms\")")
-{
- struct osmocom_ms *ms;
- int found = 0;
-
- llist_for_each_entry(ms, &ms_list, entity) {
- if (!strcmp(ms->name, argv[0])) {
- found = 1;
- break;
- }
- }
-
- if (!found) {
- vty_out(vty, "MS name '%s' does not exist%s", argv[0],
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- mobile_delete(ms, 1);
-
- return CMD_SUCCESS;
-}
-
-#define SUP_WRITE(item, cmd) \
- if (sup->item) \
- if (!hide_default || !set->item) \
- vty_out(vty, " %s%s%s", (set->item) ? "" : "no ", \
- cmd, VTY_NEWLINE);
-
-static void config_write_ms(struct vty *vty, struct osmocom_ms *ms)
-{
- struct gsm_settings *set = &ms->settings;
- struct gsm_support *sup = &ms->support;
- struct gsm_settings_abbrev *abbrev;
-
- vty_out(vty, "ms %s%s", ms->name, VTY_NEWLINE);
- vty_out(vty, " layer2-socket %s%s", set->layer2_socket_path,
- VTY_NEWLINE);
- vty_out(vty, " sap-socket %s%s", set->sap_socket_path, VTY_NEWLINE);
- switch(set->sim_type) {
- case GSM_SIM_TYPE_NONE:
- vty_out(vty, " sim none%s", VTY_NEWLINE);
- break;
- case GSM_SIM_TYPE_READER:
- vty_out(vty, " sim reader%s", VTY_NEWLINE);
- break;
- case GSM_SIM_TYPE_TEST:
- vty_out(vty, " sim test%s", VTY_NEWLINE);
- break;
- }
- vty_out(vty, " network-selection-mode %s%s", (set->plmn_mode
- == PLMN_MODE_AUTO) ? "auto" : "manual", VTY_NEWLINE);
- vty_out(vty, " imei %s %s%s", set->imei,
- set->imeisv + strlen(set->imei), VTY_NEWLINE);
- if (set->imei_random)
- vty_out(vty, " imei-random %d%s", set->imei_random,
- VTY_NEWLINE);
- else
- if (!hide_default)
- vty_out(vty, " imei-fixed%s", VTY_NEWLINE);
- if (set->emergency_imsi[0])
- vty_out(vty, " emergency-imsi %s%s", set->emergency_imsi,
- VTY_NEWLINE);
- else
- if (!hide_default)
- vty_out(vty, " no emergency-imsi%s", VTY_NEWLINE);
- if (!hide_default || set->cw)
- vty_out(vty, " %scall-waiting%s", (set->cw) ? "" : "no ",
- VTY_NEWLINE);
- if (!hide_default || set->auto_answer)
- vty_out(vty, " %sauto-answer%s",
- (set->auto_answer) ? "" : "no ", VTY_NEWLINE);
- if (!hide_default || set->clip)
- vty_out(vty, " %sclip%s", (set->clip) ? "" : "no ",
- VTY_NEWLINE);
- if (!hide_default || set->clir)
- vty_out(vty, " %sclir%s", (set->clir) ? "" : "no ",
- VTY_NEWLINE);
- if (set->alter_tx_power)
- if (set->alter_tx_power_value)
- vty_out(vty, " tx-power %d%s",
- set->alter_tx_power_value, VTY_NEWLINE);
- else
- vty_out(vty, " tx-power full%s", VTY_NEWLINE);
- else
- if (!hide_default)
- vty_out(vty, " tx-power auto%s", VTY_NEWLINE);
- if (set->alter_delay)
- vty_out(vty, " simulated-delay %d%s", set->alter_delay,
- VTY_NEWLINE);
- else
- if (!hide_default)
- vty_out(vty, " no simulated-delay%s", VTY_NEWLINE);
- if (set->stick)
- vty_out(vty, " stick %d%s%s", set->stick_arfcn & 1023,
- (set->stick_arfcn & ARFCN_PCS) ? " pcs" : "",
- VTY_NEWLINE);
- else
- if (!hide_default)
- vty_out(vty, " no stick%s", VTY_NEWLINE);
- if (!hide_default || set->no_lupd)
- vty_out(vty, " %slocation-updating%s",
- (set->no_lupd) ? "no " : "", VTY_NEWLINE);
- if (!hide_default || set->no_neighbour)
- vty_out(vty, " %sneighbour-measurement%s",
- (set->no_neighbour) ? "no " : "", VTY_NEWLINE);
- if (set->full_v1 || set->full_v2 || set->full_v3) {
- /* mandatory anyway */
- vty_out(vty, " codec full-speed%s%s",
- (!set->half_prefer) ? " prefer" : "",
- VTY_NEWLINE);
- }
- if (set->half_v1 || set->half_v3) {
- if (set->half)
- vty_out(vty, " codec half-speed%s%s",
- (set->half_prefer) ? " prefer" : "",
- VTY_NEWLINE);
- else
- vty_out(vty, " no codec half-speed%s", VTY_NEWLINE);
- }
- if (llist_empty(&set->abbrev)) {
- if (!hide_default)
- vty_out(vty, " no abbrev%s", VTY_NEWLINE);
- } else {
- llist_for_each_entry(abbrev, &set->abbrev, list)
- vty_out(vty, " abbrev %s %s%s%s%s", abbrev->abbrev,
- abbrev->number, (abbrev->name[0]) ? " " : "",
- abbrev->name, VTY_NEWLINE);
- }
- vty_out(vty, " support%s", VTY_NEWLINE);
- SUP_WRITE(sms_ptp, "sms");
- SUP_WRITE(a5_1, "a5/1");
- SUP_WRITE(a5_2, "a5/2");
- SUP_WRITE(a5_3, "a5/3");
- SUP_WRITE(a5_4, "a5/4");
- SUP_WRITE(a5_5, "a5/5");
- SUP_WRITE(a5_6, "a5/6");
- SUP_WRITE(a5_7, "a5/7");
- SUP_WRITE(p_gsm, "p-gsm");
- SUP_WRITE(e_gsm, "e-gsm");
- SUP_WRITE(r_gsm, "r-gsm");
- SUP_WRITE(pcs, "gsm-850");
- SUP_WRITE(gsm_480, "gsm-480");
- SUP_WRITE(gsm_450, "gsm-450");
- SUP_WRITE(dcs, "dcs");
- SUP_WRITE(pcs, "pcs");
- if (sup->r_gsm || sup->e_gsm || sup->p_gsm)
- if (!hide_default || sup->class_900 != set->class_900)
- vty_out(vty, " class-900 %d%s", set->class_900,
- VTY_NEWLINE);
- if (sup->gsm_850)
- if (!hide_default || sup->class_850 != set->class_850)
- vty_out(vty, " class-850 %d%s", set->class_850,
- VTY_NEWLINE);
- if (sup->gsm_480 || sup->gsm_450)
- if (!hide_default || sup->class_400 != set->class_400)
- vty_out(vty, " class-400 %d%s", set->class_400,
- VTY_NEWLINE);
- if (sup->dcs)
- if (!hide_default || sup->class_dcs != set->class_dcs)
- vty_out(vty, " class-dcs %d%s", set->class_dcs,
- VTY_NEWLINE);
- if (sup->pcs)
- if (!hide_default || sup->class_pcs != set->class_pcs)
- vty_out(vty, " class-pcs %d%s", set->class_pcs,
- VTY_NEWLINE);
- if (!hide_default || sup->ch_cap != set->ch_cap) {
- switch (set->ch_cap) {
- case GSM_CAP_SDCCH:
- vty_out(vty, " channel-capability sdcch%s",
- VTY_NEWLINE);
- break;
- case GSM_CAP_SDCCH_TCHF:
- vty_out(vty, " channel-capability sdcch+tchf%s",
- VTY_NEWLINE);
- break;
- case GSM_CAP_SDCCH_TCHF_TCHH:
- vty_out(vty, " channel-capability sdcch+tchf+tchh%s",
- VTY_NEWLINE);
- break;
- }
- }
- SUP_WRITE(full_v1, "full-speech-v1");
- SUP_WRITE(full_v2, "full-speech-v2");
- SUP_WRITE(full_v3, "full-speech-v3");
- SUP_WRITE(half_v1, "half-speech-v1");
- SUP_WRITE(half_v3, "half-speech-v3");
- if (!hide_default || sup->min_rxlev_db != set->min_rxlev_db)
- vty_out(vty, " min-rxlev %d%s", set->min_rxlev_db,
- VTY_NEWLINE);
- if (!hide_default || sup->dsc_max != set->dsc_max)
- vty_out(vty, " dsc-max %d%s", set->dsc_max, VTY_NEWLINE);
- if (!hide_default || set->skip_max_per_band)
- vty_out(vty, " %sskip-max-per-band%s",
- (set->skip_max_per_band) ? "" : "no ", VTY_NEWLINE);
- vty_out(vty, " exit%s", VTY_NEWLINE);
- vty_out(vty, " test-sim%s", VTY_NEWLINE);
- vty_out(vty, " imsi %s%s", set->test_imsi, VTY_NEWLINE);
- switch (set->test_ki_type) {
- case GSM_SIM_KEY_XOR:
- vty_out(vty, " ki xor %s%s",
- osmo_hexdump(set->test_ki, 12), VTY_NEWLINE);
- break;
- case GSM_SIM_KEY_COMP128:
- vty_out(vty, " ki comp128 %s%s",
- osmo_hexdump(set->test_ki, 16), VTY_NEWLINE);
- break;
- }
- if (!hide_default || set->test_barr)
- vty_out(vty, " %sbarred-access%s",
- (set->test_barr) ? "" : "no ", VTY_NEWLINE);
- if (set->test_rplmn_valid) {
- vty_out(vty, " rplmn %s %s",
- gsm_print_mcc(set->test_rplmn_mcc),
- gsm_print_mnc(set->test_rplmn_mnc));
- if (set->test_lac > 0x0000 && set->test_lac < 0xfffe)
- vty_out(vty, " 0x%04x", set->test_lac);
- if (set->test_tmsi != 0xffffffff)
- vty_out(vty, " 0x%08x", set->test_tmsi);
- vty_out(vty, "%s", VTY_NEWLINE);
- } else
- if (!hide_default)
- vty_out(vty, " no rplmn%s", VTY_NEWLINE);
- if (!hide_default || set->test_always)
- vty_out(vty, " hplmn-search %s%s",
- (set->test_always) ? "everywhere" : "foreign-country",
- VTY_NEWLINE);
- vty_out(vty, " exit%s", VTY_NEWLINE);
- /* no shutdown must be written to config, because shutdown is default */
- vty_out(vty, " %sshutdown%s", (ms->shutdown) ? "" : "no ",
- VTY_NEWLINE);
- vty_out(vty, "exit%s", VTY_NEWLINE);
- vty_out(vty, "!%s", VTY_NEWLINE);
-}
-
-static int config_write(struct vty *vty)
-{
- struct osmocom_ms *ms;
-
-#ifdef _HAVE_GPSD
- vty_out(vty, "gpsd host %s%s", g.gpsd_host, VTY_NEWLINE);
- vty_out(vty, "gpsd port %s%s", g.gpsd_port, VTY_NEWLINE);
-#endif
- vty_out(vty, "gps device %s%s", g.device, VTY_NEWLINE);
- if (g.baud)
- vty_out(vty, "gps baudrate %d%s", g.baud, VTY_NEWLINE);
- else
- vty_out(vty, "gps baudrate default%s", VTY_NEWLINE);
- vty_out(vty, "%sgps enable%s", (g.enable) ? "" : "no ", VTY_NEWLINE);
- vty_out(vty, "!%s", VTY_NEWLINE);
-
- vty_out(vty, "%shide-default%s", (hide_default) ? "": "no ",
- VTY_NEWLINE);
- vty_out(vty, "!%s", VTY_NEWLINE);
-
- llist_for_each_entry(ms, &ms_list, entity)
- config_write_ms(vty, ms);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_show_this, cfg_ms_show_this_cmd, "show this",
- SHOW_STR "Show config of this MS")
-{
- struct osmocom_ms *ms = vty->index;
-
- config_write_ms(vty, ms);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_layer2, cfg_ms_layer2_cmd, "layer2-socket PATH",
- "Define socket path to connect between layer 2 and layer 1\n"
- "Unix socket, default '/tmp/osmocom_l2'")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- strncpy(set->layer2_socket_path, argv[0],
- sizeof(set->layer2_socket_path) - 1);
-
- vty_restart(vty, ms);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_sap, cfg_ms_sap_cmd, "sap-socket PATH",
- "Define socket path to connect to SIM reader\n"
- "Unix socket, default '/tmp/osmocom_sap'")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- strncpy(set->sap_socket_path, argv[0],
- sizeof(set->sap_socket_path) - 1);
-
- vty_restart(vty, ms);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_sim, cfg_ms_sim_cmd, "sim (none|reader|test)",
- "Set SIM card to attach when powering on\nAttach no SIM\n"
- "Attach SIM from reader\nAttach bulit in test SIM")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- switch (argv[0][0]) {
- case 'n':
- set->sim_type = GSM_SIM_TYPE_NONE;
- break;
- case 'r':
- set->sim_type = GSM_SIM_TYPE_READER;
- break;
- case 't':
- set->sim_type = GSM_SIM_TYPE_TEST;
- break;
- default:
- vty_out(vty, "unknown SIM type%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- vty_restart_if_started(vty, ms);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_mode, cfg_ms_mode_cmd, "network-selection-mode (auto|manual)",
- "Set network selection mode\nAutomatic network selection\n"
- "Manual network selection")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
- struct msgb *nmsg;
-
- if (!ms->started) {
- if (argv[0][0] == 'a')
- set->plmn_mode = PLMN_MODE_AUTO;
- else
- set->plmn_mode = PLMN_MODE_MANUAL;
- } else {
- if (argv[0][0] == 'a')
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_AUTO);
- else
- nmsg = gsm322_msgb_alloc(GSM322_EVENT_SEL_MANUAL);
- if (!nmsg)
- return CMD_WARNING;
- gsm322_plmn_sendmsg(ms, nmsg);
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_imei, cfg_ms_imei_cmd, "imei IMEI [SV]",
- "Set IMEI (enter without control digit)\n15 Digits IMEI\n"
- "Software version digit")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
- char *error, *sv = "0";
-
- if (argc >= 2)
- sv = (char *)argv[1];
-
- error = gsm_check_imei(argv[0], sv);
- if (error) {
- vty_out(vty, "%s%s", error, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- strcpy(set->imei, argv[0]);
- strcpy(set->imeisv, argv[0]);
- strcpy(set->imeisv + 15, sv);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_imei_fixed, cfg_ms_imei_fixed_cmd, "imei-fixed",
- "Use fixed IMEI on every power on")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->imei_random = 0;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_imei_random, cfg_ms_imei_random_cmd, "imei-random <0-15>",
- "Use random IMEI on every power on\n"
- "Number of trailing digits to randomize")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->imei_random = atoi(argv[0]);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_emerg_imsi, cfg_ms_emerg_imsi_cmd, "emergency-imsi IMSI",
- "Use special IMSI for emergency calls\n15 digits IMSI")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
- char *error;
-
- error = gsm_check_imsi(argv[0]);
- if (error) {
- vty_out(vty, "%s%s", error, VTY_NEWLINE);
- return CMD_WARNING;
- }
- strcpy(set->emergency_imsi, argv[0]);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_no_emerg_imsi, cfg_ms_no_emerg_imsi_cmd, "no emergency-imsi",
- NO_STR "Use IMSI of SIM or IMEI for emergency calls")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->emergency_imsi[0] = '\0';
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_no_cw, cfg_ms_no_cw_cmd, "no call-waiting",
- NO_STR "Disallow waiting calls")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->cw = 0;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_cw, cfg_ms_cw_cmd, "call-waiting",
- "Allow waiting calls")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->cw = 1;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_no_auto_answer, cfg_ms_no_auto_answer_cmd, "no auto-answer",
- NO_STR "Disable auto-answering calls")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->auto_answer = 0;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_auto_answer, cfg_ms_auto_answer_cmd, "auto-answer",
- "Enable auto-answering calls")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->auto_answer = 1;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_clip, cfg_ms_clip_cmd, "clip",
- "Force caller ID presentation")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->clip = 1;
- set->clir = 0;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_clir, cfg_ms_clir_cmd, "clir",
- "Force caller ID restriction")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->clip = 0;
- set->clir = 1;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_no_clip, cfg_ms_no_clip_cmd, "no clip",
- NO_STR "Disable forcing of caller ID presentation")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->clip = 0;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_no_clir, cfg_ms_no_clir_cmd, "no clir",
- NO_STR "Disable forcing of caller ID restriction")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->clir = 0;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_tx_power, cfg_ms_tx_power_cmd, "tx-power (auto|full)",
- "Set the way to choose transmit power\nControlled by BTS\n"
- "Always full power\nFixed GSM power value if supported")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- switch (argv[0][0]) {
- case 'a':
- set->alter_tx_power = 0;
- break;
- case 'f':
- set->alter_tx_power = 1;
- set->alter_tx_power_value = 0;
- break;
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_tx_power_val, cfg_ms_tx_power_val_cmd, "tx-power <0-31>",
- "Set the way to choose transmit power\n"
- "Fixed GSM power value if supported")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->alter_tx_power = 1;
- set->alter_tx_power_value = atoi(argv[0]);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_sim_delay, cfg_ms_sim_delay_cmd, "simulated-delay <-128-127>",
- "Simulate a lower or higher distance from the BTS\n"
- "Delay in half bits (distance in 553.85 meter steps)")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->alter_delay = atoi(argv[0]);
- gsm48_rr_alter_delay(ms);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_no_sim_delay, cfg_ms_no_sim_delay_cmd, "no simulated-delay",
- NO_STR "Do not simulate a lower or higher distance from the BTS")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->alter_delay = 0;
- gsm48_rr_alter_delay(ms);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_stick, cfg_ms_stick_cmd, "stick <0-1023> [pcs]",
- "Stick to the given cell\nARFCN of the cell to stick to\n"
- "Given frequency is PCS band (1900) rather than DCS band.")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
- uint16_t arfcn = atoi(argv[0]);
-
- if (argc > 1) {
- if (arfcn < 512 || arfcn > 810) {
- vty_out(vty, "Given ARFCN not in PCS band%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- arfcn |= ARFCN_PCS;
- }
- set->stick = 1;
- set->stick_arfcn = arfcn;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_no_stick, cfg_ms_no_stick_cmd, "no stick",
- NO_STR "Do not stick to any cell")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->stick = 0;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_lupd, cfg_ms_lupd_cmd, "location-updating",
- "Allow location updating")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->no_lupd = 0;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_no_lupd, cfg_ms_no_lupd_cmd, "no location-updating",
- NO_STR "Do not allow location updating")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->no_lupd = 1;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_codec_full, cfg_ms_codec_full_cmd, "codec full-speed",
- "Enable codec\nFull speed speech codec")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- if (!set->full_v1 && !set->full_v2 && !set->full_v3) {
- vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_codec_full_pref, cfg_ms_codec_full_pref_cmd, "codec full-speed "
- "prefer",
- "Enable codec\nFull speed speech codec\nPrefer this codec")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- if (!set->full_v1 && !set->full_v2 && !set->full_v3) {
- vty_out(vty, "Full-rate codec not supported%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- set->half_prefer = 0;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_codec_half, cfg_ms_codec_half_cmd, "codec half-speed",
- "Enable codec\nHalf speed speech codec")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- if (!set->half_v1 && !set->half_v3) {
- vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- set->half = 1;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_codec_half_pref, cfg_ms_codec_half_pref_cmd, "codec half-speed "
- "prefer",
- "Enable codec\nHalf speed speech codec\nPrefer this codec")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- if (!set->half_v1 && !set->half_v3) {
- vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- set->half = 1;
- set->half_prefer = 1;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_no_codec_half, cfg_ms_no_codec_half_cmd, "no codec half-speed",
- NO_STR "Disable codec\nHalf speed speech codec")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- if (!set->half_v1 && !set->half_v3) {
- vty_out(vty, "Half-rate codec not supported%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- set->half = 0;
- set->half_prefer = 0;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_abbrev, cfg_ms_abbrev_cmd, "abbrev ABBREVIATION NUMBER [NAME]",
- "Store given abbreviation number\n1-3 digits abbreviation\n"
- "Number to store for the abbreviation "
- "(Use digits '0123456789*#abc', and '+' to dial international)\n"
- "Name of the abbreviation")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
- struct gsm_settings_abbrev *abbrev;
- int i;
-
- llist_for_each_entry(abbrev, &set->abbrev, list) {
- if (!strcmp(argv[0], abbrev->abbrev)) {
- vty_out(vty, "Given abbreviation '%s' already stored, "
- "delete first!%s", argv[0], VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
- if (strlen(argv[0]) >= sizeof(abbrev->abbrev)) {
- vty_out(vty, "Given abbreviation too long%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- for (i = 0; i < strlen(argv[0]); i++) {
- if (argv[0][i] < '0' || argv[0][i] > '9') {
- vty_out(vty, "Given abbreviation must have digits "
- "0..9 only!%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
- if (vty_check_number(vty, argv[1]))
- return CMD_WARNING;
-
- abbrev = talloc_zero(l23_ctx, struct gsm_settings_abbrev);
- if (!abbrev) {
- vty_out(vty, "No Memory!%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- llist_add_tail(&abbrev->list, &set->abbrev);
- strncpy(abbrev->abbrev, argv[0], sizeof(abbrev->abbrev) - 1);
- strncpy(abbrev->number, argv[1], sizeof(abbrev->number) - 1);
- if (argc >= 3)
- strncpy(abbrev->name, argv[2], sizeof(abbrev->name) - 1);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_no_abbrev, cfg_ms_no_abbrev_cmd, "no abbrev [ABBREVIATION]",
- NO_STR "Remove given abbreviation number or all numbers\n"
- "Abbreviation number to remove")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
- struct gsm_settings_abbrev *abbrev, *abbrev2;
- uint8_t deleted = 0;
-
- llist_for_each_entry_safe(abbrev, abbrev2, &set->abbrev, list) {
- if (argc < 1 || !strcmp(argv[0], abbrev->abbrev)) {
- llist_del(&abbrev->list);
- deleted = 1;
- }
- }
-
- if (argc >= 1 && !deleted) {
- vty_out(vty, "Given abbreviation '%s' not found!%s",
- argv[0], VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_neighbour, cfg_ms_neighbour_cmd, "neighbour-measurement",
- "Allow neighbour cell measurement in idle mode")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->no_neighbour = 0;
-
- vty_restart_if_started(vty, ms);
-
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_no_neighbour, cfg_ms_no_neighbour_cmd, "no neighbour-measurement",
- NO_STR "Do not allow neighbour cell measurement in idle mode")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->no_neighbour = 1;
-
- vty_restart_if_started(vty, ms);
-
- return CMD_SUCCESS;
-}
-
-static int config_write_dummy(struct vty *vty)
-{
- return CMD_SUCCESS;
-}
-
-/* per support config */
-DEFUN(cfg_ms_support, cfg_ms_support_cmd, "support",
- "Define supported features")
-{
- vty->node = SUPPORT_NODE;
-
- return CMD_SUCCESS;
-}
-
-#define SUP_EN(cfg, cfg_cmd, item, cmd, desc, restart) \
-DEFUN(cfg, cfg_cmd, cmd, "Enable " desc "support") \
-{ \
- struct osmocom_ms *ms = vty->index; \
- struct gsm_settings *set = &ms->settings; \
- struct gsm_support *sup = &ms->support; \
- if (!sup->item) { \
- vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
- if (vty_reading) \
- return CMD_SUCCESS; \
- return CMD_WARNING; \
- } \
- if (restart) \
- vty_restart(vty, ms); \
- set->item = 1; \
- return CMD_SUCCESS; \
-}
-
-#define SUP_DI(cfg, cfg_cmd, item, cmd, desc, restart) \
-DEFUN(cfg, cfg_cmd, "no " cmd, NO_STR "Disable " desc " support") \
-{ \
- struct osmocom_ms *ms = vty->index; \
- struct gsm_settings *set = &ms->settings; \
- struct gsm_support *sup = &ms->support; \
- if (!sup->item) { \
- vty_out(vty, desc " not supported%s", VTY_NEWLINE); \
- if (vty_reading) \
- return CMD_SUCCESS; \
- return CMD_WARNING; \
- } \
- if (restart) \
- vty_restart(vty, ms); \
- set->item = 0; \
- return CMD_SUCCESS; \
-}
-
-#define SET_EN(cfg, cfg_cmd, item, cmd, desc, restart) \
-DEFUN(cfg, cfg_cmd, cmd, "Enable " desc "support") \
-{ \
- struct osmocom_ms *ms = vty->index; \
- struct gsm_settings *set = &ms->settings; \
- if (restart) \
- vty_restart(vty, ms); \
- set->item = 1; \
- return CMD_SUCCESS; \
-}
-
-#define SET_DI(cfg, cfg_cmd, item, cmd, desc, restart) \
-DEFUN(cfg, cfg_cmd, "no " cmd, NO_STR "Disable " desc " support") \
-{ \
- struct osmocom_ms *ms = vty->index; \
- struct gsm_settings *set = &ms->settings; \
- if (restart) \
- vty_restart(vty, ms); \
- set->item = 0; \
- return CMD_SUCCESS; \
-}
-
-SET_EN(cfg_ms_sup_dtmf, cfg_ms_sup_dtmf_cmd, cc_dtmf, "dtmf", "DTMF", 0);
-SET_DI(cfg_ms_sup_no_dtmf, cfg_ms_sup_no_dtmf_cmd, cc_dtmf, "dtmf", "DTMF", 0);
-SUP_EN(cfg_ms_sup_sms, cfg_ms_sup_sms_cmd, sms_ptp, "sms", "SMS", 0);
-SUP_DI(cfg_ms_sup_no_sms, cfg_ms_sup_no_sms_cmd, sms_ptp, "sms", "SMS", 0);
-SUP_EN(cfg_ms_sup_a5_1, cfg_ms_sup_a5_1_cmd, a5_1, "a5/1", "A5/1", 0);
-SUP_DI(cfg_ms_sup_no_a5_1, cfg_ms_sup_no_a5_1_cmd, a5_1, "a5/1", "A5/1", 0);
-SUP_EN(cfg_ms_sup_a5_2, cfg_ms_sup_a5_2_cmd, a5_2, "a5/2", "A5/2", 0);
-SUP_DI(cfg_ms_sup_no_a5_2, cfg_ms_sup_no_a5_2_cmd, a5_2, "a5/2", "A5/2", 0);
-SUP_EN(cfg_ms_sup_a5_3, cfg_ms_sup_a5_3_cmd, a5_3, "a5/3", "A5/3", 0);
-SUP_DI(cfg_ms_sup_no_a5_3, cfg_ms_sup_no_a5_3_cmd, a5_3, "a5/3", "A5/3", 0);
-SUP_EN(cfg_ms_sup_a5_4, cfg_ms_sup_a5_4_cmd, a5_4, "a5/4", "A5/4", 0);
-SUP_DI(cfg_ms_sup_no_a5_4, cfg_ms_sup_no_a5_4_cmd, a5_4, "a5/4", "A5/4", 0);
-SUP_EN(cfg_ms_sup_a5_5, cfg_ms_sup_a5_5_cmd, a5_5, "a5/5", "A5/5", 0);
-SUP_DI(cfg_ms_sup_no_a5_5, cfg_ms_sup_no_a5_5_cmd, a5_5, "a5/5", "A5/5", 0);
-SUP_EN(cfg_ms_sup_a5_6, cfg_ms_sup_a5_6_cmd, a5_6, "a5/6", "A5/6", 0);
-SUP_DI(cfg_ms_sup_no_a5_6, cfg_ms_sup_no_a5_6_cmd, a5_6, "a5/6", "A5/6", 0);
-SUP_EN(cfg_ms_sup_a5_7, cfg_ms_sup_a5_7_cmd, a5_7, "a5/7", "A5/7", 0);
-SUP_DI(cfg_ms_sup_no_a5_7, cfg_ms_sup_no_a5_7_cmd, a5_7, "a5/7", "A5/7", 0);
-SUP_EN(cfg_ms_sup_p_gsm, cfg_ms_sup_p_gsm_cmd, p_gsm, "p-gsm", "P-GSM (900)",
- 1);
-SUP_DI(cfg_ms_sup_no_p_gsm, cfg_ms_sup_no_p_gsm_cmd, p_gsm, "p-gsm",
- "P-GSM (900)", 1);
-SUP_EN(cfg_ms_sup_e_gsm, cfg_ms_sup_e_gsm_cmd, e_gsm, "e-gsm", "E-GSM (850)",
- 1);
-SUP_DI(cfg_ms_sup_no_e_gsm, cfg_ms_sup_no_e_gsm_cmd, e_gsm, "e-gsm",
- "E-GSM (850)", 1);
-SUP_EN(cfg_ms_sup_r_gsm, cfg_ms_sup_r_gsm_cmd, r_gsm, "r-gsm", "R-GSM (850)",
- 1);
-SUP_DI(cfg_ms_sup_no_r_gsm, cfg_ms_sup_no_r_gsm_cmd, r_gsm, "r-gsm",
- "R-GSM (850)", 1);
-SUP_EN(cfg_ms_sup_dcs, cfg_ms_sup_dcs_cmd, dcs, "dcs", "DCS (1800)", 1);
-SUP_DI(cfg_ms_sup_no_dcs, cfg_ms_sup_no_dcs_cmd, dcs, "dcs", "DCS (1800)", 1);
-SUP_EN(cfg_ms_sup_gsm_850, cfg_ms_sup_gsm_850_cmd, gsm_850, "gsm-850",
- "GSM 850", 1);
-SUP_DI(cfg_ms_sup_no_gsm_850, cfg_ms_sup_no_gsm_850_cmd, gsm_850, "gsm-850",
- "GSM 850", 1);
-SUP_EN(cfg_ms_sup_pcs, cfg_ms_sup_pcs_cmd, pcs, "pcs", "PCS (1900)", 1);
-SUP_DI(cfg_ms_sup_no_pcs, cfg_ms_sup_no_pcs_cmd, pcs, "pcs", "PCS (1900)", 1);
-SUP_EN(cfg_ms_sup_gsm_480, cfg_ms_sup_gsm_480_cmd, gsm_480, "gsm-480",
- "GSM 480", 1);
-SUP_DI(cfg_ms_sup_no_gsm_480, cfg_ms_sup_no_gsm_480_cmd, gsm_480, "gsm-480",
- "GSM 480", 1);
-SUP_EN(cfg_ms_sup_gsm_450, cfg_ms_sup_gsm_450_cmd, gsm_450, "gsm-450",
- "GSM 450", 1);
-SUP_DI(cfg_ms_sup_no_gsm_450, cfg_ms_sup_no_gsm_450_cmd, gsm_450, "gsm-450",
- "GSM 450", 1);
-
-DEFUN(cfg_ms_sup_class_900, cfg_ms_sup_class_900_cmd, "class-900 (1|2|3|4|5)",
- "Select power class for GSM 900\n"
- "20 Watts\n"
- "8 Watts\n"
- "5 Watts\n"
- "2 Watts\n"
- "0.8 Watts")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
- struct gsm_support *sup = &ms->support;
-
- set->class_900 = atoi(argv[0]);
-
- if (set->class_900 < sup->class_900 && !vty_reading)
- vty_out(vty, "Note: You selected a higher class than supported "
- " by hardware!%s", VTY_NEWLINE);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_sup_class_850, cfg_ms_sup_class_850_cmd, "class-850 (1|2|3|4|5)",
- "Select power class for GSM 850\n"
- "20 Watts\n"
- "8 Watts\n"
- "5 Watts\n"
- "2 Watts\n"
- "0.8 Watts")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
- struct gsm_support *sup = &ms->support;
-
- set->class_850 = atoi(argv[0]);
-
- if (set->class_850 < sup->class_850 && !vty_reading)
- vty_out(vty, "Note: You selected a higher class than supported "
- " by hardware!%s", VTY_NEWLINE);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_sup_class_400, cfg_ms_sup_class_400_cmd, "class-400 (1|2|3|4|5)",
- "Select power class for GSM 400 (480 and 450)\n"
- "20 Watts\n"
- "8 Watts\n"
- "5 Watts\n"
- "2 Watts\n"
- "0.8 Watts")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
- struct gsm_support *sup = &ms->support;
-
- set->class_400 = atoi(argv[0]);
-
- if (set->class_400 < sup->class_400 && !vty_reading)
- vty_out(vty, "Note: You selected a higher class than supported "
- " by hardware!%s", VTY_NEWLINE);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_sup_class_dcs, cfg_ms_sup_class_dcs_cmd, "class-dcs (1|2|3)",
- "Select power class for DCS 1800\n"
- "1 Watt\n"
- "0.25 Watts\n"
- "4 Watts")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
- struct gsm_support *sup = &ms->support;
-
- set->class_dcs = atoi(argv[0]);
-
- if (((set->class_dcs + 1) & 3) < ((sup->class_dcs + 1) & 3)
- && !vty_reading)
- vty_out(vty, "Note: You selected a higher class than supported "
- " by hardware!%s", VTY_NEWLINE);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_sup_class_pcs, cfg_ms_sup_class_pcs_cmd, "class-pcs (1|2|3)",
- "Select power class for PCS 1900\n"
- "1 Watt\n"
- "0.25 Watts\n"
- "2 Watts")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
- struct gsm_support *sup = &ms->support;
-
- set->class_pcs = atoi(argv[0]);
-
- if (((set->class_pcs + 1) & 3) < ((sup->class_pcs + 1) & 3)
- && !vty_reading)
- vty_out(vty, "Note: You selected a higher class than supported "
- " by hardware!%s", VTY_NEWLINE);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_sup_ch_cap, cfg_ms_sup_ch_cap_cmd, "channel-capability "
- "(sdcch|sdcch+tchf|sdcch+tchf+tchh)",
- "Select channel capability\nSDCCH only\nSDCCH + TCH/F\nSDCCH + TCH/H")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
- struct gsm_support *sup = &ms->support;
- uint8_t ch_cap;
-
- if (!strcmp(argv[0], "sdcch+tchf+tchh"))
- ch_cap = GSM_CAP_SDCCH_TCHF_TCHH;
- else if (!strcmp(argv[0], "sdcch+tchf"))
- ch_cap = GSM_CAP_SDCCH_TCHF;
- else
- ch_cap = GSM_CAP_SDCCH;
-
- if (ch_cap > sup->ch_cap && !vty_reading) {
- vty_out(vty, "You selected an higher capability than supported "
- " by hardware!%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (ms->started && ch_cap != set->ch_cap
- && (ch_cap == GSM_CAP_SDCCH || set->ch_cap == GSM_CAP_SDCCH))
- vty_restart_if_started(vty, ms);
-
- set->ch_cap = ch_cap;
-
- return CMD_SUCCESS;
-}
-
-SUP_EN(cfg_ms_sup_full_v1, cfg_ms_sup_full_v1_cmd, full_v1, "full-speech-v1",
- "Full rate speech V1", 0);
-SUP_DI(cfg_ms_sup_no_full_v1, cfg_ms_sup_no_full_v1_cmd, full_v1,
- "full-speech-v1", "Full rate speech V1", 0);
-SUP_EN(cfg_ms_sup_full_v2, cfg_ms_sup_full_v2_cmd, full_v2, "full-speech-v2",
- "Full rate speech V2 (EFR)", 0);
-SUP_DI(cfg_ms_sup_no_full_v2, cfg_ms_sup_no_full_v2_cmd, full_v2,
- "full-speech-v2", "Full rate speech V2 (EFR)", 0);
-SUP_EN(cfg_ms_sup_full_v3, cfg_ms_sup_full_v3_cmd, full_v3, "full-speech-v3",
- "Full rate speech V3 (AMR)", 0);
-SUP_DI(cfg_ms_sup_no_full_v3, cfg_ms_sup_no_full_v3_cmd, full_v3,
- "full-speech-v3", "Full rate speech V3 (AMR)", 0);
-SUP_EN(cfg_ms_sup_half_v1, cfg_ms_sup_half_v1_cmd, half_v1, "half-speech-v1",
- "Half rate speech V1", 0);
-SUP_DI(cfg_ms_sup_no_half_v1, cfg_ms_sup_no_half_v1_cmd, half_v1,
- "half-speech-v1", "Half rate speech V1", 0);
-SUP_EN(cfg_ms_sup_half_v3, cfg_ms_sup_half_v3_cmd, half_v3, "half-speech-v3",
- "Half rate speech V3 (AMR)", 0);
-SUP_DI(cfg_ms_sup_no_half_v3, cfg_ms_sup_no_half_v3_cmd, half_v3,
- "half-speech-v3", "Half rate speech V3 (AMR)", 0);
-
-DEFUN(cfg_ms_sup_min_rxlev, cfg_ms_sup_min_rxlev_cmd, "min-rxlev <-110--47>",
- "Set the minimum receive level to select a cell\n"
- "Minimum receive level from -110 dBm to -47 dBm")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->min_rxlev_db = atoi(argv[0]);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_sup_dsc_max, cfg_ms_sup_dsc_max_cmd, "dsc-max <90-500>",
- "Set the maximum DSC value. Standard is 90. Increase to make mobile "
- "more reliable against bad RX signal. This increase the propability "
- "of missing a paging requests\n"
- "DSC initial and maximum value (standard is 90)")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->dsc_max = atoi(argv[0]);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_sup_skip_max_per_band, cfg_ms_sup_skip_max_per_band_cmd,
- "skip-max-per-band",
- "Scan all frequencies per band, not only a maximum number")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->skip_max_per_band = 1;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_ms_sup_no_skip_max_per_band, cfg_ms_sup_no_skip_max_per_band_cmd,
- "no skip-max-per-band",
- NO_STR "Scan only a maximum number of frequencies per band")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->skip_max_per_band = 0;
-
- return CMD_SUCCESS;
-}
-
-/* per testsim config */
-DEFUN(cfg_ms_testsim, cfg_ms_testsim_cmd, "test-sim",
- "Configure test SIM emulation")
-{
- vty->node = TESTSIM_NODE;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_test_imsi, cfg_test_imsi_cmd, "imsi IMSI",
- "Set IMSI on test card\n15 digits IMSI")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
- char *error = gsm_check_imsi(argv[0]);
-
- if (error) {
- vty_out(vty, "%s%s", error, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- strcpy(set->test_imsi, argv[0]);
-
- vty_restart_if_started(vty, ms);
-
- return CMD_SUCCESS;
-}
-
-#define HEX_STR "\nByte as two digits hexadecimal"
-DEFUN(cfg_test_ki_xor, cfg_test_ki_xor_cmd, "ki xor HEX HEX HEX HEX HEX HEX "
- "HEX HEX HEX HEX HEX HEX",
- "Set Key (Kc) on test card\nUse XOR algorithm" HEX_STR HEX_STR HEX_STR
- HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR)
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
- uint8_t ki[12];
- const char *p;
- int i;
-
- for (i = 0; i < 12; i++) {
- p = argv[i];
- if (!strncmp(p, "0x", 2))
- p += 2;
- if (strlen(p) != 2) {
- vty_out(vty, "Expecting two digits hex value (with or "
- "without 0x in front)%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- ki[i] = strtoul(p, NULL, 16);
- }
-
- set->test_ki_type = GSM_SIM_KEY_XOR;
- memcpy(set->test_ki, ki, 12);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_test_ki_comp128, cfg_test_ki_comp128_cmd, "ki comp128 HEX HEX HEX "
- "HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX HEX",
- "Set Key (Kc) on test card\nUse XOR algorithm" HEX_STR HEX_STR HEX_STR
- HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR HEX_STR
- HEX_STR HEX_STR HEX_STR HEX_STR)
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
- uint8_t ki[16];
- const char *p;
- int i;
-
- for (i = 0; i < 16; i++) {
- p = argv[i];
- if (!strncmp(p, "0x", 2))
- p += 2;
- if (strlen(p) != 2) {
- vty_out(vty, "Expecting two digits hex value (with or "
- "without 0x in front)%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- ki[i] = strtoul(p, NULL, 16);
- }
-
- set->test_ki_type = GSM_SIM_KEY_COMP128;
- memcpy(set->test_ki, ki, 16);
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_test_barr, cfg_test_barr_cmd, "barred-access",
- "Allow access to barred cells")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->test_barr = 1;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_test_no_barr, cfg_test_no_barr_cmd, "no barred-access",
- NO_STR "Deny access to barred cells")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->test_barr = 0;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_test_no_rplmn, cfg_test_no_rplmn_cmd, "no rplmn",
- NO_STR "Unset Registered PLMN")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- set->test_rplmn_valid = 0;
-
- vty_restart_if_started(vty, ms);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_test_rplmn, cfg_test_rplmn_cmd, "rplmn MCC MNC [LAC] [TMSI]",
- "Set Registered PLMN\nMobile Country Code\nMobile Network Code\n"
- "Optionally set locatio area code\n"
- "Optionally set current assigned TMSI")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
- uint16_t mcc = gsm_input_mcc((char *)argv[0]),
- mnc = gsm_input_mnc((char *)argv[1]);
-
- if (mcc == GSM_INPUT_INVALID) {
- vty_out(vty, "Given MCC invalid%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- if (mnc == GSM_INPUT_INVALID) {
- vty_out(vty, "Given MNC invalid%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- set->test_rplmn_valid = 1;
- set->test_rplmn_mcc = mcc;
- set->test_rplmn_mnc = mnc;
-
- if (argc >= 3)
- set->test_lac = strtoul(argv[2], NULL, 16);
- else
- set->test_lac = 0xfffe;
-
- if (argc >= 4)
- set->test_tmsi = strtoul(argv[3], NULL, 16);
- else
- set->test_tmsi = 0xffffffff;
-
- vty_restart_if_started(vty, ms);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_test_hplmn, cfg_test_hplmn_cmd, "hplmn-search (everywhere|foreign-country)",
- "Set Home PLMN search mode\n"
- "Search for HPLMN when on any other network\n"
- "Search for HPLMN when in a different country")
-{
- struct osmocom_ms *ms = vty->index;
- struct gsm_settings *set = &ms->settings;
-
- switch (argv[0][0]) {
- case 'e':
- set->test_always = 1;
- break;
- case 'f':
- set->test_always = 0;
- break;
- }
-
- vty_restart_if_started(vty, ms);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_no_shutdown, cfg_ms_no_shutdown_cmd, "no shutdown",
- NO_STR "Activate and run MS")
-{
- struct osmocom_ms *ms = vty->index, *tmp;
- int rc;
-
- if (ms->shutdown != 2)
- return CMD_SUCCESS;
-
- llist_for_each_entry(tmp, &ms_list, entity) {
- if (tmp->shutdown == 2)
- continue;
- if (!strcmp(ms->settings.layer2_socket_path,
- tmp->settings.layer2_socket_path)) {
- vty_out(vty, "Cannot start MS '%s', because MS '%s' "
- "use the same layer2-socket.%sPlease shutdown "
- "MS '%s' first.%s", ms->name, tmp->name,
- VTY_NEWLINE, tmp->name, VTY_NEWLINE);
- return CMD_WARNING;
- }
- if (!strcmp(ms->settings.sap_socket_path,
- tmp->settings.sap_socket_path)) {
- vty_out(vty, "Cannot start MS '%s', because MS '%s' "
- "use the same sap-socket.%sPlease shutdown "
- "MS '%s' first.%s", ms->name, tmp->name,
- VTY_NEWLINE, tmp->name, VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
- rc = mobile_init(ms);
- if (rc < 0) {
- vty_out(vty, "Connection to layer 1 failed!%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_shutdown, cfg_ms_shutdown_cmd, "shutdown",
- "Shut down and deactivate MS")
-{
- struct osmocom_ms *ms = vty->index;
-
- if (ms->shutdown == 0)
- mobile_exit(ms, 0);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(cfg_shutdown_force, cfg_ms_shutdown_force_cmd, "shutdown force",
- "Shut down and deactivate MS\nDo not perform IMSI detach")
-{
- struct osmocom_ms *ms = vty->index;
-
- if (ms->shutdown <= 1)
- mobile_exit(ms, 1);
-
- return CMD_SUCCESS;
-}
-
-enum node_type ms_vty_go_parent(struct vty *vty)
-{
- switch (vty->node) {
- case MS_NODE:
- vty->node = CONFIG_NODE;
- vty->index = NULL;
- break;
- case TESTSIM_NODE:
- case SUPPORT_NODE:
- vty->node = MS_NODE;
- break;
- default:
- vty->node = CONFIG_NODE;
- }
-
- return vty->node;
-}
-
-/* Down vty node level. */
-gDEFUN(ournode_exit,
- ournode_exit_cmd, "exit", "Exit current mode and down to previous mode\n")
-{
- switch (vty->node) {
- case MS_NODE:
- vty->node = CONFIG_NODE;
- vty->index = NULL;
- break;
- case TESTSIM_NODE:
- case SUPPORT_NODE:
- vty->node = MS_NODE;
- break;
- default:
- break;
- }
- return CMD_SUCCESS;
-}
-
-/* End of configuration. */
-gDEFUN(ournode_end,
- ournode_end_cmd, "end", "End current mode and change to enable mode.")
-{
- switch (vty->node) {
- case VIEW_NODE:
- case ENABLE_NODE:
- /* Nothing to do. */
- break;
- case CONFIG_NODE:
- case VTY_NODE:
- case MS_NODE:
- case TESTSIM_NODE:
- case SUPPORT_NODE:
- vty_config_unlock(vty);
- vty->node = ENABLE_NODE;
- vty->index = NULL;
- vty->index_sub = NULL;
- break;
- default:
- break;
- }
- return CMD_SUCCESS;
-}
-
-DEFUN(off, off_cmd, "off",
- "Turn mobiles off (shutdown) and exit")
-{
- osmo_signal_dispatch(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL);
-
- return CMD_SUCCESS;
-}
-
-#define SUP_NODE(item) \
- install_element(SUPPORT_NODE, &cfg_ms_sup_item_cmd);
-
-int ms_vty_init(void)
-{
- install_element_ve(&show_ms_cmd);
- install_element_ve(&show_subscr_cmd);
- install_element_ve(&show_support_cmd);
- install_element_ve(&show_cell_cmd);
- install_element_ve(&show_cell_si_cmd);
- install_element_ve(&show_nbcells_cmd);
- install_element_ve(&show_ba_cmd);
- install_element_ve(&show_forb_la_cmd);
- install_element_ve(&show_forb_plmn_cmd);
- install_element_ve(&monitor_network_cmd);
- install_element_ve(&no_monitor_network_cmd);
- install_element(ENABLE_NODE, &off_cmd);
-
- install_element(ENABLE_NODE, &sim_test_cmd);
- install_element(ENABLE_NODE, &sim_reader_cmd);
- install_element(ENABLE_NODE, &sim_remove_cmd);
- install_element(ENABLE_NODE, &sim_pin_cmd);
- install_element(ENABLE_NODE, &sim_disable_pin_cmd);
- install_element(ENABLE_NODE, &sim_enable_pin_cmd);
- install_element(ENABLE_NODE, &sim_change_pin_cmd);
- install_element(ENABLE_NODE, &sim_unblock_pin_cmd);
- install_element(ENABLE_NODE, &sim_lai_cmd);
- install_element(ENABLE_NODE, &network_search_cmd);
- install_element(ENABLE_NODE, &network_show_cmd);
- install_element(ENABLE_NODE, &network_select_cmd);
- install_element(ENABLE_NODE, &call_cmd);
- install_element(ENABLE_NODE, &call_retr_cmd);
- install_element(ENABLE_NODE, &call_dtmf_cmd);
- install_element(ENABLE_NODE, &test_reselection_cmd);
- install_element(ENABLE_NODE, &delete_forbidden_plmn_cmd);
-
-#ifdef _HAVE_GPSD
- install_element(CONFIG_NODE, &cfg_gps_host_cmd);
-#endif
- install_element(CONFIG_NODE, &cfg_gps_device_cmd);
- install_element(CONFIG_NODE, &cfg_gps_baud_cmd);
- install_element(CONFIG_NODE, &cfg_gps_enable_cmd);
- install_element(CONFIG_NODE, &cfg_no_gps_enable_cmd);
-
- install_element(CONFIG_NODE, &cfg_hide_default_cmd);
- install_element(CONFIG_NODE, &cfg_no_hide_default_cmd);
-
- install_element(CONFIG_NODE, &cfg_ms_cmd);
- install_element(CONFIG_NODE, &cfg_ms_create_cmd);
- install_element(CONFIG_NODE, &cfg_ms_rename_cmd);
- install_element(CONFIG_NODE, &cfg_no_ms_cmd);
- install_element(CONFIG_NODE, &ournode_end_cmd);
- install_node(&ms_node, config_write);
- install_default(MS_NODE);
- install_element(MS_NODE, &ournode_exit_cmd);
- install_element(MS_NODE, &ournode_end_cmd);
- install_element(MS_NODE, &cfg_ms_show_this_cmd);
- install_element(MS_NODE, &cfg_ms_layer2_cmd);
- install_element(MS_NODE, &cfg_ms_sap_cmd);
- install_element(MS_NODE, &cfg_ms_sim_cmd);
- install_element(MS_NODE, &cfg_ms_mode_cmd);
- install_element(MS_NODE, &cfg_ms_imei_cmd);
- install_element(MS_NODE, &cfg_ms_imei_fixed_cmd);
- install_element(MS_NODE, &cfg_ms_imei_random_cmd);
- install_element(MS_NODE, &cfg_ms_no_emerg_imsi_cmd);
- install_element(MS_NODE, &cfg_ms_emerg_imsi_cmd);
- install_element(MS_NODE, &cfg_ms_cw_cmd);
- install_element(MS_NODE, &cfg_ms_no_cw_cmd);
- install_element(MS_NODE, &cfg_ms_auto_answer_cmd);
- install_element(MS_NODE, &cfg_ms_no_auto_answer_cmd);
- install_element(MS_NODE, &cfg_ms_clip_cmd);
- install_element(MS_NODE, &cfg_ms_clir_cmd);
- install_element(MS_NODE, &cfg_ms_no_clip_cmd);
- install_element(MS_NODE, &cfg_ms_no_clir_cmd);
- install_element(MS_NODE, &cfg_ms_tx_power_cmd);
- install_element(MS_NODE, &cfg_ms_tx_power_val_cmd);
- install_element(MS_NODE, &cfg_ms_sim_delay_cmd);
- install_element(MS_NODE, &cfg_ms_no_sim_delay_cmd);
- install_element(MS_NODE, &cfg_ms_stick_cmd);
- install_element(MS_NODE, &cfg_ms_no_stick_cmd);
- install_element(MS_NODE, &cfg_ms_lupd_cmd);
- install_element(MS_NODE, &cfg_ms_no_lupd_cmd);
- install_element(MS_NODE, &cfg_ms_codec_full_cmd);
- install_element(MS_NODE, &cfg_ms_codec_full_pref_cmd);
- install_element(MS_NODE, &cfg_ms_codec_half_cmd);
- install_element(MS_NODE, &cfg_ms_codec_half_pref_cmd);
- install_element(MS_NODE, &cfg_ms_no_codec_half_cmd);
- install_element(MS_NODE, &cfg_ms_abbrev_cmd);
- install_element(MS_NODE, &cfg_ms_no_abbrev_cmd);
- install_element(MS_NODE, &cfg_ms_testsim_cmd);
- install_element(MS_NODE, &cfg_ms_neighbour_cmd);
- install_element(MS_NODE, &cfg_ms_no_neighbour_cmd);
- install_element(MS_NODE, &cfg_ms_support_cmd);
- install_node(&support_node, config_write_dummy);
- install_default(SUPPORT_NODE);
- install_element(SUPPORT_NODE, &ournode_exit_cmd);
- install_element(SUPPORT_NODE, &ournode_end_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_dtmf_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_no_dtmf_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_sms_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_no_sms_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_a5_1_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_1_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_a5_2_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_2_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_a5_3_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_3_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_a5_4_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_4_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_a5_5_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_5_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_a5_6_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_6_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_a5_7_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_no_a5_7_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_p_gsm_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_no_p_gsm_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_e_gsm_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_no_e_gsm_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_r_gsm_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_no_r_gsm_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_dcs_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_no_dcs_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_gsm_850_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_no_gsm_850_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_pcs_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_no_pcs_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_gsm_480_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_no_gsm_480_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_gsm_450_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_no_gsm_450_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_class_900_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_class_dcs_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_class_850_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_class_pcs_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_class_400_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_ch_cap_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_full_v1_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v1_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_full_v2_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v2_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_full_v3_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_no_full_v3_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_half_v1_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_no_half_v1_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_half_v3_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_no_half_v3_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_min_rxlev_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_dsc_max_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_skip_max_per_band_cmd);
- install_element(SUPPORT_NODE, &cfg_ms_sup_no_skip_max_per_band_cmd);
- install_node(&testsim_node, config_write_dummy);
- install_default(TESTSIM_NODE);
- install_element(TESTSIM_NODE, &ournode_exit_cmd);
- install_element(TESTSIM_NODE, &ournode_end_cmd);
- install_element(TESTSIM_NODE, &cfg_test_imsi_cmd);
- install_element(TESTSIM_NODE, &cfg_test_ki_xor_cmd);
- install_element(TESTSIM_NODE, &cfg_test_ki_comp128_cmd);
- install_element(TESTSIM_NODE, &cfg_test_barr_cmd);
- install_element(TESTSIM_NODE, &cfg_test_no_barr_cmd);
- install_element(TESTSIM_NODE, &cfg_test_no_rplmn_cmd);
- install_element(TESTSIM_NODE, &cfg_test_rplmn_cmd);
- install_element(TESTSIM_NODE, &cfg_test_hplmn_cmd);
- install_element(MS_NODE, &cfg_ms_shutdown_cmd);
- install_element(MS_NODE, &cfg_ms_shutdown_force_cmd);
- install_element(MS_NODE, &cfg_ms_no_shutdown_cmd);
-
- return 0;
-}
-
-void vty_notify(struct osmocom_ms *ms, const char *fmt, ...)
-{
- struct telnet_connection *connection;
- char buffer[1000];
- va_list args;
- struct vty *vty;
-
- if (fmt) {
- va_start(args, fmt);
- vsnprintf(buffer, sizeof(buffer) - 1, fmt, args);
- buffer[sizeof(buffer) - 1] = '\0';
- va_end(args);
-
- if (!buffer[0])
- return;
- }
-
- llist_for_each_entry(connection, &active_connections, entry) {
- vty = connection->vty;
- if (!vty)
- continue;
- if (!fmt) {
- vty_out(vty, "%s%% (MS %s)%s", VTY_NEWLINE, ms->name,
- VTY_NEWLINE);
- continue;
- }
- if (buffer[strlen(buffer) - 1] == '\n') {
- buffer[strlen(buffer) - 1] = '\0';
- vty_out(vty, "%% %s%s", buffer, VTY_NEWLINE);
- buffer[strlen(buffer)] = '\n';
- } else
- vty_out(vty, "%% %s", buffer);
- }
-}
-
diff --git a/Src/osmoconbb/src/host/osmocon/.gitignore b/Src/osmoconbb/src/host/osmocon/.gitignore
deleted file mode 100644
index ad061b7..0000000
--- a/Src/osmoconbb/src/host/osmocon/.gitignore
+++ /dev/null
@@ -1,36 +0,0 @@
-# autoreconf by-products
-*.in
-
-aclocal.m4
-autom4te.cache/
-configure
-depcomp
-install-sh
-missing
-
-# configure by-products
-.deps/
-Makefile
-
-config.status
-version.h
-
-# build by-products
-*.o
-
-osmocon
-osmoload
-
-# various
-.version
-.tarball-version
-
-# IDA file
-*.id*
-*.nam
-*.til
-
-# Other test files
-*.dump
-*.bin
-*.log
diff --git a/Src/osmoconbb/src/host/osmocon/COPYING b/Src/osmoconbb/src/host/osmocon/COPYING
deleted file mode 100644
index d511905..0000000
--- a/Src/osmoconbb/src/host/osmocon/COPYING
+++ /dev/null
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/Src/osmoconbb/src/host/osmocon/Makefile.am b/Src/osmoconbb/src/host/osmocon/Makefile.am
deleted file mode 100644
index 8b0d4bf..0000000
--- a/Src/osmoconbb/src/host/osmocon/Makefile.am
+++ /dev/null
@@ -1,21 +0,0 @@
-AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6
-
-# versioning magic
-BUILT_SOURCES = $(top_srcdir)/.version
-$(top_srcdir)/.version:
- echo $(VERSION) > $@-t && mv $@-t $@
-dist-hook:
- echo $(VERSION) > $(distdir)/.tarball-version
-
-INCLUDES = $(all_includes) -I$(top_srcdir)/include
-AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS)
-
-sbin_PROGRAMS = osmocon osmoload
-
-# FIXME: sercomm needs to move into libosmocore or another shared lib
-INCLUDES += -I../../target/firmware/include/comm -I../../target/firmware/apps -DHOST_BUILD
-osmocon_SOURCES = osmocon.c tpu_debug.c ../../target/firmware/comm/sercomm.c
-osmocon_LDADD = $(LIBOSMOCORE_LIBS)
-
-osmoload_SOURCE = osmoload.c ../../target/firmware/comm/sercomm.c
-osmoload_LDADD = $(LIBOSMOCORE_LIBS)
diff --git a/Src/osmoconbb/src/host/osmocon/configure.ac b/Src/osmoconbb/src/host/osmocon/configure.ac
deleted file mode 100644
index 4130800..0000000
--- a/Src/osmoconbb/src/host/osmocon/configure.ac
+++ /dev/null
@@ -1,25 +0,0 @@
-dnl Process this file with autoconf to produce a configure script
-AC_INIT([osmocon],
- m4_esyscmd([./git-version-gen .tarball-version]),
- [baseband-devel@lists.osmocom.org])
-
-AM_INIT_AUTOMAKE([dist-bzip2])
-
-dnl kernel style compile messages
-m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
-
-dnl checks for programs
-AC_PROG_MAKE_SET
-AC_PROG_CC
-AC_PROG_INSTALL
-
-dnl checks for libraries
-PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore)
-
-dnl checks for header files
-AC_HEADER_STDC
-
-dnl Checks for typedefs, structures and compiler characteristics
-
-AC_OUTPUT(
- Makefile)
diff --git a/Src/osmoconbb/src/host/osmocon/git-version-gen b/Src/osmoconbb/src/host/osmocon/git-version-gen
deleted file mode 100755
index 652fac6..0000000
--- a/Src/osmoconbb/src/host/osmocon/git-version-gen
+++ /dev/null
@@ -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='osmocon_v*' HEAD 2>/dev/null \
- || git describe --abbrev=4 HEAD 2>/dev/null` \
- && case $v in
- osmocon_[0-9]*) ;;
- osmocon_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-/;s/^osmocon_//'`;
-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:
diff --git a/Src/osmoconbb/src/host/osmocon/memdump_convert.pl b/Src/osmoconbb/src/host/osmocon/memdump_convert.pl
deleted file mode 100755
index 3d18a0b..0000000
--- a/Src/osmoconbb/src/host/osmocon/memdump_convert.pl
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/perl
-
-my $num_line = 0;
-my $num_hex = 0;
-my $oldaddr;
-
-while (my $line = <STDIN>) {
- chomp($line);
- $num_line++;
- my (@hex) = $line =~ /(\w{8}): (\w{8}) (\w{8}) (\w{8}) (\w{8}) (\w{8}) (\w{8}) (\w{8}) (\w{8})/;
- my $addr = hex(shift @hex);
- if ($addr != 0 && $addr != $oldaddr + 0x20) {
- printf(STDERR "gap of %u between 0x%08x and 0x%08x\n%s\n",
- $addr - $oldaddr, $addr, $oldaddr, $line);
- }
- foreach my $h (@hex) {
- $num_hex++;
- # poor mans endian conversion
- my ($a, $b, $c, $d) = $h =~/(\w\w)(\w\w)(\w\w)(\w\w)/;
- my $h_reorder = $d . $c . $b . $a;
- # convert into actual binary number
- my $tmp = pack('H8', $h_reorder);
- syswrite(STDOUT, $tmp, 4);
- }
- $oldaddr = $addr;
-}
-
-printf(STDERR "num lines/num hex: %u/%u\n", $num_line, $num_hex);
-
diff --git a/Src/osmoconbb/src/host/osmocon/osmocon.c b/Src/osmoconbb/src/host/osmocon/osmocon.c
deleted file mode 100644
index 7f74f8f..0000000
--- a/Src/osmoconbb/src/host/osmocon/osmocon.c
+++ /dev/null
@@ -1,1558 +0,0 @@
-/* osmocon */
-
-/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
- * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2010 by Steve Markgraf <steve@steve-m.de>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <termios.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/un.h>
-
-#include <sercomm.h>
-
-#include <osmocom/core/linuxlist.h>
-#include <osmocom/core/select.h>
-#include <osmocom/core/talloc.h>
-#include <osmocom/core/timer.h>
-
-#include <arpa/inet.h>
-
-#define MODEM_BAUDRATE B115200
-#define MAX_DNLOAD_SIZE 0xFFFF
-#define MAX_HDR_SIZE 128
-#define MAGIC_OFFSET 0x3be2
-
-#define DEFAULT_BEACON_INTERVAL 50000
-#define ROMLOAD_INIT_BAUDRATE B19200
-#define ROMLOAD_DL_BAUDRATE B115200
-#define ROMLOAD_BLOCK_HDR_LEN 10
-#define ROMLOAD_ADDRESS 0x820000
-
-#define MTK_INIT_BAUDRATE B19200
-#define MTK_ADDRESS 0x40001400
-#define MTK_BLOCK_SIZE 1024
-
-struct tool_server *tool_server_for_dlci[256];
-
-/**
- * a connection from some other tool
- */
-struct tool_connection {
- struct tool_server *server;
- struct llist_head entry;
- struct osmo_fd fd;
-};
-
-/**
- * server for a tool
- */
-struct tool_server {
- struct osmo_fd bfd;
- uint8_t dlci;
- struct llist_head connections;
-};
-
-
-enum dnload_state {
- WAITING_PROMPT1,
- WAITING_PROMPT2,
- DOWNLOADING,
-};
-
-enum romload_state {
- WAITING_IDENTIFICATION,
- WAITING_PARAM_ACK,
- SENDING_BLOCKS,
- SENDING_LAST_BLOCK,
- LAST_BLOCK_SENT,
- WAITING_BLOCK_ACK,
- WAITING_CHECKSUM_ACK,
- WAITING_BRANCH_ACK,
- FINISHED,
-};
-
-enum mtk_state {
- MTK_INIT_1,
- MTK_INIT_2,
- MTK_INIT_3,
- MTK_INIT_4,
- MTK_WAIT_WRITE_ACK,
- MTK_WAIT_ADDR_ACK,
- MTK_WAIT_SIZE_ACK,
- MTK_SENDING_BLOCKS,
- MTK_WAIT_BRANCH_CMD_ACK,
- MTK_WAIT_BRANCH_ADDR_ACK,
- MTK_FINISHED,
-};
-
-enum dnload_mode {
- MODE_C123,
- MODE_C123xor,
- MODE_C140,
- MODE_C140xor,
- MODE_C155,
- MODE_ROMLOAD,
- MODE_MTK,
-};
-
-struct dnload {
- enum dnload_state state;
- enum romload_state romload_state;
- enum mtk_state mtk_state;
- enum dnload_mode mode;
- struct osmo_fd serial_fd;
- char *filename;
- char *chainload_filename;
-
- int expect_hdlc;
-
- int dump_rx;
- int dump_tx;
- int beacon_interval;
-
- /* data to be downloaded */
- uint8_t *data;
- int data_len;
-
- uint8_t *write_ptr;
-
- /* romload: block to be downloaded */
- uint8_t *block;
- int block_len;
- uint8_t block_number;
- uint16_t block_payload_size;
- int romload_dl_checksum;
- uint8_t *block_ptr;
- uint8_t load_address[4];
-
- uint8_t mtk_send_size[4];
- int block_count;
- int echo_bytecount;
-
- struct tool_server layer2_server;
- struct tool_server loader_server;
-};
-
-
-static struct dnload dnload;
-static struct osmo_timer_list tick_timer;
-
-/* Compal ramloader specific */
-static const uint8_t phone_prompt1[] = { 0x1b, 0xf6, 0x02, 0x00, 0x41, 0x01, 0x40 };
-static const uint8_t dnload_cmd[] = { 0x1b, 0xf6, 0x02, 0x00, 0x52, 0x01, 0x53 };
-static const uint8_t phone_prompt2[] = { 0x1b, 0xf6, 0x02, 0x00, 0x41, 0x02, 0x43 };
-static const uint8_t phone_ack[] = { 0x1b, 0xf6, 0x02, 0x00, 0x41, 0x03, 0x42 };
-static const uint8_t phone_nack_magic[]= { 0x1b, 0xf6, 0x02, 0x00, 0x41, 0x03, 0x57 };
-static const uint8_t phone_nack[] = { 0x1b, 0xf6, 0x02, 0x00, 0x45, 0x53, 0x16 };
-static const uint8_t ftmtool[] = { 0x66, 0x74, 0x6d, 0x74, 0x6f, 0x6f, 0x6c };
-static const uint8_t phone_magic[] = { 0x31, 0x30, 0x30, 0x33 }; /* "1003" */
-
-/* The C123 has a hard-coded check inside the ramloader that requires the
- * following bytes to be always the first four bytes of the image */
-static const uint8_t data_hdr_c123[] = { 0xee, 0x4c, 0x9f, 0x63 };
-
-/* The C155 doesn't have some strange restriction on what the first four bytes
- * have to be, but it starts the ramloader in THUMB mode. We use the following
- * four bytes to switch back to ARM mode:
- 800100: 4778 bx pc
- 800102: 46c0 nop ; (mov r8, r8)
- */
-static const uint8_t data_hdr_c155[] = { 0x78, 0x47, 0xc0, 0x46 };
-
-/* Calypso romloader specific */
-static const uint8_t romload_ident_cmd[] = { 0x3c, 0x69 }; /* <i */
-static const uint8_t romload_abort_cmd[] = { 0x3c, 0x61 }; /* <a */
-static const uint8_t romload_write_cmd[] = { 0x3c, 0x77 }; /* <w */
-static const uint8_t romload_checksum_cmd[] = { 0x3c, 0x63 }; /* <c */
-static const uint8_t romload_branch_cmd[] = { 0x3c, 0x62 }; /* <b */
-static const uint8_t romload_ident_ack[] = { 0x3e, 0x69 }; /* >i */
-static const uint8_t romload_param_ack[] = { 0x3e, 0x70 }; /* >p */
-static const uint8_t romload_param_nack[] = { 0x3e, 0x50 }; /* >P */
-static const uint8_t romload_block_ack[] = { 0x3e, 0x77 }; /* >w */
-static const uint8_t romload_block_nack[] = { 0x3e, 0x57 }; /* >W */
-static const uint8_t romload_checksum_ack[] = { 0x3e, 0x63 }; /* >c */
-static const uint8_t romload_checksum_nack[] = { 0x3e, 0x43 }; /* >C */
-static const uint8_t romload_branch_ack[] = { 0x3e, 0x62 }; /* >b */
-static const uint8_t romload_branch_nack[] = { 0x3e, 0x42 }; /* >B */
-
-/* romload_param: {"<p", uint8_t baudrate, uint8_t dpll, uint16_t memory_config,
- * uint8_t strobe_af, uint32_t uart_timeout} */
-
-static const uint8_t romload_param[] = { 0x3c, 0x70, 0x00, 0x00, 0x00, 0x04,
- 0x00, 0x00, 0x00, 0x00, 0x00 };
-
-/* MTK romloader specific */
-static const uint8_t mtk_init_cmd[] = { 0xa0, 0x0a, 0x50, 0x05 };
-static const uint8_t mtk_init_resp[] = { 0x5f, 0xf5, 0xaf, 0xfa };
-static const uint8_t mtk_command[] = { 0xa1, 0xa2, 0xa4, 0xa8 };
-
-/* FIXME: this routine is more or less what openbsc/src/rs232:rs232_setup()
- * does, we should move it to libosmocore at some point */
-static int serial_init(const char *serial_port)
-{
- int rc, serial_fd, v24;
- struct termios tio;
-
- serial_fd = open(serial_port, O_RDWR | O_NOCTTY | O_NDELAY);
- if (serial_fd < 0) {
- perror("cannot open serial port");
- return serial_fd;
- }
-
- //fcntl(serial_fd, F_SETFL, 0);
-
- /* Configure serial interface */
- rc = tcgetattr(serial_fd, &tio);
- if (rc < 0) {
- perror("tcgetattr()");
- return rc;
- }
- cfsetispeed(&tio, MODEM_BAUDRATE);
- cfsetospeed(&tio, MODEM_BAUDRATE);
- tio.c_cflag &= ~(PARENB | CSTOPB | CSIZE | CRTSCTS);
- tio.c_cflag |= (CREAD | CLOCAL | CS8);
- tio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
- tio.c_iflag |= (INPCK | ISTRIP);
- tio.c_iflag &= ~(ISTRIP | IXON | IXOFF | IGNBRK | INLCR | ICRNL | IGNCR);
- tio.c_oflag &= ~(OPOST | ONLCR);
- rc = tcsetattr(serial_fd, TCSANOW, &tio);
- if (rc < 0) {
- perror("tcsetattr()");
- return rc;
- }
-
- /* set ready to read/write */
- v24 = TIOCM_DTR | TIOCM_RTS;
- rc = ioctl(serial_fd, TIOCMBIS, &v24);
- if (rc < 0) {
- perror("ioctl(TIOCMBIS)");
- return rc;
- }
-
- return serial_fd;
-}
-
-static int serial_set_baudrate(speed_t baudrate)
-{
- int rc;
- struct termios tio;
-
- rc = tcgetattr(dnload.serial_fd.fd, &tio);
- if (rc < 0) {
- perror("tcgetattr()");
- return rc;
- }
- cfsetispeed(&tio, baudrate);
- cfsetospeed(&tio, baudrate);
-
- rc = tcsetattr(dnload.serial_fd.fd, TCSANOW, &tio);
- return rc;
-}
-
-static void beacon_timer_cb(void *p)
-{
- int rc;
-
- if (dnload.romload_state == WAITING_IDENTIFICATION) {
- printf("Sending Calypso romloader beacon...\n");
- rc = write(dnload.serial_fd.fd, romload_ident_cmd,
- sizeof(romload_ident_cmd));
-
- if (!(rc == sizeof(romload_ident_cmd)))
- printf("Error sending identification beacon\n");
-
- osmo_timer_schedule(p, 0, dnload.beacon_interval);
- }
-}
-
-static void mtk_timer_cb(void *p)
-{
- int rc;
-
- if (dnload.mtk_state == MTK_INIT_1) {
- printf("Sending MTK romloader beacon...\n");
- rc = write(dnload.serial_fd.fd, &mtk_init_cmd[0], 1);
-
- if (!(rc == 1))
- printf("Error sending identification beacon\n");
-
- osmo_timer_schedule(p, 0, dnload.beacon_interval);
- }
-}
-
-/* Read the to-be-downloaded file, prepend header and length, append XOR sum */
-int read_file(const char *filename)
-{
- int fd, rc, i;
- struct stat st;
- const uint8_t *hdr = NULL;
- int payload_size;
- int hdr_len = 0;
- uint8_t *file_data;
- uint16_t tot_len;
- uint8_t nibble;
- uint8_t running_xor = 0x02;
-
- fd = open(filename, O_RDONLY);
- if (fd < 0) {
- perror("opening file");
- exit(1);
- }
-
- rc = fstat(fd, &st);
- if (st.st_size > MAX_DNLOAD_SIZE) {
- fprintf(stderr, "The maximum file size is 64kBytes (%u bytes)\n",
- MAX_DNLOAD_SIZE);
- return -EFBIG;
- }
-
- free(dnload.data);
- dnload.data = NULL;
-
- if (dnload.mode == MODE_C140 || dnload.mode == MODE_C140xor) {
- if (st.st_size < (MAGIC_OFFSET + sizeof(phone_magic)))
- payload_size = MAGIC_OFFSET + sizeof(phone_magic);
- else {
- printf("\nThe filesize is larger than 15kb, code on "
- "the magic address will be overwritten!\nUse "
- "loader.bin and upload the application with "
- "osmoload instead!\n\n");
- payload_size = st.st_size;
- }
- } else
- payload_size = st.st_size;
-
- dnload.data = malloc(MAX_HDR_SIZE + payload_size);
-
- if (!dnload.data) {
- close(fd);
- fprintf(stderr, "No memory\n");
- return -ENOMEM;
- }
-
- /* copy in the header, if any */
- switch (dnload.mode) {
- case MODE_C155:
- hdr = data_hdr_c155;
- hdr_len = sizeof(data_hdr_c155);
- break;
- case MODE_C140:
- case MODE_C140xor:
- case MODE_C123:
- case MODE_C123xor:
- hdr = data_hdr_c123;
- hdr_len = sizeof(data_hdr_c123);
- break;
- case MODE_ROMLOAD:
- break;
- default:
- break;
- }
-
- if (hdr && hdr_len)
- memcpy(dnload.data, hdr, hdr_len);
-
- /* 2 bytes for length + header */
- file_data = dnload.data + 2 + hdr_len;
-
- /* write the length, keep running XOR */
- tot_len = hdr_len + payload_size;
- nibble = tot_len >> 8;
- dnload.data[0] = nibble;
- running_xor ^= nibble;
- nibble = tot_len & 0xff;
- dnload.data[1] = nibble;
- running_xor ^= nibble;
-
- if (hdr_len && hdr) {
- memcpy(dnload.data+2, hdr, hdr_len);
-
- for (i = 0; i < hdr_len; i++)
- running_xor ^= hdr[i];
- }
-
- rc = read(fd, file_data, st.st_size);
- if (rc < 0) {
- perror("error reading file\n");
- free(dnload.data);
- dnload.data = NULL;
- close(fd);
- return -EIO;
- }
- if (rc < st.st_size) {
- free(dnload.data);
- dnload.data = NULL;
- close(fd);
- fprintf(stderr, "Short read of file (%d < %d)\n",
- rc, (int)st.st_size);
- return -EIO;
- }
-
- close(fd);
-
- dnload.data_len = (file_data+payload_size) - dnload.data;
-
- /* fill memory between data end and magic, add magic */
- if(dnload.mode == MODE_C140 || dnload.mode == MODE_C140xor) {
- if (st.st_size < MAGIC_OFFSET)
- memset(file_data + st.st_size, 0x00,
- payload_size - st.st_size);
- memcpy(dnload.data + MAGIC_OFFSET, phone_magic,
- sizeof(phone_magic));
- }
-
- /* calculate XOR sum */
- for (i = 0; i < payload_size; i++)
- running_xor ^= file_data[i];
-
- dnload.data[dnload.data_len++] = running_xor;
-
- /* initialize write pointer to start of data */
- dnload.write_ptr = dnload.data;
-
- printf("read_file(%s): file_size=%u, hdr_len=%u, dnload_len=%u\n",
- filename, (int)st.st_size, hdr_len, dnload.data_len);
-
- return 0;
-}
-
-static void osmocon_osmo_hexdump(const uint8_t *data, unsigned int len)
-{
- int n;
-
- for (n=0; n < len; n++)
- printf("%02x ", data[n]);
- printf(" ");
- for (n=0; n < len; n++)
- if (isprint(data[n]))
- putchar(data[n]);
- else
- putchar('.');
- printf("\n");
-}
-
-static int romload_prepare_block(void)
-{
- int i;
-
- int block_checksum = 5;
- int remaining_bytes;
- int fill_bytes;
- uint8_t *block_data;
- uint32_t block_address;
-
- dnload.block_len = ROMLOAD_BLOCK_HDR_LEN + dnload.block_payload_size;
-
- /* if first block, allocate memory */
- if (!dnload.block_number) {
- dnload.block = malloc(dnload.block_len);
- if (!dnload.block) {
- fprintf(stderr, "No memory\n");
- return -ENOMEM;
- }
- dnload.romload_dl_checksum = 0;
- /* initialize write pointer to start of data */
- dnload.write_ptr = dnload.data;
- }
-
- block_address = ROMLOAD_ADDRESS +
- (dnload.block_number * dnload.block_payload_size);
-
- /* prepare our block header (10 bytes) */
- memcpy(dnload.block, romload_write_cmd, sizeof(romload_write_cmd));
- dnload.block[2] = 0x01; /* block index */
- /* should normally be the block number, but hangs when sending !0x01 */
- dnload.block[3] = 0x01; /* dnload.block_number+1 */
- dnload.block[4] = (dnload.block_payload_size >> 8) & 0xff;
- dnload.block[5] = dnload.block_payload_size & 0xff;
- dnload.block[6] = (block_address >> 24) & 0xff;
- dnload.block[7] = (block_address >> 16) & 0xff;
- dnload.block[8] = (block_address >> 8) & 0xff;
- dnload.block[9] = block_address & 0xff;
-
- block_data = dnload.block + ROMLOAD_BLOCK_HDR_LEN;
- dnload.write_ptr = dnload.data + 2 +
- (dnload.block_payload_size * dnload.block_number);
-
- remaining_bytes = dnload.data_len - 3 -
- (dnload.block_payload_size * dnload.block_number);
-
- memcpy(block_data, dnload.write_ptr, dnload.block_payload_size);
-
- if (remaining_bytes <= dnload.block_payload_size) {
- fill_bytes = (dnload.block_payload_size - remaining_bytes);
- printf("Preparing the last block, filling %i bytes,",
- fill_bytes);
- memset(block_data + remaining_bytes, 0x00, fill_bytes);
- dnload.romload_state = SENDING_LAST_BLOCK;
- } else {
- dnload.romload_state = SENDING_BLOCKS;
- printf("Preparing block %i,", dnload.block_number+1);
- }
-
- /* block checksum is lsb of ~(5 + block_size_lsb + all bytes of
- * block_address + all data bytes) */
- for (i = 5; i < ROMLOAD_BLOCK_HDR_LEN + dnload.block_payload_size; i++)
- block_checksum += dnload.block[i];
-
- /* checksum is lsb of ~(sum of LSBs of all block checksums) */
- printf(" block checksum is 0x%02x \n", ~(block_checksum) & 0xff);
- dnload.romload_dl_checksum += ~(block_checksum) & 0xff;
-
- /* initialize block pointer to start of block */
- dnload.block_ptr = dnload.block;
-
- dnload.block_number++;
- dnload.serial_fd.when = BSC_FD_READ | BSC_FD_WRITE;
- return 0;
-}
-
-static int mtk_prepare_block(void)
-{
- int rc, i;
-
- int remaining_bytes;
- int fill_bytes;
- uint8_t *block_data;
- uint8_t tmp_byteswap;
- uint32_t tmp_size;
-
- dnload.block_len = MTK_BLOCK_SIZE;
- dnload.echo_bytecount = 0;
-
- /* if first block, allocate memory */
- if (!dnload.block_number) {
- dnload.block = malloc(dnload.block_len);
- if (!dnload.block) {
- fprintf(stderr, "No memory\n");
- return -ENOMEM;
- }
-
- /* calculate the number of blocks we need to send */
- dnload.block_count = (dnload.data_len-3) / MTK_BLOCK_SIZE;
- /* add one more block if no multiple of blocksize */
- if((dnload.data_len-3) % MTK_BLOCK_SIZE)
- dnload.block_count++;
-
- /* divide by 2, since we have to tell the mtk loader the size
- * as count of uint16 (odd transfer sizes are not possible) */
- tmp_size = (dnload.block_count * MTK_BLOCK_SIZE)/2;
- dnload.mtk_send_size[0] = (tmp_size >> 24) & 0xff;
- dnload.mtk_send_size[1] = (tmp_size >> 16) & 0xff;
- dnload.mtk_send_size[2] = (tmp_size >> 8) & 0xff;
- dnload.mtk_send_size[3] = tmp_size & 0xff;
-
- /* initialize write pointer to start of data */
- dnload.write_ptr = dnload.data;
- }
-
- block_data = dnload.block;
- dnload.write_ptr = dnload.data + 2 +
- (dnload.block_len * dnload.block_number);
-
- remaining_bytes = dnload.data_len - 3 -
- (dnload.block_len * dnload.block_number);
-
- memcpy(block_data, dnload.write_ptr, MTK_BLOCK_SIZE);
-
- if (remaining_bytes <= MTK_BLOCK_SIZE) {
- fill_bytes = (MTK_BLOCK_SIZE - remaining_bytes);
- printf("Preparing the last block, filling %i bytes\n",
- fill_bytes);
- memset(block_data + remaining_bytes, 0x00, fill_bytes);
- dnload.romload_state = SENDING_LAST_BLOCK;
- } else {
- dnload.romload_state = SENDING_BLOCKS;
- printf("Preparing block %i\n", dnload.block_number+1);
- }
-
- /* for the mtk romloader we need to swap MSB <-> LSB */
- for (i = 0; i < dnload.block_len; i += 2) {
- tmp_byteswap = dnload.block[i];
- dnload.block[i] = dnload.block[i+1];
- dnload.block[i+1] = tmp_byteswap;
- }
-
- /* initialize block pointer to start of block */
- dnload.block_ptr = dnload.block;
-
- dnload.block_number++;
- return rc;
-}
-
-static int handle_write_block(void)
-{
- int bytes_left, write_len, rc;
-
- printf("handle_write_block(): ");
-
- if (dnload.block_ptr >= dnload.block + dnload.block_len) {
- printf("Block %i finished\n", dnload.block_number);
- dnload.write_ptr = dnload.data;
- dnload.serial_fd.when &= ~BSC_FD_WRITE;
- if (dnload.romload_state == SENDING_LAST_BLOCK) {
- dnload.romload_state = LAST_BLOCK_SENT;
- printf("Finished, sent %i blocks in total\n",
- dnload.block_number);
- } else {
- dnload.romload_state = WAITING_BLOCK_ACK;
- }
-
- return 0;
- }
-
- /* try to write a maximum of block_len bytes */
- bytes_left = (dnload.block + dnload.block_len) - dnload.block_ptr;
- write_len = dnload.block_len;
- if (bytes_left < dnload.block_len)
- write_len = bytes_left;
-
- rc = write(dnload.serial_fd.fd, dnload.block_ptr, write_len);
- if (rc < 0) {
- perror("Error during write");
- return rc;
- }
-
- dnload.block_ptr += rc;
-
- printf("%u bytes (%tu/%u)\n", rc, dnload.block_ptr - dnload.block,
- dnload.block_len);
-
- return 0;
-}
-
-#define WRITE_BLOCK 4096
-
-static int handle_write_dnload(void)
-{
- int bytes_left, write_len, rc;
- uint8_t xor_init = 0x02;
-
- printf("handle_write(): ");
- if (dnload.write_ptr == dnload.data) {
- /* no bytes have been transferred yet */
- switch (dnload.mode) {
- case MODE_C155:
- case MODE_C140xor:
- case MODE_C123xor:
- rc = write(dnload.serial_fd.fd, &xor_init, 1);
- break;
- default:
- break;
- }
- } else if (dnload.write_ptr >= dnload.data + dnload.data_len) {
- printf("finished\n");
- dnload.write_ptr = dnload.data;
- dnload.serial_fd.when &= ~BSC_FD_WRITE;
- return 1;
- }
-
- /* try to write a maximum of WRITE_BLOCK bytes */
- bytes_left = (dnload.data + dnload.data_len) - dnload.write_ptr;
- write_len = WRITE_BLOCK;
- if (bytes_left < WRITE_BLOCK)
- write_len = bytes_left;
-
- rc = write(dnload.serial_fd.fd, dnload.write_ptr, write_len);
- if (rc < 0) {
- perror("Error during write");
- return rc;
- }
-
- dnload.write_ptr += rc;
-
- printf("%u bytes (%tu/%u)\n", rc, dnload.write_ptr - dnload.data,
- dnload.data_len);
-
- return 0;
-}
-
-static int handle_sercomm_write(void)
-{
- uint8_t c;
-
- if (sercomm_drv_pull(&c) != 0) {
- if (write(dnload.serial_fd.fd, &c, 1) != 1)
- perror("short write");
- } else
- dnload.serial_fd.when &= ~BSC_FD_WRITE;
-
- return 0;
-}
-
-static int handle_write(void)
-{
- /* TODO: simplify this again (global state: downloading, sercomm) */
- switch (dnload.mode) {
- case MODE_ROMLOAD:
- switch (dnload.romload_state) {
- case SENDING_BLOCKS:
- case SENDING_LAST_BLOCK:
- return handle_write_block();
- default:
- return handle_sercomm_write();
- }
- break;
- case MODE_MTK:
- switch (dnload.mtk_state) {
- case MTK_SENDING_BLOCKS:
- return handle_write_block();
- default:
- return handle_sercomm_write();
- }
- break;
- default:
- switch (dnload.state) {
- case DOWNLOADING:
- return handle_write_dnload();
- default:
- return handle_sercomm_write();
- }
- }
-
- return 0;
-}
-
-static uint8_t buffer[sizeof(phone_prompt1)];
-static uint8_t *bufptr = buffer;
-
-static void hdlc_send_to_phone(uint8_t dlci, uint8_t *data, int len)
-{
- struct msgb *msg;
- uint8_t *dest;
-
- if(dnload.dump_tx) {
- printf("hdlc_send(dlci=%u): ", dlci);
- osmocon_osmo_hexdump(data, len);
- }
-
- if (len > 512) {
- fprintf(stderr, "Too much data to send. %u\n", len);
- return;
- }
-
- /* push the message into the stack */
- msg = sercomm_alloc_msgb(512);
- if (!msg) {
- fprintf(stderr, "Failed to create data for the frame.\n");
- return;
- }
-
- /* copy the data */
- dest = msgb_put(msg, len);
- memcpy(dest, data, len);
-
- sercomm_sendmsg(dlci, msg);
-
- dnload.serial_fd.when |= BSC_FD_WRITE;
-}
-
-static void hdlc_console_cb(uint8_t dlci, struct msgb *msg)
-{
- write(1, msg->data, msg->len);
- msgb_free(msg);
-}
-
-static void hdlc_tool_cb(uint8_t dlci, struct msgb *msg)
-{
- struct tool_server *srv = tool_server_for_dlci[dlci];
-
- if(dnload.dump_rx) {
- printf("hdlc_recv(dlci=%u): ", dlci);
- osmocon_osmo_hexdump(msg->data, msg->len);
- }
-
- if(srv) {
- struct tool_connection *con;
- uint16_t *len;
-
- len = (uint16_t *) msgb_push(msg, 2);
- *len = htons(msg->len - sizeof(*len));
-
- llist_for_each_entry(con, &srv->connections, entry) {
- if (write(con->fd.fd, msg->data, msg->len) != msg->len) {
- fprintf(stderr,
- "Failed to write msg to the socket..\n");
- continue;
- }
- }
- }
-
- msgb_free(msg);
-}
-
-static int handle_buffer(int buf_used_len)
-{
- int nbytes, buf_left, i;
-
- buf_left = buf_used_len - (bufptr - buffer);
- if (buf_left <= 0) {
- memmove(buffer, buffer+1, buf_used_len-1);
- bufptr -= 1;
- buf_left = 1;
- }
-
- nbytes = read(dnload.serial_fd.fd, bufptr, buf_left);
- if (nbytes <= 0)
- return nbytes;
-
- if (!dnload.expect_hdlc) {
- printf("got %i bytes from modem, ", nbytes);
- printf("data looks like: ");
- osmocon_osmo_hexdump(bufptr, nbytes);
- } else {
- for (i = 0; i < nbytes; ++i)
- if (sercomm_drv_rx_char(bufptr[i]) == 0)
- printf("Dropping sample '%c'\n", bufptr[i]);
- }
-
- return nbytes;
-}
-
-/* Compal ramloader */
-static int handle_read(void)
-{
- int rc, nbytes;
-
- nbytes = handle_buffer(sizeof(buffer));
- if (nbytes <= 0)
- return nbytes;
-
- if (!memcmp(buffer, phone_prompt1, sizeof(phone_prompt1))) {
- printf("Received PROMPT1 from phone, responding with CMD\n");
- dnload.expect_hdlc = 0;
- dnload.state = WAITING_PROMPT2;
- if(dnload.filename) {
- rc = write(dnload.serial_fd.fd, dnload_cmd, sizeof(dnload_cmd));
-
- /* re-read file */
- rc = read_file(dnload.filename);
- if (rc < 0) {
- fprintf(stderr, "read_file(%s) failed with %d\n",
- dnload.filename, rc);
- exit(1);
- }
- }
- } else if (!memcmp(buffer, phone_prompt2, sizeof(phone_prompt2))) {
- printf("Received PROMPT2 from phone, starting download\n");
- dnload.serial_fd.when = BSC_FD_READ | BSC_FD_WRITE;
- dnload.state = DOWNLOADING;
- } else if (!memcmp(buffer, phone_ack, sizeof(phone_ack))) {
- printf("Received DOWNLOAD ACK from phone, your code is"
- " running now!\n");
- dnload.serial_fd.when = BSC_FD_READ;
- dnload.state = WAITING_PROMPT1;
- dnload.write_ptr = dnload.data;
- dnload.expect_hdlc = 1;
-
- /* check for romloader chainloading mode used as a workaround
- * for the magic on the C139/C140 and J100i */
- if (dnload.chainload_filename != NULL) {
- printf("Enabled Compal ramloader -> Calypso romloader"
- " chainloading mode\n");
- bufptr = buffer;
- dnload.filename = dnload.chainload_filename;
- dnload.mode = MODE_ROMLOAD;
- serial_set_baudrate(ROMLOAD_INIT_BAUDRATE);
- tick_timer.cb = &beacon_timer_cb;
- tick_timer.data = &tick_timer;
- osmo_timer_schedule(&tick_timer, 0, dnload.beacon_interval);
- }
- } else if (!memcmp(buffer, phone_nack, sizeof(phone_nack))) {
- printf("Received DOWNLOAD NACK from phone, something went"
- " wrong :(\n");
- dnload.serial_fd.when = BSC_FD_READ;
- dnload.state = WAITING_PROMPT1;
- dnload.write_ptr = dnload.data;
- } else if (!memcmp(buffer, phone_nack_magic, sizeof(phone_nack_magic))) {
- printf("Received MAGIC NACK from phone, you need to"
- " have \"1003\" at 0x803ce0\n");
- dnload.serial_fd.when = BSC_FD_READ;
- dnload.state = WAITING_PROMPT1;
- dnload.write_ptr = dnload.data;
- } else if (!memcmp(buffer, ftmtool, sizeof(ftmtool))) {
- printf("Received FTMTOOL from phone, ramloader has aborted\n");
- dnload.serial_fd.when = BSC_FD_READ;
- dnload.state = WAITING_PROMPT1;
- dnload.write_ptr = dnload.data;
- }
- bufptr += nbytes;
-
- return nbytes;
-}
-
-/* "Calypso non-secure romloader" */
-static int handle_read_romload(void)
-{
- int rc, nbytes, buf_used_len;
-
- /* virtually limit buffer length for romloader, since responses
- * are shorter and vary in length */
-
- switch (dnload.romload_state) {
- case WAITING_PARAM_ACK:
- buf_used_len = 4; /* ">p" + uint16_t len */
- break;
- case WAITING_CHECKSUM_ACK:
- buf_used_len = 3; /* ">c" + uint8_t checksum */
- break;
- case FINISHED:
- buf_used_len = sizeof(buffer);
- break;
- default:
- buf_used_len = 2; /* ">*" */
- }
-
- nbytes = handle_buffer(buf_used_len);
- if (nbytes <= 0)
- return nbytes;
-
- switch (dnload.romload_state) {
- case WAITING_IDENTIFICATION:
- if (memcmp(buffer, romload_ident_ack,
- sizeof(romload_ident_ack)))
- break;
-
- printf("Received ident ack from phone, sending "
- "parameter sequence\n");
- dnload.expect_hdlc = 1;
- dnload.romload_state = WAITING_PARAM_ACK;
- rc = write(dnload.serial_fd.fd, romload_param,
- sizeof(romload_param));
- /* re-read file */
- rc = read_file(dnload.filename);
- if (rc < 0) {
- fprintf(stderr, "read_file(%s) failed with %d\n",
- dnload.filename, rc);
- exit(1);
- }
- break;
- case WAITING_PARAM_ACK:
- if (memcmp(buffer, romload_param_ack,
- sizeof(romload_param_ack)))
- break;
-
- printf("Received parameter ack from phone, "
- "starting download\n");
- serial_set_baudrate(ROMLOAD_DL_BAUDRATE);
-
- /* using the max blocksize the phone tells us */
- dnload.block_payload_size = ((buffer[3] << 8) + buffer[2]);
- printf("Used blocksize for download is %i bytes\n",
- dnload.block_payload_size);
- dnload.block_payload_size -= ROMLOAD_BLOCK_HDR_LEN;
- dnload.romload_state = SENDING_BLOCKS;
- dnload.block_number = 0;
- romload_prepare_block();
- bufptr -= 2;
- break;
- case WAITING_BLOCK_ACK:
- case LAST_BLOCK_SENT:
- if (!memcmp(buffer, romload_block_ack,
- sizeof(romload_block_ack))) {
- printf("Received block ack from phone\n");
- if (dnload.romload_state == LAST_BLOCK_SENT) {
- /* send the checksum */
- uint8_t final_checksum =
- (~(dnload.romload_dl_checksum) & 0xff);
- printf("Sending checksum: 0x%02x \n",
- final_checksum);
- rc = write(dnload.serial_fd.fd,
- romload_checksum_cmd,
- sizeof(romload_checksum_cmd));
- rc = write(dnload.serial_fd.fd,
- &final_checksum, 1);
- dnload.romload_state = WAITING_CHECKSUM_ACK;
- } else
- romload_prepare_block();
- } else if (!memcmp(buffer, romload_block_nack,
- sizeof(romload_block_nack))) {
- printf("Received block nack from phone, "
- "something went wrong, aborting\n");
- serial_set_baudrate(ROMLOAD_INIT_BAUDRATE);
- dnload.romload_state = WAITING_IDENTIFICATION;
- osmo_timer_schedule(&tick_timer, 0, dnload.beacon_interval);
- }
- break;
- case WAITING_CHECKSUM_ACK:
- if (!memcmp(buffer, romload_checksum_ack,
- sizeof(romload_checksum_ack))) {
- printf("Checksum on phone side matches, "
- "let's branch to your code\n");
- printf("Branching to 0x%08x\n", ROMLOAD_ADDRESS);
-
- rc = write(dnload.serial_fd.fd, romload_branch_cmd,
- sizeof(romload_branch_cmd));
- rc = write(dnload.serial_fd.fd, &dnload.load_address,
- sizeof(dnload.load_address));
- dnload.romload_state = WAITING_BRANCH_ACK;
- bufptr -= 1;
- } else if (!memcmp(buffer, romload_checksum_nack,
- sizeof(romload_checksum_nack))) {
- printf("Checksum on phone side (0x%02x) doesn't "
- "match ours, aborting\n", ~buffer[2]);
- serial_set_baudrate(ROMLOAD_INIT_BAUDRATE);
- dnload.romload_state = WAITING_IDENTIFICATION;
- osmo_timer_schedule(&tick_timer, 0, dnload.beacon_interval);
- bufptr -= 1;
- }
- break;
- case WAITING_BRANCH_ACK:
- if (!memcmp(buffer, romload_branch_ack,
- sizeof(romload_branch_ack))) {
- printf("Received branch ack, your code is running now!\n");
- dnload.serial_fd.when = BSC_FD_READ;
- dnload.romload_state = FINISHED;
- dnload.write_ptr = dnload.data;
- dnload.expect_hdlc = 1;
- } else if (!memcmp(buffer, romload_branch_nack,
- sizeof(romload_branch_nack))) {
- printf("Received branch nack, aborting\n");
- serial_set_baudrate(ROMLOAD_INIT_BAUDRATE);
- dnload.romload_state = WAITING_IDENTIFICATION;
- osmo_timer_schedule(&tick_timer, 0, dnload.beacon_interval);
- }
- break;
- default:
- break;
- }
-
- bufptr += nbytes;
- return nbytes;
-}
-
-/* MTK romloader */
-static int handle_read_mtk(void)
-{
- int rc, nbytes, buf_used_len;
-
- switch (dnload.mtk_state) {
- case MTK_WAIT_ADDR_ACK:
- case MTK_WAIT_SIZE_ACK:
- case MTK_WAIT_BRANCH_ADDR_ACK:
- buf_used_len = 4;
- break;
- case MTK_FINISHED:
- buf_used_len = sizeof(buffer);
- break;
- default:
- buf_used_len = 1;
- }
-
- nbytes = handle_buffer(buf_used_len);
- if (nbytes <= 0)
- return nbytes;
-
- switch (dnload.mtk_state) {
- case MTK_INIT_1:
- if (!(buffer[0] == mtk_init_resp[0]))
- break;
- dnload.mtk_state = MTK_INIT_2;
- printf("Received init magic byte 1\n");
- rc = write(dnload.serial_fd.fd, &mtk_init_cmd[1], 1);
- break;
- case MTK_INIT_2:
- if (!(buffer[0] == mtk_init_resp[1]))
- break;
- dnload.mtk_state = MTK_INIT_3;
- printf("Received init magic byte 2\n");
- rc = write(dnload.serial_fd.fd, &mtk_init_cmd[2], 1);
- break;
- case MTK_INIT_3:
- if (!(buffer[0] == mtk_init_resp[2]))
- break;
- dnload.mtk_state = MTK_INIT_4;
- printf("Received init magic byte 3\n");
- rc = write(dnload.serial_fd.fd, &mtk_init_cmd[3], 1);
- break;
- case MTK_INIT_4:
- if (!(buffer[0] == mtk_init_resp[3]))
- break;
- dnload.mtk_state = MTK_WAIT_WRITE_ACK;
- printf("Received init magic byte 4, requesting write\n");
- rc = write(dnload.serial_fd.fd, &mtk_command[0], 1);
- break;
- case MTK_WAIT_WRITE_ACK:
- if (!(buffer[0] == mtk_command[0]))
- break;
- dnload.mtk_state = MTK_WAIT_ADDR_ACK;
- printf("Received write ack, sending load address\n");
-
- rc = write(dnload.serial_fd.fd, &dnload.load_address,
- sizeof(dnload.load_address));
- break;
- case MTK_WAIT_ADDR_ACK:
- if (memcmp(buffer, dnload.load_address,
- sizeof(dnload.load_address)))
- break;
- printf("Received address ack from phone, sending loadsize\n");
- /* re-read file */
- rc = read_file(dnload.filename);
- if (rc < 0) {
- fprintf(stderr, "read_file(%s) failed with %d\n",
- dnload.filename, rc);
- exit(1);
- }
- dnload.block_number = 0;
- mtk_prepare_block();
- dnload.mtk_state = MTK_WAIT_SIZE_ACK;
- rc = write(dnload.serial_fd.fd, &dnload.mtk_send_size,
- sizeof(dnload.mtk_send_size));
- break;
- case MTK_WAIT_SIZE_ACK:
- if (memcmp(buffer, dnload.mtk_send_size,
- sizeof(dnload.mtk_send_size)))
- break;
- printf("Received size ack\n");
- dnload.expect_hdlc = 1;
- dnload.mtk_state = MTK_SENDING_BLOCKS;
- dnload.serial_fd.when = BSC_FD_READ | BSC_FD_WRITE;
- bufptr -= 3;
- break;
- case MTK_SENDING_BLOCKS:
- if (!(buffer[0] == dnload.block[dnload.echo_bytecount]))
- printf("Warning: Byte %i of Block %i doesn't match,"
- " check your serial connection!\n",
- dnload.echo_bytecount, dnload.block_number);
- dnload.echo_bytecount++;
-
- if ((dnload.echo_bytecount+1) > MTK_BLOCK_SIZE) {
- if ( dnload.block_number == dnload.block_count) {
- rc = write(dnload.serial_fd.fd,
- &mtk_command[3], 1);
- printf("Sending branch command\n");
- dnload.expect_hdlc = 0;
- dnload.mtk_state = MTK_WAIT_BRANCH_CMD_ACK;
- break;
- }
- printf("Received Block %i preparing next block\n",
- dnload.block_number);
- mtk_prepare_block();
- dnload.serial_fd.when = BSC_FD_READ | BSC_FD_WRITE;
- }
- break;
- case MTK_WAIT_BRANCH_CMD_ACK:
- if (!(buffer[0] == mtk_command[3]))
- break;
- dnload.mtk_state = MTK_WAIT_BRANCH_ADDR_ACK;
- printf("Received branch command ack, sending address\n");
-
- rc = write(dnload.serial_fd.fd, &dnload.load_address,
- sizeof(dnload.load_address));
- break;
- case MTK_WAIT_BRANCH_ADDR_ACK:
- if (memcmp(buffer, dnload.load_address,
- sizeof(dnload.load_address)))
- break;
- printf("Received branch address ack, code should run now\n");
- serial_set_baudrate(MODEM_BAUDRATE);
- dnload.serial_fd.when = BSC_FD_READ;
- dnload.mtk_state = MTK_FINISHED;
- dnload.write_ptr = dnload.data;
- dnload.expect_hdlc = 1;
- break;
- default:
- break;
- }
-
- bufptr += nbytes;
- return nbytes;
-}
-
-static int serial_read(struct osmo_fd *fd, unsigned int flags)
-{
- int rc;
- if (flags & BSC_FD_READ) {
- switch (dnload.mode) {
- case MODE_ROMLOAD:
- rc = handle_read_romload();
- break;
- case MODE_MTK:
- rc = handle_read_mtk();
- break;
- default:
- rc = handle_read();
- break;
- }
- if (rc == 0)
- exit(2);
- }
-
- if (flags & BSC_FD_WRITE) {
- rc = handle_write();
- if (rc == 1)
- dnload.state = WAITING_PROMPT1;
- }
- return 0;
-}
-
-static int parse_mode(const char *arg)
-{
- if (!strcasecmp(arg, "c123"))
- return MODE_C123;
- else if (!strcasecmp(arg, "c123xor"))
- return MODE_C123xor;
- else if (!strcasecmp(arg, "c140"))
- return MODE_C140;
- else if (!strcasecmp(arg, "c140xor"))
- return MODE_C140xor;
- else if (!strcasecmp(arg, "c155"))
- return MODE_C155;
- else if (!strcasecmp(arg, "romload"))
- return MODE_ROMLOAD;
- else if (!strcasecmp(arg, "mtk"))
- return MODE_MTK;
-
- return -1;
-}
-
-#define HELP_TEXT \
- "[ -v | -h ] [ -d [t][r] ] [ -p /dev/ttyXXXX ]\n" \
- "\t\t [ -s /tmp/osmocom_l2 ]\n" \
- "\t\t [ -l /tmp/osmocom_loader ]\n" \
- "\t\t [ -m {c123,c123xor,c140,c140xor,c155,romload,mtk} ]\n" \
- "\t\t [ -c /to-be-chainloaded-file.bin ]\n" \
- "\t\t [ -i beacon-interval (mS) ]\n" \
- "\t\t file.bin\n\n" \
- "* Open serial port /dev/ttyXXXX (connected to your phone)\n" \
- "* Perform handshaking with the ramloader in the phone\n" \
- "* Download file.bin to the attached phone (base address 0x00800100)\n"
-
-static int usage(const char *name)
-{
- printf("Usage: %s ", name);
- printf(HELP_TEXT);
- exit(2);
-}
-
-static int version(const char *name)
-{
- printf("%s version %s\n", name, PACKAGE_VERSION);
- exit(2);
-}
-
-static int un_tool_read(struct osmo_fd *fd, unsigned int flags)
-{
- int rc, c;
- uint16_t length = 0xffff;
- uint8_t buf[4096];
- struct tool_connection *con = (struct tool_connection *)fd->data;
-
- c = 0;
- while(c < 2) {
- rc = read(fd->fd, &buf + c, 2 - c);
- if(rc == 0) {
- // disconnect
- goto close;
- }
- if(rc < 0) {
- if(errno == EAGAIN) {
- continue;
- }
- fprintf(stderr, "Err from socket: %s\n", strerror(errno));
- goto close;
- }
- c += rc;
- }
-
- length = ntohs(*(uint16_t*)buf);
-
- c = 0;
- while(c < length) {
- rc = read(fd->fd, &buf + c, length - c);
- if(rc == 0) {
- // disconnect
- goto close;
- }
- if(rc < 0) {
- if(errno == EAGAIN) {
- continue;
- }
- fprintf(stderr, "Err from socket: %s\n", strerror(errno));
- goto close;
- }
- c += rc;
- }
-
- hdlc_send_to_phone(con->server->dlci, buf, length);
-
- return 0;
-close:
-
- close(fd->fd);
- osmo_fd_unregister(fd);
- llist_del(&con->entry);
- talloc_free(con);
- return -1;
-}
-
-/* accept a new connection */
-static int tool_accept(struct osmo_fd *fd, unsigned int flags)
-{
- struct tool_server *srv = (struct tool_server *)fd->data;
- struct tool_connection *con;
- struct sockaddr_un un_addr;
- socklen_t len;
- int rc;
-
- len = sizeof(un_addr);
- rc = accept(fd->fd, (struct sockaddr *) &un_addr, &len);
- if (rc < 0) {
- fprintf(stderr, "Failed to accept a new connection.\n");
- return -1;
- }
-
- con = talloc_zero(NULL, struct tool_connection);
- if (!con) {
- fprintf(stderr, "Failed to create tool connection.\n");
- return -1;
- }
-
- con->server = srv;
-
- con->fd.fd = rc;
- con->fd.when = BSC_FD_READ;
- con->fd.cb = un_tool_read;
- con->fd.data = con;
- if (osmo_fd_register(&con->fd) != 0) {
- fprintf(stderr, "Failed to register the fd.\n");
- return -1;
- }
-
- llist_add(&con->entry, &srv->connections);
- return 0;
-}
-
-/*
- * Register and start a tool server
- */
-static int register_tool_server(struct tool_server *ts,
- const char *path,
- uint8_t dlci)
-{
- struct osmo_fd *bfd = &ts->bfd;
- struct sockaddr_un local;
- unsigned int namelen;
- int rc;
-
- bfd->fd = socket(AF_UNIX, SOCK_STREAM, 0);
-
- if (bfd->fd < 0) {
- fprintf(stderr, "Failed to create Unix Domain Socket.\n");
- return -1;
- }
-
- local.sun_family = AF_UNIX;
- strncpy(local.sun_path, path, sizeof(local.sun_path));
- local.sun_path[sizeof(local.sun_path) - 1] = '\0';
- unlink(local.sun_path);
-
- /* we use the same magic that X11 uses in Xtranssock.c for
- * calculating the proper length of the sockaddr */
-#if defined(BSD44SOCKETS) || defined(__UNIXWARE__)
- local.sun_len = strlen(local.sun_path);
-#endif
-#if defined(BSD44SOCKETS) || defined(SUN_LEN)
- namelen = SUN_LEN(&local);
-#else
- namelen = strlen(local.sun_path) +
- offsetof(struct sockaddr_un, sun_path);
-#endif
-
- rc = bind(bfd->fd, (struct sockaddr *) &local, namelen);
- if (rc != 0) {
- fprintf(stderr, "Failed to bind the unix domain socket. '%s'\n",
- local.sun_path);
- return -1;
- }
-
- if (listen(bfd->fd, 0) != 0) {
- fprintf(stderr, "Failed to listen.\n");
- return -1;
- }
-
- bfd->when = BSC_FD_READ;
- bfd->cb = tool_accept;
- bfd->data = ts;
-
- ts->dlci = dlci;
- INIT_LLIST_HEAD(&ts->connections);
-
- tool_server_for_dlci[dlci] = ts;
-
- sercomm_register_rx_cb(dlci, hdlc_tool_cb);
-
- if (osmo_fd_register(bfd) != 0) {
- fprintf(stderr, "Failed to register the bfd.\n");
- return -1;
- }
-
- return 0;
-}
-
-extern void hdlc_tpudbg_cb(uint8_t dlci, struct msgb *msg);
-
-void parse_debug(const char *str)
-{
- while(*str) {
- switch(*str) {
- case 't':
- dnload.dump_tx = 1;
- break;
- case 'r':
- dnload.dump_rx = 1;
- break;
- default:
- printf("Unknown debug flag %c\n", *str);
- abort();
- break;
- }
- str++;
- }
-}
-
-int main(int argc, char **argv)
-{
- int opt, flags;
- uint32_t tmp_load_address = ROMLOAD_ADDRESS;
- const char *serial_dev = "/dev/ttyUSB1";
- const char *layer2_un_path = "/tmp/osmocom_l2";
- const char *loader_un_path = "/tmp/osmocom_loader";
-
- dnload.mode = MODE_C123;
- dnload.chainload_filename = NULL;
- dnload.beacon_interval = DEFAULT_BEACON_INTERVAL;
-
- while ((opt = getopt(argc, argv, "d:hl:p:m:c:s:i:v")) != -1) {
- switch (opt) {
- case 'p':
- serial_dev = optarg;
- break;
- case 'm':
- dnload.mode = parse_mode(optarg);
- if (dnload.mode < 0)
- usage(argv[0]);
- break;
- case 's':
- layer2_un_path = optarg;
- break;
- case 'l':
- loader_un_path = optarg;
- break;
- case 'v':
- version(argv[0]);
- break;
- case 'd':
- parse_debug(optarg);
- break;
- case 'c':
- dnload.chainload_filename = optarg;
- break;
- case 'i':
- dnload.beacon_interval = atoi(optarg) * 1000;
- break;
- case 'h':
- default:
- usage(argv[0]);
- break;
- }
- }
-
- if (argc <= optind) {
- dnload.filename = NULL;
- } else {
- dnload.filename = argv[optind];
- }
-
- dnload.serial_fd.fd = serial_init(serial_dev);
- if (dnload.serial_fd.fd < 0) {
- fprintf(stderr, "Cannot open serial device %s\n", serial_dev);
- exit(1);
- }
-
- if (osmo_fd_register(&dnload.serial_fd) != 0) {
- fprintf(stderr, "Failed to register the serial.\n");
- exit(1);
- }
-
- /* Set serial socket to non-blocking mode of operation */
- flags = fcntl(dnload.serial_fd.fd, F_GETFL);
- flags |= O_NONBLOCK;
- fcntl(dnload.serial_fd.fd, F_SETFL, flags);
-
- dnload.serial_fd.when = BSC_FD_READ;
- dnload.serial_fd.cb = serial_read;
-
- /* initialize the HDLC layer */
- sercomm_init();
- sercomm_register_rx_cb(SC_DLCI_CONSOLE, hdlc_console_cb);
- sercomm_register_rx_cb(SC_DLCI_DEBUG, hdlc_tpudbg_cb);
-
- /* unix domain socket handling */
- if (register_tool_server(&dnload.layer2_server, layer2_un_path,
- SC_DLCI_L1A_L23) != 0)
- exit(1);
-
- if (register_tool_server(&dnload.loader_server, loader_un_path,
- SC_DLCI_LOADER) != 0)
- exit(1);
-
- /* if in romload mode, start our beacon timer */
- if (dnload.mode == MODE_ROMLOAD) {
- tmp_load_address = ROMLOAD_ADDRESS;
- serial_set_baudrate(ROMLOAD_INIT_BAUDRATE);
- tick_timer.cb = &beacon_timer_cb;
- tick_timer.data = &tick_timer;
- osmo_timer_schedule(&tick_timer, 0, dnload.beacon_interval);
- }
- else if (dnload.mode == MODE_MTK) {
- tmp_load_address = MTK_ADDRESS;
- serial_set_baudrate(MTK_INIT_BAUDRATE);
- tick_timer.cb = &mtk_timer_cb;
- tick_timer.data = &tick_timer;
- osmo_timer_schedule(&tick_timer, 0, dnload.beacon_interval);
- }
-
- dnload.load_address[0] = (tmp_load_address >> 24) & 0xff;
- dnload.load_address[1] = (tmp_load_address >> 16) & 0xff;
- dnload.load_address[2] = (tmp_load_address >> 8) & 0xff;
- dnload.load_address[3] = tmp_load_address & 0xff;
-
- while (1) {
- if (osmo_select_main(0) < 0)
- break;
- }
-
- close(dnload.serial_fd.fd);
-
- exit(0);
-}
diff --git a/Src/osmoconbb/src/host/osmocon/osmoload.c b/Src/osmoconbb/src/host/osmocon/osmoload.c
deleted file mode 100644
index 8a0b21c..0000000
--- a/Src/osmoconbb/src/host/osmocon/osmoload.c
+++ /dev/null
@@ -1,1216 +0,0 @@
-/* control utility for the Calypso bootloader */
-
-/* (C) 2010 by Ingo Albrecht <prom@berlin.ccc.de>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <errno.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <getopt.h>
-
-#include <arpa/inet.h>
-
-#include <sys/stat.h>
-
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/select.h>
-#include <osmocom/core/timer.h>
-#include <osmocom/core/crc16.h>
-
-#include <loader/protocol.h>
-
-#define MSGB_MAX 256
-
-#define MEM_MSG_MAX (MSGB_MAX - 16)
-
-#define DEFAULT_SOCKET "/tmp/osmocom_loader"
-
-static struct osmo_fd connection;
-
-enum {
- STATE_INIT,
- STATE_QUERY_PENDING,
- STATE_DUMP_IN_PROGRESS,
- STATE_LOAD_IN_PROGRESS,
- STATE_FLASHRANGE_GET_INFO,
- STATE_FLASHRANGE_IN_PROGRESS,
- STATE_PROGRAM_GET_INFO,
- STATE_PROGRAM_IN_PROGRESS,
- STATE_DUMPING,
-};
-
-struct flashblock {
- uint8_t fb_chip;
- uint32_t fb_offset;
- uint32_t fb_addr;
- uint32_t fb_size;
-};
-
-static struct {
- /* debug flags */
- unsigned char print_requests;
- unsigned char print_replies;
-
- /* quit flag for main loop */
- unsigned char quit;
-
- /* main state machine */
- int state;
-
- /* pending query command */
- uint8_t command;
-
- /* general timeout */
- struct osmo_timer_list timeout;
-
- /* binary i/o for firmware images */
- FILE *binfile;
- /* buffer containing binfile data */
- char *binbuf;
-
- /* memory operation state */
- uint8_t memchip; /* target chip (for flashes) */
- uint32_t membase; /* target base address of operation */
- uint32_t memlen; /* length of entire operation */
- uint32_t memoff; /* offset for next request */
- uint16_t memcrc; /* crc for current request */
- uint16_t memreq; /* length of current request */
-
- /* array of all flash blocks */
- uint8_t flashcommand;
- uint32_t numblocks;
- struct flashblock blocks[512];
-} osmoload;
-
-static int usage(const char *name)
-{
- printf("Usage: %s [ -v | -h ] [ -d tr ] [ -m {c123,c155} ] [ -l /tmp/osmocom_loader ] COMMAND ...\n", name);
-
- puts("\n Memory commands:");
- puts(" memget <hex-address> <hex-length> - Peek at memory");
- puts(" memput <hex-address> <hex-bytes> - Poke at memory");
- puts(" memdump <hex-address> <hex-length> <file>- Dump memory to file");
- puts(" memload <hex-address> <file> - Load file into memory");
-
- puts("\n Flash commands:");
- puts(" finfo - Information about flash chips");
- puts(" funlock <address> <length> - Unlock flash block");
- puts(" flock <address> <length> - Lock flash block");
- puts(" flockdown <address> <length> - Lock down flash block");
- puts(" fgetlock <address> <length> - Get locking state of block");
- puts(" ferase <address> <length> - Erase flash range");
- puts(" fprogram <chip> <address> <file> - Program file into flash");
-
- puts("\n Execution commands:");
- puts(" jump <hex-address> - Jump to address");
- puts(" jumpflash - Jump to flash loader");
- puts(" jumprom - Jump to rom loader");
-
- puts("\n Device lifecycle:");
- puts(" ping - Ping the loader");
- puts(" reset - Reset device");
- puts(" off - Power off device");
-
- puts("\n Debug:");
- puts(" dump - Dump loader traffic to console");
-
- exit(2);
-}
-
-static int version(const char *name)
-{
- //printf("\n%s version %s\n", name, VERSION);
- exit(2);
-}
-
-static void osmoload_osmo_hexdump(const uint8_t *data, unsigned int len)
-{
- const uint8_t *bufptr = data;
- const uint8_t const *endptr = bufptr + len;
- int n, m, i, hexchr;
-
- for (n=0; n < len; n+=32, bufptr += 32) {
- hexchr = 0;
- for(m = 0; m < 32 && bufptr < endptr; m++, bufptr++) {
- if((m) && !(m%4)) {
- putchar(' ');
- hexchr++;
- }
- printf("%02x", *bufptr);
- hexchr+=2;
- }
- bufptr -= m;
- int n = 71 - hexchr;
- for(i = 0; i < n; i++) {
- putchar(' ');
- }
-
- putchar(' ');
-
- for(m = 0; m < 32 && bufptr < endptr; m++, bufptr++) {
- if(isgraph(*bufptr)) {
- putchar(*bufptr);
- } else {
- putchar('.');
- }
- }
- bufptr -= m;
-
- putchar('\n');
- }
-}
-
-static void
-loader_send_request(struct msgb *msg) {
- int rc;
- u_int16_t len = htons(msg->len);
-
- if(osmoload.print_requests) {
- printf("Sending %d bytes:\n", msg->len);
- osmoload_osmo_hexdump(msg->data, msg->len);
- }
-
- rc = write(connection.fd, &len, sizeof(len));
- if(rc != sizeof(len)) {
- fprintf(stderr, "Error writing.\n");
- exit(2);
- }
-
- rc = write(connection.fd, msg->data, msg->len);
- if(rc != msg->len) {
- fprintf(stderr, "Error writing.\n");
- exit(2);
- }
-}
-
-static void loader_do_memdump(uint16_t crc, void *address, size_t length);
-static void loader_do_memload();
-static void loader_do_fprogram();
-static void loader_do_flashrange(uint8_t cmd, struct msgb *msg, uint8_t chip, uint32_t address, uint32_t status);
-
-static void memop_timeout(void *dummy) {
- switch(osmoload.state) {
- case STATE_LOAD_IN_PROGRESS:
- printf("Timeout. Repeating.");
- osmoload.memoff -= osmoload.memreq;
- loader_do_memload();
- break;
- default:
- break;
- }
- return;
-}
-
-static void
-loader_parse_flash_info(struct msgb *msg) {
- uint8_t nchips;
-
- nchips = msgb_get_u8(msg);
-
- osmoload.numblocks = 0;
-
- int chip;
- for(chip = 0; chip < nchips; chip++) {
-
- uint32_t address;
- address = msgb_get_u32(msg);
-
- uint32_t chipsize;
- chipsize = msgb_get_u32(msg);
-
- uint8_t nregions;
- nregions = msgb_get_u8(msg);
-
- printf(" chip %d at 0x%8.8x of %d bytes in %d regions\n", chip, address, chipsize, nregions);
-
- uint32_t curoffset = 0;
- int region;
- for(region = 0; region < nregions; region++) {
- uint16_t blockcount = msgb_get_u32(msg);
- uint32_t blocksize = msgb_get_u32(msg);
-
- printf(" region %d with %d blocks of %d bytes each\n", region, blockcount, blocksize);
-
- int block;
- for(block = 0; block < blockcount; block++) {
- osmoload.blocks[osmoload.numblocks].fb_chip = chip;
- osmoload.blocks[osmoload.numblocks].fb_offset = curoffset;
- osmoload.blocks[osmoload.numblocks].fb_addr = address + curoffset;
- osmoload.blocks[osmoload.numblocks].fb_size = blocksize;
-
- printf(" block %d with %d bytes at 0x%8.8x on chip %d\n",
- osmoload.numblocks, blocksize, address + curoffset, chip);
-
- curoffset += blocksize;
-
- osmoload.numblocks++;
- }
- }
- }
-}
-
-
-static void
-loader_handle_reply(struct msgb *msg) {
- if(osmoload.print_replies) {
- printf("Received %d bytes:\n", msg->len);
- osmoload_osmo_hexdump(msg->data, msg->len);
- }
-
- uint8_t cmd = msgb_get_u8(msg);
-
- uint8_t chip;
- uint8_t length;
- uint16_t crc;
- uint32_t address;
- uint32_t entrypoint;
- uint32_t status;
-
- void *data;
-
- switch(cmd) {
- case LOADER_INIT:
- address = msgb_get_u32(msg);
- entrypoint = msgb_get_u32(msg);
- printf("Loader at entry %x has been started, requesting load to %x\n", entrypoint, address);
- break;
- case LOADER_PING:
- case LOADER_RESET:
- case LOADER_POWEROFF:
- case LOADER_ENTER_ROM_LOADER:
- case LOADER_ENTER_FLASH_LOADER:
- break;
- case LOADER_MEM_READ:
- length = msgb_get_u8(msg);
- crc = msgb_get_u16(msg);
- address = msgb_get_u32(msg);
- data = msgb_get(msg, length);
- break;
- case LOADER_MEM_WRITE:
- length = msgb_get_u8(msg);
- crc = msgb_get_u16(msg);
- address = msgb_get_u32(msg);
- break;
- case LOADER_JUMP:
- address = msgb_get_u32(msg);
- break;
- case LOADER_FLASH_INFO:
- break;
- case LOADER_FLASH_GETLOCK:
- case LOADER_FLASH_ERASE:
- case LOADER_FLASH_UNLOCK:
- case LOADER_FLASH_LOCK:
- case LOADER_FLASH_LOCKDOWN:
- chip = msgb_get_u8(msg);
- address = msgb_get_u32(msg);
- status = msgb_get_u32(msg);
- break;
- case LOADER_FLASH_PROGRAM:
- length = msgb_get_u8(msg);
- crc = msgb_get_u16(msg);
- msgb_get_u8(msg); // XXX align
- chip = msgb_get_u8(msg);
- address = msgb_get_u32(msg);
- status = msgb_get_u32(msg);
- break;
- default:
- printf("Received unknown reply %d:\n", cmd);
- osmoload_osmo_hexdump(msg->data, msg->len);
- osmoload.quit = 1;
- return;
- }
-
- switch(osmoload.state) {
- case STATE_QUERY_PENDING:
- case STATE_DUMPING:
- switch(cmd) {
- case LOADER_PING:
- printf("Received pong.\n");
- break;
- case LOADER_RESET:
- printf("Reset confirmed.\n");
- break;
- case LOADER_POWEROFF:
- printf("Poweroff confirmed.\n");
- break;
- case LOADER_ENTER_ROM_LOADER:
- printf("Jump to ROM loader confirmed.\n");
- break;
- case LOADER_ENTER_FLASH_LOADER:
- printf("Jump to flash loader confirmed.\n");
- break;
- case LOADER_MEM_READ:
- printf("Received memory dump of %d bytes at 0x%x:\n", length, address);
- osmoload_osmo_hexdump(data, length);
- break;
- case LOADER_MEM_WRITE:
- printf("Confirmed memory write of %d bytes at 0x%x.\n", length, address);
- break;
- case LOADER_JUMP:
- printf("Confirmed jump to 0x%x.\n", address);
- break;
- case LOADER_FLASH_ERASE:
- printf("Confirmed flash erase of chip %d address 0x%8.8x, status %s\n",
- chip, address, status ? "FAILED" : "ok");
- break;
- case LOADER_FLASH_GETLOCK:
- printf("Lock state of chip %d address 0x%8.8x is %s\n",
- chip, address, (status == LOADER_FLASH_LOCKED ? "locked"
- : (status == LOADER_FLASH_LOCKED_DOWN ? "locked down"
- : (status == LOADER_FLASH_UNLOCKED ? "unlocked"
- : "UNKNOWN"))));
- break;
- case LOADER_FLASH_UNLOCK:
- printf("Confirmed flash unlock of chip %d address 0x%8.8x, status %s\n",
- chip, address, status ? "FAILED" : "ok");
- break;
- case LOADER_FLASH_LOCK:
- printf("Confirmed flash lock of chip %d address 0x%8.8x, status %s\n",
- chip, address, status ? "FAILED" : "ok");
- break;
- case LOADER_FLASH_LOCKDOWN:
- printf("Confirmed flash lockdown of chip %d address 0x%8.8x, status %s\n",
- chip, address, status ? "FAILED" : "ok");
- break;
- case LOADER_FLASH_INFO:
- loader_parse_flash_info(msg);
- break;
- default:
- break;
- }
- if(osmoload.state == STATE_QUERY_PENDING) {
- if(osmoload.command == cmd) {
- osmoload.quit = 1;
- }
- }
- break;
- case STATE_DUMP_IN_PROGRESS:
- if(cmd == LOADER_MEM_READ) {
- loader_do_memdump(crc, data, length);
- }
- break;
- case STATE_LOAD_IN_PROGRESS:
- if(cmd == LOADER_MEM_WRITE) {
- if(osmoload.memcrc != crc) {
- osmoload.memoff -= osmoload.memreq;
- printf("\nbad crc %4.4x (not %4.4x) at offset 0x%8.8x", crc, osmoload.memcrc, osmoload.memoff);
- } else {
- putchar('.');
- }
- loader_do_memload();
- }
- break;
- case STATE_PROGRAM_GET_INFO:
- case STATE_PROGRAM_IN_PROGRESS:
- if(cmd == LOADER_FLASH_PROGRAM) {
- if(osmoload.memcrc != crc) {
- osmoload.memoff -= osmoload.memreq;
- printf("\nbad crc %4.4x (not %4.4x) at offset 0x%8.8x", crc, osmoload.memcrc, osmoload.memoff);
- } else {
- putchar('.');
- }
- if(((int)status) != 0) {
- printf("\nstatus %d, aborting\n", status);
- exit(1);
- }
- loader_do_fprogram();
- }
- break;
- case STATE_FLASHRANGE_GET_INFO:
- case STATE_FLASHRANGE_IN_PROGRESS:
- loader_do_flashrange(cmd, msg, chip, address, status);
- break;
- default:
- break;
- }
-
- fflush(stdout);
-}
-
-static int
-loader_read_cb(struct osmo_fd *fd, unsigned int flags) {
- struct msgb *msg;
- u_int16_t len;
- int rc;
-
- msg = msgb_alloc(MSGB_MAX, "loader");
- if (!msg) {
- fprintf(stderr, "Failed to allocate msg.\n");
- return -1;
- }
-
- rc = read(fd->fd, &len, sizeof(len));
- if (rc < sizeof(len)) {
- fprintf(stderr, "Short read. Error.\n");
- exit(2);
- }
-
- if (ntohs(len) > MSGB_MAX) {
- fprintf(stderr, "Length is too big: %u\n", ntohs(len));
- msgb_free(msg);
- return -1;
- }
-
- /* blocking read for the poor... we can starve in here... */
- msg->l2h = msgb_put(msg, ntohs(len));
- rc = read(fd->fd, msg->l2h, msgb_l2len(msg));
- if (rc != msgb_l2len(msg)) {
- fprintf(stderr, "Can not read data: rc: %d errno: %d\n", rc, errno);
- msgb_free(msg);
- return -1;
- }
-
- loader_handle_reply(msg);
-
- msgb_free(msg);
-
- return 0;
-}
-
-static void
-loader_connect(const char *socket_path) {
- int rc;
- struct sockaddr_un local;
- struct osmo_fd *conn = &connection;
-
- local.sun_family = AF_UNIX;
- strncpy(local.sun_path, socket_path, sizeof(local.sun_path));
- local.sun_path[sizeof(local.sun_path) - 1] = '\0';
-
- conn->fd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (conn->fd < 0) {
- fprintf(stderr, "Failed to create unix domain socket.\n");
- exit(1);
- }
-
- rc = connect(conn->fd, (struct sockaddr *) &local,
- sizeof(local.sun_family) + strlen(local.sun_path));
- if (rc < 0) {
- fprintf(stderr, "Failed to connect to '%s'.\n", local.sun_path);
- exit(1);
- }
-
- conn->when = BSC_FD_READ;
- conn->cb = loader_read_cb;
- conn->data = NULL;
-
- if (osmo_fd_register(conn) != 0) {
- fprintf(stderr, "Failed to register fd.\n");
- exit(1);
- }
-}
-
-static void
-loader_send_simple(uint8_t command) {
- struct msgb *msg = msgb_alloc(MSGB_MAX, "loader");
- msgb_put_u8(msg, command);
- loader_send_request(msg);
- msgb_free(msg);
-
- osmoload.command = command;
-}
-
-static void
-loader_start_query(uint8_t command) {
- loader_send_simple(command);
- osmoload.state = STATE_QUERY_PENDING;
-}
-
-static void
-loader_send_flash_query(uint8_t command, uint8_t chip, uint32_t address) {
- struct msgb *msg = msgb_alloc(MSGB_MAX, "loader");
- msgb_put_u8(msg, command);
- msgb_put_u8(msg, chip);
- msgb_put_u32(msg, address);
- loader_send_request(msg);
- msgb_free(msg);
-
- osmoload.command = command;
-}
-
-static void
-loader_start_flash_query(uint8_t command, uint8_t chip, uint32_t address) {
- loader_send_flash_query(command, chip, address);
- osmoload.state = STATE_QUERY_PENDING;
-}
-
-static void
-loader_start_memget(uint8_t length, uint32_t address) {
- struct msgb *msg = msgb_alloc(MSGB_MAX, "loader");
- msgb_put_u8(msg, LOADER_MEM_READ);
- msgb_put_u8(msg, length);
- msgb_put_u32(msg, address);
- loader_send_request(msg);
- msgb_free(msg);
-
- osmoload.state = STATE_QUERY_PENDING;
- osmoload.command = LOADER_MEM_READ;
-}
-
-static void
-loader_start_memput(uint8_t length, uint32_t address, void *data) {
- struct msgb *msg = msgb_alloc(MSGB_MAX, "loader");
- msgb_put_u8(msg, LOADER_MEM_WRITE);
- msgb_put_u8(msg, length);
- msgb_put_u16(msg, osmo_crc16(0, data, length));
- msgb_put_u32(msg, address);
- memcpy(msgb_put(msg, length), data, length);
- loader_send_request(msg);
- msgb_free(msg);
-
- osmoload.state = STATE_QUERY_PENDING;
- osmoload.command = LOADER_MEM_WRITE;
-}
-
-static void
-loader_start_jump(uint32_t address) {
- struct msgb *msg = msgb_alloc(MSGB_MAX, "loader");
- msgb_put_u8(msg, LOADER_JUMP);
- msgb_put_u32(msg, address);
- loader_send_request(msg);
- msgb_free(msg);
-
- osmoload.state = STATE_QUERY_PENDING;
- osmoload.command = LOADER_JUMP;
-}
-
-
-static void
-loader_do_memdump(uint16_t crc, void *data, size_t length) {
- int rc;
-
- if(data && length) {
- osmoload.memcrc = osmo_crc16(0, data, length);
- if(osmoload.memcrc != crc) {
- osmoload.memoff -= osmoload.memreq;
- printf("\nbad crc %4.4x (not %4.4x) at offset 0x%8.8x", crc, osmoload.memcrc, osmoload.memoff);
- } else {
- putchar('.');
- }
-
- memcpy(osmoload.binbuf + osmoload.memoff, data, length);
- osmoload.memoff += length;
- }
-
- uint32_t rembytes = osmoload.memlen - osmoload.memoff;
-
- if(!rembytes) {
- puts("done.");
- osmoload.quit = 1;
-
- unsigned c = osmoload.memlen;
- char *p = osmoload.binbuf;
- while(c) {
- rc = fwrite(p, 1, c, osmoload.binfile);
- if(ferror(osmoload.binfile)) {
- printf("Could not read from file: %s\n", strerror(errno));
- exit(1);
- }
- c -= rc;
- p += rc;
- }
- fclose(osmoload.binfile);
- osmoload.binfile = NULL;
-
- free(osmoload.binbuf);
-
- return;
- }
-
- uint8_t reqbytes = (rembytes < MEM_MSG_MAX) ? rembytes : MEM_MSG_MAX;
-
- struct msgb *msg = msgb_alloc(MSGB_MAX, "loader");
-
- msgb_put_u8(msg, LOADER_MEM_READ);
- msgb_put_u8(msg, reqbytes);
- msgb_put_u32(msg, osmoload.membase + osmoload.memoff);
- loader_send_request(msg);
- msgb_free(msg);
-}
-
-static void
-loader_do_memload() {
- uint32_t rembytes = osmoload.memlen - osmoload.memoff;
-
- if(!rembytes) {
- puts("done.");
- osmoload.quit = 1;
- return;
- }
-
- osmo_timer_schedule(&osmoload.timeout, 0, 500000);
-
- uint8_t reqbytes = (rembytes < MEM_MSG_MAX) ? rembytes : MEM_MSG_MAX;
-
- osmoload.memcrc = osmo_crc16(0, (uint8_t *) osmoload.binbuf + osmoload.memoff, reqbytes);
- osmoload.memreq = reqbytes;
-
- struct msgb *msg = msgb_alloc(MSGB_MAX, "loader");
-
- msgb_put_u8(msg, LOADER_MEM_WRITE);
- msgb_put_u8(msg, reqbytes);
- msgb_put_u16(msg, osmoload.memcrc);
- msgb_put_u32(msg, osmoload.membase + osmoload.memoff);
-
- unsigned char *p = msgb_put(msg, reqbytes);
- memcpy(p, osmoload.binbuf + osmoload.memoff, reqbytes);
-
-#if 0
- printf("Sending %u bytes at offset %u to address %x with crc %x\n",
- reqbytes, osmoload.memoff, osmoload.membase + osmoload.memoff,
- osmoload.memcrc);
-#endif
-
- loader_send_request(msg);
-
- msgb_free(msg);
-
- osmoload.memoff += reqbytes;
-}
-
-static void
-loader_do_fprogram() {
- uint32_t rembytes = osmoload.memlen - osmoload.memoff;
-
- if(!rembytes) {
- puts("done.");
- osmoload.quit = 1;
- return;
- }
-
- osmo_timer_schedule(&osmoload.timeout, 0, 10000000);
-
- uint8_t reqbytes = (rembytes < MEM_MSG_MAX) ? rembytes : MEM_MSG_MAX;
-
- osmoload.memcrc = osmo_crc16(0, (uint8_t *) osmoload.binbuf + osmoload.memoff, reqbytes);
- osmoload.memreq = reqbytes;
-
- struct msgb *msg = msgb_alloc(MSGB_MAX, "loader");
-
- msgb_put_u8(msg, LOADER_FLASH_PROGRAM);
- msgb_put_u8(msg, reqbytes);
- msgb_put_u16(msg, osmoload.memcrc);
- msgb_put_u8(msg, 0); // XXX: align data to 16bit
- msgb_put_u8(msg, osmoload.memchip);
- msgb_put_u32(msg, osmoload.membase + osmoload.memoff);
-
- unsigned char *p = msgb_put(msg, reqbytes);
- memcpy(p, osmoload.binbuf + osmoload.memoff, reqbytes);
-
-#if 0
- printf("Sending %u bytes at offset %u to address %x with crc %x\n",
- reqbytes, osmoload.memoff, osmoload.membase + osmoload.memoff,
- osmoload.memcrc);
-#endif
-
- loader_send_request(msg);
-
- msgb_free(msg);
-
- osmoload.memoff += reqbytes;
-}
-
-static void
-loader_start_memdump(uint32_t length, uint32_t address, char *file) {
- printf("Dumping %u bytes of memory at 0x%x to file %s\n", length, address, file);
-
- osmoload.binbuf = malloc(length);
- if(!osmoload.binbuf) {
- printf("Could not allocate %u bytes for %s.\n", length, file);
- exit(1);
- }
-
- osmoload.binfile = fopen(file, "wb");
- if(!osmoload.binfile) {
- printf("Could not open %s: %s\n", file, strerror(errno));
- exit(1);
- }
-
- osmoload.membase = address;
- osmoload.memlen = length;
- osmoload.memoff = 0;
-
- osmoload.state = STATE_DUMP_IN_PROGRESS;
- loader_do_memdump(0, NULL, 0);
-}
-
-static void
-loader_start_memload(uint32_t address, char *file) {
- int rc;
- struct stat st;
-
- rc = stat(file, &st);
- if(rc < 0) {
- printf("Could not stat %s: %s\n", file, strerror(errno));
- exit(1);
- }
-
- uint32_t length = st.st_size;
-
- printf("Loading %u bytes of memory to address 0x%x from file %s\n", length, address, file);
-
- osmoload.binbuf = malloc(length);
- if(!osmoload.binbuf) {
- printf("Could not allocate %u bytes for %s.\n", length, file);
- exit(1);
- }
-
- osmoload.binfile = fopen(file, "rb");
- if(!osmoload.binfile) {
- printf("Could not open %s: %s\n", file, strerror(errno));
- exit(1);
- }
-
- unsigned c = length;
- char *p = osmoload.binbuf;
- while(c) {
- rc = fread(p, 1, c, osmoload.binfile);
- if(ferror(osmoload.binfile)) {
- printf("Could not read from file: %s\n", strerror(errno));
- exit(1);
- }
- c -= rc;
- p += rc;
- }
- fclose(osmoload.binfile);
- osmoload.binfile = NULL;
-
- osmoload.membase = address;
- osmoload.memlen = length;
- osmoload.memoff = 0;
-
- osmoload.state = STATE_LOAD_IN_PROGRESS;
- loader_do_memload();
-}
-
-static void
-loader_start_flashrange(uint8_t command, uint32_t address, uint32_t length) {
- switch(command) {
- case LOADER_FLASH_ERASE:
- printf("Erasing %u bytes of flash at 0x%x\n", length, address);
- break;
- case LOADER_FLASH_LOCK:
- printf("Locking %u bytes of flash at 0x%x\n", length, address);
- break;
- case LOADER_FLASH_LOCKDOWN:
- printf("Locking down %u bytes of flash at 0x%x\n", length, address);
- break;
- case LOADER_FLASH_UNLOCK:
- printf("Unlocking %u bytes of flash at 0x%x\n", length, address);
- break;
- case LOADER_FLASH_GETLOCK:
- printf("Getlocking %u bytes of flash at 0x%x\n", length, address);
- break;
- default:
- puts("Unknown range command");
- abort();
- break;
- }
-
- osmoload.flashcommand = command;
-
- osmoload.membase = address;
- osmoload.memlen = length;
- osmoload.memoff = 0;
-
- printf(" requesting flash info to determine block layout\n");
-
- osmoload.state = STATE_FLASHRANGE_GET_INFO;
-
- loader_send_simple(LOADER_FLASH_INFO);
-}
-
-static void
-loader_do_flashrange(uint8_t cmd, struct msgb *msg, uint8_t chip, uint32_t address, uint32_t status) {
- switch(osmoload.state) {
- case STATE_FLASHRANGE_GET_INFO:
- if(cmd == LOADER_FLASH_INFO) {
- loader_parse_flash_info(msg);
- osmoload.state = STATE_FLASHRANGE_IN_PROGRESS;
- loader_do_flashrange(0, NULL, 0, 0, 0);
- }
- break;
- case STATE_FLASHRANGE_IN_PROGRESS:
- {
- if(msg) {
- if(cmd == osmoload.flashcommand) {
- if(cmd == LOADER_FLASH_GETLOCK) {
- printf(" lock state of chip %d address 0x%8.8x is %s\n",
- chip, address, (status == LOADER_FLASH_LOCKED ? "locked"
- : (status == LOADER_FLASH_LOCKED_DOWN ? "locked down"
- : (status == LOADER_FLASH_UNLOCKED ? "unlocked"
- : "UNKNOWN"))));
- } else {
- printf(" confirmed operation on chip %d address 0x%8.8x, status %s\n",
- chip, address, status ? "FAILED" : "ok");
- }
- } else {
- break;
- }
- }
-
- uint32_t addr = osmoload.membase + osmoload.memoff;
-
- if(osmoload.memoff >= osmoload.memlen) {
- puts(" operation done");
- osmoload.quit = 1;
- break;
- }
-
- uint8_t found = 0;
- int i;
- for(i = 0; i < osmoload.numblocks; i++) {
- struct flashblock *b = &osmoload.blocks[i];
- if(b->fb_addr == addr) {
- loader_send_flash_query(osmoload.flashcommand, b->fb_chip, b->fb_offset);
- osmoload.memoff += b->fb_size;
- found = 1;
- break;
- }
- }
- if(!found) {
- puts("Oops!? Block not found?"); // XXX message
- abort();
- }
- }
- break;
- }
-}
-
-static void
-loader_start_fprogram(uint8_t chip, uint32_t address, char *file) {
- int rc;
- struct stat st;
-
- rc = stat(file, &st);
- if(rc < 0) {
- printf("Could not stat %s: %s\n", file, strerror(errno));
- exit(1);
- }
-
- uint32_t length = st.st_size;
-
- printf("Loading %u bytes of memory at 0x%x in chip %d from file %s\n", length, address, chip, file);
-
- osmoload.binbuf = malloc(length);
- if(!osmoload.binbuf) {
- printf("Could not allocate %u bytes for %s.\n", length, file);
- exit(1);
- }
-
- osmoload.binfile = fopen(file, "rb");
- if(!osmoload.binfile) {
- printf("Could not open %s: %s\n", file, strerror(errno));
- exit(1);
- }
-
- unsigned c = length;
- char *p = osmoload.binbuf;
- while(c) {
- rc = fread(p, 1, c, osmoload.binfile);
- if(ferror(osmoload.binfile)) {
- printf("Could not read from file: %s\n", strerror(errno));
- exit(1);
- }
- c -= rc;
- p += rc;
- }
- fclose(osmoload.binfile);
- osmoload.binfile = NULL;
-
- osmoload.memchip = chip;
- osmoload.membase = address;
- osmoload.memlen = length;
- osmoload.memoff = 0;
-
- osmoload.state = STATE_PROGRAM_IN_PROGRESS;
-
- loader_do_fprogram();
-}
-
-static void
-query_timeout(void *dummy) {
- puts("Query timed out.");
- exit(2);
-}
-
-static void
-loader_command(char *name, int cmdc, char **cmdv) {
- if(!cmdc) {
- usage(name);
- }
-
- char *cmd = cmdv[0];
-
- char buf[MEM_MSG_MAX];
- memset(buf, 23, sizeof(buf));
-
- if(!strcmp(cmd, "dump")) {
- osmoload.state = STATE_DUMPING;
- } else if(!strcmp(cmd, "ping")) {
- loader_start_query(LOADER_PING);
- } else if(!strcmp(cmd, "off")) {
- loader_start_query(LOADER_POWEROFF);
- } else if(!strcmp(cmd, "reset")) {
- loader_start_query(LOADER_RESET);
- } else if(!strcmp(cmd, "jumprom")) {
- loader_start_query(LOADER_ENTER_ROM_LOADER);
- } else if(!strcmp(cmd, "jumpflash")) {
- loader_start_query(LOADER_ENTER_FLASH_LOADER);
- } else if(!strcmp(cmd, "finfo")) {
- puts("Requesting flash layout info");
- loader_start_query(LOADER_FLASH_INFO);
- } else if(!strcmp(cmd, "memput")) {
- uint32_t address;
-
- if(cmdc < 3) {
- usage(name);
- }
-
- address = strtoul(cmdv[1], NULL, 16);
-
- unsigned int i;
- char *hex = cmdv[2];
- if(strlen(hex)&1) {
- puts("Invalid hex string.");
- exit(2);
- }
- for(i = 0; i <= sizeof(buf) && i < strlen(hex)/2; i++) {
- if(i >= sizeof(buf)) {
- puts("Value too long for single message");
- exit(2);
- }
- unsigned int byte;
- int count = sscanf(hex + i * 2, "%02x", &byte);
- if(count != 1) {
- puts("Invalid hex string.");
- exit(2);
- }
- buf[i] = byte & 0xFF;
- }
-
- loader_start_memput(i & 0xFF, address, buf);
- } else if(!strcmp(cmd, "memget")) {
- uint32_t address;
- uint8_t length;
-
- if(cmdc < 3) {
- usage(name);
- }
-
- address = strtoul(cmdv[1], NULL, 16);
- length = strtoul(cmdv[2], NULL, 16);
-
- if(length > MEM_MSG_MAX) {
- puts("Too many bytes");
- exit(2);
- }
-
- loader_start_memget(length, address);
- } else if(!strcmp(cmd, "jump")) {
- uint32_t address;
-
- if(cmdc < 2) {
- usage(name);
- }
-
- address = strtoul(cmdv[1], NULL, 16);
-
- loader_start_jump(address);
- } else if(!strcmp(cmd, "memdump")) {
- uint32_t address;
- uint32_t length;
-
- if(cmdc < 4) {
- usage(name);
- }
-
- address = strtoul(cmdv[1], NULL, 16);
- length = strtoul(cmdv[2], NULL, 16);
-
- loader_start_memdump(length, address, cmdv[3]);
- } else if(!strcmp(cmd, "memload")) {
- uint32_t address;
-
- if(cmdc < 3) {
- usage(name);
- }
-
- address = strtoul(cmdv[1], NULL, 16);
-
- loader_start_memload(address, cmdv[2]);
- } else if(!strcmp(cmd, "fprogram")) {
- uint8_t chip;
- uint32_t address;
-
- if(cmdc < 4) {
- usage(name);
- }
-
- chip = strtoul(cmdv[1], NULL, 10);
- address = strtoul(cmdv[2], NULL, 16);
-
- loader_start_fprogram(chip, address, cmdv[3]);
- } else if(!strcmp(cmd, "ferase")) {
- uint32_t address;
- uint32_t length;
-
- if(cmdc < 3) {
- usage(name);
- }
-
- address = strtoul(cmdv[1], NULL, 16);
- length = strtoul(cmdv[2], NULL, 16);
-
- loader_start_flashrange(LOADER_FLASH_ERASE, address, length);
- } else if(!strcmp(cmd, "flock")) {
- uint32_t address;
- uint32_t length;
-
- if(cmdc < 3) {
- usage(name);
- }
-
- address = strtoul(cmdv[1], NULL, 16);
- length = strtoul(cmdv[2], NULL, 16);
-
- loader_start_flashrange(LOADER_FLASH_LOCK, address, length);
- } else if(!strcmp(cmd, "flockdown")) {
- uint32_t address;
- uint32_t length;
-
- if(cmdc < 3) {
- usage(name);
- }
-
- address = strtoul(cmdv[1], NULL, 16);
- length = strtoul(cmdv[2], NULL, 16);
-
- loader_start_flashrange(LOADER_FLASH_LOCKDOWN, address, length);
- } else if(!strcmp(cmd, "funlock")) {
- uint32_t address;
- uint32_t length;
-
- if(cmdc < 3) {
- usage(name);
- }
-
- address = strtoul(cmdv[1], NULL, 16);
- length = strtoul(cmdv[2], NULL, 16);
-
- loader_start_flashrange(LOADER_FLASH_UNLOCK, address, length);
- } else if(!strcmp(cmd, "fgetlock")) {
- uint32_t address;
- uint32_t length;
-
- if(cmdc < 3) {
- usage(name);
- }
-
- address = strtoul(cmdv[1], NULL, 16);
- length = strtoul(cmdv[2], NULL, 16);
-
- loader_start_flashrange(LOADER_FLASH_GETLOCK, address, length);
- } else if(!strcmp(cmd, "help")) {
- usage(name);
- } else {
- printf("Unknown command '%s'\n", cmd);
- usage(name);
- }
-
- if(osmoload.state == STATE_QUERY_PENDING) {
- osmoload.timeout.cb = &query_timeout;
- osmo_timer_schedule(&osmoload.timeout, 0, 5000000);
- }
- if(osmoload.state == STATE_LOAD_IN_PROGRESS) {
- osmoload.timeout.cb = &memop_timeout;
- }
-
-}
-
-void
-setdebug(const char *name, char c) {
- switch(c) {
- case 't':
- osmoload.print_requests = 1;
- break;
- case 'r':
- osmoload.print_replies = 1;
- break;
- default:
- usage(name);
- break;
- }
-}
-
-int
-main(int argc, char **argv) {
- int opt;
- char *loader_un_path = "/tmp/osmocom_loader";
- const char *debugopt;
-
- while((opt = getopt(argc, argv, "d:hl:m:v")) != -1) {
- switch(opt) {
- case 'd':
- debugopt = optarg;
- while(*debugopt) {
- setdebug(argv[0], *debugopt);
- debugopt++;
- }
- break;
- case 'l':
- loader_un_path = optarg;
- break;
- case 'm':
- puts("model selection not implemented");
- exit(2);
- break;
- case 'v':
- version(argv[0]);
- break;
- case 'h':
- default:
- usage(argv[0]);
- break;
- }
- }
-
- osmoload.quit = 0;
-
- loader_connect(loader_un_path);
-
- loader_command(argv[0], argc - optind, argv + optind);
-
- while(!osmoload.quit) {
- osmo_select_main(0);
- }
-
- if(osmoload.binfile) {
- fclose(osmoload.binfile);
- }
-
- return 0;
-}
diff --git a/Src/osmoconbb/src/host/osmocon/tpu_debug.c b/Src/osmoconbb/src/host/osmocon/tpu_debug.c
deleted file mode 100644
index c9dac90..0000000
--- a/Src/osmoconbb/src/host/osmocon/tpu_debug.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/* Calypso TPU debugger, displays and decodes TPU instruction RAM */
-
-/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <osmocom/core/msgb.h>
-
-/* TPU disassembler begin */
-
-static const char *tpu_instr_name[] = {
- [0] = "SLEEP",
- [1] = "AT",
- [2] = "OFFSET",
- [3] = "SYNCHRO",
- [4] = "MOVE",
- [5] = "WAIT",
- [6] = "UNDEFINED6",
- [7] = "UNDEFINED7",
-};
-
-static const char *tpu_addr_name[0x1f] = {
- [0] = "TSP_CTLR1",
- [1] = "TSP_CTRL2",
- [4] = "TSP_TX_1",
- [3] = "TSP_TX_2",
- [2] = "TSP_TX_3",
- [5] = "TSP_TX_4",
- [6] = "TSPACT_L",
- [7] = "TSPACT_H",
- [9] = "TSP_SET1",
- [0xa] = "TSP_SET2",
- [0xb] = "TSP_SET3",
- [0x10] = "DSP_INT_PG",
- [0x11] = "GAUGING_EN",
-};
-
-static uint8_t tpu_reg_cache[0x1f];
-static uint16_t tpu_qbit;
-
-static void tpu_show_instr(uint16_t tpu)
-{
- uint16_t instr = tpu >> 13;
- uint16_t param = tpu & 0x1fff;
- uint16_t addr, data, bitlen;
- uint32_t tsp_data;
-
- tpu_qbit++;
-
- printf("\t %04u %04x %s ", tpu_qbit, tpu, tpu_instr_name[instr]);
- switch (instr) {
- case 0:
- tpu_qbit = 0;
- default:
- break;
- case 1:
- tpu_qbit = param;
- printf("%u ", param);
- break;
- case 5:
- tpu_qbit += param;
- printf("%u ", param);
- break;
- case 2:
- case 3:
- printf("%u ", param);
- break;
- case 4:
- addr = param & 0x1f;
- data = param >> 5;
- tpu_reg_cache[addr] = data;
- printf("%10s=0x%04x ", tpu_addr_name[addr], data);
- switch (addr) {
- case 0:
- bitlen = (data & 0x1f) + 1;
- printf("DEV_IDX=%u, BITLEN=%u ", data >> 5, bitlen);
- if (bitlen <= 8) {
- tsp_data = tpu_reg_cache[4];
- printf(" TSP_DATA=0x%02x ", tsp_data);
- } else if (bitlen <= 16) {
- tsp_data = tpu_reg_cache[3];
- tsp_data |= tpu_reg_cache[4] << 8;
- printf(" TSP_DATA=0x%04x ", tsp_data);
- } else if (bitlen <= 24) {
- tsp_data = tpu_reg_cache[2];
- tsp_data |= tpu_reg_cache[3] << 8;
- tsp_data |= tpu_reg_cache[4] << 16;
- printf(" TSP_DATA=0x%06x ", tsp_data);
- } else {
- tsp_data = tpu_reg_cache[5];
- tsp_data |= tpu_reg_cache[2] << 8;
- tsp_data |= tpu_reg_cache[3] << 16;
- tsp_data |= tpu_reg_cache[4] << 24;
- printf(" TSP_DATA=0x%08x ", tsp_data);
- }
- break;
- case 1:
- if (data & 0x01)
- printf("READ ");
- if (data & 0x02)
- printf("WRITE ");
- break;
- }
- }
- printf("\n");
-}
-
-void hdlc_tpudbg_cb(uint8_t dlci, struct msgb *msg)
-{
- uint32_t *fn = (uint32_t *) msg->data;
- uint16_t *tpu;
-
- printf("TPU FN %u\n", *fn);
- for (tpu = (uint16_t *) (msg->data + 4); tpu < (uint16_t *) msg->tail; tpu++)
- tpu_show_instr(*tpu);
-
- msgb_free(msg);
-}
diff --git a/Src/osmoconbb/src/host/rita_pll/mtk_pll.pl b/Src/osmoconbb/src/host/rita_pll/mtk_pll.pl
deleted file mode 100755
index ff931c5..0000000
--- a/Src/osmoconbb/src/host/rita_pll/mtk_pll.pl
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/perl
-
-# Rx Mode and Tx Mode:
-# N = Nint + (Nfrac / 130) = (0.5*Fvco) / 26M
-# where 0 <= Nfrac < 130
-# where 0 <= Ninit <= 127 (as Nint is 7 bit)
-# where Fvco = 4 * Fch (GSM 850/900), Fvco = 2 * Fch (GSM 1800/1900)
-
-# (Nint + (Nfrac / 130)) * 52 MHz = Fvco
-
-sub mtk_fvco($$) {
- my ($nint, $nfrac) = @_;
- return ($nint + ($nfrac / 130)) * (26 * 2)
-}
-
-sub hr() {
- printf("======================================================================\n");
-}
-
-sub vco_print($$$)
-{
- my ($nint, $nfrac, $hiband) = @_;
- my $fvco = mtk_fvco($nint, $nfrac);
- my $mult;
-
- if ($hiband == 1) {
- $mult = 2;
- } else {
- $mult = 4;
- }
-
- printf("Fch=%4.2f (Fvco=%4.2f, Nint=%03u, Nfrac=%03u)\n",
- $fvco/$mult, $fvco, $nint, $nfrac);
-}
-
-#for (my $nint = 0; $nint <= 127; $nint++) {
-# for (my $nfrac = 0; $nfrac <= 130; $nfrac++) {
-# vco_print($nint, $nfrac);
-# }
-#}
-
-printf("PLL Rx Low Band:\n");
-for (my $nint = 68; $nint <= 73; $nint++) {
-#for GSM 810
-#for (my $b = 132; $b <= 150; $b++) {
- for (my $nfrac = 0; $nfrac <= 130; $nfrac++) {
- vco_print($nint, $nfrac, 0);
- }
-}
-
-hr();
-printf("PLL Rx High Band:\n");
-for (my $nint = 69; $nint <= 79; $nint++) {
- for (my $nfrac = 0; $nfrac <= 130; $nfrac++) {
- vco_print($nint, $nfrac, 1);
- }
-}
-
-hr();
-printf("PLL Tx Low Band:\n");
-for (my $nint = 63; $nint <= 70; $nint++) {
- for (my $nfrac = 0; $nfrac <= 130; $nfrac++) {
- vco_print($nint, $nfrac, 0);
- }
-}
-
-
-hr();
-printf("PLL Tx High Band\n");
-for (my $nint = 65; $nint <= 73; $nint++) {
- for (my $nfrac = 0; $nfrac <= 130; $nfrac++) {
- vco_print($nint, $nfrac, 1);
- }
-}
-
-
-
-exit(0);
-
diff --git a/Src/osmoconbb/src/host/rita_pll/mtk_pll.txt b/Src/osmoconbb/src/host/rita_pll/mtk_pll.txt
deleted file mode 100644
index a008656..0000000
--- a/Src/osmoconbb/src/host/rita_pll/mtk_pll.txt
+++ /dev/null
@@ -1,4461 +0,0 @@
-PLL Rx Low Band:
-Fch=884.00 (Fvco=3536.00, Nint=068, Nfrac=000)
-Fch=884.10 (Fvco=3536.40, Nint=068, Nfrac=001)
-Fch=884.20 (Fvco=3536.80, Nint=068, Nfrac=002)
-Fch=884.30 (Fvco=3537.20, Nint=068, Nfrac=003)
-Fch=884.40 (Fvco=3537.60, Nint=068, Nfrac=004)
-Fch=884.50 (Fvco=3538.00, Nint=068, Nfrac=005)
-Fch=884.60 (Fvco=3538.40, Nint=068, Nfrac=006)
-Fch=884.70 (Fvco=3538.80, Nint=068, Nfrac=007)
-Fch=884.80 (Fvco=3539.20, Nint=068, Nfrac=008)
-Fch=884.90 (Fvco=3539.60, Nint=068, Nfrac=009)
-Fch=885.00 (Fvco=3540.00, Nint=068, Nfrac=010)
-Fch=885.10 (Fvco=3540.40, Nint=068, Nfrac=011)
-Fch=885.20 (Fvco=3540.80, Nint=068, Nfrac=012)
-Fch=885.30 (Fvco=3541.20, Nint=068, Nfrac=013)
-Fch=885.40 (Fvco=3541.60, Nint=068, Nfrac=014)
-Fch=885.50 (Fvco=3542.00, Nint=068, Nfrac=015)
-Fch=885.60 (Fvco=3542.40, Nint=068, Nfrac=016)
-Fch=885.70 (Fvco=3542.80, Nint=068, Nfrac=017)
-Fch=885.80 (Fvco=3543.20, Nint=068, Nfrac=018)
-Fch=885.90 (Fvco=3543.60, Nint=068, Nfrac=019)
-Fch=886.00 (Fvco=3544.00, Nint=068, Nfrac=020)
-Fch=886.10 (Fvco=3544.40, Nint=068, Nfrac=021)
-Fch=886.20 (Fvco=3544.80, Nint=068, Nfrac=022)
-Fch=886.30 (Fvco=3545.20, Nint=068, Nfrac=023)
-Fch=886.40 (Fvco=3545.60, Nint=068, Nfrac=024)
-Fch=886.50 (Fvco=3546.00, Nint=068, Nfrac=025)
-Fch=886.60 (Fvco=3546.40, Nint=068, Nfrac=026)
-Fch=886.70 (Fvco=3546.80, Nint=068, Nfrac=027)
-Fch=886.80 (Fvco=3547.20, Nint=068, Nfrac=028)
-Fch=886.90 (Fvco=3547.60, Nint=068, Nfrac=029)
-Fch=887.00 (Fvco=3548.00, Nint=068, Nfrac=030)
-Fch=887.10 (Fvco=3548.40, Nint=068, Nfrac=031)
-Fch=887.20 (Fvco=3548.80, Nint=068, Nfrac=032)
-Fch=887.30 (Fvco=3549.20, Nint=068, Nfrac=033)
-Fch=887.40 (Fvco=3549.60, Nint=068, Nfrac=034)
-Fch=887.50 (Fvco=3550.00, Nint=068, Nfrac=035)
-Fch=887.60 (Fvco=3550.40, Nint=068, Nfrac=036)
-Fch=887.70 (Fvco=3550.80, Nint=068, Nfrac=037)
-Fch=887.80 (Fvco=3551.20, Nint=068, Nfrac=038)
-Fch=887.90 (Fvco=3551.60, Nint=068, Nfrac=039)
-Fch=888.00 (Fvco=3552.00, Nint=068, Nfrac=040)
-Fch=888.10 (Fvco=3552.40, Nint=068, Nfrac=041)
-Fch=888.20 (Fvco=3552.80, Nint=068, Nfrac=042)
-Fch=888.30 (Fvco=3553.20, Nint=068, Nfrac=043)
-Fch=888.40 (Fvco=3553.60, Nint=068, Nfrac=044)
-Fch=888.50 (Fvco=3554.00, Nint=068, Nfrac=045)
-Fch=888.60 (Fvco=3554.40, Nint=068, Nfrac=046)
-Fch=888.70 (Fvco=3554.80, Nint=068, Nfrac=047)
-Fch=888.80 (Fvco=3555.20, Nint=068, Nfrac=048)
-Fch=888.90 (Fvco=3555.60, Nint=068, Nfrac=049)
-Fch=889.00 (Fvco=3556.00, Nint=068, Nfrac=050)
-Fch=889.10 (Fvco=3556.40, Nint=068, Nfrac=051)
-Fch=889.20 (Fvco=3556.80, Nint=068, Nfrac=052)
-Fch=889.30 (Fvco=3557.20, Nint=068, Nfrac=053)
-Fch=889.40 (Fvco=3557.60, Nint=068, Nfrac=054)
-Fch=889.50 (Fvco=3558.00, Nint=068, Nfrac=055)
-Fch=889.60 (Fvco=3558.40, Nint=068, Nfrac=056)
-Fch=889.70 (Fvco=3558.80, Nint=068, Nfrac=057)
-Fch=889.80 (Fvco=3559.20, Nint=068, Nfrac=058)
-Fch=889.90 (Fvco=3559.60, Nint=068, Nfrac=059)
-Fch=890.00 (Fvco=3560.00, Nint=068, Nfrac=060)
-Fch=890.10 (Fvco=3560.40, Nint=068, Nfrac=061)
-Fch=890.20 (Fvco=3560.80, Nint=068, Nfrac=062)
-Fch=890.30 (Fvco=3561.20, Nint=068, Nfrac=063)
-Fch=890.40 (Fvco=3561.60, Nint=068, Nfrac=064)
-Fch=890.50 (Fvco=3562.00, Nint=068, Nfrac=065)
-Fch=890.60 (Fvco=3562.40, Nint=068, Nfrac=066)
-Fch=890.70 (Fvco=3562.80, Nint=068, Nfrac=067)
-Fch=890.80 (Fvco=3563.20, Nint=068, Nfrac=068)
-Fch=890.90 (Fvco=3563.60, Nint=068, Nfrac=069)
-Fch=891.00 (Fvco=3564.00, Nint=068, Nfrac=070)
-Fch=891.10 (Fvco=3564.40, Nint=068, Nfrac=071)
-Fch=891.20 (Fvco=3564.80, Nint=068, Nfrac=072)
-Fch=891.30 (Fvco=3565.20, Nint=068, Nfrac=073)
-Fch=891.40 (Fvco=3565.60, Nint=068, Nfrac=074)
-Fch=891.50 (Fvco=3566.00, Nint=068, Nfrac=075)
-Fch=891.60 (Fvco=3566.40, Nint=068, Nfrac=076)
-Fch=891.70 (Fvco=3566.80, Nint=068, Nfrac=077)
-Fch=891.80 (Fvco=3567.20, Nint=068, Nfrac=078)
-Fch=891.90 (Fvco=3567.60, Nint=068, Nfrac=079)
-Fch=892.00 (Fvco=3568.00, Nint=068, Nfrac=080)
-Fch=892.10 (Fvco=3568.40, Nint=068, Nfrac=081)
-Fch=892.20 (Fvco=3568.80, Nint=068, Nfrac=082)
-Fch=892.30 (Fvco=3569.20, Nint=068, Nfrac=083)
-Fch=892.40 (Fvco=3569.60, Nint=068, Nfrac=084)
-Fch=892.50 (Fvco=3570.00, Nint=068, Nfrac=085)
-Fch=892.60 (Fvco=3570.40, Nint=068, Nfrac=086)
-Fch=892.70 (Fvco=3570.80, Nint=068, Nfrac=087)
-Fch=892.80 (Fvco=3571.20, Nint=068, Nfrac=088)
-Fch=892.90 (Fvco=3571.60, Nint=068, Nfrac=089)
-Fch=893.00 (Fvco=3572.00, Nint=068, Nfrac=090)
-Fch=893.10 (Fvco=3572.40, Nint=068, Nfrac=091)
-Fch=893.20 (Fvco=3572.80, Nint=068, Nfrac=092)
-Fch=893.30 (Fvco=3573.20, Nint=068, Nfrac=093)
-Fch=893.40 (Fvco=3573.60, Nint=068, Nfrac=094)
-Fch=893.50 (Fvco=3574.00, Nint=068, Nfrac=095)
-Fch=893.60 (Fvco=3574.40, Nint=068, Nfrac=096)
-Fch=893.70 (Fvco=3574.80, Nint=068, Nfrac=097)
-Fch=893.80 (Fvco=3575.20, Nint=068, Nfrac=098)
-Fch=893.90 (Fvco=3575.60, Nint=068, Nfrac=099)
-Fch=894.00 (Fvco=3576.00, Nint=068, Nfrac=100)
-Fch=894.10 (Fvco=3576.40, Nint=068, Nfrac=101)
-Fch=894.20 (Fvco=3576.80, Nint=068, Nfrac=102)
-Fch=894.30 (Fvco=3577.20, Nint=068, Nfrac=103)
-Fch=894.40 (Fvco=3577.60, Nint=068, Nfrac=104)
-Fch=894.50 (Fvco=3578.00, Nint=068, Nfrac=105)
-Fch=894.60 (Fvco=3578.40, Nint=068, Nfrac=106)
-Fch=894.70 (Fvco=3578.80, Nint=068, Nfrac=107)
-Fch=894.80 (Fvco=3579.20, Nint=068, Nfrac=108)
-Fch=894.90 (Fvco=3579.60, Nint=068, Nfrac=109)
-Fch=895.00 (Fvco=3580.00, Nint=068, Nfrac=110)
-Fch=895.10 (Fvco=3580.40, Nint=068, Nfrac=111)
-Fch=895.20 (Fvco=3580.80, Nint=068, Nfrac=112)
-Fch=895.30 (Fvco=3581.20, Nint=068, Nfrac=113)
-Fch=895.40 (Fvco=3581.60, Nint=068, Nfrac=114)
-Fch=895.50 (Fvco=3582.00, Nint=068, Nfrac=115)
-Fch=895.60 (Fvco=3582.40, Nint=068, Nfrac=116)
-Fch=895.70 (Fvco=3582.80, Nint=068, Nfrac=117)
-Fch=895.80 (Fvco=3583.20, Nint=068, Nfrac=118)
-Fch=895.90 (Fvco=3583.60, Nint=068, Nfrac=119)
-Fch=896.00 (Fvco=3584.00, Nint=068, Nfrac=120)
-Fch=896.10 (Fvco=3584.40, Nint=068, Nfrac=121)
-Fch=896.20 (Fvco=3584.80, Nint=068, Nfrac=122)
-Fch=896.30 (Fvco=3585.20, Nint=068, Nfrac=123)
-Fch=896.40 (Fvco=3585.60, Nint=068, Nfrac=124)
-Fch=896.50 (Fvco=3586.00, Nint=068, Nfrac=125)
-Fch=896.60 (Fvco=3586.40, Nint=068, Nfrac=126)
-Fch=896.70 (Fvco=3586.80, Nint=068, Nfrac=127)
-Fch=896.80 (Fvco=3587.20, Nint=068, Nfrac=128)
-Fch=896.90 (Fvco=3587.60, Nint=068, Nfrac=129)
-Fch=897.00 (Fvco=3588.00, Nint=068, Nfrac=130)
-Fch=897.00 (Fvco=3588.00, Nint=069, Nfrac=000)
-Fch=897.10 (Fvco=3588.40, Nint=069, Nfrac=001)
-Fch=897.20 (Fvco=3588.80, Nint=069, Nfrac=002)
-Fch=897.30 (Fvco=3589.20, Nint=069, Nfrac=003)
-Fch=897.40 (Fvco=3589.60, Nint=069, Nfrac=004)
-Fch=897.50 (Fvco=3590.00, Nint=069, Nfrac=005)
-Fch=897.60 (Fvco=3590.40, Nint=069, Nfrac=006)
-Fch=897.70 (Fvco=3590.80, Nint=069, Nfrac=007)
-Fch=897.80 (Fvco=3591.20, Nint=069, Nfrac=008)
-Fch=897.90 (Fvco=3591.60, Nint=069, Nfrac=009)
-Fch=898.00 (Fvco=3592.00, Nint=069, Nfrac=010)
-Fch=898.10 (Fvco=3592.40, Nint=069, Nfrac=011)
-Fch=898.20 (Fvco=3592.80, Nint=069, Nfrac=012)
-Fch=898.30 (Fvco=3593.20, Nint=069, Nfrac=013)
-Fch=898.40 (Fvco=3593.60, Nint=069, Nfrac=014)
-Fch=898.50 (Fvco=3594.00, Nint=069, Nfrac=015)
-Fch=898.60 (Fvco=3594.40, Nint=069, Nfrac=016)
-Fch=898.70 (Fvco=3594.80, Nint=069, Nfrac=017)
-Fch=898.80 (Fvco=3595.20, Nint=069, Nfrac=018)
-Fch=898.90 (Fvco=3595.60, Nint=069, Nfrac=019)
-Fch=899.00 (Fvco=3596.00, Nint=069, Nfrac=020)
-Fch=899.10 (Fvco=3596.40, Nint=069, Nfrac=021)
-Fch=899.20 (Fvco=3596.80, Nint=069, Nfrac=022)
-Fch=899.30 (Fvco=3597.20, Nint=069, Nfrac=023)
-Fch=899.40 (Fvco=3597.60, Nint=069, Nfrac=024)
-Fch=899.50 (Fvco=3598.00, Nint=069, Nfrac=025)
-Fch=899.60 (Fvco=3598.40, Nint=069, Nfrac=026)
-Fch=899.70 (Fvco=3598.80, Nint=069, Nfrac=027)
-Fch=899.80 (Fvco=3599.20, Nint=069, Nfrac=028)
-Fch=899.90 (Fvco=3599.60, Nint=069, Nfrac=029)
-Fch=900.00 (Fvco=3600.00, Nint=069, Nfrac=030)
-Fch=900.10 (Fvco=3600.40, Nint=069, Nfrac=031)
-Fch=900.20 (Fvco=3600.80, Nint=069, Nfrac=032)
-Fch=900.30 (Fvco=3601.20, Nint=069, Nfrac=033)
-Fch=900.40 (Fvco=3601.60, Nint=069, Nfrac=034)
-Fch=900.50 (Fvco=3602.00, Nint=069, Nfrac=035)
-Fch=900.60 (Fvco=3602.40, Nint=069, Nfrac=036)
-Fch=900.70 (Fvco=3602.80, Nint=069, Nfrac=037)
-Fch=900.80 (Fvco=3603.20, Nint=069, Nfrac=038)
-Fch=900.90 (Fvco=3603.60, Nint=069, Nfrac=039)
-Fch=901.00 (Fvco=3604.00, Nint=069, Nfrac=040)
-Fch=901.10 (Fvco=3604.40, Nint=069, Nfrac=041)
-Fch=901.20 (Fvco=3604.80, Nint=069, Nfrac=042)
-Fch=901.30 (Fvco=3605.20, Nint=069, Nfrac=043)
-Fch=901.40 (Fvco=3605.60, Nint=069, Nfrac=044)
-Fch=901.50 (Fvco=3606.00, Nint=069, Nfrac=045)
-Fch=901.60 (Fvco=3606.40, Nint=069, Nfrac=046)
-Fch=901.70 (Fvco=3606.80, Nint=069, Nfrac=047)
-Fch=901.80 (Fvco=3607.20, Nint=069, Nfrac=048)
-Fch=901.90 (Fvco=3607.60, Nint=069, Nfrac=049)
-Fch=902.00 (Fvco=3608.00, Nint=069, Nfrac=050)
-Fch=902.10 (Fvco=3608.40, Nint=069, Nfrac=051)
-Fch=902.20 (Fvco=3608.80, Nint=069, Nfrac=052)
-Fch=902.30 (Fvco=3609.20, Nint=069, Nfrac=053)
-Fch=902.40 (Fvco=3609.60, Nint=069, Nfrac=054)
-Fch=902.50 (Fvco=3610.00, Nint=069, Nfrac=055)
-Fch=902.60 (Fvco=3610.40, Nint=069, Nfrac=056)
-Fch=902.70 (Fvco=3610.80, Nint=069, Nfrac=057)
-Fch=902.80 (Fvco=3611.20, Nint=069, Nfrac=058)
-Fch=902.90 (Fvco=3611.60, Nint=069, Nfrac=059)
-Fch=903.00 (Fvco=3612.00, Nint=069, Nfrac=060)
-Fch=903.10 (Fvco=3612.40, Nint=069, Nfrac=061)
-Fch=903.20 (Fvco=3612.80, Nint=069, Nfrac=062)
-Fch=903.30 (Fvco=3613.20, Nint=069, Nfrac=063)
-Fch=903.40 (Fvco=3613.60, Nint=069, Nfrac=064)
-Fch=903.50 (Fvco=3614.00, Nint=069, Nfrac=065)
-Fch=903.60 (Fvco=3614.40, Nint=069, Nfrac=066)
-Fch=903.70 (Fvco=3614.80, Nint=069, Nfrac=067)
-Fch=903.80 (Fvco=3615.20, Nint=069, Nfrac=068)
-Fch=903.90 (Fvco=3615.60, Nint=069, Nfrac=069)
-Fch=904.00 (Fvco=3616.00, Nint=069, Nfrac=070)
-Fch=904.10 (Fvco=3616.40, Nint=069, Nfrac=071)
-Fch=904.20 (Fvco=3616.80, Nint=069, Nfrac=072)
-Fch=904.30 (Fvco=3617.20, Nint=069, Nfrac=073)
-Fch=904.40 (Fvco=3617.60, Nint=069, Nfrac=074)
-Fch=904.50 (Fvco=3618.00, Nint=069, Nfrac=075)
-Fch=904.60 (Fvco=3618.40, Nint=069, Nfrac=076)
-Fch=904.70 (Fvco=3618.80, Nint=069, Nfrac=077)
-Fch=904.80 (Fvco=3619.20, Nint=069, Nfrac=078)
-Fch=904.90 (Fvco=3619.60, Nint=069, Nfrac=079)
-Fch=905.00 (Fvco=3620.00, Nint=069, Nfrac=080)
-Fch=905.10 (Fvco=3620.40, Nint=069, Nfrac=081)
-Fch=905.20 (Fvco=3620.80, Nint=069, Nfrac=082)
-Fch=905.30 (Fvco=3621.20, Nint=069, Nfrac=083)
-Fch=905.40 (Fvco=3621.60, Nint=069, Nfrac=084)
-Fch=905.50 (Fvco=3622.00, Nint=069, Nfrac=085)
-Fch=905.60 (Fvco=3622.40, Nint=069, Nfrac=086)
-Fch=905.70 (Fvco=3622.80, Nint=069, Nfrac=087)
-Fch=905.80 (Fvco=3623.20, Nint=069, Nfrac=088)
-Fch=905.90 (Fvco=3623.60, Nint=069, Nfrac=089)
-Fch=906.00 (Fvco=3624.00, Nint=069, Nfrac=090)
-Fch=906.10 (Fvco=3624.40, Nint=069, Nfrac=091)
-Fch=906.20 (Fvco=3624.80, Nint=069, Nfrac=092)
-Fch=906.30 (Fvco=3625.20, Nint=069, Nfrac=093)
-Fch=906.40 (Fvco=3625.60, Nint=069, Nfrac=094)
-Fch=906.50 (Fvco=3626.00, Nint=069, Nfrac=095)
-Fch=906.60 (Fvco=3626.40, Nint=069, Nfrac=096)
-Fch=906.70 (Fvco=3626.80, Nint=069, Nfrac=097)
-Fch=906.80 (Fvco=3627.20, Nint=069, Nfrac=098)
-Fch=906.90 (Fvco=3627.60, Nint=069, Nfrac=099)
-Fch=907.00 (Fvco=3628.00, Nint=069, Nfrac=100)
-Fch=907.10 (Fvco=3628.40, Nint=069, Nfrac=101)
-Fch=907.20 (Fvco=3628.80, Nint=069, Nfrac=102)
-Fch=907.30 (Fvco=3629.20, Nint=069, Nfrac=103)
-Fch=907.40 (Fvco=3629.60, Nint=069, Nfrac=104)
-Fch=907.50 (Fvco=3630.00, Nint=069, Nfrac=105)
-Fch=907.60 (Fvco=3630.40, Nint=069, Nfrac=106)
-Fch=907.70 (Fvco=3630.80, Nint=069, Nfrac=107)
-Fch=907.80 (Fvco=3631.20, Nint=069, Nfrac=108)
-Fch=907.90 (Fvco=3631.60, Nint=069, Nfrac=109)
-Fch=908.00 (Fvco=3632.00, Nint=069, Nfrac=110)
-Fch=908.10 (Fvco=3632.40, Nint=069, Nfrac=111)
-Fch=908.20 (Fvco=3632.80, Nint=069, Nfrac=112)
-Fch=908.30 (Fvco=3633.20, Nint=069, Nfrac=113)
-Fch=908.40 (Fvco=3633.60, Nint=069, Nfrac=114)
-Fch=908.50 (Fvco=3634.00, Nint=069, Nfrac=115)
-Fch=908.60 (Fvco=3634.40, Nint=069, Nfrac=116)
-Fch=908.70 (Fvco=3634.80, Nint=069, Nfrac=117)
-Fch=908.80 (Fvco=3635.20, Nint=069, Nfrac=118)
-Fch=908.90 (Fvco=3635.60, Nint=069, Nfrac=119)
-Fch=909.00 (Fvco=3636.00, Nint=069, Nfrac=120)
-Fch=909.10 (Fvco=3636.40, Nint=069, Nfrac=121)
-Fch=909.20 (Fvco=3636.80, Nint=069, Nfrac=122)
-Fch=909.30 (Fvco=3637.20, Nint=069, Nfrac=123)
-Fch=909.40 (Fvco=3637.60, Nint=069, Nfrac=124)
-Fch=909.50 (Fvco=3638.00, Nint=069, Nfrac=125)
-Fch=909.60 (Fvco=3638.40, Nint=069, Nfrac=126)
-Fch=909.70 (Fvco=3638.80, Nint=069, Nfrac=127)
-Fch=909.80 (Fvco=3639.20, Nint=069, Nfrac=128)
-Fch=909.90 (Fvco=3639.60, Nint=069, Nfrac=129)
-Fch=910.00 (Fvco=3640.00, Nint=069, Nfrac=130)
-Fch=910.00 (Fvco=3640.00, Nint=070, Nfrac=000)
-Fch=910.10 (Fvco=3640.40, Nint=070, Nfrac=001)
-Fch=910.20 (Fvco=3640.80, Nint=070, Nfrac=002)
-Fch=910.30 (Fvco=3641.20, Nint=070, Nfrac=003)
-Fch=910.40 (Fvco=3641.60, Nint=070, Nfrac=004)
-Fch=910.50 (Fvco=3642.00, Nint=070, Nfrac=005)
-Fch=910.60 (Fvco=3642.40, Nint=070, Nfrac=006)
-Fch=910.70 (Fvco=3642.80, Nint=070, Nfrac=007)
-Fch=910.80 (Fvco=3643.20, Nint=070, Nfrac=008)
-Fch=910.90 (Fvco=3643.60, Nint=070, Nfrac=009)
-Fch=911.00 (Fvco=3644.00, Nint=070, Nfrac=010)
-Fch=911.10 (Fvco=3644.40, Nint=070, Nfrac=011)
-Fch=911.20 (Fvco=3644.80, Nint=070, Nfrac=012)
-Fch=911.30 (Fvco=3645.20, Nint=070, Nfrac=013)
-Fch=911.40 (Fvco=3645.60, Nint=070, Nfrac=014)
-Fch=911.50 (Fvco=3646.00, Nint=070, Nfrac=015)
-Fch=911.60 (Fvco=3646.40, Nint=070, Nfrac=016)
-Fch=911.70 (Fvco=3646.80, Nint=070, Nfrac=017)
-Fch=911.80 (Fvco=3647.20, Nint=070, Nfrac=018)
-Fch=911.90 (Fvco=3647.60, Nint=070, Nfrac=019)
-Fch=912.00 (Fvco=3648.00, Nint=070, Nfrac=020)
-Fch=912.10 (Fvco=3648.40, Nint=070, Nfrac=021)
-Fch=912.20 (Fvco=3648.80, Nint=070, Nfrac=022)
-Fch=912.30 (Fvco=3649.20, Nint=070, Nfrac=023)
-Fch=912.40 (Fvco=3649.60, Nint=070, Nfrac=024)
-Fch=912.50 (Fvco=3650.00, Nint=070, Nfrac=025)
-Fch=912.60 (Fvco=3650.40, Nint=070, Nfrac=026)
-Fch=912.70 (Fvco=3650.80, Nint=070, Nfrac=027)
-Fch=912.80 (Fvco=3651.20, Nint=070, Nfrac=028)
-Fch=912.90 (Fvco=3651.60, Nint=070, Nfrac=029)
-Fch=913.00 (Fvco=3652.00, Nint=070, Nfrac=030)
-Fch=913.10 (Fvco=3652.40, Nint=070, Nfrac=031)
-Fch=913.20 (Fvco=3652.80, Nint=070, Nfrac=032)
-Fch=913.30 (Fvco=3653.20, Nint=070, Nfrac=033)
-Fch=913.40 (Fvco=3653.60, Nint=070, Nfrac=034)
-Fch=913.50 (Fvco=3654.00, Nint=070, Nfrac=035)
-Fch=913.60 (Fvco=3654.40, Nint=070, Nfrac=036)
-Fch=913.70 (Fvco=3654.80, Nint=070, Nfrac=037)
-Fch=913.80 (Fvco=3655.20, Nint=070, Nfrac=038)
-Fch=913.90 (Fvco=3655.60, Nint=070, Nfrac=039)
-Fch=914.00 (Fvco=3656.00, Nint=070, Nfrac=040)
-Fch=914.10 (Fvco=3656.40, Nint=070, Nfrac=041)
-Fch=914.20 (Fvco=3656.80, Nint=070, Nfrac=042)
-Fch=914.30 (Fvco=3657.20, Nint=070, Nfrac=043)
-Fch=914.40 (Fvco=3657.60, Nint=070, Nfrac=044)
-Fch=914.50 (Fvco=3658.00, Nint=070, Nfrac=045)
-Fch=914.60 (Fvco=3658.40, Nint=070, Nfrac=046)
-Fch=914.70 (Fvco=3658.80, Nint=070, Nfrac=047)
-Fch=914.80 (Fvco=3659.20, Nint=070, Nfrac=048)
-Fch=914.90 (Fvco=3659.60, Nint=070, Nfrac=049)
-Fch=915.00 (Fvco=3660.00, Nint=070, Nfrac=050)
-Fch=915.10 (Fvco=3660.40, Nint=070, Nfrac=051)
-Fch=915.20 (Fvco=3660.80, Nint=070, Nfrac=052)
-Fch=915.30 (Fvco=3661.20, Nint=070, Nfrac=053)
-Fch=915.40 (Fvco=3661.60, Nint=070, Nfrac=054)
-Fch=915.50 (Fvco=3662.00, Nint=070, Nfrac=055)
-Fch=915.60 (Fvco=3662.40, Nint=070, Nfrac=056)
-Fch=915.70 (Fvco=3662.80, Nint=070, Nfrac=057)
-Fch=915.80 (Fvco=3663.20, Nint=070, Nfrac=058)
-Fch=915.90 (Fvco=3663.60, Nint=070, Nfrac=059)
-Fch=916.00 (Fvco=3664.00, Nint=070, Nfrac=060)
-Fch=916.10 (Fvco=3664.40, Nint=070, Nfrac=061)
-Fch=916.20 (Fvco=3664.80, Nint=070, Nfrac=062)
-Fch=916.30 (Fvco=3665.20, Nint=070, Nfrac=063)
-Fch=916.40 (Fvco=3665.60, Nint=070, Nfrac=064)
-Fch=916.50 (Fvco=3666.00, Nint=070, Nfrac=065)
-Fch=916.60 (Fvco=3666.40, Nint=070, Nfrac=066)
-Fch=916.70 (Fvco=3666.80, Nint=070, Nfrac=067)
-Fch=916.80 (Fvco=3667.20, Nint=070, Nfrac=068)
-Fch=916.90 (Fvco=3667.60, Nint=070, Nfrac=069)
-Fch=917.00 (Fvco=3668.00, Nint=070, Nfrac=070)
-Fch=917.10 (Fvco=3668.40, Nint=070, Nfrac=071)
-Fch=917.20 (Fvco=3668.80, Nint=070, Nfrac=072)
-Fch=917.30 (Fvco=3669.20, Nint=070, Nfrac=073)
-Fch=917.40 (Fvco=3669.60, Nint=070, Nfrac=074)
-Fch=917.50 (Fvco=3670.00, Nint=070, Nfrac=075)
-Fch=917.60 (Fvco=3670.40, Nint=070, Nfrac=076)
-Fch=917.70 (Fvco=3670.80, Nint=070, Nfrac=077)
-Fch=917.80 (Fvco=3671.20, Nint=070, Nfrac=078)
-Fch=917.90 (Fvco=3671.60, Nint=070, Nfrac=079)
-Fch=918.00 (Fvco=3672.00, Nint=070, Nfrac=080)
-Fch=918.10 (Fvco=3672.40, Nint=070, Nfrac=081)
-Fch=918.20 (Fvco=3672.80, Nint=070, Nfrac=082)
-Fch=918.30 (Fvco=3673.20, Nint=070, Nfrac=083)
-Fch=918.40 (Fvco=3673.60, Nint=070, Nfrac=084)
-Fch=918.50 (Fvco=3674.00, Nint=070, Nfrac=085)
-Fch=918.60 (Fvco=3674.40, Nint=070, Nfrac=086)
-Fch=918.70 (Fvco=3674.80, Nint=070, Nfrac=087)
-Fch=918.80 (Fvco=3675.20, Nint=070, Nfrac=088)
-Fch=918.90 (Fvco=3675.60, Nint=070, Nfrac=089)
-Fch=919.00 (Fvco=3676.00, Nint=070, Nfrac=090)
-Fch=919.10 (Fvco=3676.40, Nint=070, Nfrac=091)
-Fch=919.20 (Fvco=3676.80, Nint=070, Nfrac=092)
-Fch=919.30 (Fvco=3677.20, Nint=070, Nfrac=093)
-Fch=919.40 (Fvco=3677.60, Nint=070, Nfrac=094)
-Fch=919.50 (Fvco=3678.00, Nint=070, Nfrac=095)
-Fch=919.60 (Fvco=3678.40, Nint=070, Nfrac=096)
-Fch=919.70 (Fvco=3678.80, Nint=070, Nfrac=097)
-Fch=919.80 (Fvco=3679.20, Nint=070, Nfrac=098)
-Fch=919.90 (Fvco=3679.60, Nint=070, Nfrac=099)
-Fch=920.00 (Fvco=3680.00, Nint=070, Nfrac=100)
-Fch=920.10 (Fvco=3680.40, Nint=070, Nfrac=101)
-Fch=920.20 (Fvco=3680.80, Nint=070, Nfrac=102)
-Fch=920.30 (Fvco=3681.20, Nint=070, Nfrac=103)
-Fch=920.40 (Fvco=3681.60, Nint=070, Nfrac=104)
-Fch=920.50 (Fvco=3682.00, Nint=070, Nfrac=105)
-Fch=920.60 (Fvco=3682.40, Nint=070, Nfrac=106)
-Fch=920.70 (Fvco=3682.80, Nint=070, Nfrac=107)
-Fch=920.80 (Fvco=3683.20, Nint=070, Nfrac=108)
-Fch=920.90 (Fvco=3683.60, Nint=070, Nfrac=109)
-Fch=921.00 (Fvco=3684.00, Nint=070, Nfrac=110)
-Fch=921.10 (Fvco=3684.40, Nint=070, Nfrac=111)
-Fch=921.20 (Fvco=3684.80, Nint=070, Nfrac=112)
-Fch=921.30 (Fvco=3685.20, Nint=070, Nfrac=113)
-Fch=921.40 (Fvco=3685.60, Nint=070, Nfrac=114)
-Fch=921.50 (Fvco=3686.00, Nint=070, Nfrac=115)
-Fch=921.60 (Fvco=3686.40, Nint=070, Nfrac=116)
-Fch=921.70 (Fvco=3686.80, Nint=070, Nfrac=117)
-Fch=921.80 (Fvco=3687.20, Nint=070, Nfrac=118)
-Fch=921.90 (Fvco=3687.60, Nint=070, Nfrac=119)
-Fch=922.00 (Fvco=3688.00, Nint=070, Nfrac=120)
-Fch=922.10 (Fvco=3688.40, Nint=070, Nfrac=121)
-Fch=922.20 (Fvco=3688.80, Nint=070, Nfrac=122)
-Fch=922.30 (Fvco=3689.20, Nint=070, Nfrac=123)
-Fch=922.40 (Fvco=3689.60, Nint=070, Nfrac=124)
-Fch=922.50 (Fvco=3690.00, Nint=070, Nfrac=125)
-Fch=922.60 (Fvco=3690.40, Nint=070, Nfrac=126)
-Fch=922.70 (Fvco=3690.80, Nint=070, Nfrac=127)
-Fch=922.80 (Fvco=3691.20, Nint=070, Nfrac=128)
-Fch=922.90 (Fvco=3691.60, Nint=070, Nfrac=129)
-Fch=923.00 (Fvco=3692.00, Nint=070, Nfrac=130)
-Fch=923.00 (Fvco=3692.00, Nint=071, Nfrac=000)
-Fch=923.10 (Fvco=3692.40, Nint=071, Nfrac=001)
-Fch=923.20 (Fvco=3692.80, Nint=071, Nfrac=002)
-Fch=923.30 (Fvco=3693.20, Nint=071, Nfrac=003)
-Fch=923.40 (Fvco=3693.60, Nint=071, Nfrac=004)
-Fch=923.50 (Fvco=3694.00, Nint=071, Nfrac=005)
-Fch=923.60 (Fvco=3694.40, Nint=071, Nfrac=006)
-Fch=923.70 (Fvco=3694.80, Nint=071, Nfrac=007)
-Fch=923.80 (Fvco=3695.20, Nint=071, Nfrac=008)
-Fch=923.90 (Fvco=3695.60, Nint=071, Nfrac=009)
-Fch=924.00 (Fvco=3696.00, Nint=071, Nfrac=010)
-Fch=924.10 (Fvco=3696.40, Nint=071, Nfrac=011)
-Fch=924.20 (Fvco=3696.80, Nint=071, Nfrac=012)
-Fch=924.30 (Fvco=3697.20, Nint=071, Nfrac=013)
-Fch=924.40 (Fvco=3697.60, Nint=071, Nfrac=014)
-Fch=924.50 (Fvco=3698.00, Nint=071, Nfrac=015)
-Fch=924.60 (Fvco=3698.40, Nint=071, Nfrac=016)
-Fch=924.70 (Fvco=3698.80, Nint=071, Nfrac=017)
-Fch=924.80 (Fvco=3699.20, Nint=071, Nfrac=018)
-Fch=924.90 (Fvco=3699.60, Nint=071, Nfrac=019)
-Fch=925.00 (Fvco=3700.00, Nint=071, Nfrac=020)
-Fch=925.10 (Fvco=3700.40, Nint=071, Nfrac=021)
-Fch=925.20 (Fvco=3700.80, Nint=071, Nfrac=022)
-Fch=925.30 (Fvco=3701.20, Nint=071, Nfrac=023)
-Fch=925.40 (Fvco=3701.60, Nint=071, Nfrac=024)
-Fch=925.50 (Fvco=3702.00, Nint=071, Nfrac=025)
-Fch=925.60 (Fvco=3702.40, Nint=071, Nfrac=026)
-Fch=925.70 (Fvco=3702.80, Nint=071, Nfrac=027)
-Fch=925.80 (Fvco=3703.20, Nint=071, Nfrac=028)
-Fch=925.90 (Fvco=3703.60, Nint=071, Nfrac=029)
-Fch=926.00 (Fvco=3704.00, Nint=071, Nfrac=030)
-Fch=926.10 (Fvco=3704.40, Nint=071, Nfrac=031)
-Fch=926.20 (Fvco=3704.80, Nint=071, Nfrac=032)
-Fch=926.30 (Fvco=3705.20, Nint=071, Nfrac=033)
-Fch=926.40 (Fvco=3705.60, Nint=071, Nfrac=034)
-Fch=926.50 (Fvco=3706.00, Nint=071, Nfrac=035)
-Fch=926.60 (Fvco=3706.40, Nint=071, Nfrac=036)
-Fch=926.70 (Fvco=3706.80, Nint=071, Nfrac=037)
-Fch=926.80 (Fvco=3707.20, Nint=071, Nfrac=038)
-Fch=926.90 (Fvco=3707.60, Nint=071, Nfrac=039)
-Fch=927.00 (Fvco=3708.00, Nint=071, Nfrac=040)
-Fch=927.10 (Fvco=3708.40, Nint=071, Nfrac=041)
-Fch=927.20 (Fvco=3708.80, Nint=071, Nfrac=042)
-Fch=927.30 (Fvco=3709.20, Nint=071, Nfrac=043)
-Fch=927.40 (Fvco=3709.60, Nint=071, Nfrac=044)
-Fch=927.50 (Fvco=3710.00, Nint=071, Nfrac=045)
-Fch=927.60 (Fvco=3710.40, Nint=071, Nfrac=046)
-Fch=927.70 (Fvco=3710.80, Nint=071, Nfrac=047)
-Fch=927.80 (Fvco=3711.20, Nint=071, Nfrac=048)
-Fch=927.90 (Fvco=3711.60, Nint=071, Nfrac=049)
-Fch=928.00 (Fvco=3712.00, Nint=071, Nfrac=050)
-Fch=928.10 (Fvco=3712.40, Nint=071, Nfrac=051)
-Fch=928.20 (Fvco=3712.80, Nint=071, Nfrac=052)
-Fch=928.30 (Fvco=3713.20, Nint=071, Nfrac=053)
-Fch=928.40 (Fvco=3713.60, Nint=071, Nfrac=054)
-Fch=928.50 (Fvco=3714.00, Nint=071, Nfrac=055)
-Fch=928.60 (Fvco=3714.40, Nint=071, Nfrac=056)
-Fch=928.70 (Fvco=3714.80, Nint=071, Nfrac=057)
-Fch=928.80 (Fvco=3715.20, Nint=071, Nfrac=058)
-Fch=928.90 (Fvco=3715.60, Nint=071, Nfrac=059)
-Fch=929.00 (Fvco=3716.00, Nint=071, Nfrac=060)
-Fch=929.10 (Fvco=3716.40, Nint=071, Nfrac=061)
-Fch=929.20 (Fvco=3716.80, Nint=071, Nfrac=062)
-Fch=929.30 (Fvco=3717.20, Nint=071, Nfrac=063)
-Fch=929.40 (Fvco=3717.60, Nint=071, Nfrac=064)
-Fch=929.50 (Fvco=3718.00, Nint=071, Nfrac=065)
-Fch=929.60 (Fvco=3718.40, Nint=071, Nfrac=066)
-Fch=929.70 (Fvco=3718.80, Nint=071, Nfrac=067)
-Fch=929.80 (Fvco=3719.20, Nint=071, Nfrac=068)
-Fch=929.90 (Fvco=3719.60, Nint=071, Nfrac=069)
-Fch=930.00 (Fvco=3720.00, Nint=071, Nfrac=070)
-Fch=930.10 (Fvco=3720.40, Nint=071, Nfrac=071)
-Fch=930.20 (Fvco=3720.80, Nint=071, Nfrac=072)
-Fch=930.30 (Fvco=3721.20, Nint=071, Nfrac=073)
-Fch=930.40 (Fvco=3721.60, Nint=071, Nfrac=074)
-Fch=930.50 (Fvco=3722.00, Nint=071, Nfrac=075)
-Fch=930.60 (Fvco=3722.40, Nint=071, Nfrac=076)
-Fch=930.70 (Fvco=3722.80, Nint=071, Nfrac=077)
-Fch=930.80 (Fvco=3723.20, Nint=071, Nfrac=078)
-Fch=930.90 (Fvco=3723.60, Nint=071, Nfrac=079)
-Fch=931.00 (Fvco=3724.00, Nint=071, Nfrac=080)
-Fch=931.10 (Fvco=3724.40, Nint=071, Nfrac=081)
-Fch=931.20 (Fvco=3724.80, Nint=071, Nfrac=082)
-Fch=931.30 (Fvco=3725.20, Nint=071, Nfrac=083)
-Fch=931.40 (Fvco=3725.60, Nint=071, Nfrac=084)
-Fch=931.50 (Fvco=3726.00, Nint=071, Nfrac=085)
-Fch=931.60 (Fvco=3726.40, Nint=071, Nfrac=086)
-Fch=931.70 (Fvco=3726.80, Nint=071, Nfrac=087)
-Fch=931.80 (Fvco=3727.20, Nint=071, Nfrac=088)
-Fch=931.90 (Fvco=3727.60, Nint=071, Nfrac=089)
-Fch=932.00 (Fvco=3728.00, Nint=071, Nfrac=090)
-Fch=932.10 (Fvco=3728.40, Nint=071, Nfrac=091)
-Fch=932.20 (Fvco=3728.80, Nint=071, Nfrac=092)
-Fch=932.30 (Fvco=3729.20, Nint=071, Nfrac=093)
-Fch=932.40 (Fvco=3729.60, Nint=071, Nfrac=094)
-Fch=932.50 (Fvco=3730.00, Nint=071, Nfrac=095)
-Fch=932.60 (Fvco=3730.40, Nint=071, Nfrac=096)
-Fch=932.70 (Fvco=3730.80, Nint=071, Nfrac=097)
-Fch=932.80 (Fvco=3731.20, Nint=071, Nfrac=098)
-Fch=932.90 (Fvco=3731.60, Nint=071, Nfrac=099)
-Fch=933.00 (Fvco=3732.00, Nint=071, Nfrac=100)
-Fch=933.10 (Fvco=3732.40, Nint=071, Nfrac=101)
-Fch=933.20 (Fvco=3732.80, Nint=071, Nfrac=102)
-Fch=933.30 (Fvco=3733.20, Nint=071, Nfrac=103)
-Fch=933.40 (Fvco=3733.60, Nint=071, Nfrac=104)
-Fch=933.50 (Fvco=3734.00, Nint=071, Nfrac=105)
-Fch=933.60 (Fvco=3734.40, Nint=071, Nfrac=106)
-Fch=933.70 (Fvco=3734.80, Nint=071, Nfrac=107)
-Fch=933.80 (Fvco=3735.20, Nint=071, Nfrac=108)
-Fch=933.90 (Fvco=3735.60, Nint=071, Nfrac=109)
-Fch=934.00 (Fvco=3736.00, Nint=071, Nfrac=110)
-Fch=934.10 (Fvco=3736.40, Nint=071, Nfrac=111)
-Fch=934.20 (Fvco=3736.80, Nint=071, Nfrac=112)
-Fch=934.30 (Fvco=3737.20, Nint=071, Nfrac=113)
-Fch=934.40 (Fvco=3737.60, Nint=071, Nfrac=114)
-Fch=934.50 (Fvco=3738.00, Nint=071, Nfrac=115)
-Fch=934.60 (Fvco=3738.40, Nint=071, Nfrac=116)
-Fch=934.70 (Fvco=3738.80, Nint=071, Nfrac=117)
-Fch=934.80 (Fvco=3739.20, Nint=071, Nfrac=118)
-Fch=934.90 (Fvco=3739.60, Nint=071, Nfrac=119)
-Fch=935.00 (Fvco=3740.00, Nint=071, Nfrac=120)
-Fch=935.10 (Fvco=3740.40, Nint=071, Nfrac=121)
-Fch=935.20 (Fvco=3740.80, Nint=071, Nfrac=122)
-Fch=935.30 (Fvco=3741.20, Nint=071, Nfrac=123)
-Fch=935.40 (Fvco=3741.60, Nint=071, Nfrac=124)
-Fch=935.50 (Fvco=3742.00, Nint=071, Nfrac=125)
-Fch=935.60 (Fvco=3742.40, Nint=071, Nfrac=126)
-Fch=935.70 (Fvco=3742.80, Nint=071, Nfrac=127)
-Fch=935.80 (Fvco=3743.20, Nint=071, Nfrac=128)
-Fch=935.90 (Fvco=3743.60, Nint=071, Nfrac=129)
-Fch=936.00 (Fvco=3744.00, Nint=071, Nfrac=130)
-Fch=936.00 (Fvco=3744.00, Nint=072, Nfrac=000)
-Fch=936.10 (Fvco=3744.40, Nint=072, Nfrac=001)
-Fch=936.20 (Fvco=3744.80, Nint=072, Nfrac=002)
-Fch=936.30 (Fvco=3745.20, Nint=072, Nfrac=003)
-Fch=936.40 (Fvco=3745.60, Nint=072, Nfrac=004)
-Fch=936.50 (Fvco=3746.00, Nint=072, Nfrac=005)
-Fch=936.60 (Fvco=3746.40, Nint=072, Nfrac=006)
-Fch=936.70 (Fvco=3746.80, Nint=072, Nfrac=007)
-Fch=936.80 (Fvco=3747.20, Nint=072, Nfrac=008)
-Fch=936.90 (Fvco=3747.60, Nint=072, Nfrac=009)
-Fch=937.00 (Fvco=3748.00, Nint=072, Nfrac=010)
-Fch=937.10 (Fvco=3748.40, Nint=072, Nfrac=011)
-Fch=937.20 (Fvco=3748.80, Nint=072, Nfrac=012)
-Fch=937.30 (Fvco=3749.20, Nint=072, Nfrac=013)
-Fch=937.40 (Fvco=3749.60, Nint=072, Nfrac=014)
-Fch=937.50 (Fvco=3750.00, Nint=072, Nfrac=015)
-Fch=937.60 (Fvco=3750.40, Nint=072, Nfrac=016)
-Fch=937.70 (Fvco=3750.80, Nint=072, Nfrac=017)
-Fch=937.80 (Fvco=3751.20, Nint=072, Nfrac=018)
-Fch=937.90 (Fvco=3751.60, Nint=072, Nfrac=019)
-Fch=938.00 (Fvco=3752.00, Nint=072, Nfrac=020)
-Fch=938.10 (Fvco=3752.40, Nint=072, Nfrac=021)
-Fch=938.20 (Fvco=3752.80, Nint=072, Nfrac=022)
-Fch=938.30 (Fvco=3753.20, Nint=072, Nfrac=023)
-Fch=938.40 (Fvco=3753.60, Nint=072, Nfrac=024)
-Fch=938.50 (Fvco=3754.00, Nint=072, Nfrac=025)
-Fch=938.60 (Fvco=3754.40, Nint=072, Nfrac=026)
-Fch=938.70 (Fvco=3754.80, Nint=072, Nfrac=027)
-Fch=938.80 (Fvco=3755.20, Nint=072, Nfrac=028)
-Fch=938.90 (Fvco=3755.60, Nint=072, Nfrac=029)
-Fch=939.00 (Fvco=3756.00, Nint=072, Nfrac=030)
-Fch=939.10 (Fvco=3756.40, Nint=072, Nfrac=031)
-Fch=939.20 (Fvco=3756.80, Nint=072, Nfrac=032)
-Fch=939.30 (Fvco=3757.20, Nint=072, Nfrac=033)
-Fch=939.40 (Fvco=3757.60, Nint=072, Nfrac=034)
-Fch=939.50 (Fvco=3758.00, Nint=072, Nfrac=035)
-Fch=939.60 (Fvco=3758.40, Nint=072, Nfrac=036)
-Fch=939.70 (Fvco=3758.80, Nint=072, Nfrac=037)
-Fch=939.80 (Fvco=3759.20, Nint=072, Nfrac=038)
-Fch=939.90 (Fvco=3759.60, Nint=072, Nfrac=039)
-Fch=940.00 (Fvco=3760.00, Nint=072, Nfrac=040)
-Fch=940.10 (Fvco=3760.40, Nint=072, Nfrac=041)
-Fch=940.20 (Fvco=3760.80, Nint=072, Nfrac=042)
-Fch=940.30 (Fvco=3761.20, Nint=072, Nfrac=043)
-Fch=940.40 (Fvco=3761.60, Nint=072, Nfrac=044)
-Fch=940.50 (Fvco=3762.00, Nint=072, Nfrac=045)
-Fch=940.60 (Fvco=3762.40, Nint=072, Nfrac=046)
-Fch=940.70 (Fvco=3762.80, Nint=072, Nfrac=047)
-Fch=940.80 (Fvco=3763.20, Nint=072, Nfrac=048)
-Fch=940.90 (Fvco=3763.60, Nint=072, Nfrac=049)
-Fch=941.00 (Fvco=3764.00, Nint=072, Nfrac=050)
-Fch=941.10 (Fvco=3764.40, Nint=072, Nfrac=051)
-Fch=941.20 (Fvco=3764.80, Nint=072, Nfrac=052)
-Fch=941.30 (Fvco=3765.20, Nint=072, Nfrac=053)
-Fch=941.40 (Fvco=3765.60, Nint=072, Nfrac=054)
-Fch=941.50 (Fvco=3766.00, Nint=072, Nfrac=055)
-Fch=941.60 (Fvco=3766.40, Nint=072, Nfrac=056)
-Fch=941.70 (Fvco=3766.80, Nint=072, Nfrac=057)
-Fch=941.80 (Fvco=3767.20, Nint=072, Nfrac=058)
-Fch=941.90 (Fvco=3767.60, Nint=072, Nfrac=059)
-Fch=942.00 (Fvco=3768.00, Nint=072, Nfrac=060)
-Fch=942.10 (Fvco=3768.40, Nint=072, Nfrac=061)
-Fch=942.20 (Fvco=3768.80, Nint=072, Nfrac=062)
-Fch=942.30 (Fvco=3769.20, Nint=072, Nfrac=063)
-Fch=942.40 (Fvco=3769.60, Nint=072, Nfrac=064)
-Fch=942.50 (Fvco=3770.00, Nint=072, Nfrac=065)
-Fch=942.60 (Fvco=3770.40, Nint=072, Nfrac=066)
-Fch=942.70 (Fvco=3770.80, Nint=072, Nfrac=067)
-Fch=942.80 (Fvco=3771.20, Nint=072, Nfrac=068)
-Fch=942.90 (Fvco=3771.60, Nint=072, Nfrac=069)
-Fch=943.00 (Fvco=3772.00, Nint=072, Nfrac=070)
-Fch=943.10 (Fvco=3772.40, Nint=072, Nfrac=071)
-Fch=943.20 (Fvco=3772.80, Nint=072, Nfrac=072)
-Fch=943.30 (Fvco=3773.20, Nint=072, Nfrac=073)
-Fch=943.40 (Fvco=3773.60, Nint=072, Nfrac=074)
-Fch=943.50 (Fvco=3774.00, Nint=072, Nfrac=075)
-Fch=943.60 (Fvco=3774.40, Nint=072, Nfrac=076)
-Fch=943.70 (Fvco=3774.80, Nint=072, Nfrac=077)
-Fch=943.80 (Fvco=3775.20, Nint=072, Nfrac=078)
-Fch=943.90 (Fvco=3775.60, Nint=072, Nfrac=079)
-Fch=944.00 (Fvco=3776.00, Nint=072, Nfrac=080)
-Fch=944.10 (Fvco=3776.40, Nint=072, Nfrac=081)
-Fch=944.20 (Fvco=3776.80, Nint=072, Nfrac=082)
-Fch=944.30 (Fvco=3777.20, Nint=072, Nfrac=083)
-Fch=944.40 (Fvco=3777.60, Nint=072, Nfrac=084)
-Fch=944.50 (Fvco=3778.00, Nint=072, Nfrac=085)
-Fch=944.60 (Fvco=3778.40, Nint=072, Nfrac=086)
-Fch=944.70 (Fvco=3778.80, Nint=072, Nfrac=087)
-Fch=944.80 (Fvco=3779.20, Nint=072, Nfrac=088)
-Fch=944.90 (Fvco=3779.60, Nint=072, Nfrac=089)
-Fch=945.00 (Fvco=3780.00, Nint=072, Nfrac=090)
-Fch=945.10 (Fvco=3780.40, Nint=072, Nfrac=091)
-Fch=945.20 (Fvco=3780.80, Nint=072, Nfrac=092)
-Fch=945.30 (Fvco=3781.20, Nint=072, Nfrac=093)
-Fch=945.40 (Fvco=3781.60, Nint=072, Nfrac=094)
-Fch=945.50 (Fvco=3782.00, Nint=072, Nfrac=095)
-Fch=945.60 (Fvco=3782.40, Nint=072, Nfrac=096)
-Fch=945.70 (Fvco=3782.80, Nint=072, Nfrac=097)
-Fch=945.80 (Fvco=3783.20, Nint=072, Nfrac=098)
-Fch=945.90 (Fvco=3783.60, Nint=072, Nfrac=099)
-Fch=946.00 (Fvco=3784.00, Nint=072, Nfrac=100)
-Fch=946.10 (Fvco=3784.40, Nint=072, Nfrac=101)
-Fch=946.20 (Fvco=3784.80, Nint=072, Nfrac=102)
-Fch=946.30 (Fvco=3785.20, Nint=072, Nfrac=103)
-Fch=946.40 (Fvco=3785.60, Nint=072, Nfrac=104)
-Fch=946.50 (Fvco=3786.00, Nint=072, Nfrac=105)
-Fch=946.60 (Fvco=3786.40, Nint=072, Nfrac=106)
-Fch=946.70 (Fvco=3786.80, Nint=072, Nfrac=107)
-Fch=946.80 (Fvco=3787.20, Nint=072, Nfrac=108)
-Fch=946.90 (Fvco=3787.60, Nint=072, Nfrac=109)
-Fch=947.00 (Fvco=3788.00, Nint=072, Nfrac=110)
-Fch=947.10 (Fvco=3788.40, Nint=072, Nfrac=111)
-Fch=947.20 (Fvco=3788.80, Nint=072, Nfrac=112)
-Fch=947.30 (Fvco=3789.20, Nint=072, Nfrac=113)
-Fch=947.40 (Fvco=3789.60, Nint=072, Nfrac=114)
-Fch=947.50 (Fvco=3790.00, Nint=072, Nfrac=115)
-Fch=947.60 (Fvco=3790.40, Nint=072, Nfrac=116)
-Fch=947.70 (Fvco=3790.80, Nint=072, Nfrac=117)
-Fch=947.80 (Fvco=3791.20, Nint=072, Nfrac=118)
-Fch=947.90 (Fvco=3791.60, Nint=072, Nfrac=119)
-Fch=948.00 (Fvco=3792.00, Nint=072, Nfrac=120)
-Fch=948.10 (Fvco=3792.40, Nint=072, Nfrac=121)
-Fch=948.20 (Fvco=3792.80, Nint=072, Nfrac=122)
-Fch=948.30 (Fvco=3793.20, Nint=072, Nfrac=123)
-Fch=948.40 (Fvco=3793.60, Nint=072, Nfrac=124)
-Fch=948.50 (Fvco=3794.00, Nint=072, Nfrac=125)
-Fch=948.60 (Fvco=3794.40, Nint=072, Nfrac=126)
-Fch=948.70 (Fvco=3794.80, Nint=072, Nfrac=127)
-Fch=948.80 (Fvco=3795.20, Nint=072, Nfrac=128)
-Fch=948.90 (Fvco=3795.60, Nint=072, Nfrac=129)
-Fch=949.00 (Fvco=3796.00, Nint=072, Nfrac=130)
-Fch=949.00 (Fvco=3796.00, Nint=073, Nfrac=000)
-Fch=949.10 (Fvco=3796.40, Nint=073, Nfrac=001)
-Fch=949.20 (Fvco=3796.80, Nint=073, Nfrac=002)
-Fch=949.30 (Fvco=3797.20, Nint=073, Nfrac=003)
-Fch=949.40 (Fvco=3797.60, Nint=073, Nfrac=004)
-Fch=949.50 (Fvco=3798.00, Nint=073, Nfrac=005)
-Fch=949.60 (Fvco=3798.40, Nint=073, Nfrac=006)
-Fch=949.70 (Fvco=3798.80, Nint=073, Nfrac=007)
-Fch=949.80 (Fvco=3799.20, Nint=073, Nfrac=008)
-Fch=949.90 (Fvco=3799.60, Nint=073, Nfrac=009)
-Fch=950.00 (Fvco=3800.00, Nint=073, Nfrac=010)
-Fch=950.10 (Fvco=3800.40, Nint=073, Nfrac=011)
-Fch=950.20 (Fvco=3800.80, Nint=073, Nfrac=012)
-Fch=950.30 (Fvco=3801.20, Nint=073, Nfrac=013)
-Fch=950.40 (Fvco=3801.60, Nint=073, Nfrac=014)
-Fch=950.50 (Fvco=3802.00, Nint=073, Nfrac=015)
-Fch=950.60 (Fvco=3802.40, Nint=073, Nfrac=016)
-Fch=950.70 (Fvco=3802.80, Nint=073, Nfrac=017)
-Fch=950.80 (Fvco=3803.20, Nint=073, Nfrac=018)
-Fch=950.90 (Fvco=3803.60, Nint=073, Nfrac=019)
-Fch=951.00 (Fvco=3804.00, Nint=073, Nfrac=020)
-Fch=951.10 (Fvco=3804.40, Nint=073, Nfrac=021)
-Fch=951.20 (Fvco=3804.80, Nint=073, Nfrac=022)
-Fch=951.30 (Fvco=3805.20, Nint=073, Nfrac=023)
-Fch=951.40 (Fvco=3805.60, Nint=073, Nfrac=024)
-Fch=951.50 (Fvco=3806.00, Nint=073, Nfrac=025)
-Fch=951.60 (Fvco=3806.40, Nint=073, Nfrac=026)
-Fch=951.70 (Fvco=3806.80, Nint=073, Nfrac=027)
-Fch=951.80 (Fvco=3807.20, Nint=073, Nfrac=028)
-Fch=951.90 (Fvco=3807.60, Nint=073, Nfrac=029)
-Fch=952.00 (Fvco=3808.00, Nint=073, Nfrac=030)
-Fch=952.10 (Fvco=3808.40, Nint=073, Nfrac=031)
-Fch=952.20 (Fvco=3808.80, Nint=073, Nfrac=032)
-Fch=952.30 (Fvco=3809.20, Nint=073, Nfrac=033)
-Fch=952.40 (Fvco=3809.60, Nint=073, Nfrac=034)
-Fch=952.50 (Fvco=3810.00, Nint=073, Nfrac=035)
-Fch=952.60 (Fvco=3810.40, Nint=073, Nfrac=036)
-Fch=952.70 (Fvco=3810.80, Nint=073, Nfrac=037)
-Fch=952.80 (Fvco=3811.20, Nint=073, Nfrac=038)
-Fch=952.90 (Fvco=3811.60, Nint=073, Nfrac=039)
-Fch=953.00 (Fvco=3812.00, Nint=073, Nfrac=040)
-Fch=953.10 (Fvco=3812.40, Nint=073, Nfrac=041)
-Fch=953.20 (Fvco=3812.80, Nint=073, Nfrac=042)
-Fch=953.30 (Fvco=3813.20, Nint=073, Nfrac=043)
-Fch=953.40 (Fvco=3813.60, Nint=073, Nfrac=044)
-Fch=953.50 (Fvco=3814.00, Nint=073, Nfrac=045)
-Fch=953.60 (Fvco=3814.40, Nint=073, Nfrac=046)
-Fch=953.70 (Fvco=3814.80, Nint=073, Nfrac=047)
-Fch=953.80 (Fvco=3815.20, Nint=073, Nfrac=048)
-Fch=953.90 (Fvco=3815.60, Nint=073, Nfrac=049)
-Fch=954.00 (Fvco=3816.00, Nint=073, Nfrac=050)
-Fch=954.10 (Fvco=3816.40, Nint=073, Nfrac=051)
-Fch=954.20 (Fvco=3816.80, Nint=073, Nfrac=052)
-Fch=954.30 (Fvco=3817.20, Nint=073, Nfrac=053)
-Fch=954.40 (Fvco=3817.60, Nint=073, Nfrac=054)
-Fch=954.50 (Fvco=3818.00, Nint=073, Nfrac=055)
-Fch=954.60 (Fvco=3818.40, Nint=073, Nfrac=056)
-Fch=954.70 (Fvco=3818.80, Nint=073, Nfrac=057)
-Fch=954.80 (Fvco=3819.20, Nint=073, Nfrac=058)
-Fch=954.90 (Fvco=3819.60, Nint=073, Nfrac=059)
-Fch=955.00 (Fvco=3820.00, Nint=073, Nfrac=060)
-Fch=955.10 (Fvco=3820.40, Nint=073, Nfrac=061)
-Fch=955.20 (Fvco=3820.80, Nint=073, Nfrac=062)
-Fch=955.30 (Fvco=3821.20, Nint=073, Nfrac=063)
-Fch=955.40 (Fvco=3821.60, Nint=073, Nfrac=064)
-Fch=955.50 (Fvco=3822.00, Nint=073, Nfrac=065)
-Fch=955.60 (Fvco=3822.40, Nint=073, Nfrac=066)
-Fch=955.70 (Fvco=3822.80, Nint=073, Nfrac=067)
-Fch=955.80 (Fvco=3823.20, Nint=073, Nfrac=068)
-Fch=955.90 (Fvco=3823.60, Nint=073, Nfrac=069)
-Fch=956.00 (Fvco=3824.00, Nint=073, Nfrac=070)
-Fch=956.10 (Fvco=3824.40, Nint=073, Nfrac=071)
-Fch=956.20 (Fvco=3824.80, Nint=073, Nfrac=072)
-Fch=956.30 (Fvco=3825.20, Nint=073, Nfrac=073)
-Fch=956.40 (Fvco=3825.60, Nint=073, Nfrac=074)
-Fch=956.50 (Fvco=3826.00, Nint=073, Nfrac=075)
-Fch=956.60 (Fvco=3826.40, Nint=073, Nfrac=076)
-Fch=956.70 (Fvco=3826.80, Nint=073, Nfrac=077)
-Fch=956.80 (Fvco=3827.20, Nint=073, Nfrac=078)
-Fch=956.90 (Fvco=3827.60, Nint=073, Nfrac=079)
-Fch=957.00 (Fvco=3828.00, Nint=073, Nfrac=080)
-Fch=957.10 (Fvco=3828.40, Nint=073, Nfrac=081)
-Fch=957.20 (Fvco=3828.80, Nint=073, Nfrac=082)
-Fch=957.30 (Fvco=3829.20, Nint=073, Nfrac=083)
-Fch=957.40 (Fvco=3829.60, Nint=073, Nfrac=084)
-Fch=957.50 (Fvco=3830.00, Nint=073, Nfrac=085)
-Fch=957.60 (Fvco=3830.40, Nint=073, Nfrac=086)
-Fch=957.70 (Fvco=3830.80, Nint=073, Nfrac=087)
-Fch=957.80 (Fvco=3831.20, Nint=073, Nfrac=088)
-Fch=957.90 (Fvco=3831.60, Nint=073, Nfrac=089)
-Fch=958.00 (Fvco=3832.00, Nint=073, Nfrac=090)
-Fch=958.10 (Fvco=3832.40, Nint=073, Nfrac=091)
-Fch=958.20 (Fvco=3832.80, Nint=073, Nfrac=092)
-Fch=958.30 (Fvco=3833.20, Nint=073, Nfrac=093)
-Fch=958.40 (Fvco=3833.60, Nint=073, Nfrac=094)
-Fch=958.50 (Fvco=3834.00, Nint=073, Nfrac=095)
-Fch=958.60 (Fvco=3834.40, Nint=073, Nfrac=096)
-Fch=958.70 (Fvco=3834.80, Nint=073, Nfrac=097)
-Fch=958.80 (Fvco=3835.20, Nint=073, Nfrac=098)
-Fch=958.90 (Fvco=3835.60, Nint=073, Nfrac=099)
-Fch=959.00 (Fvco=3836.00, Nint=073, Nfrac=100)
-Fch=959.10 (Fvco=3836.40, Nint=073, Nfrac=101)
-Fch=959.20 (Fvco=3836.80, Nint=073, Nfrac=102)
-Fch=959.30 (Fvco=3837.20, Nint=073, Nfrac=103)
-Fch=959.40 (Fvco=3837.60, Nint=073, Nfrac=104)
-Fch=959.50 (Fvco=3838.00, Nint=073, Nfrac=105)
-Fch=959.60 (Fvco=3838.40, Nint=073, Nfrac=106)
-Fch=959.70 (Fvco=3838.80, Nint=073, Nfrac=107)
-Fch=959.80 (Fvco=3839.20, Nint=073, Nfrac=108)
-Fch=959.90 (Fvco=3839.60, Nint=073, Nfrac=109)
-Fch=960.00 (Fvco=3840.00, Nint=073, Nfrac=110)
-Fch=960.10 (Fvco=3840.40, Nint=073, Nfrac=111)
-Fch=960.20 (Fvco=3840.80, Nint=073, Nfrac=112)
-Fch=960.30 (Fvco=3841.20, Nint=073, Nfrac=113)
-Fch=960.40 (Fvco=3841.60, Nint=073, Nfrac=114)
-Fch=960.50 (Fvco=3842.00, Nint=073, Nfrac=115)
-Fch=960.60 (Fvco=3842.40, Nint=073, Nfrac=116)
-Fch=960.70 (Fvco=3842.80, Nint=073, Nfrac=117)
-Fch=960.80 (Fvco=3843.20, Nint=073, Nfrac=118)
-Fch=960.90 (Fvco=3843.60, Nint=073, Nfrac=119)
-Fch=961.00 (Fvco=3844.00, Nint=073, Nfrac=120)
-Fch=961.10 (Fvco=3844.40, Nint=073, Nfrac=121)
-Fch=961.20 (Fvco=3844.80, Nint=073, Nfrac=122)
-Fch=961.30 (Fvco=3845.20, Nint=073, Nfrac=123)
-Fch=961.40 (Fvco=3845.60, Nint=073, Nfrac=124)
-Fch=961.50 (Fvco=3846.00, Nint=073, Nfrac=125)
-Fch=961.60 (Fvco=3846.40, Nint=073, Nfrac=126)
-Fch=961.70 (Fvco=3846.80, Nint=073, Nfrac=127)
-Fch=961.80 (Fvco=3847.20, Nint=073, Nfrac=128)
-Fch=961.90 (Fvco=3847.60, Nint=073, Nfrac=129)
-Fch=962.00 (Fvco=3848.00, Nint=073, Nfrac=130)
-======================================================================
-PLL Rx High Band:
-Fch=1794.00 (Fvco=3588.00, Nint=069, Nfrac=000)
-Fch=1794.20 (Fvco=3588.40, Nint=069, Nfrac=001)
-Fch=1794.40 (Fvco=3588.80, Nint=069, Nfrac=002)
-Fch=1794.60 (Fvco=3589.20, Nint=069, Nfrac=003)
-Fch=1794.80 (Fvco=3589.60, Nint=069, Nfrac=004)
-Fch=1795.00 (Fvco=3590.00, Nint=069, Nfrac=005)
-Fch=1795.20 (Fvco=3590.40, Nint=069, Nfrac=006)
-Fch=1795.40 (Fvco=3590.80, Nint=069, Nfrac=007)
-Fch=1795.60 (Fvco=3591.20, Nint=069, Nfrac=008)
-Fch=1795.80 (Fvco=3591.60, Nint=069, Nfrac=009)
-Fch=1796.00 (Fvco=3592.00, Nint=069, Nfrac=010)
-Fch=1796.20 (Fvco=3592.40, Nint=069, Nfrac=011)
-Fch=1796.40 (Fvco=3592.80, Nint=069, Nfrac=012)
-Fch=1796.60 (Fvco=3593.20, Nint=069, Nfrac=013)
-Fch=1796.80 (Fvco=3593.60, Nint=069, Nfrac=014)
-Fch=1797.00 (Fvco=3594.00, Nint=069, Nfrac=015)
-Fch=1797.20 (Fvco=3594.40, Nint=069, Nfrac=016)
-Fch=1797.40 (Fvco=3594.80, Nint=069, Nfrac=017)
-Fch=1797.60 (Fvco=3595.20, Nint=069, Nfrac=018)
-Fch=1797.80 (Fvco=3595.60, Nint=069, Nfrac=019)
-Fch=1798.00 (Fvco=3596.00, Nint=069, Nfrac=020)
-Fch=1798.20 (Fvco=3596.40, Nint=069, Nfrac=021)
-Fch=1798.40 (Fvco=3596.80, Nint=069, Nfrac=022)
-Fch=1798.60 (Fvco=3597.20, Nint=069, Nfrac=023)
-Fch=1798.80 (Fvco=3597.60, Nint=069, Nfrac=024)
-Fch=1799.00 (Fvco=3598.00, Nint=069, Nfrac=025)
-Fch=1799.20 (Fvco=3598.40, Nint=069, Nfrac=026)
-Fch=1799.40 (Fvco=3598.80, Nint=069, Nfrac=027)
-Fch=1799.60 (Fvco=3599.20, Nint=069, Nfrac=028)
-Fch=1799.80 (Fvco=3599.60, Nint=069, Nfrac=029)
-Fch=1800.00 (Fvco=3600.00, Nint=069, Nfrac=030)
-Fch=1800.20 (Fvco=3600.40, Nint=069, Nfrac=031)
-Fch=1800.40 (Fvco=3600.80, Nint=069, Nfrac=032)
-Fch=1800.60 (Fvco=3601.20, Nint=069, Nfrac=033)
-Fch=1800.80 (Fvco=3601.60, Nint=069, Nfrac=034)
-Fch=1801.00 (Fvco=3602.00, Nint=069, Nfrac=035)
-Fch=1801.20 (Fvco=3602.40, Nint=069, Nfrac=036)
-Fch=1801.40 (Fvco=3602.80, Nint=069, Nfrac=037)
-Fch=1801.60 (Fvco=3603.20, Nint=069, Nfrac=038)
-Fch=1801.80 (Fvco=3603.60, Nint=069, Nfrac=039)
-Fch=1802.00 (Fvco=3604.00, Nint=069, Nfrac=040)
-Fch=1802.20 (Fvco=3604.40, Nint=069, Nfrac=041)
-Fch=1802.40 (Fvco=3604.80, Nint=069, Nfrac=042)
-Fch=1802.60 (Fvco=3605.20, Nint=069, Nfrac=043)
-Fch=1802.80 (Fvco=3605.60, Nint=069, Nfrac=044)
-Fch=1803.00 (Fvco=3606.00, Nint=069, Nfrac=045)
-Fch=1803.20 (Fvco=3606.40, Nint=069, Nfrac=046)
-Fch=1803.40 (Fvco=3606.80, Nint=069, Nfrac=047)
-Fch=1803.60 (Fvco=3607.20, Nint=069, Nfrac=048)
-Fch=1803.80 (Fvco=3607.60, Nint=069, Nfrac=049)
-Fch=1804.00 (Fvco=3608.00, Nint=069, Nfrac=050)
-Fch=1804.20 (Fvco=3608.40, Nint=069, Nfrac=051)
-Fch=1804.40 (Fvco=3608.80, Nint=069, Nfrac=052)
-Fch=1804.60 (Fvco=3609.20, Nint=069, Nfrac=053)
-Fch=1804.80 (Fvco=3609.60, Nint=069, Nfrac=054)
-Fch=1805.00 (Fvco=3610.00, Nint=069, Nfrac=055)
-Fch=1805.20 (Fvco=3610.40, Nint=069, Nfrac=056)
-Fch=1805.40 (Fvco=3610.80, Nint=069, Nfrac=057)
-Fch=1805.60 (Fvco=3611.20, Nint=069, Nfrac=058)
-Fch=1805.80 (Fvco=3611.60, Nint=069, Nfrac=059)
-Fch=1806.00 (Fvco=3612.00, Nint=069, Nfrac=060)
-Fch=1806.20 (Fvco=3612.40, Nint=069, Nfrac=061)
-Fch=1806.40 (Fvco=3612.80, Nint=069, Nfrac=062)
-Fch=1806.60 (Fvco=3613.20, Nint=069, Nfrac=063)
-Fch=1806.80 (Fvco=3613.60, Nint=069, Nfrac=064)
-Fch=1807.00 (Fvco=3614.00, Nint=069, Nfrac=065)
-Fch=1807.20 (Fvco=3614.40, Nint=069, Nfrac=066)
-Fch=1807.40 (Fvco=3614.80, Nint=069, Nfrac=067)
-Fch=1807.60 (Fvco=3615.20, Nint=069, Nfrac=068)
-Fch=1807.80 (Fvco=3615.60, Nint=069, Nfrac=069)
-Fch=1808.00 (Fvco=3616.00, Nint=069, Nfrac=070)
-Fch=1808.20 (Fvco=3616.40, Nint=069, Nfrac=071)
-Fch=1808.40 (Fvco=3616.80, Nint=069, Nfrac=072)
-Fch=1808.60 (Fvco=3617.20, Nint=069, Nfrac=073)
-Fch=1808.80 (Fvco=3617.60, Nint=069, Nfrac=074)
-Fch=1809.00 (Fvco=3618.00, Nint=069, Nfrac=075)
-Fch=1809.20 (Fvco=3618.40, Nint=069, Nfrac=076)
-Fch=1809.40 (Fvco=3618.80, Nint=069, Nfrac=077)
-Fch=1809.60 (Fvco=3619.20, Nint=069, Nfrac=078)
-Fch=1809.80 (Fvco=3619.60, Nint=069, Nfrac=079)
-Fch=1810.00 (Fvco=3620.00, Nint=069, Nfrac=080)
-Fch=1810.20 (Fvco=3620.40, Nint=069, Nfrac=081)
-Fch=1810.40 (Fvco=3620.80, Nint=069, Nfrac=082)
-Fch=1810.60 (Fvco=3621.20, Nint=069, Nfrac=083)
-Fch=1810.80 (Fvco=3621.60, Nint=069, Nfrac=084)
-Fch=1811.00 (Fvco=3622.00, Nint=069, Nfrac=085)
-Fch=1811.20 (Fvco=3622.40, Nint=069, Nfrac=086)
-Fch=1811.40 (Fvco=3622.80, Nint=069, Nfrac=087)
-Fch=1811.60 (Fvco=3623.20, Nint=069, Nfrac=088)
-Fch=1811.80 (Fvco=3623.60, Nint=069, Nfrac=089)
-Fch=1812.00 (Fvco=3624.00, Nint=069, Nfrac=090)
-Fch=1812.20 (Fvco=3624.40, Nint=069, Nfrac=091)
-Fch=1812.40 (Fvco=3624.80, Nint=069, Nfrac=092)
-Fch=1812.60 (Fvco=3625.20, Nint=069, Nfrac=093)
-Fch=1812.80 (Fvco=3625.60, Nint=069, Nfrac=094)
-Fch=1813.00 (Fvco=3626.00, Nint=069, Nfrac=095)
-Fch=1813.20 (Fvco=3626.40, Nint=069, Nfrac=096)
-Fch=1813.40 (Fvco=3626.80, Nint=069, Nfrac=097)
-Fch=1813.60 (Fvco=3627.20, Nint=069, Nfrac=098)
-Fch=1813.80 (Fvco=3627.60, Nint=069, Nfrac=099)
-Fch=1814.00 (Fvco=3628.00, Nint=069, Nfrac=100)
-Fch=1814.20 (Fvco=3628.40, Nint=069, Nfrac=101)
-Fch=1814.40 (Fvco=3628.80, Nint=069, Nfrac=102)
-Fch=1814.60 (Fvco=3629.20, Nint=069, Nfrac=103)
-Fch=1814.80 (Fvco=3629.60, Nint=069, Nfrac=104)
-Fch=1815.00 (Fvco=3630.00, Nint=069, Nfrac=105)
-Fch=1815.20 (Fvco=3630.40, Nint=069, Nfrac=106)
-Fch=1815.40 (Fvco=3630.80, Nint=069, Nfrac=107)
-Fch=1815.60 (Fvco=3631.20, Nint=069, Nfrac=108)
-Fch=1815.80 (Fvco=3631.60, Nint=069, Nfrac=109)
-Fch=1816.00 (Fvco=3632.00, Nint=069, Nfrac=110)
-Fch=1816.20 (Fvco=3632.40, Nint=069, Nfrac=111)
-Fch=1816.40 (Fvco=3632.80, Nint=069, Nfrac=112)
-Fch=1816.60 (Fvco=3633.20, Nint=069, Nfrac=113)
-Fch=1816.80 (Fvco=3633.60, Nint=069, Nfrac=114)
-Fch=1817.00 (Fvco=3634.00, Nint=069, Nfrac=115)
-Fch=1817.20 (Fvco=3634.40, Nint=069, Nfrac=116)
-Fch=1817.40 (Fvco=3634.80, Nint=069, Nfrac=117)
-Fch=1817.60 (Fvco=3635.20, Nint=069, Nfrac=118)
-Fch=1817.80 (Fvco=3635.60, Nint=069, Nfrac=119)
-Fch=1818.00 (Fvco=3636.00, Nint=069, Nfrac=120)
-Fch=1818.20 (Fvco=3636.40, Nint=069, Nfrac=121)
-Fch=1818.40 (Fvco=3636.80, Nint=069, Nfrac=122)
-Fch=1818.60 (Fvco=3637.20, Nint=069, Nfrac=123)
-Fch=1818.80 (Fvco=3637.60, Nint=069, Nfrac=124)
-Fch=1819.00 (Fvco=3638.00, Nint=069, Nfrac=125)
-Fch=1819.20 (Fvco=3638.40, Nint=069, Nfrac=126)
-Fch=1819.40 (Fvco=3638.80, Nint=069, Nfrac=127)
-Fch=1819.60 (Fvco=3639.20, Nint=069, Nfrac=128)
-Fch=1819.80 (Fvco=3639.60, Nint=069, Nfrac=129)
-Fch=1820.00 (Fvco=3640.00, Nint=069, Nfrac=130)
-Fch=1820.00 (Fvco=3640.00, Nint=070, Nfrac=000)
-Fch=1820.20 (Fvco=3640.40, Nint=070, Nfrac=001)
-Fch=1820.40 (Fvco=3640.80, Nint=070, Nfrac=002)
-Fch=1820.60 (Fvco=3641.20, Nint=070, Nfrac=003)
-Fch=1820.80 (Fvco=3641.60, Nint=070, Nfrac=004)
-Fch=1821.00 (Fvco=3642.00, Nint=070, Nfrac=005)
-Fch=1821.20 (Fvco=3642.40, Nint=070, Nfrac=006)
-Fch=1821.40 (Fvco=3642.80, Nint=070, Nfrac=007)
-Fch=1821.60 (Fvco=3643.20, Nint=070, Nfrac=008)
-Fch=1821.80 (Fvco=3643.60, Nint=070, Nfrac=009)
-Fch=1822.00 (Fvco=3644.00, Nint=070, Nfrac=010)
-Fch=1822.20 (Fvco=3644.40, Nint=070, Nfrac=011)
-Fch=1822.40 (Fvco=3644.80, Nint=070, Nfrac=012)
-Fch=1822.60 (Fvco=3645.20, Nint=070, Nfrac=013)
-Fch=1822.80 (Fvco=3645.60, Nint=070, Nfrac=014)
-Fch=1823.00 (Fvco=3646.00, Nint=070, Nfrac=015)
-Fch=1823.20 (Fvco=3646.40, Nint=070, Nfrac=016)
-Fch=1823.40 (Fvco=3646.80, Nint=070, Nfrac=017)
-Fch=1823.60 (Fvco=3647.20, Nint=070, Nfrac=018)
-Fch=1823.80 (Fvco=3647.60, Nint=070, Nfrac=019)
-Fch=1824.00 (Fvco=3648.00, Nint=070, Nfrac=020)
-Fch=1824.20 (Fvco=3648.40, Nint=070, Nfrac=021)
-Fch=1824.40 (Fvco=3648.80, Nint=070, Nfrac=022)
-Fch=1824.60 (Fvco=3649.20, Nint=070, Nfrac=023)
-Fch=1824.80 (Fvco=3649.60, Nint=070, Nfrac=024)
-Fch=1825.00 (Fvco=3650.00, Nint=070, Nfrac=025)
-Fch=1825.20 (Fvco=3650.40, Nint=070, Nfrac=026)
-Fch=1825.40 (Fvco=3650.80, Nint=070, Nfrac=027)
-Fch=1825.60 (Fvco=3651.20, Nint=070, Nfrac=028)
-Fch=1825.80 (Fvco=3651.60, Nint=070, Nfrac=029)
-Fch=1826.00 (Fvco=3652.00, Nint=070, Nfrac=030)
-Fch=1826.20 (Fvco=3652.40, Nint=070, Nfrac=031)
-Fch=1826.40 (Fvco=3652.80, Nint=070, Nfrac=032)
-Fch=1826.60 (Fvco=3653.20, Nint=070, Nfrac=033)
-Fch=1826.80 (Fvco=3653.60, Nint=070, Nfrac=034)
-Fch=1827.00 (Fvco=3654.00, Nint=070, Nfrac=035)
-Fch=1827.20 (Fvco=3654.40, Nint=070, Nfrac=036)
-Fch=1827.40 (Fvco=3654.80, Nint=070, Nfrac=037)
-Fch=1827.60 (Fvco=3655.20, Nint=070, Nfrac=038)
-Fch=1827.80 (Fvco=3655.60, Nint=070, Nfrac=039)
-Fch=1828.00 (Fvco=3656.00, Nint=070, Nfrac=040)
-Fch=1828.20 (Fvco=3656.40, Nint=070, Nfrac=041)
-Fch=1828.40 (Fvco=3656.80, Nint=070, Nfrac=042)
-Fch=1828.60 (Fvco=3657.20, Nint=070, Nfrac=043)
-Fch=1828.80 (Fvco=3657.60, Nint=070, Nfrac=044)
-Fch=1829.00 (Fvco=3658.00, Nint=070, Nfrac=045)
-Fch=1829.20 (Fvco=3658.40, Nint=070, Nfrac=046)
-Fch=1829.40 (Fvco=3658.80, Nint=070, Nfrac=047)
-Fch=1829.60 (Fvco=3659.20, Nint=070, Nfrac=048)
-Fch=1829.80 (Fvco=3659.60, Nint=070, Nfrac=049)
-Fch=1830.00 (Fvco=3660.00, Nint=070, Nfrac=050)
-Fch=1830.20 (Fvco=3660.40, Nint=070, Nfrac=051)
-Fch=1830.40 (Fvco=3660.80, Nint=070, Nfrac=052)
-Fch=1830.60 (Fvco=3661.20, Nint=070, Nfrac=053)
-Fch=1830.80 (Fvco=3661.60, Nint=070, Nfrac=054)
-Fch=1831.00 (Fvco=3662.00, Nint=070, Nfrac=055)
-Fch=1831.20 (Fvco=3662.40, Nint=070, Nfrac=056)
-Fch=1831.40 (Fvco=3662.80, Nint=070, Nfrac=057)
-Fch=1831.60 (Fvco=3663.20, Nint=070, Nfrac=058)
-Fch=1831.80 (Fvco=3663.60, Nint=070, Nfrac=059)
-Fch=1832.00 (Fvco=3664.00, Nint=070, Nfrac=060)
-Fch=1832.20 (Fvco=3664.40, Nint=070, Nfrac=061)
-Fch=1832.40 (Fvco=3664.80, Nint=070, Nfrac=062)
-Fch=1832.60 (Fvco=3665.20, Nint=070, Nfrac=063)
-Fch=1832.80 (Fvco=3665.60, Nint=070, Nfrac=064)
-Fch=1833.00 (Fvco=3666.00, Nint=070, Nfrac=065)
-Fch=1833.20 (Fvco=3666.40, Nint=070, Nfrac=066)
-Fch=1833.40 (Fvco=3666.80, Nint=070, Nfrac=067)
-Fch=1833.60 (Fvco=3667.20, Nint=070, Nfrac=068)
-Fch=1833.80 (Fvco=3667.60, Nint=070, Nfrac=069)
-Fch=1834.00 (Fvco=3668.00, Nint=070, Nfrac=070)
-Fch=1834.20 (Fvco=3668.40, Nint=070, Nfrac=071)
-Fch=1834.40 (Fvco=3668.80, Nint=070, Nfrac=072)
-Fch=1834.60 (Fvco=3669.20, Nint=070, Nfrac=073)
-Fch=1834.80 (Fvco=3669.60, Nint=070, Nfrac=074)
-Fch=1835.00 (Fvco=3670.00, Nint=070, Nfrac=075)
-Fch=1835.20 (Fvco=3670.40, Nint=070, Nfrac=076)
-Fch=1835.40 (Fvco=3670.80, Nint=070, Nfrac=077)
-Fch=1835.60 (Fvco=3671.20, Nint=070, Nfrac=078)
-Fch=1835.80 (Fvco=3671.60, Nint=070, Nfrac=079)
-Fch=1836.00 (Fvco=3672.00, Nint=070, Nfrac=080)
-Fch=1836.20 (Fvco=3672.40, Nint=070, Nfrac=081)
-Fch=1836.40 (Fvco=3672.80, Nint=070, Nfrac=082)
-Fch=1836.60 (Fvco=3673.20, Nint=070, Nfrac=083)
-Fch=1836.80 (Fvco=3673.60, Nint=070, Nfrac=084)
-Fch=1837.00 (Fvco=3674.00, Nint=070, Nfrac=085)
-Fch=1837.20 (Fvco=3674.40, Nint=070, Nfrac=086)
-Fch=1837.40 (Fvco=3674.80, Nint=070, Nfrac=087)
-Fch=1837.60 (Fvco=3675.20, Nint=070, Nfrac=088)
-Fch=1837.80 (Fvco=3675.60, Nint=070, Nfrac=089)
-Fch=1838.00 (Fvco=3676.00, Nint=070, Nfrac=090)
-Fch=1838.20 (Fvco=3676.40, Nint=070, Nfrac=091)
-Fch=1838.40 (Fvco=3676.80, Nint=070, Nfrac=092)
-Fch=1838.60 (Fvco=3677.20, Nint=070, Nfrac=093)
-Fch=1838.80 (Fvco=3677.60, Nint=070, Nfrac=094)
-Fch=1839.00 (Fvco=3678.00, Nint=070, Nfrac=095)
-Fch=1839.20 (Fvco=3678.40, Nint=070, Nfrac=096)
-Fch=1839.40 (Fvco=3678.80, Nint=070, Nfrac=097)
-Fch=1839.60 (Fvco=3679.20, Nint=070, Nfrac=098)
-Fch=1839.80 (Fvco=3679.60, Nint=070, Nfrac=099)
-Fch=1840.00 (Fvco=3680.00, Nint=070, Nfrac=100)
-Fch=1840.20 (Fvco=3680.40, Nint=070, Nfrac=101)
-Fch=1840.40 (Fvco=3680.80, Nint=070, Nfrac=102)
-Fch=1840.60 (Fvco=3681.20, Nint=070, Nfrac=103)
-Fch=1840.80 (Fvco=3681.60, Nint=070, Nfrac=104)
-Fch=1841.00 (Fvco=3682.00, Nint=070, Nfrac=105)
-Fch=1841.20 (Fvco=3682.40, Nint=070, Nfrac=106)
-Fch=1841.40 (Fvco=3682.80, Nint=070, Nfrac=107)
-Fch=1841.60 (Fvco=3683.20, Nint=070, Nfrac=108)
-Fch=1841.80 (Fvco=3683.60, Nint=070, Nfrac=109)
-Fch=1842.00 (Fvco=3684.00, Nint=070, Nfrac=110)
-Fch=1842.20 (Fvco=3684.40, Nint=070, Nfrac=111)
-Fch=1842.40 (Fvco=3684.80, Nint=070, Nfrac=112)
-Fch=1842.60 (Fvco=3685.20, Nint=070, Nfrac=113)
-Fch=1842.80 (Fvco=3685.60, Nint=070, Nfrac=114)
-Fch=1843.00 (Fvco=3686.00, Nint=070, Nfrac=115)
-Fch=1843.20 (Fvco=3686.40, Nint=070, Nfrac=116)
-Fch=1843.40 (Fvco=3686.80, Nint=070, Nfrac=117)
-Fch=1843.60 (Fvco=3687.20, Nint=070, Nfrac=118)
-Fch=1843.80 (Fvco=3687.60, Nint=070, Nfrac=119)
-Fch=1844.00 (Fvco=3688.00, Nint=070, Nfrac=120)
-Fch=1844.20 (Fvco=3688.40, Nint=070, Nfrac=121)
-Fch=1844.40 (Fvco=3688.80, Nint=070, Nfrac=122)
-Fch=1844.60 (Fvco=3689.20, Nint=070, Nfrac=123)
-Fch=1844.80 (Fvco=3689.60, Nint=070, Nfrac=124)
-Fch=1845.00 (Fvco=3690.00, Nint=070, Nfrac=125)
-Fch=1845.20 (Fvco=3690.40, Nint=070, Nfrac=126)
-Fch=1845.40 (Fvco=3690.80, Nint=070, Nfrac=127)
-Fch=1845.60 (Fvco=3691.20, Nint=070, Nfrac=128)
-Fch=1845.80 (Fvco=3691.60, Nint=070, Nfrac=129)
-Fch=1846.00 (Fvco=3692.00, Nint=070, Nfrac=130)
-Fch=1846.00 (Fvco=3692.00, Nint=071, Nfrac=000)
-Fch=1846.20 (Fvco=3692.40, Nint=071, Nfrac=001)
-Fch=1846.40 (Fvco=3692.80, Nint=071, Nfrac=002)
-Fch=1846.60 (Fvco=3693.20, Nint=071, Nfrac=003)
-Fch=1846.80 (Fvco=3693.60, Nint=071, Nfrac=004)
-Fch=1847.00 (Fvco=3694.00, Nint=071, Nfrac=005)
-Fch=1847.20 (Fvco=3694.40, Nint=071, Nfrac=006)
-Fch=1847.40 (Fvco=3694.80, Nint=071, Nfrac=007)
-Fch=1847.60 (Fvco=3695.20, Nint=071, Nfrac=008)
-Fch=1847.80 (Fvco=3695.60, Nint=071, Nfrac=009)
-Fch=1848.00 (Fvco=3696.00, Nint=071, Nfrac=010)
-Fch=1848.20 (Fvco=3696.40, Nint=071, Nfrac=011)
-Fch=1848.40 (Fvco=3696.80, Nint=071, Nfrac=012)
-Fch=1848.60 (Fvco=3697.20, Nint=071, Nfrac=013)
-Fch=1848.80 (Fvco=3697.60, Nint=071, Nfrac=014)
-Fch=1849.00 (Fvco=3698.00, Nint=071, Nfrac=015)
-Fch=1849.20 (Fvco=3698.40, Nint=071, Nfrac=016)
-Fch=1849.40 (Fvco=3698.80, Nint=071, Nfrac=017)
-Fch=1849.60 (Fvco=3699.20, Nint=071, Nfrac=018)
-Fch=1849.80 (Fvco=3699.60, Nint=071, Nfrac=019)
-Fch=1850.00 (Fvco=3700.00, Nint=071, Nfrac=020)
-Fch=1850.20 (Fvco=3700.40, Nint=071, Nfrac=021)
-Fch=1850.40 (Fvco=3700.80, Nint=071, Nfrac=022)
-Fch=1850.60 (Fvco=3701.20, Nint=071, Nfrac=023)
-Fch=1850.80 (Fvco=3701.60, Nint=071, Nfrac=024)
-Fch=1851.00 (Fvco=3702.00, Nint=071, Nfrac=025)
-Fch=1851.20 (Fvco=3702.40, Nint=071, Nfrac=026)
-Fch=1851.40 (Fvco=3702.80, Nint=071, Nfrac=027)
-Fch=1851.60 (Fvco=3703.20, Nint=071, Nfrac=028)
-Fch=1851.80 (Fvco=3703.60, Nint=071, Nfrac=029)
-Fch=1852.00 (Fvco=3704.00, Nint=071, Nfrac=030)
-Fch=1852.20 (Fvco=3704.40, Nint=071, Nfrac=031)
-Fch=1852.40 (Fvco=3704.80, Nint=071, Nfrac=032)
-Fch=1852.60 (Fvco=3705.20, Nint=071, Nfrac=033)
-Fch=1852.80 (Fvco=3705.60, Nint=071, Nfrac=034)
-Fch=1853.00 (Fvco=3706.00, Nint=071, Nfrac=035)
-Fch=1853.20 (Fvco=3706.40, Nint=071, Nfrac=036)
-Fch=1853.40 (Fvco=3706.80, Nint=071, Nfrac=037)
-Fch=1853.60 (Fvco=3707.20, Nint=071, Nfrac=038)
-Fch=1853.80 (Fvco=3707.60, Nint=071, Nfrac=039)
-Fch=1854.00 (Fvco=3708.00, Nint=071, Nfrac=040)
-Fch=1854.20 (Fvco=3708.40, Nint=071, Nfrac=041)
-Fch=1854.40 (Fvco=3708.80, Nint=071, Nfrac=042)
-Fch=1854.60 (Fvco=3709.20, Nint=071, Nfrac=043)
-Fch=1854.80 (Fvco=3709.60, Nint=071, Nfrac=044)
-Fch=1855.00 (Fvco=3710.00, Nint=071, Nfrac=045)
-Fch=1855.20 (Fvco=3710.40, Nint=071, Nfrac=046)
-Fch=1855.40 (Fvco=3710.80, Nint=071, Nfrac=047)
-Fch=1855.60 (Fvco=3711.20, Nint=071, Nfrac=048)
-Fch=1855.80 (Fvco=3711.60, Nint=071, Nfrac=049)
-Fch=1856.00 (Fvco=3712.00, Nint=071, Nfrac=050)
-Fch=1856.20 (Fvco=3712.40, Nint=071, Nfrac=051)
-Fch=1856.40 (Fvco=3712.80, Nint=071, Nfrac=052)
-Fch=1856.60 (Fvco=3713.20, Nint=071, Nfrac=053)
-Fch=1856.80 (Fvco=3713.60, Nint=071, Nfrac=054)
-Fch=1857.00 (Fvco=3714.00, Nint=071, Nfrac=055)
-Fch=1857.20 (Fvco=3714.40, Nint=071, Nfrac=056)
-Fch=1857.40 (Fvco=3714.80, Nint=071, Nfrac=057)
-Fch=1857.60 (Fvco=3715.20, Nint=071, Nfrac=058)
-Fch=1857.80 (Fvco=3715.60, Nint=071, Nfrac=059)
-Fch=1858.00 (Fvco=3716.00, Nint=071, Nfrac=060)
-Fch=1858.20 (Fvco=3716.40, Nint=071, Nfrac=061)
-Fch=1858.40 (Fvco=3716.80, Nint=071, Nfrac=062)
-Fch=1858.60 (Fvco=3717.20, Nint=071, Nfrac=063)
-Fch=1858.80 (Fvco=3717.60, Nint=071, Nfrac=064)
-Fch=1859.00 (Fvco=3718.00, Nint=071, Nfrac=065)
-Fch=1859.20 (Fvco=3718.40, Nint=071, Nfrac=066)
-Fch=1859.40 (Fvco=3718.80, Nint=071, Nfrac=067)
-Fch=1859.60 (Fvco=3719.20, Nint=071, Nfrac=068)
-Fch=1859.80 (Fvco=3719.60, Nint=071, Nfrac=069)
-Fch=1860.00 (Fvco=3720.00, Nint=071, Nfrac=070)
-Fch=1860.20 (Fvco=3720.40, Nint=071, Nfrac=071)
-Fch=1860.40 (Fvco=3720.80, Nint=071, Nfrac=072)
-Fch=1860.60 (Fvco=3721.20, Nint=071, Nfrac=073)
-Fch=1860.80 (Fvco=3721.60, Nint=071, Nfrac=074)
-Fch=1861.00 (Fvco=3722.00, Nint=071, Nfrac=075)
-Fch=1861.20 (Fvco=3722.40, Nint=071, Nfrac=076)
-Fch=1861.40 (Fvco=3722.80, Nint=071, Nfrac=077)
-Fch=1861.60 (Fvco=3723.20, Nint=071, Nfrac=078)
-Fch=1861.80 (Fvco=3723.60, Nint=071, Nfrac=079)
-Fch=1862.00 (Fvco=3724.00, Nint=071, Nfrac=080)
-Fch=1862.20 (Fvco=3724.40, Nint=071, Nfrac=081)
-Fch=1862.40 (Fvco=3724.80, Nint=071, Nfrac=082)
-Fch=1862.60 (Fvco=3725.20, Nint=071, Nfrac=083)
-Fch=1862.80 (Fvco=3725.60, Nint=071, Nfrac=084)
-Fch=1863.00 (Fvco=3726.00, Nint=071, Nfrac=085)
-Fch=1863.20 (Fvco=3726.40, Nint=071, Nfrac=086)
-Fch=1863.40 (Fvco=3726.80, Nint=071, Nfrac=087)
-Fch=1863.60 (Fvco=3727.20, Nint=071, Nfrac=088)
-Fch=1863.80 (Fvco=3727.60, Nint=071, Nfrac=089)
-Fch=1864.00 (Fvco=3728.00, Nint=071, Nfrac=090)
-Fch=1864.20 (Fvco=3728.40, Nint=071, Nfrac=091)
-Fch=1864.40 (Fvco=3728.80, Nint=071, Nfrac=092)
-Fch=1864.60 (Fvco=3729.20, Nint=071, Nfrac=093)
-Fch=1864.80 (Fvco=3729.60, Nint=071, Nfrac=094)
-Fch=1865.00 (Fvco=3730.00, Nint=071, Nfrac=095)
-Fch=1865.20 (Fvco=3730.40, Nint=071, Nfrac=096)
-Fch=1865.40 (Fvco=3730.80, Nint=071, Nfrac=097)
-Fch=1865.60 (Fvco=3731.20, Nint=071, Nfrac=098)
-Fch=1865.80 (Fvco=3731.60, Nint=071, Nfrac=099)
-Fch=1866.00 (Fvco=3732.00, Nint=071, Nfrac=100)
-Fch=1866.20 (Fvco=3732.40, Nint=071, Nfrac=101)
-Fch=1866.40 (Fvco=3732.80, Nint=071, Nfrac=102)
-Fch=1866.60 (Fvco=3733.20, Nint=071, Nfrac=103)
-Fch=1866.80 (Fvco=3733.60, Nint=071, Nfrac=104)
-Fch=1867.00 (Fvco=3734.00, Nint=071, Nfrac=105)
-Fch=1867.20 (Fvco=3734.40, Nint=071, Nfrac=106)
-Fch=1867.40 (Fvco=3734.80, Nint=071, Nfrac=107)
-Fch=1867.60 (Fvco=3735.20, Nint=071, Nfrac=108)
-Fch=1867.80 (Fvco=3735.60, Nint=071, Nfrac=109)
-Fch=1868.00 (Fvco=3736.00, Nint=071, Nfrac=110)
-Fch=1868.20 (Fvco=3736.40, Nint=071, Nfrac=111)
-Fch=1868.40 (Fvco=3736.80, Nint=071, Nfrac=112)
-Fch=1868.60 (Fvco=3737.20, Nint=071, Nfrac=113)
-Fch=1868.80 (Fvco=3737.60, Nint=071, Nfrac=114)
-Fch=1869.00 (Fvco=3738.00, Nint=071, Nfrac=115)
-Fch=1869.20 (Fvco=3738.40, Nint=071, Nfrac=116)
-Fch=1869.40 (Fvco=3738.80, Nint=071, Nfrac=117)
-Fch=1869.60 (Fvco=3739.20, Nint=071, Nfrac=118)
-Fch=1869.80 (Fvco=3739.60, Nint=071, Nfrac=119)
-Fch=1870.00 (Fvco=3740.00, Nint=071, Nfrac=120)
-Fch=1870.20 (Fvco=3740.40, Nint=071, Nfrac=121)
-Fch=1870.40 (Fvco=3740.80, Nint=071, Nfrac=122)
-Fch=1870.60 (Fvco=3741.20, Nint=071, Nfrac=123)
-Fch=1870.80 (Fvco=3741.60, Nint=071, Nfrac=124)
-Fch=1871.00 (Fvco=3742.00, Nint=071, Nfrac=125)
-Fch=1871.20 (Fvco=3742.40, Nint=071, Nfrac=126)
-Fch=1871.40 (Fvco=3742.80, Nint=071, Nfrac=127)
-Fch=1871.60 (Fvco=3743.20, Nint=071, Nfrac=128)
-Fch=1871.80 (Fvco=3743.60, Nint=071, Nfrac=129)
-Fch=1872.00 (Fvco=3744.00, Nint=071, Nfrac=130)
-Fch=1872.00 (Fvco=3744.00, Nint=072, Nfrac=000)
-Fch=1872.20 (Fvco=3744.40, Nint=072, Nfrac=001)
-Fch=1872.40 (Fvco=3744.80, Nint=072, Nfrac=002)
-Fch=1872.60 (Fvco=3745.20, Nint=072, Nfrac=003)
-Fch=1872.80 (Fvco=3745.60, Nint=072, Nfrac=004)
-Fch=1873.00 (Fvco=3746.00, Nint=072, Nfrac=005)
-Fch=1873.20 (Fvco=3746.40, Nint=072, Nfrac=006)
-Fch=1873.40 (Fvco=3746.80, Nint=072, Nfrac=007)
-Fch=1873.60 (Fvco=3747.20, Nint=072, Nfrac=008)
-Fch=1873.80 (Fvco=3747.60, Nint=072, Nfrac=009)
-Fch=1874.00 (Fvco=3748.00, Nint=072, Nfrac=010)
-Fch=1874.20 (Fvco=3748.40, Nint=072, Nfrac=011)
-Fch=1874.40 (Fvco=3748.80, Nint=072, Nfrac=012)
-Fch=1874.60 (Fvco=3749.20, Nint=072, Nfrac=013)
-Fch=1874.80 (Fvco=3749.60, Nint=072, Nfrac=014)
-Fch=1875.00 (Fvco=3750.00, Nint=072, Nfrac=015)
-Fch=1875.20 (Fvco=3750.40, Nint=072, Nfrac=016)
-Fch=1875.40 (Fvco=3750.80, Nint=072, Nfrac=017)
-Fch=1875.60 (Fvco=3751.20, Nint=072, Nfrac=018)
-Fch=1875.80 (Fvco=3751.60, Nint=072, Nfrac=019)
-Fch=1876.00 (Fvco=3752.00, Nint=072, Nfrac=020)
-Fch=1876.20 (Fvco=3752.40, Nint=072, Nfrac=021)
-Fch=1876.40 (Fvco=3752.80, Nint=072, Nfrac=022)
-Fch=1876.60 (Fvco=3753.20, Nint=072, Nfrac=023)
-Fch=1876.80 (Fvco=3753.60, Nint=072, Nfrac=024)
-Fch=1877.00 (Fvco=3754.00, Nint=072, Nfrac=025)
-Fch=1877.20 (Fvco=3754.40, Nint=072, Nfrac=026)
-Fch=1877.40 (Fvco=3754.80, Nint=072, Nfrac=027)
-Fch=1877.60 (Fvco=3755.20, Nint=072, Nfrac=028)
-Fch=1877.80 (Fvco=3755.60, Nint=072, Nfrac=029)
-Fch=1878.00 (Fvco=3756.00, Nint=072, Nfrac=030)
-Fch=1878.20 (Fvco=3756.40, Nint=072, Nfrac=031)
-Fch=1878.40 (Fvco=3756.80, Nint=072, Nfrac=032)
-Fch=1878.60 (Fvco=3757.20, Nint=072, Nfrac=033)
-Fch=1878.80 (Fvco=3757.60, Nint=072, Nfrac=034)
-Fch=1879.00 (Fvco=3758.00, Nint=072, Nfrac=035)
-Fch=1879.20 (Fvco=3758.40, Nint=072, Nfrac=036)
-Fch=1879.40 (Fvco=3758.80, Nint=072, Nfrac=037)
-Fch=1879.60 (Fvco=3759.20, Nint=072, Nfrac=038)
-Fch=1879.80 (Fvco=3759.60, Nint=072, Nfrac=039)
-Fch=1880.00 (Fvco=3760.00, Nint=072, Nfrac=040)
-Fch=1880.20 (Fvco=3760.40, Nint=072, Nfrac=041)
-Fch=1880.40 (Fvco=3760.80, Nint=072, Nfrac=042)
-Fch=1880.60 (Fvco=3761.20, Nint=072, Nfrac=043)
-Fch=1880.80 (Fvco=3761.60, Nint=072, Nfrac=044)
-Fch=1881.00 (Fvco=3762.00, Nint=072, Nfrac=045)
-Fch=1881.20 (Fvco=3762.40, Nint=072, Nfrac=046)
-Fch=1881.40 (Fvco=3762.80, Nint=072, Nfrac=047)
-Fch=1881.60 (Fvco=3763.20, Nint=072, Nfrac=048)
-Fch=1881.80 (Fvco=3763.60, Nint=072, Nfrac=049)
-Fch=1882.00 (Fvco=3764.00, Nint=072, Nfrac=050)
-Fch=1882.20 (Fvco=3764.40, Nint=072, Nfrac=051)
-Fch=1882.40 (Fvco=3764.80, Nint=072, Nfrac=052)
-Fch=1882.60 (Fvco=3765.20, Nint=072, Nfrac=053)
-Fch=1882.80 (Fvco=3765.60, Nint=072, Nfrac=054)
-Fch=1883.00 (Fvco=3766.00, Nint=072, Nfrac=055)
-Fch=1883.20 (Fvco=3766.40, Nint=072, Nfrac=056)
-Fch=1883.40 (Fvco=3766.80, Nint=072, Nfrac=057)
-Fch=1883.60 (Fvco=3767.20, Nint=072, Nfrac=058)
-Fch=1883.80 (Fvco=3767.60, Nint=072, Nfrac=059)
-Fch=1884.00 (Fvco=3768.00, Nint=072, Nfrac=060)
-Fch=1884.20 (Fvco=3768.40, Nint=072, Nfrac=061)
-Fch=1884.40 (Fvco=3768.80, Nint=072, Nfrac=062)
-Fch=1884.60 (Fvco=3769.20, Nint=072, Nfrac=063)
-Fch=1884.80 (Fvco=3769.60, Nint=072, Nfrac=064)
-Fch=1885.00 (Fvco=3770.00, Nint=072, Nfrac=065)
-Fch=1885.20 (Fvco=3770.40, Nint=072, Nfrac=066)
-Fch=1885.40 (Fvco=3770.80, Nint=072, Nfrac=067)
-Fch=1885.60 (Fvco=3771.20, Nint=072, Nfrac=068)
-Fch=1885.80 (Fvco=3771.60, Nint=072, Nfrac=069)
-Fch=1886.00 (Fvco=3772.00, Nint=072, Nfrac=070)
-Fch=1886.20 (Fvco=3772.40, Nint=072, Nfrac=071)
-Fch=1886.40 (Fvco=3772.80, Nint=072, Nfrac=072)
-Fch=1886.60 (Fvco=3773.20, Nint=072, Nfrac=073)
-Fch=1886.80 (Fvco=3773.60, Nint=072, Nfrac=074)
-Fch=1887.00 (Fvco=3774.00, Nint=072, Nfrac=075)
-Fch=1887.20 (Fvco=3774.40, Nint=072, Nfrac=076)
-Fch=1887.40 (Fvco=3774.80, Nint=072, Nfrac=077)
-Fch=1887.60 (Fvco=3775.20, Nint=072, Nfrac=078)
-Fch=1887.80 (Fvco=3775.60, Nint=072, Nfrac=079)
-Fch=1888.00 (Fvco=3776.00, Nint=072, Nfrac=080)
-Fch=1888.20 (Fvco=3776.40, Nint=072, Nfrac=081)
-Fch=1888.40 (Fvco=3776.80, Nint=072, Nfrac=082)
-Fch=1888.60 (Fvco=3777.20, Nint=072, Nfrac=083)
-Fch=1888.80 (Fvco=3777.60, Nint=072, Nfrac=084)
-Fch=1889.00 (Fvco=3778.00, Nint=072, Nfrac=085)
-Fch=1889.20 (Fvco=3778.40, Nint=072, Nfrac=086)
-Fch=1889.40 (Fvco=3778.80, Nint=072, Nfrac=087)
-Fch=1889.60 (Fvco=3779.20, Nint=072, Nfrac=088)
-Fch=1889.80 (Fvco=3779.60, Nint=072, Nfrac=089)
-Fch=1890.00 (Fvco=3780.00, Nint=072, Nfrac=090)
-Fch=1890.20 (Fvco=3780.40, Nint=072, Nfrac=091)
-Fch=1890.40 (Fvco=3780.80, Nint=072, Nfrac=092)
-Fch=1890.60 (Fvco=3781.20, Nint=072, Nfrac=093)
-Fch=1890.80 (Fvco=3781.60, Nint=072, Nfrac=094)
-Fch=1891.00 (Fvco=3782.00, Nint=072, Nfrac=095)
-Fch=1891.20 (Fvco=3782.40, Nint=072, Nfrac=096)
-Fch=1891.40 (Fvco=3782.80, Nint=072, Nfrac=097)
-Fch=1891.60 (Fvco=3783.20, Nint=072, Nfrac=098)
-Fch=1891.80 (Fvco=3783.60, Nint=072, Nfrac=099)
-Fch=1892.00 (Fvco=3784.00, Nint=072, Nfrac=100)
-Fch=1892.20 (Fvco=3784.40, Nint=072, Nfrac=101)
-Fch=1892.40 (Fvco=3784.80, Nint=072, Nfrac=102)
-Fch=1892.60 (Fvco=3785.20, Nint=072, Nfrac=103)
-Fch=1892.80 (Fvco=3785.60, Nint=072, Nfrac=104)
-Fch=1893.00 (Fvco=3786.00, Nint=072, Nfrac=105)
-Fch=1893.20 (Fvco=3786.40, Nint=072, Nfrac=106)
-Fch=1893.40 (Fvco=3786.80, Nint=072, Nfrac=107)
-Fch=1893.60 (Fvco=3787.20, Nint=072, Nfrac=108)
-Fch=1893.80 (Fvco=3787.60, Nint=072, Nfrac=109)
-Fch=1894.00 (Fvco=3788.00, Nint=072, Nfrac=110)
-Fch=1894.20 (Fvco=3788.40, Nint=072, Nfrac=111)
-Fch=1894.40 (Fvco=3788.80, Nint=072, Nfrac=112)
-Fch=1894.60 (Fvco=3789.20, Nint=072, Nfrac=113)
-Fch=1894.80 (Fvco=3789.60, Nint=072, Nfrac=114)
-Fch=1895.00 (Fvco=3790.00, Nint=072, Nfrac=115)
-Fch=1895.20 (Fvco=3790.40, Nint=072, Nfrac=116)
-Fch=1895.40 (Fvco=3790.80, Nint=072, Nfrac=117)
-Fch=1895.60 (Fvco=3791.20, Nint=072, Nfrac=118)
-Fch=1895.80 (Fvco=3791.60, Nint=072, Nfrac=119)
-Fch=1896.00 (Fvco=3792.00, Nint=072, Nfrac=120)
-Fch=1896.20 (Fvco=3792.40, Nint=072, Nfrac=121)
-Fch=1896.40 (Fvco=3792.80, Nint=072, Nfrac=122)
-Fch=1896.60 (Fvco=3793.20, Nint=072, Nfrac=123)
-Fch=1896.80 (Fvco=3793.60, Nint=072, Nfrac=124)
-Fch=1897.00 (Fvco=3794.00, Nint=072, Nfrac=125)
-Fch=1897.20 (Fvco=3794.40, Nint=072, Nfrac=126)
-Fch=1897.40 (Fvco=3794.80, Nint=072, Nfrac=127)
-Fch=1897.60 (Fvco=3795.20, Nint=072, Nfrac=128)
-Fch=1897.80 (Fvco=3795.60, Nint=072, Nfrac=129)
-Fch=1898.00 (Fvco=3796.00, Nint=072, Nfrac=130)
-Fch=1898.00 (Fvco=3796.00, Nint=073, Nfrac=000)
-Fch=1898.20 (Fvco=3796.40, Nint=073, Nfrac=001)
-Fch=1898.40 (Fvco=3796.80, Nint=073, Nfrac=002)
-Fch=1898.60 (Fvco=3797.20, Nint=073, Nfrac=003)
-Fch=1898.80 (Fvco=3797.60, Nint=073, Nfrac=004)
-Fch=1899.00 (Fvco=3798.00, Nint=073, Nfrac=005)
-Fch=1899.20 (Fvco=3798.40, Nint=073, Nfrac=006)
-Fch=1899.40 (Fvco=3798.80, Nint=073, Nfrac=007)
-Fch=1899.60 (Fvco=3799.20, Nint=073, Nfrac=008)
-Fch=1899.80 (Fvco=3799.60, Nint=073, Nfrac=009)
-Fch=1900.00 (Fvco=3800.00, Nint=073, Nfrac=010)
-Fch=1900.20 (Fvco=3800.40, Nint=073, Nfrac=011)
-Fch=1900.40 (Fvco=3800.80, Nint=073, Nfrac=012)
-Fch=1900.60 (Fvco=3801.20, Nint=073, Nfrac=013)
-Fch=1900.80 (Fvco=3801.60, Nint=073, Nfrac=014)
-Fch=1901.00 (Fvco=3802.00, Nint=073, Nfrac=015)
-Fch=1901.20 (Fvco=3802.40, Nint=073, Nfrac=016)
-Fch=1901.40 (Fvco=3802.80, Nint=073, Nfrac=017)
-Fch=1901.60 (Fvco=3803.20, Nint=073, Nfrac=018)
-Fch=1901.80 (Fvco=3803.60, Nint=073, Nfrac=019)
-Fch=1902.00 (Fvco=3804.00, Nint=073, Nfrac=020)
-Fch=1902.20 (Fvco=3804.40, Nint=073, Nfrac=021)
-Fch=1902.40 (Fvco=3804.80, Nint=073, Nfrac=022)
-Fch=1902.60 (Fvco=3805.20, Nint=073, Nfrac=023)
-Fch=1902.80 (Fvco=3805.60, Nint=073, Nfrac=024)
-Fch=1903.00 (Fvco=3806.00, Nint=073, Nfrac=025)
-Fch=1903.20 (Fvco=3806.40, Nint=073, Nfrac=026)
-Fch=1903.40 (Fvco=3806.80, Nint=073, Nfrac=027)
-Fch=1903.60 (Fvco=3807.20, Nint=073, Nfrac=028)
-Fch=1903.80 (Fvco=3807.60, Nint=073, Nfrac=029)
-Fch=1904.00 (Fvco=3808.00, Nint=073, Nfrac=030)
-Fch=1904.20 (Fvco=3808.40, Nint=073, Nfrac=031)
-Fch=1904.40 (Fvco=3808.80, Nint=073, Nfrac=032)
-Fch=1904.60 (Fvco=3809.20, Nint=073, Nfrac=033)
-Fch=1904.80 (Fvco=3809.60, Nint=073, Nfrac=034)
-Fch=1905.00 (Fvco=3810.00, Nint=073, Nfrac=035)
-Fch=1905.20 (Fvco=3810.40, Nint=073, Nfrac=036)
-Fch=1905.40 (Fvco=3810.80, Nint=073, Nfrac=037)
-Fch=1905.60 (Fvco=3811.20, Nint=073, Nfrac=038)
-Fch=1905.80 (Fvco=3811.60, Nint=073, Nfrac=039)
-Fch=1906.00 (Fvco=3812.00, Nint=073, Nfrac=040)
-Fch=1906.20 (Fvco=3812.40, Nint=073, Nfrac=041)
-Fch=1906.40 (Fvco=3812.80, Nint=073, Nfrac=042)
-Fch=1906.60 (Fvco=3813.20, Nint=073, Nfrac=043)
-Fch=1906.80 (Fvco=3813.60, Nint=073, Nfrac=044)
-Fch=1907.00 (Fvco=3814.00, Nint=073, Nfrac=045)
-Fch=1907.20 (Fvco=3814.40, Nint=073, Nfrac=046)
-Fch=1907.40 (Fvco=3814.80, Nint=073, Nfrac=047)
-Fch=1907.60 (Fvco=3815.20, Nint=073, Nfrac=048)
-Fch=1907.80 (Fvco=3815.60, Nint=073, Nfrac=049)
-Fch=1908.00 (Fvco=3816.00, Nint=073, Nfrac=050)
-Fch=1908.20 (Fvco=3816.40, Nint=073, Nfrac=051)
-Fch=1908.40 (Fvco=3816.80, Nint=073, Nfrac=052)
-Fch=1908.60 (Fvco=3817.20, Nint=073, Nfrac=053)
-Fch=1908.80 (Fvco=3817.60, Nint=073, Nfrac=054)
-Fch=1909.00 (Fvco=3818.00, Nint=073, Nfrac=055)
-Fch=1909.20 (Fvco=3818.40, Nint=073, Nfrac=056)
-Fch=1909.40 (Fvco=3818.80, Nint=073, Nfrac=057)
-Fch=1909.60 (Fvco=3819.20, Nint=073, Nfrac=058)
-Fch=1909.80 (Fvco=3819.60, Nint=073, Nfrac=059)
-Fch=1910.00 (Fvco=3820.00, Nint=073, Nfrac=060)
-Fch=1910.20 (Fvco=3820.40, Nint=073, Nfrac=061)
-Fch=1910.40 (Fvco=3820.80, Nint=073, Nfrac=062)
-Fch=1910.60 (Fvco=3821.20, Nint=073, Nfrac=063)
-Fch=1910.80 (Fvco=3821.60, Nint=073, Nfrac=064)
-Fch=1911.00 (Fvco=3822.00, Nint=073, Nfrac=065)
-Fch=1911.20 (Fvco=3822.40, Nint=073, Nfrac=066)
-Fch=1911.40 (Fvco=3822.80, Nint=073, Nfrac=067)
-Fch=1911.60 (Fvco=3823.20, Nint=073, Nfrac=068)
-Fch=1911.80 (Fvco=3823.60, Nint=073, Nfrac=069)
-Fch=1912.00 (Fvco=3824.00, Nint=073, Nfrac=070)
-Fch=1912.20 (Fvco=3824.40, Nint=073, Nfrac=071)
-Fch=1912.40 (Fvco=3824.80, Nint=073, Nfrac=072)
-Fch=1912.60 (Fvco=3825.20, Nint=073, Nfrac=073)
-Fch=1912.80 (Fvco=3825.60, Nint=073, Nfrac=074)
-Fch=1913.00 (Fvco=3826.00, Nint=073, Nfrac=075)
-Fch=1913.20 (Fvco=3826.40, Nint=073, Nfrac=076)
-Fch=1913.40 (Fvco=3826.80, Nint=073, Nfrac=077)
-Fch=1913.60 (Fvco=3827.20, Nint=073, Nfrac=078)
-Fch=1913.80 (Fvco=3827.60, Nint=073, Nfrac=079)
-Fch=1914.00 (Fvco=3828.00, Nint=073, Nfrac=080)
-Fch=1914.20 (Fvco=3828.40, Nint=073, Nfrac=081)
-Fch=1914.40 (Fvco=3828.80, Nint=073, Nfrac=082)
-Fch=1914.60 (Fvco=3829.20, Nint=073, Nfrac=083)
-Fch=1914.80 (Fvco=3829.60, Nint=073, Nfrac=084)
-Fch=1915.00 (Fvco=3830.00, Nint=073, Nfrac=085)
-Fch=1915.20 (Fvco=3830.40, Nint=073, Nfrac=086)
-Fch=1915.40 (Fvco=3830.80, Nint=073, Nfrac=087)
-Fch=1915.60 (Fvco=3831.20, Nint=073, Nfrac=088)
-Fch=1915.80 (Fvco=3831.60, Nint=073, Nfrac=089)
-Fch=1916.00 (Fvco=3832.00, Nint=073, Nfrac=090)
-Fch=1916.20 (Fvco=3832.40, Nint=073, Nfrac=091)
-Fch=1916.40 (Fvco=3832.80, Nint=073, Nfrac=092)
-Fch=1916.60 (Fvco=3833.20, Nint=073, Nfrac=093)
-Fch=1916.80 (Fvco=3833.60, Nint=073, Nfrac=094)
-Fch=1917.00 (Fvco=3834.00, Nint=073, Nfrac=095)
-Fch=1917.20 (Fvco=3834.40, Nint=073, Nfrac=096)
-Fch=1917.40 (Fvco=3834.80, Nint=073, Nfrac=097)
-Fch=1917.60 (Fvco=3835.20, Nint=073, Nfrac=098)
-Fch=1917.80 (Fvco=3835.60, Nint=073, Nfrac=099)
-Fch=1918.00 (Fvco=3836.00, Nint=073, Nfrac=100)
-Fch=1918.20 (Fvco=3836.40, Nint=073, Nfrac=101)
-Fch=1918.40 (Fvco=3836.80, Nint=073, Nfrac=102)
-Fch=1918.60 (Fvco=3837.20, Nint=073, Nfrac=103)
-Fch=1918.80 (Fvco=3837.60, Nint=073, Nfrac=104)
-Fch=1919.00 (Fvco=3838.00, Nint=073, Nfrac=105)
-Fch=1919.20 (Fvco=3838.40, Nint=073, Nfrac=106)
-Fch=1919.40 (Fvco=3838.80, Nint=073, Nfrac=107)
-Fch=1919.60 (Fvco=3839.20, Nint=073, Nfrac=108)
-Fch=1919.80 (Fvco=3839.60, Nint=073, Nfrac=109)
-Fch=1920.00 (Fvco=3840.00, Nint=073, Nfrac=110)
-Fch=1920.20 (Fvco=3840.40, Nint=073, Nfrac=111)
-Fch=1920.40 (Fvco=3840.80, Nint=073, Nfrac=112)
-Fch=1920.60 (Fvco=3841.20, Nint=073, Nfrac=113)
-Fch=1920.80 (Fvco=3841.60, Nint=073, Nfrac=114)
-Fch=1921.00 (Fvco=3842.00, Nint=073, Nfrac=115)
-Fch=1921.20 (Fvco=3842.40, Nint=073, Nfrac=116)
-Fch=1921.40 (Fvco=3842.80, Nint=073, Nfrac=117)
-Fch=1921.60 (Fvco=3843.20, Nint=073, Nfrac=118)
-Fch=1921.80 (Fvco=3843.60, Nint=073, Nfrac=119)
-Fch=1922.00 (Fvco=3844.00, Nint=073, Nfrac=120)
-Fch=1922.20 (Fvco=3844.40, Nint=073, Nfrac=121)
-Fch=1922.40 (Fvco=3844.80, Nint=073, Nfrac=122)
-Fch=1922.60 (Fvco=3845.20, Nint=073, Nfrac=123)
-Fch=1922.80 (Fvco=3845.60, Nint=073, Nfrac=124)
-Fch=1923.00 (Fvco=3846.00, Nint=073, Nfrac=125)
-Fch=1923.20 (Fvco=3846.40, Nint=073, Nfrac=126)
-Fch=1923.40 (Fvco=3846.80, Nint=073, Nfrac=127)
-Fch=1923.60 (Fvco=3847.20, Nint=073, Nfrac=128)
-Fch=1923.80 (Fvco=3847.60, Nint=073, Nfrac=129)
-Fch=1924.00 (Fvco=3848.00, Nint=073, Nfrac=130)
-Fch=1924.00 (Fvco=3848.00, Nint=074, Nfrac=000)
-Fch=1924.20 (Fvco=3848.40, Nint=074, Nfrac=001)
-Fch=1924.40 (Fvco=3848.80, Nint=074, Nfrac=002)
-Fch=1924.60 (Fvco=3849.20, Nint=074, Nfrac=003)
-Fch=1924.80 (Fvco=3849.60, Nint=074, Nfrac=004)
-Fch=1925.00 (Fvco=3850.00, Nint=074, Nfrac=005)
-Fch=1925.20 (Fvco=3850.40, Nint=074, Nfrac=006)
-Fch=1925.40 (Fvco=3850.80, Nint=074, Nfrac=007)
-Fch=1925.60 (Fvco=3851.20, Nint=074, Nfrac=008)
-Fch=1925.80 (Fvco=3851.60, Nint=074, Nfrac=009)
-Fch=1926.00 (Fvco=3852.00, Nint=074, Nfrac=010)
-Fch=1926.20 (Fvco=3852.40, Nint=074, Nfrac=011)
-Fch=1926.40 (Fvco=3852.80, Nint=074, Nfrac=012)
-Fch=1926.60 (Fvco=3853.20, Nint=074, Nfrac=013)
-Fch=1926.80 (Fvco=3853.60, Nint=074, Nfrac=014)
-Fch=1927.00 (Fvco=3854.00, Nint=074, Nfrac=015)
-Fch=1927.20 (Fvco=3854.40, Nint=074, Nfrac=016)
-Fch=1927.40 (Fvco=3854.80, Nint=074, Nfrac=017)
-Fch=1927.60 (Fvco=3855.20, Nint=074, Nfrac=018)
-Fch=1927.80 (Fvco=3855.60, Nint=074, Nfrac=019)
-Fch=1928.00 (Fvco=3856.00, Nint=074, Nfrac=020)
-Fch=1928.20 (Fvco=3856.40, Nint=074, Nfrac=021)
-Fch=1928.40 (Fvco=3856.80, Nint=074, Nfrac=022)
-Fch=1928.60 (Fvco=3857.20, Nint=074, Nfrac=023)
-Fch=1928.80 (Fvco=3857.60, Nint=074, Nfrac=024)
-Fch=1929.00 (Fvco=3858.00, Nint=074, Nfrac=025)
-Fch=1929.20 (Fvco=3858.40, Nint=074, Nfrac=026)
-Fch=1929.40 (Fvco=3858.80, Nint=074, Nfrac=027)
-Fch=1929.60 (Fvco=3859.20, Nint=074, Nfrac=028)
-Fch=1929.80 (Fvco=3859.60, Nint=074, Nfrac=029)
-Fch=1930.00 (Fvco=3860.00, Nint=074, Nfrac=030)
-Fch=1930.20 (Fvco=3860.40, Nint=074, Nfrac=031)
-Fch=1930.40 (Fvco=3860.80, Nint=074, Nfrac=032)
-Fch=1930.60 (Fvco=3861.20, Nint=074, Nfrac=033)
-Fch=1930.80 (Fvco=3861.60, Nint=074, Nfrac=034)
-Fch=1931.00 (Fvco=3862.00, Nint=074, Nfrac=035)
-Fch=1931.20 (Fvco=3862.40, Nint=074, Nfrac=036)
-Fch=1931.40 (Fvco=3862.80, Nint=074, Nfrac=037)
-Fch=1931.60 (Fvco=3863.20, Nint=074, Nfrac=038)
-Fch=1931.80 (Fvco=3863.60, Nint=074, Nfrac=039)
-Fch=1932.00 (Fvco=3864.00, Nint=074, Nfrac=040)
-Fch=1932.20 (Fvco=3864.40, Nint=074, Nfrac=041)
-Fch=1932.40 (Fvco=3864.80, Nint=074, Nfrac=042)
-Fch=1932.60 (Fvco=3865.20, Nint=074, Nfrac=043)
-Fch=1932.80 (Fvco=3865.60, Nint=074, Nfrac=044)
-Fch=1933.00 (Fvco=3866.00, Nint=074, Nfrac=045)
-Fch=1933.20 (Fvco=3866.40, Nint=074, Nfrac=046)
-Fch=1933.40 (Fvco=3866.80, Nint=074, Nfrac=047)
-Fch=1933.60 (Fvco=3867.20, Nint=074, Nfrac=048)
-Fch=1933.80 (Fvco=3867.60, Nint=074, Nfrac=049)
-Fch=1934.00 (Fvco=3868.00, Nint=074, Nfrac=050)
-Fch=1934.20 (Fvco=3868.40, Nint=074, Nfrac=051)
-Fch=1934.40 (Fvco=3868.80, Nint=074, Nfrac=052)
-Fch=1934.60 (Fvco=3869.20, Nint=074, Nfrac=053)
-Fch=1934.80 (Fvco=3869.60, Nint=074, Nfrac=054)
-Fch=1935.00 (Fvco=3870.00, Nint=074, Nfrac=055)
-Fch=1935.20 (Fvco=3870.40, Nint=074, Nfrac=056)
-Fch=1935.40 (Fvco=3870.80, Nint=074, Nfrac=057)
-Fch=1935.60 (Fvco=3871.20, Nint=074, Nfrac=058)
-Fch=1935.80 (Fvco=3871.60, Nint=074, Nfrac=059)
-Fch=1936.00 (Fvco=3872.00, Nint=074, Nfrac=060)
-Fch=1936.20 (Fvco=3872.40, Nint=074, Nfrac=061)
-Fch=1936.40 (Fvco=3872.80, Nint=074, Nfrac=062)
-Fch=1936.60 (Fvco=3873.20, Nint=074, Nfrac=063)
-Fch=1936.80 (Fvco=3873.60, Nint=074, Nfrac=064)
-Fch=1937.00 (Fvco=3874.00, Nint=074, Nfrac=065)
-Fch=1937.20 (Fvco=3874.40, Nint=074, Nfrac=066)
-Fch=1937.40 (Fvco=3874.80, Nint=074, Nfrac=067)
-Fch=1937.60 (Fvco=3875.20, Nint=074, Nfrac=068)
-Fch=1937.80 (Fvco=3875.60, Nint=074, Nfrac=069)
-Fch=1938.00 (Fvco=3876.00, Nint=074, Nfrac=070)
-Fch=1938.20 (Fvco=3876.40, Nint=074, Nfrac=071)
-Fch=1938.40 (Fvco=3876.80, Nint=074, Nfrac=072)
-Fch=1938.60 (Fvco=3877.20, Nint=074, Nfrac=073)
-Fch=1938.80 (Fvco=3877.60, Nint=074, Nfrac=074)
-Fch=1939.00 (Fvco=3878.00, Nint=074, Nfrac=075)
-Fch=1939.20 (Fvco=3878.40, Nint=074, Nfrac=076)
-Fch=1939.40 (Fvco=3878.80, Nint=074, Nfrac=077)
-Fch=1939.60 (Fvco=3879.20, Nint=074, Nfrac=078)
-Fch=1939.80 (Fvco=3879.60, Nint=074, Nfrac=079)
-Fch=1940.00 (Fvco=3880.00, Nint=074, Nfrac=080)
-Fch=1940.20 (Fvco=3880.40, Nint=074, Nfrac=081)
-Fch=1940.40 (Fvco=3880.80, Nint=074, Nfrac=082)
-Fch=1940.60 (Fvco=3881.20, Nint=074, Nfrac=083)
-Fch=1940.80 (Fvco=3881.60, Nint=074, Nfrac=084)
-Fch=1941.00 (Fvco=3882.00, Nint=074, Nfrac=085)
-Fch=1941.20 (Fvco=3882.40, Nint=074, Nfrac=086)
-Fch=1941.40 (Fvco=3882.80, Nint=074, Nfrac=087)
-Fch=1941.60 (Fvco=3883.20, Nint=074, Nfrac=088)
-Fch=1941.80 (Fvco=3883.60, Nint=074, Nfrac=089)
-Fch=1942.00 (Fvco=3884.00, Nint=074, Nfrac=090)
-Fch=1942.20 (Fvco=3884.40, Nint=074, Nfrac=091)
-Fch=1942.40 (Fvco=3884.80, Nint=074, Nfrac=092)
-Fch=1942.60 (Fvco=3885.20, Nint=074, Nfrac=093)
-Fch=1942.80 (Fvco=3885.60, Nint=074, Nfrac=094)
-Fch=1943.00 (Fvco=3886.00, Nint=074, Nfrac=095)
-Fch=1943.20 (Fvco=3886.40, Nint=074, Nfrac=096)
-Fch=1943.40 (Fvco=3886.80, Nint=074, Nfrac=097)
-Fch=1943.60 (Fvco=3887.20, Nint=074, Nfrac=098)
-Fch=1943.80 (Fvco=3887.60, Nint=074, Nfrac=099)
-Fch=1944.00 (Fvco=3888.00, Nint=074, Nfrac=100)
-Fch=1944.20 (Fvco=3888.40, Nint=074, Nfrac=101)
-Fch=1944.40 (Fvco=3888.80, Nint=074, Nfrac=102)
-Fch=1944.60 (Fvco=3889.20, Nint=074, Nfrac=103)
-Fch=1944.80 (Fvco=3889.60, Nint=074, Nfrac=104)
-Fch=1945.00 (Fvco=3890.00, Nint=074, Nfrac=105)
-Fch=1945.20 (Fvco=3890.40, Nint=074, Nfrac=106)
-Fch=1945.40 (Fvco=3890.80, Nint=074, Nfrac=107)
-Fch=1945.60 (Fvco=3891.20, Nint=074, Nfrac=108)
-Fch=1945.80 (Fvco=3891.60, Nint=074, Nfrac=109)
-Fch=1946.00 (Fvco=3892.00, Nint=074, Nfrac=110)
-Fch=1946.20 (Fvco=3892.40, Nint=074, Nfrac=111)
-Fch=1946.40 (Fvco=3892.80, Nint=074, Nfrac=112)
-Fch=1946.60 (Fvco=3893.20, Nint=074, Nfrac=113)
-Fch=1946.80 (Fvco=3893.60, Nint=074, Nfrac=114)
-Fch=1947.00 (Fvco=3894.00, Nint=074, Nfrac=115)
-Fch=1947.20 (Fvco=3894.40, Nint=074, Nfrac=116)
-Fch=1947.40 (Fvco=3894.80, Nint=074, Nfrac=117)
-Fch=1947.60 (Fvco=3895.20, Nint=074, Nfrac=118)
-Fch=1947.80 (Fvco=3895.60, Nint=074, Nfrac=119)
-Fch=1948.00 (Fvco=3896.00, Nint=074, Nfrac=120)
-Fch=1948.20 (Fvco=3896.40, Nint=074, Nfrac=121)
-Fch=1948.40 (Fvco=3896.80, Nint=074, Nfrac=122)
-Fch=1948.60 (Fvco=3897.20, Nint=074, Nfrac=123)
-Fch=1948.80 (Fvco=3897.60, Nint=074, Nfrac=124)
-Fch=1949.00 (Fvco=3898.00, Nint=074, Nfrac=125)
-Fch=1949.20 (Fvco=3898.40, Nint=074, Nfrac=126)
-Fch=1949.40 (Fvco=3898.80, Nint=074, Nfrac=127)
-Fch=1949.60 (Fvco=3899.20, Nint=074, Nfrac=128)
-Fch=1949.80 (Fvco=3899.60, Nint=074, Nfrac=129)
-Fch=1950.00 (Fvco=3900.00, Nint=074, Nfrac=130)
-Fch=1950.00 (Fvco=3900.00, Nint=075, Nfrac=000)
-Fch=1950.20 (Fvco=3900.40, Nint=075, Nfrac=001)
-Fch=1950.40 (Fvco=3900.80, Nint=075, Nfrac=002)
-Fch=1950.60 (Fvco=3901.20, Nint=075, Nfrac=003)
-Fch=1950.80 (Fvco=3901.60, Nint=075, Nfrac=004)
-Fch=1951.00 (Fvco=3902.00, Nint=075, Nfrac=005)
-Fch=1951.20 (Fvco=3902.40, Nint=075, Nfrac=006)
-Fch=1951.40 (Fvco=3902.80, Nint=075, Nfrac=007)
-Fch=1951.60 (Fvco=3903.20, Nint=075, Nfrac=008)
-Fch=1951.80 (Fvco=3903.60, Nint=075, Nfrac=009)
-Fch=1952.00 (Fvco=3904.00, Nint=075, Nfrac=010)
-Fch=1952.20 (Fvco=3904.40, Nint=075, Nfrac=011)
-Fch=1952.40 (Fvco=3904.80, Nint=075, Nfrac=012)
-Fch=1952.60 (Fvco=3905.20, Nint=075, Nfrac=013)
-Fch=1952.80 (Fvco=3905.60, Nint=075, Nfrac=014)
-Fch=1953.00 (Fvco=3906.00, Nint=075, Nfrac=015)
-Fch=1953.20 (Fvco=3906.40, Nint=075, Nfrac=016)
-Fch=1953.40 (Fvco=3906.80, Nint=075, Nfrac=017)
-Fch=1953.60 (Fvco=3907.20, Nint=075, Nfrac=018)
-Fch=1953.80 (Fvco=3907.60, Nint=075, Nfrac=019)
-Fch=1954.00 (Fvco=3908.00, Nint=075, Nfrac=020)
-Fch=1954.20 (Fvco=3908.40, Nint=075, Nfrac=021)
-Fch=1954.40 (Fvco=3908.80, Nint=075, Nfrac=022)
-Fch=1954.60 (Fvco=3909.20, Nint=075, Nfrac=023)
-Fch=1954.80 (Fvco=3909.60, Nint=075, Nfrac=024)
-Fch=1955.00 (Fvco=3910.00, Nint=075, Nfrac=025)
-Fch=1955.20 (Fvco=3910.40, Nint=075, Nfrac=026)
-Fch=1955.40 (Fvco=3910.80, Nint=075, Nfrac=027)
-Fch=1955.60 (Fvco=3911.20, Nint=075, Nfrac=028)
-Fch=1955.80 (Fvco=3911.60, Nint=075, Nfrac=029)
-Fch=1956.00 (Fvco=3912.00, Nint=075, Nfrac=030)
-Fch=1956.20 (Fvco=3912.40, Nint=075, Nfrac=031)
-Fch=1956.40 (Fvco=3912.80, Nint=075, Nfrac=032)
-Fch=1956.60 (Fvco=3913.20, Nint=075, Nfrac=033)
-Fch=1956.80 (Fvco=3913.60, Nint=075, Nfrac=034)
-Fch=1957.00 (Fvco=3914.00, Nint=075, Nfrac=035)
-Fch=1957.20 (Fvco=3914.40, Nint=075, Nfrac=036)
-Fch=1957.40 (Fvco=3914.80, Nint=075, Nfrac=037)
-Fch=1957.60 (Fvco=3915.20, Nint=075, Nfrac=038)
-Fch=1957.80 (Fvco=3915.60, Nint=075, Nfrac=039)
-Fch=1958.00 (Fvco=3916.00, Nint=075, Nfrac=040)
-Fch=1958.20 (Fvco=3916.40, Nint=075, Nfrac=041)
-Fch=1958.40 (Fvco=3916.80, Nint=075, Nfrac=042)
-Fch=1958.60 (Fvco=3917.20, Nint=075, Nfrac=043)
-Fch=1958.80 (Fvco=3917.60, Nint=075, Nfrac=044)
-Fch=1959.00 (Fvco=3918.00, Nint=075, Nfrac=045)
-Fch=1959.20 (Fvco=3918.40, Nint=075, Nfrac=046)
-Fch=1959.40 (Fvco=3918.80, Nint=075, Nfrac=047)
-Fch=1959.60 (Fvco=3919.20, Nint=075, Nfrac=048)
-Fch=1959.80 (Fvco=3919.60, Nint=075, Nfrac=049)
-Fch=1960.00 (Fvco=3920.00, Nint=075, Nfrac=050)
-Fch=1960.20 (Fvco=3920.40, Nint=075, Nfrac=051)
-Fch=1960.40 (Fvco=3920.80, Nint=075, Nfrac=052)
-Fch=1960.60 (Fvco=3921.20, Nint=075, Nfrac=053)
-Fch=1960.80 (Fvco=3921.60, Nint=075, Nfrac=054)
-Fch=1961.00 (Fvco=3922.00, Nint=075, Nfrac=055)
-Fch=1961.20 (Fvco=3922.40, Nint=075, Nfrac=056)
-Fch=1961.40 (Fvco=3922.80, Nint=075, Nfrac=057)
-Fch=1961.60 (Fvco=3923.20, Nint=075, Nfrac=058)
-Fch=1961.80 (Fvco=3923.60, Nint=075, Nfrac=059)
-Fch=1962.00 (Fvco=3924.00, Nint=075, Nfrac=060)
-Fch=1962.20 (Fvco=3924.40, Nint=075, Nfrac=061)
-Fch=1962.40 (Fvco=3924.80, Nint=075, Nfrac=062)
-Fch=1962.60 (Fvco=3925.20, Nint=075, Nfrac=063)
-Fch=1962.80 (Fvco=3925.60, Nint=075, Nfrac=064)
-Fch=1963.00 (Fvco=3926.00, Nint=075, Nfrac=065)
-Fch=1963.20 (Fvco=3926.40, Nint=075, Nfrac=066)
-Fch=1963.40 (Fvco=3926.80, Nint=075, Nfrac=067)
-Fch=1963.60 (Fvco=3927.20, Nint=075, Nfrac=068)
-Fch=1963.80 (Fvco=3927.60, Nint=075, Nfrac=069)
-Fch=1964.00 (Fvco=3928.00, Nint=075, Nfrac=070)
-Fch=1964.20 (Fvco=3928.40, Nint=075, Nfrac=071)
-Fch=1964.40 (Fvco=3928.80, Nint=075, Nfrac=072)
-Fch=1964.60 (Fvco=3929.20, Nint=075, Nfrac=073)
-Fch=1964.80 (Fvco=3929.60, Nint=075, Nfrac=074)
-Fch=1965.00 (Fvco=3930.00, Nint=075, Nfrac=075)
-Fch=1965.20 (Fvco=3930.40, Nint=075, Nfrac=076)
-Fch=1965.40 (Fvco=3930.80, Nint=075, Nfrac=077)
-Fch=1965.60 (Fvco=3931.20, Nint=075, Nfrac=078)
-Fch=1965.80 (Fvco=3931.60, Nint=075, Nfrac=079)
-Fch=1966.00 (Fvco=3932.00, Nint=075, Nfrac=080)
-Fch=1966.20 (Fvco=3932.40, Nint=075, Nfrac=081)
-Fch=1966.40 (Fvco=3932.80, Nint=075, Nfrac=082)
-Fch=1966.60 (Fvco=3933.20, Nint=075, Nfrac=083)
-Fch=1966.80 (Fvco=3933.60, Nint=075, Nfrac=084)
-Fch=1967.00 (Fvco=3934.00, Nint=075, Nfrac=085)
-Fch=1967.20 (Fvco=3934.40, Nint=075, Nfrac=086)
-Fch=1967.40 (Fvco=3934.80, Nint=075, Nfrac=087)
-Fch=1967.60 (Fvco=3935.20, Nint=075, Nfrac=088)
-Fch=1967.80 (Fvco=3935.60, Nint=075, Nfrac=089)
-Fch=1968.00 (Fvco=3936.00, Nint=075, Nfrac=090)
-Fch=1968.20 (Fvco=3936.40, Nint=075, Nfrac=091)
-Fch=1968.40 (Fvco=3936.80, Nint=075, Nfrac=092)
-Fch=1968.60 (Fvco=3937.20, Nint=075, Nfrac=093)
-Fch=1968.80 (Fvco=3937.60, Nint=075, Nfrac=094)
-Fch=1969.00 (Fvco=3938.00, Nint=075, Nfrac=095)
-Fch=1969.20 (Fvco=3938.40, Nint=075, Nfrac=096)
-Fch=1969.40 (Fvco=3938.80, Nint=075, Nfrac=097)
-Fch=1969.60 (Fvco=3939.20, Nint=075, Nfrac=098)
-Fch=1969.80 (Fvco=3939.60, Nint=075, Nfrac=099)
-Fch=1970.00 (Fvco=3940.00, Nint=075, Nfrac=100)
-Fch=1970.20 (Fvco=3940.40, Nint=075, Nfrac=101)
-Fch=1970.40 (Fvco=3940.80, Nint=075, Nfrac=102)
-Fch=1970.60 (Fvco=3941.20, Nint=075, Nfrac=103)
-Fch=1970.80 (Fvco=3941.60, Nint=075, Nfrac=104)
-Fch=1971.00 (Fvco=3942.00, Nint=075, Nfrac=105)
-Fch=1971.20 (Fvco=3942.40, Nint=075, Nfrac=106)
-Fch=1971.40 (Fvco=3942.80, Nint=075, Nfrac=107)
-Fch=1971.60 (Fvco=3943.20, Nint=075, Nfrac=108)
-Fch=1971.80 (Fvco=3943.60, Nint=075, Nfrac=109)
-Fch=1972.00 (Fvco=3944.00, Nint=075, Nfrac=110)
-Fch=1972.20 (Fvco=3944.40, Nint=075, Nfrac=111)
-Fch=1972.40 (Fvco=3944.80, Nint=075, Nfrac=112)
-Fch=1972.60 (Fvco=3945.20, Nint=075, Nfrac=113)
-Fch=1972.80 (Fvco=3945.60, Nint=075, Nfrac=114)
-Fch=1973.00 (Fvco=3946.00, Nint=075, Nfrac=115)
-Fch=1973.20 (Fvco=3946.40, Nint=075, Nfrac=116)
-Fch=1973.40 (Fvco=3946.80, Nint=075, Nfrac=117)
-Fch=1973.60 (Fvco=3947.20, Nint=075, Nfrac=118)
-Fch=1973.80 (Fvco=3947.60, Nint=075, Nfrac=119)
-Fch=1974.00 (Fvco=3948.00, Nint=075, Nfrac=120)
-Fch=1974.20 (Fvco=3948.40, Nint=075, Nfrac=121)
-Fch=1974.40 (Fvco=3948.80, Nint=075, Nfrac=122)
-Fch=1974.60 (Fvco=3949.20, Nint=075, Nfrac=123)
-Fch=1974.80 (Fvco=3949.60, Nint=075, Nfrac=124)
-Fch=1975.00 (Fvco=3950.00, Nint=075, Nfrac=125)
-Fch=1975.20 (Fvco=3950.40, Nint=075, Nfrac=126)
-Fch=1975.40 (Fvco=3950.80, Nint=075, Nfrac=127)
-Fch=1975.60 (Fvco=3951.20, Nint=075, Nfrac=128)
-Fch=1975.80 (Fvco=3951.60, Nint=075, Nfrac=129)
-Fch=1976.00 (Fvco=3952.00, Nint=075, Nfrac=130)
-Fch=1976.00 (Fvco=3952.00, Nint=076, Nfrac=000)
-Fch=1976.20 (Fvco=3952.40, Nint=076, Nfrac=001)
-Fch=1976.40 (Fvco=3952.80, Nint=076, Nfrac=002)
-Fch=1976.60 (Fvco=3953.20, Nint=076, Nfrac=003)
-Fch=1976.80 (Fvco=3953.60, Nint=076, Nfrac=004)
-Fch=1977.00 (Fvco=3954.00, Nint=076, Nfrac=005)
-Fch=1977.20 (Fvco=3954.40, Nint=076, Nfrac=006)
-Fch=1977.40 (Fvco=3954.80, Nint=076, Nfrac=007)
-Fch=1977.60 (Fvco=3955.20, Nint=076, Nfrac=008)
-Fch=1977.80 (Fvco=3955.60, Nint=076, Nfrac=009)
-Fch=1978.00 (Fvco=3956.00, Nint=076, Nfrac=010)
-Fch=1978.20 (Fvco=3956.40, Nint=076, Nfrac=011)
-Fch=1978.40 (Fvco=3956.80, Nint=076, Nfrac=012)
-Fch=1978.60 (Fvco=3957.20, Nint=076, Nfrac=013)
-Fch=1978.80 (Fvco=3957.60, Nint=076, Nfrac=014)
-Fch=1979.00 (Fvco=3958.00, Nint=076, Nfrac=015)
-Fch=1979.20 (Fvco=3958.40, Nint=076, Nfrac=016)
-Fch=1979.40 (Fvco=3958.80, Nint=076, Nfrac=017)
-Fch=1979.60 (Fvco=3959.20, Nint=076, Nfrac=018)
-Fch=1979.80 (Fvco=3959.60, Nint=076, Nfrac=019)
-Fch=1980.00 (Fvco=3960.00, Nint=076, Nfrac=020)
-Fch=1980.20 (Fvco=3960.40, Nint=076, Nfrac=021)
-Fch=1980.40 (Fvco=3960.80, Nint=076, Nfrac=022)
-Fch=1980.60 (Fvco=3961.20, Nint=076, Nfrac=023)
-Fch=1980.80 (Fvco=3961.60, Nint=076, Nfrac=024)
-Fch=1981.00 (Fvco=3962.00, Nint=076, Nfrac=025)
-Fch=1981.20 (Fvco=3962.40, Nint=076, Nfrac=026)
-Fch=1981.40 (Fvco=3962.80, Nint=076, Nfrac=027)
-Fch=1981.60 (Fvco=3963.20, Nint=076, Nfrac=028)
-Fch=1981.80 (Fvco=3963.60, Nint=076, Nfrac=029)
-Fch=1982.00 (Fvco=3964.00, Nint=076, Nfrac=030)
-Fch=1982.20 (Fvco=3964.40, Nint=076, Nfrac=031)
-Fch=1982.40 (Fvco=3964.80, Nint=076, Nfrac=032)
-Fch=1982.60 (Fvco=3965.20, Nint=076, Nfrac=033)
-Fch=1982.80 (Fvco=3965.60, Nint=076, Nfrac=034)
-Fch=1983.00 (Fvco=3966.00, Nint=076, Nfrac=035)
-Fch=1983.20 (Fvco=3966.40, Nint=076, Nfrac=036)
-Fch=1983.40 (Fvco=3966.80, Nint=076, Nfrac=037)
-Fch=1983.60 (Fvco=3967.20, Nint=076, Nfrac=038)
-Fch=1983.80 (Fvco=3967.60, Nint=076, Nfrac=039)
-Fch=1984.00 (Fvco=3968.00, Nint=076, Nfrac=040)
-Fch=1984.20 (Fvco=3968.40, Nint=076, Nfrac=041)
-Fch=1984.40 (Fvco=3968.80, Nint=076, Nfrac=042)
-Fch=1984.60 (Fvco=3969.20, Nint=076, Nfrac=043)
-Fch=1984.80 (Fvco=3969.60, Nint=076, Nfrac=044)
-Fch=1985.00 (Fvco=3970.00, Nint=076, Nfrac=045)
-Fch=1985.20 (Fvco=3970.40, Nint=076, Nfrac=046)
-Fch=1985.40 (Fvco=3970.80, Nint=076, Nfrac=047)
-Fch=1985.60 (Fvco=3971.20, Nint=076, Nfrac=048)
-Fch=1985.80 (Fvco=3971.60, Nint=076, Nfrac=049)
-Fch=1986.00 (Fvco=3972.00, Nint=076, Nfrac=050)
-Fch=1986.20 (Fvco=3972.40, Nint=076, Nfrac=051)
-Fch=1986.40 (Fvco=3972.80, Nint=076, Nfrac=052)
-Fch=1986.60 (Fvco=3973.20, Nint=076, Nfrac=053)
-Fch=1986.80 (Fvco=3973.60, Nint=076, Nfrac=054)
-Fch=1987.00 (Fvco=3974.00, Nint=076, Nfrac=055)
-Fch=1987.20 (Fvco=3974.40, Nint=076, Nfrac=056)
-Fch=1987.40 (Fvco=3974.80, Nint=076, Nfrac=057)
-Fch=1987.60 (Fvco=3975.20, Nint=076, Nfrac=058)
-Fch=1987.80 (Fvco=3975.60, Nint=076, Nfrac=059)
-Fch=1988.00 (Fvco=3976.00, Nint=076, Nfrac=060)
-Fch=1988.20 (Fvco=3976.40, Nint=076, Nfrac=061)
-Fch=1988.40 (Fvco=3976.80, Nint=076, Nfrac=062)
-Fch=1988.60 (Fvco=3977.20, Nint=076, Nfrac=063)
-Fch=1988.80 (Fvco=3977.60, Nint=076, Nfrac=064)
-Fch=1989.00 (Fvco=3978.00, Nint=076, Nfrac=065)
-Fch=1989.20 (Fvco=3978.40, Nint=076, Nfrac=066)
-Fch=1989.40 (Fvco=3978.80, Nint=076, Nfrac=067)
-Fch=1989.60 (Fvco=3979.20, Nint=076, Nfrac=068)
-Fch=1989.80 (Fvco=3979.60, Nint=076, Nfrac=069)
-Fch=1990.00 (Fvco=3980.00, Nint=076, Nfrac=070)
-Fch=1990.20 (Fvco=3980.40, Nint=076, Nfrac=071)
-Fch=1990.40 (Fvco=3980.80, Nint=076, Nfrac=072)
-Fch=1990.60 (Fvco=3981.20, Nint=076, Nfrac=073)
-Fch=1990.80 (Fvco=3981.60, Nint=076, Nfrac=074)
-Fch=1991.00 (Fvco=3982.00, Nint=076, Nfrac=075)
-Fch=1991.20 (Fvco=3982.40, Nint=076, Nfrac=076)
-Fch=1991.40 (Fvco=3982.80, Nint=076, Nfrac=077)
-Fch=1991.60 (Fvco=3983.20, Nint=076, Nfrac=078)
-Fch=1991.80 (Fvco=3983.60, Nint=076, Nfrac=079)
-Fch=1992.00 (Fvco=3984.00, Nint=076, Nfrac=080)
-Fch=1992.20 (Fvco=3984.40, Nint=076, Nfrac=081)
-Fch=1992.40 (Fvco=3984.80, Nint=076, Nfrac=082)
-Fch=1992.60 (Fvco=3985.20, Nint=076, Nfrac=083)
-Fch=1992.80 (Fvco=3985.60, Nint=076, Nfrac=084)
-Fch=1993.00 (Fvco=3986.00, Nint=076, Nfrac=085)
-Fch=1993.20 (Fvco=3986.40, Nint=076, Nfrac=086)
-Fch=1993.40 (Fvco=3986.80, Nint=076, Nfrac=087)
-Fch=1993.60 (Fvco=3987.20, Nint=076, Nfrac=088)
-Fch=1993.80 (Fvco=3987.60, Nint=076, Nfrac=089)
-Fch=1994.00 (Fvco=3988.00, Nint=076, Nfrac=090)
-Fch=1994.20 (Fvco=3988.40, Nint=076, Nfrac=091)
-Fch=1994.40 (Fvco=3988.80, Nint=076, Nfrac=092)
-Fch=1994.60 (Fvco=3989.20, Nint=076, Nfrac=093)
-Fch=1994.80 (Fvco=3989.60, Nint=076, Nfrac=094)
-Fch=1995.00 (Fvco=3990.00, Nint=076, Nfrac=095)
-Fch=1995.20 (Fvco=3990.40, Nint=076, Nfrac=096)
-Fch=1995.40 (Fvco=3990.80, Nint=076, Nfrac=097)
-Fch=1995.60 (Fvco=3991.20, Nint=076, Nfrac=098)
-Fch=1995.80 (Fvco=3991.60, Nint=076, Nfrac=099)
-Fch=1996.00 (Fvco=3992.00, Nint=076, Nfrac=100)
-Fch=1996.20 (Fvco=3992.40, Nint=076, Nfrac=101)
-Fch=1996.40 (Fvco=3992.80, Nint=076, Nfrac=102)
-Fch=1996.60 (Fvco=3993.20, Nint=076, Nfrac=103)
-Fch=1996.80 (Fvco=3993.60, Nint=076, Nfrac=104)
-Fch=1997.00 (Fvco=3994.00, Nint=076, Nfrac=105)
-Fch=1997.20 (Fvco=3994.40, Nint=076, Nfrac=106)
-Fch=1997.40 (Fvco=3994.80, Nint=076, Nfrac=107)
-Fch=1997.60 (Fvco=3995.20, Nint=076, Nfrac=108)
-Fch=1997.80 (Fvco=3995.60, Nint=076, Nfrac=109)
-Fch=1998.00 (Fvco=3996.00, Nint=076, Nfrac=110)
-Fch=1998.20 (Fvco=3996.40, Nint=076, Nfrac=111)
-Fch=1998.40 (Fvco=3996.80, Nint=076, Nfrac=112)
-Fch=1998.60 (Fvco=3997.20, Nint=076, Nfrac=113)
-Fch=1998.80 (Fvco=3997.60, Nint=076, Nfrac=114)
-Fch=1999.00 (Fvco=3998.00, Nint=076, Nfrac=115)
-Fch=1999.20 (Fvco=3998.40, Nint=076, Nfrac=116)
-Fch=1999.40 (Fvco=3998.80, Nint=076, Nfrac=117)
-Fch=1999.60 (Fvco=3999.20, Nint=076, Nfrac=118)
-Fch=1999.80 (Fvco=3999.60, Nint=076, Nfrac=119)
-Fch=2000.00 (Fvco=4000.00, Nint=076, Nfrac=120)
-Fch=2000.20 (Fvco=4000.40, Nint=076, Nfrac=121)
-Fch=2000.40 (Fvco=4000.80, Nint=076, Nfrac=122)
-Fch=2000.60 (Fvco=4001.20, Nint=076, Nfrac=123)
-Fch=2000.80 (Fvco=4001.60, Nint=076, Nfrac=124)
-Fch=2001.00 (Fvco=4002.00, Nint=076, Nfrac=125)
-Fch=2001.20 (Fvco=4002.40, Nint=076, Nfrac=126)
-Fch=2001.40 (Fvco=4002.80, Nint=076, Nfrac=127)
-Fch=2001.60 (Fvco=4003.20, Nint=076, Nfrac=128)
-Fch=2001.80 (Fvco=4003.60, Nint=076, Nfrac=129)
-Fch=2002.00 (Fvco=4004.00, Nint=076, Nfrac=130)
-Fch=2002.00 (Fvco=4004.00, Nint=077, Nfrac=000)
-Fch=2002.20 (Fvco=4004.40, Nint=077, Nfrac=001)
-Fch=2002.40 (Fvco=4004.80, Nint=077, Nfrac=002)
-Fch=2002.60 (Fvco=4005.20, Nint=077, Nfrac=003)
-Fch=2002.80 (Fvco=4005.60, Nint=077, Nfrac=004)
-Fch=2003.00 (Fvco=4006.00, Nint=077, Nfrac=005)
-Fch=2003.20 (Fvco=4006.40, Nint=077, Nfrac=006)
-Fch=2003.40 (Fvco=4006.80, Nint=077, Nfrac=007)
-Fch=2003.60 (Fvco=4007.20, Nint=077, Nfrac=008)
-Fch=2003.80 (Fvco=4007.60, Nint=077, Nfrac=009)
-Fch=2004.00 (Fvco=4008.00, Nint=077, Nfrac=010)
-Fch=2004.20 (Fvco=4008.40, Nint=077, Nfrac=011)
-Fch=2004.40 (Fvco=4008.80, Nint=077, Nfrac=012)
-Fch=2004.60 (Fvco=4009.20, Nint=077, Nfrac=013)
-Fch=2004.80 (Fvco=4009.60, Nint=077, Nfrac=014)
-Fch=2005.00 (Fvco=4010.00, Nint=077, Nfrac=015)
-Fch=2005.20 (Fvco=4010.40, Nint=077, Nfrac=016)
-Fch=2005.40 (Fvco=4010.80, Nint=077, Nfrac=017)
-Fch=2005.60 (Fvco=4011.20, Nint=077, Nfrac=018)
-Fch=2005.80 (Fvco=4011.60, Nint=077, Nfrac=019)
-Fch=2006.00 (Fvco=4012.00, Nint=077, Nfrac=020)
-Fch=2006.20 (Fvco=4012.40, Nint=077, Nfrac=021)
-Fch=2006.40 (Fvco=4012.80, Nint=077, Nfrac=022)
-Fch=2006.60 (Fvco=4013.20, Nint=077, Nfrac=023)
-Fch=2006.80 (Fvco=4013.60, Nint=077, Nfrac=024)
-Fch=2007.00 (Fvco=4014.00, Nint=077, Nfrac=025)
-Fch=2007.20 (Fvco=4014.40, Nint=077, Nfrac=026)
-Fch=2007.40 (Fvco=4014.80, Nint=077, Nfrac=027)
-Fch=2007.60 (Fvco=4015.20, Nint=077, Nfrac=028)
-Fch=2007.80 (Fvco=4015.60, Nint=077, Nfrac=029)
-Fch=2008.00 (Fvco=4016.00, Nint=077, Nfrac=030)
-Fch=2008.20 (Fvco=4016.40, Nint=077, Nfrac=031)
-Fch=2008.40 (Fvco=4016.80, Nint=077, Nfrac=032)
-Fch=2008.60 (Fvco=4017.20, Nint=077, Nfrac=033)
-Fch=2008.80 (Fvco=4017.60, Nint=077, Nfrac=034)
-Fch=2009.00 (Fvco=4018.00, Nint=077, Nfrac=035)
-Fch=2009.20 (Fvco=4018.40, Nint=077, Nfrac=036)
-Fch=2009.40 (Fvco=4018.80, Nint=077, Nfrac=037)
-Fch=2009.60 (Fvco=4019.20, Nint=077, Nfrac=038)
-Fch=2009.80 (Fvco=4019.60, Nint=077, Nfrac=039)
-Fch=2010.00 (Fvco=4020.00, Nint=077, Nfrac=040)
-Fch=2010.20 (Fvco=4020.40, Nint=077, Nfrac=041)
-Fch=2010.40 (Fvco=4020.80, Nint=077, Nfrac=042)
-Fch=2010.60 (Fvco=4021.20, Nint=077, Nfrac=043)
-Fch=2010.80 (Fvco=4021.60, Nint=077, Nfrac=044)
-Fch=2011.00 (Fvco=4022.00, Nint=077, Nfrac=045)
-Fch=2011.20 (Fvco=4022.40, Nint=077, Nfrac=046)
-Fch=2011.40 (Fvco=4022.80, Nint=077, Nfrac=047)
-Fch=2011.60 (Fvco=4023.20, Nint=077, Nfrac=048)
-Fch=2011.80 (Fvco=4023.60, Nint=077, Nfrac=049)
-Fch=2012.00 (Fvco=4024.00, Nint=077, Nfrac=050)
-Fch=2012.20 (Fvco=4024.40, Nint=077, Nfrac=051)
-Fch=2012.40 (Fvco=4024.80, Nint=077, Nfrac=052)
-Fch=2012.60 (Fvco=4025.20, Nint=077, Nfrac=053)
-Fch=2012.80 (Fvco=4025.60, Nint=077, Nfrac=054)
-Fch=2013.00 (Fvco=4026.00, Nint=077, Nfrac=055)
-Fch=2013.20 (Fvco=4026.40, Nint=077, Nfrac=056)
-Fch=2013.40 (Fvco=4026.80, Nint=077, Nfrac=057)
-Fch=2013.60 (Fvco=4027.20, Nint=077, Nfrac=058)
-Fch=2013.80 (Fvco=4027.60, Nint=077, Nfrac=059)
-Fch=2014.00 (Fvco=4028.00, Nint=077, Nfrac=060)
-Fch=2014.20 (Fvco=4028.40, Nint=077, Nfrac=061)
-Fch=2014.40 (Fvco=4028.80, Nint=077, Nfrac=062)
-Fch=2014.60 (Fvco=4029.20, Nint=077, Nfrac=063)
-Fch=2014.80 (Fvco=4029.60, Nint=077, Nfrac=064)
-Fch=2015.00 (Fvco=4030.00, Nint=077, Nfrac=065)
-Fch=2015.20 (Fvco=4030.40, Nint=077, Nfrac=066)
-Fch=2015.40 (Fvco=4030.80, Nint=077, Nfrac=067)
-Fch=2015.60 (Fvco=4031.20, Nint=077, Nfrac=068)
-Fch=2015.80 (Fvco=4031.60, Nint=077, Nfrac=069)
-Fch=2016.00 (Fvco=4032.00, Nint=077, Nfrac=070)
-Fch=2016.20 (Fvco=4032.40, Nint=077, Nfrac=071)
-Fch=2016.40 (Fvco=4032.80, Nint=077, Nfrac=072)
-Fch=2016.60 (Fvco=4033.20, Nint=077, Nfrac=073)
-Fch=2016.80 (Fvco=4033.60, Nint=077, Nfrac=074)
-Fch=2017.00 (Fvco=4034.00, Nint=077, Nfrac=075)
-Fch=2017.20 (Fvco=4034.40, Nint=077, Nfrac=076)
-Fch=2017.40 (Fvco=4034.80, Nint=077, Nfrac=077)
-Fch=2017.60 (Fvco=4035.20, Nint=077, Nfrac=078)
-Fch=2017.80 (Fvco=4035.60, Nint=077, Nfrac=079)
-Fch=2018.00 (Fvco=4036.00, Nint=077, Nfrac=080)
-Fch=2018.20 (Fvco=4036.40, Nint=077, Nfrac=081)
-Fch=2018.40 (Fvco=4036.80, Nint=077, Nfrac=082)
-Fch=2018.60 (Fvco=4037.20, Nint=077, Nfrac=083)
-Fch=2018.80 (Fvco=4037.60, Nint=077, Nfrac=084)
-Fch=2019.00 (Fvco=4038.00, Nint=077, Nfrac=085)
-Fch=2019.20 (Fvco=4038.40, Nint=077, Nfrac=086)
-Fch=2019.40 (Fvco=4038.80, Nint=077, Nfrac=087)
-Fch=2019.60 (Fvco=4039.20, Nint=077, Nfrac=088)
-Fch=2019.80 (Fvco=4039.60, Nint=077, Nfrac=089)
-Fch=2020.00 (Fvco=4040.00, Nint=077, Nfrac=090)
-Fch=2020.20 (Fvco=4040.40, Nint=077, Nfrac=091)
-Fch=2020.40 (Fvco=4040.80, Nint=077, Nfrac=092)
-Fch=2020.60 (Fvco=4041.20, Nint=077, Nfrac=093)
-Fch=2020.80 (Fvco=4041.60, Nint=077, Nfrac=094)
-Fch=2021.00 (Fvco=4042.00, Nint=077, Nfrac=095)
-Fch=2021.20 (Fvco=4042.40, Nint=077, Nfrac=096)
-Fch=2021.40 (Fvco=4042.80, Nint=077, Nfrac=097)
-Fch=2021.60 (Fvco=4043.20, Nint=077, Nfrac=098)
-Fch=2021.80 (Fvco=4043.60, Nint=077, Nfrac=099)
-Fch=2022.00 (Fvco=4044.00, Nint=077, Nfrac=100)
-Fch=2022.20 (Fvco=4044.40, Nint=077, Nfrac=101)
-Fch=2022.40 (Fvco=4044.80, Nint=077, Nfrac=102)
-Fch=2022.60 (Fvco=4045.20, Nint=077, Nfrac=103)
-Fch=2022.80 (Fvco=4045.60, Nint=077, Nfrac=104)
-Fch=2023.00 (Fvco=4046.00, Nint=077, Nfrac=105)
-Fch=2023.20 (Fvco=4046.40, Nint=077, Nfrac=106)
-Fch=2023.40 (Fvco=4046.80, Nint=077, Nfrac=107)
-Fch=2023.60 (Fvco=4047.20, Nint=077, Nfrac=108)
-Fch=2023.80 (Fvco=4047.60, Nint=077, Nfrac=109)
-Fch=2024.00 (Fvco=4048.00, Nint=077, Nfrac=110)
-Fch=2024.20 (Fvco=4048.40, Nint=077, Nfrac=111)
-Fch=2024.40 (Fvco=4048.80, Nint=077, Nfrac=112)
-Fch=2024.60 (Fvco=4049.20, Nint=077, Nfrac=113)
-Fch=2024.80 (Fvco=4049.60, Nint=077, Nfrac=114)
-Fch=2025.00 (Fvco=4050.00, Nint=077, Nfrac=115)
-Fch=2025.20 (Fvco=4050.40, Nint=077, Nfrac=116)
-Fch=2025.40 (Fvco=4050.80, Nint=077, Nfrac=117)
-Fch=2025.60 (Fvco=4051.20, Nint=077, Nfrac=118)
-Fch=2025.80 (Fvco=4051.60, Nint=077, Nfrac=119)
-Fch=2026.00 (Fvco=4052.00, Nint=077, Nfrac=120)
-Fch=2026.20 (Fvco=4052.40, Nint=077, Nfrac=121)
-Fch=2026.40 (Fvco=4052.80, Nint=077, Nfrac=122)
-Fch=2026.60 (Fvco=4053.20, Nint=077, Nfrac=123)
-Fch=2026.80 (Fvco=4053.60, Nint=077, Nfrac=124)
-Fch=2027.00 (Fvco=4054.00, Nint=077, Nfrac=125)
-Fch=2027.20 (Fvco=4054.40, Nint=077, Nfrac=126)
-Fch=2027.40 (Fvco=4054.80, Nint=077, Nfrac=127)
-Fch=2027.60 (Fvco=4055.20, Nint=077, Nfrac=128)
-Fch=2027.80 (Fvco=4055.60, Nint=077, Nfrac=129)
-Fch=2028.00 (Fvco=4056.00, Nint=077, Nfrac=130)
-Fch=2028.00 (Fvco=4056.00, Nint=078, Nfrac=000)
-Fch=2028.20 (Fvco=4056.40, Nint=078, Nfrac=001)
-Fch=2028.40 (Fvco=4056.80, Nint=078, Nfrac=002)
-Fch=2028.60 (Fvco=4057.20, Nint=078, Nfrac=003)
-Fch=2028.80 (Fvco=4057.60, Nint=078, Nfrac=004)
-Fch=2029.00 (Fvco=4058.00, Nint=078, Nfrac=005)
-Fch=2029.20 (Fvco=4058.40, Nint=078, Nfrac=006)
-Fch=2029.40 (Fvco=4058.80, Nint=078, Nfrac=007)
-Fch=2029.60 (Fvco=4059.20, Nint=078, Nfrac=008)
-Fch=2029.80 (Fvco=4059.60, Nint=078, Nfrac=009)
-Fch=2030.00 (Fvco=4060.00, Nint=078, Nfrac=010)
-Fch=2030.20 (Fvco=4060.40, Nint=078, Nfrac=011)
-Fch=2030.40 (Fvco=4060.80, Nint=078, Nfrac=012)
-Fch=2030.60 (Fvco=4061.20, Nint=078, Nfrac=013)
-Fch=2030.80 (Fvco=4061.60, Nint=078, Nfrac=014)
-Fch=2031.00 (Fvco=4062.00, Nint=078, Nfrac=015)
-Fch=2031.20 (Fvco=4062.40, Nint=078, Nfrac=016)
-Fch=2031.40 (Fvco=4062.80, Nint=078, Nfrac=017)
-Fch=2031.60 (Fvco=4063.20, Nint=078, Nfrac=018)
-Fch=2031.80 (Fvco=4063.60, Nint=078, Nfrac=019)
-Fch=2032.00 (Fvco=4064.00, Nint=078, Nfrac=020)
-Fch=2032.20 (Fvco=4064.40, Nint=078, Nfrac=021)
-Fch=2032.40 (Fvco=4064.80, Nint=078, Nfrac=022)
-Fch=2032.60 (Fvco=4065.20, Nint=078, Nfrac=023)
-Fch=2032.80 (Fvco=4065.60, Nint=078, Nfrac=024)
-Fch=2033.00 (Fvco=4066.00, Nint=078, Nfrac=025)
-Fch=2033.20 (Fvco=4066.40, Nint=078, Nfrac=026)
-Fch=2033.40 (Fvco=4066.80, Nint=078, Nfrac=027)
-Fch=2033.60 (Fvco=4067.20, Nint=078, Nfrac=028)
-Fch=2033.80 (Fvco=4067.60, Nint=078, Nfrac=029)
-Fch=2034.00 (Fvco=4068.00, Nint=078, Nfrac=030)
-Fch=2034.20 (Fvco=4068.40, Nint=078, Nfrac=031)
-Fch=2034.40 (Fvco=4068.80, Nint=078, Nfrac=032)
-Fch=2034.60 (Fvco=4069.20, Nint=078, Nfrac=033)
-Fch=2034.80 (Fvco=4069.60, Nint=078, Nfrac=034)
-Fch=2035.00 (Fvco=4070.00, Nint=078, Nfrac=035)
-Fch=2035.20 (Fvco=4070.40, Nint=078, Nfrac=036)
-Fch=2035.40 (Fvco=4070.80, Nint=078, Nfrac=037)
-Fch=2035.60 (Fvco=4071.20, Nint=078, Nfrac=038)
-Fch=2035.80 (Fvco=4071.60, Nint=078, Nfrac=039)
-Fch=2036.00 (Fvco=4072.00, Nint=078, Nfrac=040)
-Fch=2036.20 (Fvco=4072.40, Nint=078, Nfrac=041)
-Fch=2036.40 (Fvco=4072.80, Nint=078, Nfrac=042)
-Fch=2036.60 (Fvco=4073.20, Nint=078, Nfrac=043)
-Fch=2036.80 (Fvco=4073.60, Nint=078, Nfrac=044)
-Fch=2037.00 (Fvco=4074.00, Nint=078, Nfrac=045)
-Fch=2037.20 (Fvco=4074.40, Nint=078, Nfrac=046)
-Fch=2037.40 (Fvco=4074.80, Nint=078, Nfrac=047)
-Fch=2037.60 (Fvco=4075.20, Nint=078, Nfrac=048)
-Fch=2037.80 (Fvco=4075.60, Nint=078, Nfrac=049)
-Fch=2038.00 (Fvco=4076.00, Nint=078, Nfrac=050)
-Fch=2038.20 (Fvco=4076.40, Nint=078, Nfrac=051)
-Fch=2038.40 (Fvco=4076.80, Nint=078, Nfrac=052)
-Fch=2038.60 (Fvco=4077.20, Nint=078, Nfrac=053)
-Fch=2038.80 (Fvco=4077.60, Nint=078, Nfrac=054)
-Fch=2039.00 (Fvco=4078.00, Nint=078, Nfrac=055)
-Fch=2039.20 (Fvco=4078.40, Nint=078, Nfrac=056)
-Fch=2039.40 (Fvco=4078.80, Nint=078, Nfrac=057)
-Fch=2039.60 (Fvco=4079.20, Nint=078, Nfrac=058)
-Fch=2039.80 (Fvco=4079.60, Nint=078, Nfrac=059)
-Fch=2040.00 (Fvco=4080.00, Nint=078, Nfrac=060)
-Fch=2040.20 (Fvco=4080.40, Nint=078, Nfrac=061)
-Fch=2040.40 (Fvco=4080.80, Nint=078, Nfrac=062)
-Fch=2040.60 (Fvco=4081.20, Nint=078, Nfrac=063)
-Fch=2040.80 (Fvco=4081.60, Nint=078, Nfrac=064)
-Fch=2041.00 (Fvco=4082.00, Nint=078, Nfrac=065)
-Fch=2041.20 (Fvco=4082.40, Nint=078, Nfrac=066)
-Fch=2041.40 (Fvco=4082.80, Nint=078, Nfrac=067)
-Fch=2041.60 (Fvco=4083.20, Nint=078, Nfrac=068)
-Fch=2041.80 (Fvco=4083.60, Nint=078, Nfrac=069)
-Fch=2042.00 (Fvco=4084.00, Nint=078, Nfrac=070)
-Fch=2042.20 (Fvco=4084.40, Nint=078, Nfrac=071)
-Fch=2042.40 (Fvco=4084.80, Nint=078, Nfrac=072)
-Fch=2042.60 (Fvco=4085.20, Nint=078, Nfrac=073)
-Fch=2042.80 (Fvco=4085.60, Nint=078, Nfrac=074)
-Fch=2043.00 (Fvco=4086.00, Nint=078, Nfrac=075)
-Fch=2043.20 (Fvco=4086.40, Nint=078, Nfrac=076)
-Fch=2043.40 (Fvco=4086.80, Nint=078, Nfrac=077)
-Fch=2043.60 (Fvco=4087.20, Nint=078, Nfrac=078)
-Fch=2043.80 (Fvco=4087.60, Nint=078, Nfrac=079)
-Fch=2044.00 (Fvco=4088.00, Nint=078, Nfrac=080)
-Fch=2044.20 (Fvco=4088.40, Nint=078, Nfrac=081)
-Fch=2044.40 (Fvco=4088.80, Nint=078, Nfrac=082)
-Fch=2044.60 (Fvco=4089.20, Nint=078, Nfrac=083)
-Fch=2044.80 (Fvco=4089.60, Nint=078, Nfrac=084)
-Fch=2045.00 (Fvco=4090.00, Nint=078, Nfrac=085)
-Fch=2045.20 (Fvco=4090.40, Nint=078, Nfrac=086)
-Fch=2045.40 (Fvco=4090.80, Nint=078, Nfrac=087)
-Fch=2045.60 (Fvco=4091.20, Nint=078, Nfrac=088)
-Fch=2045.80 (Fvco=4091.60, Nint=078, Nfrac=089)
-Fch=2046.00 (Fvco=4092.00, Nint=078, Nfrac=090)
-Fch=2046.20 (Fvco=4092.40, Nint=078, Nfrac=091)
-Fch=2046.40 (Fvco=4092.80, Nint=078, Nfrac=092)
-Fch=2046.60 (Fvco=4093.20, Nint=078, Nfrac=093)
-Fch=2046.80 (Fvco=4093.60, Nint=078, Nfrac=094)
-Fch=2047.00 (Fvco=4094.00, Nint=078, Nfrac=095)
-Fch=2047.20 (Fvco=4094.40, Nint=078, Nfrac=096)
-Fch=2047.40 (Fvco=4094.80, Nint=078, Nfrac=097)
-Fch=2047.60 (Fvco=4095.20, Nint=078, Nfrac=098)
-Fch=2047.80 (Fvco=4095.60, Nint=078, Nfrac=099)
-Fch=2048.00 (Fvco=4096.00, Nint=078, Nfrac=100)
-Fch=2048.20 (Fvco=4096.40, Nint=078, Nfrac=101)
-Fch=2048.40 (Fvco=4096.80, Nint=078, Nfrac=102)
-Fch=2048.60 (Fvco=4097.20, Nint=078, Nfrac=103)
-Fch=2048.80 (Fvco=4097.60, Nint=078, Nfrac=104)
-Fch=2049.00 (Fvco=4098.00, Nint=078, Nfrac=105)
-Fch=2049.20 (Fvco=4098.40, Nint=078, Nfrac=106)
-Fch=2049.40 (Fvco=4098.80, Nint=078, Nfrac=107)
-Fch=2049.60 (Fvco=4099.20, Nint=078, Nfrac=108)
-Fch=2049.80 (Fvco=4099.60, Nint=078, Nfrac=109)
-Fch=2050.00 (Fvco=4100.00, Nint=078, Nfrac=110)
-Fch=2050.20 (Fvco=4100.40, Nint=078, Nfrac=111)
-Fch=2050.40 (Fvco=4100.80, Nint=078, Nfrac=112)
-Fch=2050.60 (Fvco=4101.20, Nint=078, Nfrac=113)
-Fch=2050.80 (Fvco=4101.60, Nint=078, Nfrac=114)
-Fch=2051.00 (Fvco=4102.00, Nint=078, Nfrac=115)
-Fch=2051.20 (Fvco=4102.40, Nint=078, Nfrac=116)
-Fch=2051.40 (Fvco=4102.80, Nint=078, Nfrac=117)
-Fch=2051.60 (Fvco=4103.20, Nint=078, Nfrac=118)
-Fch=2051.80 (Fvco=4103.60, Nint=078, Nfrac=119)
-Fch=2052.00 (Fvco=4104.00, Nint=078, Nfrac=120)
-Fch=2052.20 (Fvco=4104.40, Nint=078, Nfrac=121)
-Fch=2052.40 (Fvco=4104.80, Nint=078, Nfrac=122)
-Fch=2052.60 (Fvco=4105.20, Nint=078, Nfrac=123)
-Fch=2052.80 (Fvco=4105.60, Nint=078, Nfrac=124)
-Fch=2053.00 (Fvco=4106.00, Nint=078, Nfrac=125)
-Fch=2053.20 (Fvco=4106.40, Nint=078, Nfrac=126)
-Fch=2053.40 (Fvco=4106.80, Nint=078, Nfrac=127)
-Fch=2053.60 (Fvco=4107.20, Nint=078, Nfrac=128)
-Fch=2053.80 (Fvco=4107.60, Nint=078, Nfrac=129)
-Fch=2054.00 (Fvco=4108.00, Nint=078, Nfrac=130)
-Fch=2054.00 (Fvco=4108.00, Nint=079, Nfrac=000)
-Fch=2054.20 (Fvco=4108.40, Nint=079, Nfrac=001)
-Fch=2054.40 (Fvco=4108.80, Nint=079, Nfrac=002)
-Fch=2054.60 (Fvco=4109.20, Nint=079, Nfrac=003)
-Fch=2054.80 (Fvco=4109.60, Nint=079, Nfrac=004)
-Fch=2055.00 (Fvco=4110.00, Nint=079, Nfrac=005)
-Fch=2055.20 (Fvco=4110.40, Nint=079, Nfrac=006)
-Fch=2055.40 (Fvco=4110.80, Nint=079, Nfrac=007)
-Fch=2055.60 (Fvco=4111.20, Nint=079, Nfrac=008)
-Fch=2055.80 (Fvco=4111.60, Nint=079, Nfrac=009)
-Fch=2056.00 (Fvco=4112.00, Nint=079, Nfrac=010)
-Fch=2056.20 (Fvco=4112.40, Nint=079, Nfrac=011)
-Fch=2056.40 (Fvco=4112.80, Nint=079, Nfrac=012)
-Fch=2056.60 (Fvco=4113.20, Nint=079, Nfrac=013)
-Fch=2056.80 (Fvco=4113.60, Nint=079, Nfrac=014)
-Fch=2057.00 (Fvco=4114.00, Nint=079, Nfrac=015)
-Fch=2057.20 (Fvco=4114.40, Nint=079, Nfrac=016)
-Fch=2057.40 (Fvco=4114.80, Nint=079, Nfrac=017)
-Fch=2057.60 (Fvco=4115.20, Nint=079, Nfrac=018)
-Fch=2057.80 (Fvco=4115.60, Nint=079, Nfrac=019)
-Fch=2058.00 (Fvco=4116.00, Nint=079, Nfrac=020)
-Fch=2058.20 (Fvco=4116.40, Nint=079, Nfrac=021)
-Fch=2058.40 (Fvco=4116.80, Nint=079, Nfrac=022)
-Fch=2058.60 (Fvco=4117.20, Nint=079, Nfrac=023)
-Fch=2058.80 (Fvco=4117.60, Nint=079, Nfrac=024)
-Fch=2059.00 (Fvco=4118.00, Nint=079, Nfrac=025)
-Fch=2059.20 (Fvco=4118.40, Nint=079, Nfrac=026)
-Fch=2059.40 (Fvco=4118.80, Nint=079, Nfrac=027)
-Fch=2059.60 (Fvco=4119.20, Nint=079, Nfrac=028)
-Fch=2059.80 (Fvco=4119.60, Nint=079, Nfrac=029)
-Fch=2060.00 (Fvco=4120.00, Nint=079, Nfrac=030)
-Fch=2060.20 (Fvco=4120.40, Nint=079, Nfrac=031)
-Fch=2060.40 (Fvco=4120.80, Nint=079, Nfrac=032)
-Fch=2060.60 (Fvco=4121.20, Nint=079, Nfrac=033)
-Fch=2060.80 (Fvco=4121.60, Nint=079, Nfrac=034)
-Fch=2061.00 (Fvco=4122.00, Nint=079, Nfrac=035)
-Fch=2061.20 (Fvco=4122.40, Nint=079, Nfrac=036)
-Fch=2061.40 (Fvco=4122.80, Nint=079, Nfrac=037)
-Fch=2061.60 (Fvco=4123.20, Nint=079, Nfrac=038)
-Fch=2061.80 (Fvco=4123.60, Nint=079, Nfrac=039)
-Fch=2062.00 (Fvco=4124.00, Nint=079, Nfrac=040)
-Fch=2062.20 (Fvco=4124.40, Nint=079, Nfrac=041)
-Fch=2062.40 (Fvco=4124.80, Nint=079, Nfrac=042)
-Fch=2062.60 (Fvco=4125.20, Nint=079, Nfrac=043)
-Fch=2062.80 (Fvco=4125.60, Nint=079, Nfrac=044)
-Fch=2063.00 (Fvco=4126.00, Nint=079, Nfrac=045)
-Fch=2063.20 (Fvco=4126.40, Nint=079, Nfrac=046)
-Fch=2063.40 (Fvco=4126.80, Nint=079, Nfrac=047)
-Fch=2063.60 (Fvco=4127.20, Nint=079, Nfrac=048)
-Fch=2063.80 (Fvco=4127.60, Nint=079, Nfrac=049)
-Fch=2064.00 (Fvco=4128.00, Nint=079, Nfrac=050)
-Fch=2064.20 (Fvco=4128.40, Nint=079, Nfrac=051)
-Fch=2064.40 (Fvco=4128.80, Nint=079, Nfrac=052)
-Fch=2064.60 (Fvco=4129.20, Nint=079, Nfrac=053)
-Fch=2064.80 (Fvco=4129.60, Nint=079, Nfrac=054)
-Fch=2065.00 (Fvco=4130.00, Nint=079, Nfrac=055)
-Fch=2065.20 (Fvco=4130.40, Nint=079, Nfrac=056)
-Fch=2065.40 (Fvco=4130.80, Nint=079, Nfrac=057)
-Fch=2065.60 (Fvco=4131.20, Nint=079, Nfrac=058)
-Fch=2065.80 (Fvco=4131.60, Nint=079, Nfrac=059)
-Fch=2066.00 (Fvco=4132.00, Nint=079, Nfrac=060)
-Fch=2066.20 (Fvco=4132.40, Nint=079, Nfrac=061)
-Fch=2066.40 (Fvco=4132.80, Nint=079, Nfrac=062)
-Fch=2066.60 (Fvco=4133.20, Nint=079, Nfrac=063)
-Fch=2066.80 (Fvco=4133.60, Nint=079, Nfrac=064)
-Fch=2067.00 (Fvco=4134.00, Nint=079, Nfrac=065)
-Fch=2067.20 (Fvco=4134.40, Nint=079, Nfrac=066)
-Fch=2067.40 (Fvco=4134.80, Nint=079, Nfrac=067)
-Fch=2067.60 (Fvco=4135.20, Nint=079, Nfrac=068)
-Fch=2067.80 (Fvco=4135.60, Nint=079, Nfrac=069)
-Fch=2068.00 (Fvco=4136.00, Nint=079, Nfrac=070)
-Fch=2068.20 (Fvco=4136.40, Nint=079, Nfrac=071)
-Fch=2068.40 (Fvco=4136.80, Nint=079, Nfrac=072)
-Fch=2068.60 (Fvco=4137.20, Nint=079, Nfrac=073)
-Fch=2068.80 (Fvco=4137.60, Nint=079, Nfrac=074)
-Fch=2069.00 (Fvco=4138.00, Nint=079, Nfrac=075)
-Fch=2069.20 (Fvco=4138.40, Nint=079, Nfrac=076)
-Fch=2069.40 (Fvco=4138.80, Nint=079, Nfrac=077)
-Fch=2069.60 (Fvco=4139.20, Nint=079, Nfrac=078)
-Fch=2069.80 (Fvco=4139.60, Nint=079, Nfrac=079)
-Fch=2070.00 (Fvco=4140.00, Nint=079, Nfrac=080)
-Fch=2070.20 (Fvco=4140.40, Nint=079, Nfrac=081)
-Fch=2070.40 (Fvco=4140.80, Nint=079, Nfrac=082)
-Fch=2070.60 (Fvco=4141.20, Nint=079, Nfrac=083)
-Fch=2070.80 (Fvco=4141.60, Nint=079, Nfrac=084)
-Fch=2071.00 (Fvco=4142.00, Nint=079, Nfrac=085)
-Fch=2071.20 (Fvco=4142.40, Nint=079, Nfrac=086)
-Fch=2071.40 (Fvco=4142.80, Nint=079, Nfrac=087)
-Fch=2071.60 (Fvco=4143.20, Nint=079, Nfrac=088)
-Fch=2071.80 (Fvco=4143.60, Nint=079, Nfrac=089)
-Fch=2072.00 (Fvco=4144.00, Nint=079, Nfrac=090)
-Fch=2072.20 (Fvco=4144.40, Nint=079, Nfrac=091)
-Fch=2072.40 (Fvco=4144.80, Nint=079, Nfrac=092)
-Fch=2072.60 (Fvco=4145.20, Nint=079, Nfrac=093)
-Fch=2072.80 (Fvco=4145.60, Nint=079, Nfrac=094)
-Fch=2073.00 (Fvco=4146.00, Nint=079, Nfrac=095)
-Fch=2073.20 (Fvco=4146.40, Nint=079, Nfrac=096)
-Fch=2073.40 (Fvco=4146.80, Nint=079, Nfrac=097)
-Fch=2073.60 (Fvco=4147.20, Nint=079, Nfrac=098)
-Fch=2073.80 (Fvco=4147.60, Nint=079, Nfrac=099)
-Fch=2074.00 (Fvco=4148.00, Nint=079, Nfrac=100)
-Fch=2074.20 (Fvco=4148.40, Nint=079, Nfrac=101)
-Fch=2074.40 (Fvco=4148.80, Nint=079, Nfrac=102)
-Fch=2074.60 (Fvco=4149.20, Nint=079, Nfrac=103)
-Fch=2074.80 (Fvco=4149.60, Nint=079, Nfrac=104)
-Fch=2075.00 (Fvco=4150.00, Nint=079, Nfrac=105)
-Fch=2075.20 (Fvco=4150.40, Nint=079, Nfrac=106)
-Fch=2075.40 (Fvco=4150.80, Nint=079, Nfrac=107)
-Fch=2075.60 (Fvco=4151.20, Nint=079, Nfrac=108)
-Fch=2075.80 (Fvco=4151.60, Nint=079, Nfrac=109)
-Fch=2076.00 (Fvco=4152.00, Nint=079, Nfrac=110)
-Fch=2076.20 (Fvco=4152.40, Nint=079, Nfrac=111)
-Fch=2076.40 (Fvco=4152.80, Nint=079, Nfrac=112)
-Fch=2076.60 (Fvco=4153.20, Nint=079, Nfrac=113)
-Fch=2076.80 (Fvco=4153.60, Nint=079, Nfrac=114)
-Fch=2077.00 (Fvco=4154.00, Nint=079, Nfrac=115)
-Fch=2077.20 (Fvco=4154.40, Nint=079, Nfrac=116)
-Fch=2077.40 (Fvco=4154.80, Nint=079, Nfrac=117)
-Fch=2077.60 (Fvco=4155.20, Nint=079, Nfrac=118)
-Fch=2077.80 (Fvco=4155.60, Nint=079, Nfrac=119)
-Fch=2078.00 (Fvco=4156.00, Nint=079, Nfrac=120)
-Fch=2078.20 (Fvco=4156.40, Nint=079, Nfrac=121)
-Fch=2078.40 (Fvco=4156.80, Nint=079, Nfrac=122)
-Fch=2078.60 (Fvco=4157.20, Nint=079, Nfrac=123)
-Fch=2078.80 (Fvco=4157.60, Nint=079, Nfrac=124)
-Fch=2079.00 (Fvco=4158.00, Nint=079, Nfrac=125)
-Fch=2079.20 (Fvco=4158.40, Nint=079, Nfrac=126)
-Fch=2079.40 (Fvco=4158.80, Nint=079, Nfrac=127)
-Fch=2079.60 (Fvco=4159.20, Nint=079, Nfrac=128)
-Fch=2079.80 (Fvco=4159.60, Nint=079, Nfrac=129)
-Fch=2080.00 (Fvco=4160.00, Nint=079, Nfrac=130)
-======================================================================
-PLL Tx Low Band:
-Fch=819.00 (Fvco=3276.00, Nint=063, Nfrac=000)
-Fch=819.10 (Fvco=3276.40, Nint=063, Nfrac=001)
-Fch=819.20 (Fvco=3276.80, Nint=063, Nfrac=002)
-Fch=819.30 (Fvco=3277.20, Nint=063, Nfrac=003)
-Fch=819.40 (Fvco=3277.60, Nint=063, Nfrac=004)
-Fch=819.50 (Fvco=3278.00, Nint=063, Nfrac=005)
-Fch=819.60 (Fvco=3278.40, Nint=063, Nfrac=006)
-Fch=819.70 (Fvco=3278.80, Nint=063, Nfrac=007)
-Fch=819.80 (Fvco=3279.20, Nint=063, Nfrac=008)
-Fch=819.90 (Fvco=3279.60, Nint=063, Nfrac=009)
-Fch=820.00 (Fvco=3280.00, Nint=063, Nfrac=010)
-Fch=820.10 (Fvco=3280.40, Nint=063, Nfrac=011)
-Fch=820.20 (Fvco=3280.80, Nint=063, Nfrac=012)
-Fch=820.30 (Fvco=3281.20, Nint=063, Nfrac=013)
-Fch=820.40 (Fvco=3281.60, Nint=063, Nfrac=014)
-Fch=820.50 (Fvco=3282.00, Nint=063, Nfrac=015)
-Fch=820.60 (Fvco=3282.40, Nint=063, Nfrac=016)
-Fch=820.70 (Fvco=3282.80, Nint=063, Nfrac=017)
-Fch=820.80 (Fvco=3283.20, Nint=063, Nfrac=018)
-Fch=820.90 (Fvco=3283.60, Nint=063, Nfrac=019)
-Fch=821.00 (Fvco=3284.00, Nint=063, Nfrac=020)
-Fch=821.10 (Fvco=3284.40, Nint=063, Nfrac=021)
-Fch=821.20 (Fvco=3284.80, Nint=063, Nfrac=022)
-Fch=821.30 (Fvco=3285.20, Nint=063, Nfrac=023)
-Fch=821.40 (Fvco=3285.60, Nint=063, Nfrac=024)
-Fch=821.50 (Fvco=3286.00, Nint=063, Nfrac=025)
-Fch=821.60 (Fvco=3286.40, Nint=063, Nfrac=026)
-Fch=821.70 (Fvco=3286.80, Nint=063, Nfrac=027)
-Fch=821.80 (Fvco=3287.20, Nint=063, Nfrac=028)
-Fch=821.90 (Fvco=3287.60, Nint=063, Nfrac=029)
-Fch=822.00 (Fvco=3288.00, Nint=063, Nfrac=030)
-Fch=822.10 (Fvco=3288.40, Nint=063, Nfrac=031)
-Fch=822.20 (Fvco=3288.80, Nint=063, Nfrac=032)
-Fch=822.30 (Fvco=3289.20, Nint=063, Nfrac=033)
-Fch=822.40 (Fvco=3289.60, Nint=063, Nfrac=034)
-Fch=822.50 (Fvco=3290.00, Nint=063, Nfrac=035)
-Fch=822.60 (Fvco=3290.40, Nint=063, Nfrac=036)
-Fch=822.70 (Fvco=3290.80, Nint=063, Nfrac=037)
-Fch=822.80 (Fvco=3291.20, Nint=063, Nfrac=038)
-Fch=822.90 (Fvco=3291.60, Nint=063, Nfrac=039)
-Fch=823.00 (Fvco=3292.00, Nint=063, Nfrac=040)
-Fch=823.10 (Fvco=3292.40, Nint=063, Nfrac=041)
-Fch=823.20 (Fvco=3292.80, Nint=063, Nfrac=042)
-Fch=823.30 (Fvco=3293.20, Nint=063, Nfrac=043)
-Fch=823.40 (Fvco=3293.60, Nint=063, Nfrac=044)
-Fch=823.50 (Fvco=3294.00, Nint=063, Nfrac=045)
-Fch=823.60 (Fvco=3294.40, Nint=063, Nfrac=046)
-Fch=823.70 (Fvco=3294.80, Nint=063, Nfrac=047)
-Fch=823.80 (Fvco=3295.20, Nint=063, Nfrac=048)
-Fch=823.90 (Fvco=3295.60, Nint=063, Nfrac=049)
-Fch=824.00 (Fvco=3296.00, Nint=063, Nfrac=050)
-Fch=824.10 (Fvco=3296.40, Nint=063, Nfrac=051)
-Fch=824.20 (Fvco=3296.80, Nint=063, Nfrac=052)
-Fch=824.30 (Fvco=3297.20, Nint=063, Nfrac=053)
-Fch=824.40 (Fvco=3297.60, Nint=063, Nfrac=054)
-Fch=824.50 (Fvco=3298.00, Nint=063, Nfrac=055)
-Fch=824.60 (Fvco=3298.40, Nint=063, Nfrac=056)
-Fch=824.70 (Fvco=3298.80, Nint=063, Nfrac=057)
-Fch=824.80 (Fvco=3299.20, Nint=063, Nfrac=058)
-Fch=824.90 (Fvco=3299.60, Nint=063, Nfrac=059)
-Fch=825.00 (Fvco=3300.00, Nint=063, Nfrac=060)
-Fch=825.10 (Fvco=3300.40, Nint=063, Nfrac=061)
-Fch=825.20 (Fvco=3300.80, Nint=063, Nfrac=062)
-Fch=825.30 (Fvco=3301.20, Nint=063, Nfrac=063)
-Fch=825.40 (Fvco=3301.60, Nint=063, Nfrac=064)
-Fch=825.50 (Fvco=3302.00, Nint=063, Nfrac=065)
-Fch=825.60 (Fvco=3302.40, Nint=063, Nfrac=066)
-Fch=825.70 (Fvco=3302.80, Nint=063, Nfrac=067)
-Fch=825.80 (Fvco=3303.20, Nint=063, Nfrac=068)
-Fch=825.90 (Fvco=3303.60, Nint=063, Nfrac=069)
-Fch=826.00 (Fvco=3304.00, Nint=063, Nfrac=070)
-Fch=826.10 (Fvco=3304.40, Nint=063, Nfrac=071)
-Fch=826.20 (Fvco=3304.80, Nint=063, Nfrac=072)
-Fch=826.30 (Fvco=3305.20, Nint=063, Nfrac=073)
-Fch=826.40 (Fvco=3305.60, Nint=063, Nfrac=074)
-Fch=826.50 (Fvco=3306.00, Nint=063, Nfrac=075)
-Fch=826.60 (Fvco=3306.40, Nint=063, Nfrac=076)
-Fch=826.70 (Fvco=3306.80, Nint=063, Nfrac=077)
-Fch=826.80 (Fvco=3307.20, Nint=063, Nfrac=078)
-Fch=826.90 (Fvco=3307.60, Nint=063, Nfrac=079)
-Fch=827.00 (Fvco=3308.00, Nint=063, Nfrac=080)
-Fch=827.10 (Fvco=3308.40, Nint=063, Nfrac=081)
-Fch=827.20 (Fvco=3308.80, Nint=063, Nfrac=082)
-Fch=827.30 (Fvco=3309.20, Nint=063, Nfrac=083)
-Fch=827.40 (Fvco=3309.60, Nint=063, Nfrac=084)
-Fch=827.50 (Fvco=3310.00, Nint=063, Nfrac=085)
-Fch=827.60 (Fvco=3310.40, Nint=063, Nfrac=086)
-Fch=827.70 (Fvco=3310.80, Nint=063, Nfrac=087)
-Fch=827.80 (Fvco=3311.20, Nint=063, Nfrac=088)
-Fch=827.90 (Fvco=3311.60, Nint=063, Nfrac=089)
-Fch=828.00 (Fvco=3312.00, Nint=063, Nfrac=090)
-Fch=828.10 (Fvco=3312.40, Nint=063, Nfrac=091)
-Fch=828.20 (Fvco=3312.80, Nint=063, Nfrac=092)
-Fch=828.30 (Fvco=3313.20, Nint=063, Nfrac=093)
-Fch=828.40 (Fvco=3313.60, Nint=063, Nfrac=094)
-Fch=828.50 (Fvco=3314.00, Nint=063, Nfrac=095)
-Fch=828.60 (Fvco=3314.40, Nint=063, Nfrac=096)
-Fch=828.70 (Fvco=3314.80, Nint=063, Nfrac=097)
-Fch=828.80 (Fvco=3315.20, Nint=063, Nfrac=098)
-Fch=828.90 (Fvco=3315.60, Nint=063, Nfrac=099)
-Fch=829.00 (Fvco=3316.00, Nint=063, Nfrac=100)
-Fch=829.10 (Fvco=3316.40, Nint=063, Nfrac=101)
-Fch=829.20 (Fvco=3316.80, Nint=063, Nfrac=102)
-Fch=829.30 (Fvco=3317.20, Nint=063, Nfrac=103)
-Fch=829.40 (Fvco=3317.60, Nint=063, Nfrac=104)
-Fch=829.50 (Fvco=3318.00, Nint=063, Nfrac=105)
-Fch=829.60 (Fvco=3318.40, Nint=063, Nfrac=106)
-Fch=829.70 (Fvco=3318.80, Nint=063, Nfrac=107)
-Fch=829.80 (Fvco=3319.20, Nint=063, Nfrac=108)
-Fch=829.90 (Fvco=3319.60, Nint=063, Nfrac=109)
-Fch=830.00 (Fvco=3320.00, Nint=063, Nfrac=110)
-Fch=830.10 (Fvco=3320.40, Nint=063, Nfrac=111)
-Fch=830.20 (Fvco=3320.80, Nint=063, Nfrac=112)
-Fch=830.30 (Fvco=3321.20, Nint=063, Nfrac=113)
-Fch=830.40 (Fvco=3321.60, Nint=063, Nfrac=114)
-Fch=830.50 (Fvco=3322.00, Nint=063, Nfrac=115)
-Fch=830.60 (Fvco=3322.40, Nint=063, Nfrac=116)
-Fch=830.70 (Fvco=3322.80, Nint=063, Nfrac=117)
-Fch=830.80 (Fvco=3323.20, Nint=063, Nfrac=118)
-Fch=830.90 (Fvco=3323.60, Nint=063, Nfrac=119)
-Fch=831.00 (Fvco=3324.00, Nint=063, Nfrac=120)
-Fch=831.10 (Fvco=3324.40, Nint=063, Nfrac=121)
-Fch=831.20 (Fvco=3324.80, Nint=063, Nfrac=122)
-Fch=831.30 (Fvco=3325.20, Nint=063, Nfrac=123)
-Fch=831.40 (Fvco=3325.60, Nint=063, Nfrac=124)
-Fch=831.50 (Fvco=3326.00, Nint=063, Nfrac=125)
-Fch=831.60 (Fvco=3326.40, Nint=063, Nfrac=126)
-Fch=831.70 (Fvco=3326.80, Nint=063, Nfrac=127)
-Fch=831.80 (Fvco=3327.20, Nint=063, Nfrac=128)
-Fch=831.90 (Fvco=3327.60, Nint=063, Nfrac=129)
-Fch=832.00 (Fvco=3328.00, Nint=063, Nfrac=130)
-Fch=832.00 (Fvco=3328.00, Nint=064, Nfrac=000)
-Fch=832.10 (Fvco=3328.40, Nint=064, Nfrac=001)
-Fch=832.20 (Fvco=3328.80, Nint=064, Nfrac=002)
-Fch=832.30 (Fvco=3329.20, Nint=064, Nfrac=003)
-Fch=832.40 (Fvco=3329.60, Nint=064, Nfrac=004)
-Fch=832.50 (Fvco=3330.00, Nint=064, Nfrac=005)
-Fch=832.60 (Fvco=3330.40, Nint=064, Nfrac=006)
-Fch=832.70 (Fvco=3330.80, Nint=064, Nfrac=007)
-Fch=832.80 (Fvco=3331.20, Nint=064, Nfrac=008)
-Fch=832.90 (Fvco=3331.60, Nint=064, Nfrac=009)
-Fch=833.00 (Fvco=3332.00, Nint=064, Nfrac=010)
-Fch=833.10 (Fvco=3332.40, Nint=064, Nfrac=011)
-Fch=833.20 (Fvco=3332.80, Nint=064, Nfrac=012)
-Fch=833.30 (Fvco=3333.20, Nint=064, Nfrac=013)
-Fch=833.40 (Fvco=3333.60, Nint=064, Nfrac=014)
-Fch=833.50 (Fvco=3334.00, Nint=064, Nfrac=015)
-Fch=833.60 (Fvco=3334.40, Nint=064, Nfrac=016)
-Fch=833.70 (Fvco=3334.80, Nint=064, Nfrac=017)
-Fch=833.80 (Fvco=3335.20, Nint=064, Nfrac=018)
-Fch=833.90 (Fvco=3335.60, Nint=064, Nfrac=019)
-Fch=834.00 (Fvco=3336.00, Nint=064, Nfrac=020)
-Fch=834.10 (Fvco=3336.40, Nint=064, Nfrac=021)
-Fch=834.20 (Fvco=3336.80, Nint=064, Nfrac=022)
-Fch=834.30 (Fvco=3337.20, Nint=064, Nfrac=023)
-Fch=834.40 (Fvco=3337.60, Nint=064, Nfrac=024)
-Fch=834.50 (Fvco=3338.00, Nint=064, Nfrac=025)
-Fch=834.60 (Fvco=3338.40, Nint=064, Nfrac=026)
-Fch=834.70 (Fvco=3338.80, Nint=064, Nfrac=027)
-Fch=834.80 (Fvco=3339.20, Nint=064, Nfrac=028)
-Fch=834.90 (Fvco=3339.60, Nint=064, Nfrac=029)
-Fch=835.00 (Fvco=3340.00, Nint=064, Nfrac=030)
-Fch=835.10 (Fvco=3340.40, Nint=064, Nfrac=031)
-Fch=835.20 (Fvco=3340.80, Nint=064, Nfrac=032)
-Fch=835.30 (Fvco=3341.20, Nint=064, Nfrac=033)
-Fch=835.40 (Fvco=3341.60, Nint=064, Nfrac=034)
-Fch=835.50 (Fvco=3342.00, Nint=064, Nfrac=035)
-Fch=835.60 (Fvco=3342.40, Nint=064, Nfrac=036)
-Fch=835.70 (Fvco=3342.80, Nint=064, Nfrac=037)
-Fch=835.80 (Fvco=3343.20, Nint=064, Nfrac=038)
-Fch=835.90 (Fvco=3343.60, Nint=064, Nfrac=039)
-Fch=836.00 (Fvco=3344.00, Nint=064, Nfrac=040)
-Fch=836.10 (Fvco=3344.40, Nint=064, Nfrac=041)
-Fch=836.20 (Fvco=3344.80, Nint=064, Nfrac=042)
-Fch=836.30 (Fvco=3345.20, Nint=064, Nfrac=043)
-Fch=836.40 (Fvco=3345.60, Nint=064, Nfrac=044)
-Fch=836.50 (Fvco=3346.00, Nint=064, Nfrac=045)
-Fch=836.60 (Fvco=3346.40, Nint=064, Nfrac=046)
-Fch=836.70 (Fvco=3346.80, Nint=064, Nfrac=047)
-Fch=836.80 (Fvco=3347.20, Nint=064, Nfrac=048)
-Fch=836.90 (Fvco=3347.60, Nint=064, Nfrac=049)
-Fch=837.00 (Fvco=3348.00, Nint=064, Nfrac=050)
-Fch=837.10 (Fvco=3348.40, Nint=064, Nfrac=051)
-Fch=837.20 (Fvco=3348.80, Nint=064, Nfrac=052)
-Fch=837.30 (Fvco=3349.20, Nint=064, Nfrac=053)
-Fch=837.40 (Fvco=3349.60, Nint=064, Nfrac=054)
-Fch=837.50 (Fvco=3350.00, Nint=064, Nfrac=055)
-Fch=837.60 (Fvco=3350.40, Nint=064, Nfrac=056)
-Fch=837.70 (Fvco=3350.80, Nint=064, Nfrac=057)
-Fch=837.80 (Fvco=3351.20, Nint=064, Nfrac=058)
-Fch=837.90 (Fvco=3351.60, Nint=064, Nfrac=059)
-Fch=838.00 (Fvco=3352.00, Nint=064, Nfrac=060)
-Fch=838.10 (Fvco=3352.40, Nint=064, Nfrac=061)
-Fch=838.20 (Fvco=3352.80, Nint=064, Nfrac=062)
-Fch=838.30 (Fvco=3353.20, Nint=064, Nfrac=063)
-Fch=838.40 (Fvco=3353.60, Nint=064, Nfrac=064)
-Fch=838.50 (Fvco=3354.00, Nint=064, Nfrac=065)
-Fch=838.60 (Fvco=3354.40, Nint=064, Nfrac=066)
-Fch=838.70 (Fvco=3354.80, Nint=064, Nfrac=067)
-Fch=838.80 (Fvco=3355.20, Nint=064, Nfrac=068)
-Fch=838.90 (Fvco=3355.60, Nint=064, Nfrac=069)
-Fch=839.00 (Fvco=3356.00, Nint=064, Nfrac=070)
-Fch=839.10 (Fvco=3356.40, Nint=064, Nfrac=071)
-Fch=839.20 (Fvco=3356.80, Nint=064, Nfrac=072)
-Fch=839.30 (Fvco=3357.20, Nint=064, Nfrac=073)
-Fch=839.40 (Fvco=3357.60, Nint=064, Nfrac=074)
-Fch=839.50 (Fvco=3358.00, Nint=064, Nfrac=075)
-Fch=839.60 (Fvco=3358.40, Nint=064, Nfrac=076)
-Fch=839.70 (Fvco=3358.80, Nint=064, Nfrac=077)
-Fch=839.80 (Fvco=3359.20, Nint=064, Nfrac=078)
-Fch=839.90 (Fvco=3359.60, Nint=064, Nfrac=079)
-Fch=840.00 (Fvco=3360.00, Nint=064, Nfrac=080)
-Fch=840.10 (Fvco=3360.40, Nint=064, Nfrac=081)
-Fch=840.20 (Fvco=3360.80, Nint=064, Nfrac=082)
-Fch=840.30 (Fvco=3361.20, Nint=064, Nfrac=083)
-Fch=840.40 (Fvco=3361.60, Nint=064, Nfrac=084)
-Fch=840.50 (Fvco=3362.00, Nint=064, Nfrac=085)
-Fch=840.60 (Fvco=3362.40, Nint=064, Nfrac=086)
-Fch=840.70 (Fvco=3362.80, Nint=064, Nfrac=087)
-Fch=840.80 (Fvco=3363.20, Nint=064, Nfrac=088)
-Fch=840.90 (Fvco=3363.60, Nint=064, Nfrac=089)
-Fch=841.00 (Fvco=3364.00, Nint=064, Nfrac=090)
-Fch=841.10 (Fvco=3364.40, Nint=064, Nfrac=091)
-Fch=841.20 (Fvco=3364.80, Nint=064, Nfrac=092)
-Fch=841.30 (Fvco=3365.20, Nint=064, Nfrac=093)
-Fch=841.40 (Fvco=3365.60, Nint=064, Nfrac=094)
-Fch=841.50 (Fvco=3366.00, Nint=064, Nfrac=095)
-Fch=841.60 (Fvco=3366.40, Nint=064, Nfrac=096)
-Fch=841.70 (Fvco=3366.80, Nint=064, Nfrac=097)
-Fch=841.80 (Fvco=3367.20, Nint=064, Nfrac=098)
-Fch=841.90 (Fvco=3367.60, Nint=064, Nfrac=099)
-Fch=842.00 (Fvco=3368.00, Nint=064, Nfrac=100)
-Fch=842.10 (Fvco=3368.40, Nint=064, Nfrac=101)
-Fch=842.20 (Fvco=3368.80, Nint=064, Nfrac=102)
-Fch=842.30 (Fvco=3369.20, Nint=064, Nfrac=103)
-Fch=842.40 (Fvco=3369.60, Nint=064, Nfrac=104)
-Fch=842.50 (Fvco=3370.00, Nint=064, Nfrac=105)
-Fch=842.60 (Fvco=3370.40, Nint=064, Nfrac=106)
-Fch=842.70 (Fvco=3370.80, Nint=064, Nfrac=107)
-Fch=842.80 (Fvco=3371.20, Nint=064, Nfrac=108)
-Fch=842.90 (Fvco=3371.60, Nint=064, Nfrac=109)
-Fch=843.00 (Fvco=3372.00, Nint=064, Nfrac=110)
-Fch=843.10 (Fvco=3372.40, Nint=064, Nfrac=111)
-Fch=843.20 (Fvco=3372.80, Nint=064, Nfrac=112)
-Fch=843.30 (Fvco=3373.20, Nint=064, Nfrac=113)
-Fch=843.40 (Fvco=3373.60, Nint=064, Nfrac=114)
-Fch=843.50 (Fvco=3374.00, Nint=064, Nfrac=115)
-Fch=843.60 (Fvco=3374.40, Nint=064, Nfrac=116)
-Fch=843.70 (Fvco=3374.80, Nint=064, Nfrac=117)
-Fch=843.80 (Fvco=3375.20, Nint=064, Nfrac=118)
-Fch=843.90 (Fvco=3375.60, Nint=064, Nfrac=119)
-Fch=844.00 (Fvco=3376.00, Nint=064, Nfrac=120)
-Fch=844.10 (Fvco=3376.40, Nint=064, Nfrac=121)
-Fch=844.20 (Fvco=3376.80, Nint=064, Nfrac=122)
-Fch=844.30 (Fvco=3377.20, Nint=064, Nfrac=123)
-Fch=844.40 (Fvco=3377.60, Nint=064, Nfrac=124)
-Fch=844.50 (Fvco=3378.00, Nint=064, Nfrac=125)
-Fch=844.60 (Fvco=3378.40, Nint=064, Nfrac=126)
-Fch=844.70 (Fvco=3378.80, Nint=064, Nfrac=127)
-Fch=844.80 (Fvco=3379.20, Nint=064, Nfrac=128)
-Fch=844.90 (Fvco=3379.60, Nint=064, Nfrac=129)
-Fch=845.00 (Fvco=3380.00, Nint=064, Nfrac=130)
-Fch=845.00 (Fvco=3380.00, Nint=065, Nfrac=000)
-Fch=845.10 (Fvco=3380.40, Nint=065, Nfrac=001)
-Fch=845.20 (Fvco=3380.80, Nint=065, Nfrac=002)
-Fch=845.30 (Fvco=3381.20, Nint=065, Nfrac=003)
-Fch=845.40 (Fvco=3381.60, Nint=065, Nfrac=004)
-Fch=845.50 (Fvco=3382.00, Nint=065, Nfrac=005)
-Fch=845.60 (Fvco=3382.40, Nint=065, Nfrac=006)
-Fch=845.70 (Fvco=3382.80, Nint=065, Nfrac=007)
-Fch=845.80 (Fvco=3383.20, Nint=065, Nfrac=008)
-Fch=845.90 (Fvco=3383.60, Nint=065, Nfrac=009)
-Fch=846.00 (Fvco=3384.00, Nint=065, Nfrac=010)
-Fch=846.10 (Fvco=3384.40, Nint=065, Nfrac=011)
-Fch=846.20 (Fvco=3384.80, Nint=065, Nfrac=012)
-Fch=846.30 (Fvco=3385.20, Nint=065, Nfrac=013)
-Fch=846.40 (Fvco=3385.60, Nint=065, Nfrac=014)
-Fch=846.50 (Fvco=3386.00, Nint=065, Nfrac=015)
-Fch=846.60 (Fvco=3386.40, Nint=065, Nfrac=016)
-Fch=846.70 (Fvco=3386.80, Nint=065, Nfrac=017)
-Fch=846.80 (Fvco=3387.20, Nint=065, Nfrac=018)
-Fch=846.90 (Fvco=3387.60, Nint=065, Nfrac=019)
-Fch=847.00 (Fvco=3388.00, Nint=065, Nfrac=020)
-Fch=847.10 (Fvco=3388.40, Nint=065, Nfrac=021)
-Fch=847.20 (Fvco=3388.80, Nint=065, Nfrac=022)
-Fch=847.30 (Fvco=3389.20, Nint=065, Nfrac=023)
-Fch=847.40 (Fvco=3389.60, Nint=065, Nfrac=024)
-Fch=847.50 (Fvco=3390.00, Nint=065, Nfrac=025)
-Fch=847.60 (Fvco=3390.40, Nint=065, Nfrac=026)
-Fch=847.70 (Fvco=3390.80, Nint=065, Nfrac=027)
-Fch=847.80 (Fvco=3391.20, Nint=065, Nfrac=028)
-Fch=847.90 (Fvco=3391.60, Nint=065, Nfrac=029)
-Fch=848.00 (Fvco=3392.00, Nint=065, Nfrac=030)
-Fch=848.10 (Fvco=3392.40, Nint=065, Nfrac=031)
-Fch=848.20 (Fvco=3392.80, Nint=065, Nfrac=032)
-Fch=848.30 (Fvco=3393.20, Nint=065, Nfrac=033)
-Fch=848.40 (Fvco=3393.60, Nint=065, Nfrac=034)
-Fch=848.50 (Fvco=3394.00, Nint=065, Nfrac=035)
-Fch=848.60 (Fvco=3394.40, Nint=065, Nfrac=036)
-Fch=848.70 (Fvco=3394.80, Nint=065, Nfrac=037)
-Fch=848.80 (Fvco=3395.20, Nint=065, Nfrac=038)
-Fch=848.90 (Fvco=3395.60, Nint=065, Nfrac=039)
-Fch=849.00 (Fvco=3396.00, Nint=065, Nfrac=040)
-Fch=849.10 (Fvco=3396.40, Nint=065, Nfrac=041)
-Fch=849.20 (Fvco=3396.80, Nint=065, Nfrac=042)
-Fch=849.30 (Fvco=3397.20, Nint=065, Nfrac=043)
-Fch=849.40 (Fvco=3397.60, Nint=065, Nfrac=044)
-Fch=849.50 (Fvco=3398.00, Nint=065, Nfrac=045)
-Fch=849.60 (Fvco=3398.40, Nint=065, Nfrac=046)
-Fch=849.70 (Fvco=3398.80, Nint=065, Nfrac=047)
-Fch=849.80 (Fvco=3399.20, Nint=065, Nfrac=048)
-Fch=849.90 (Fvco=3399.60, Nint=065, Nfrac=049)
-Fch=850.00 (Fvco=3400.00, Nint=065, Nfrac=050)
-Fch=850.10 (Fvco=3400.40, Nint=065, Nfrac=051)
-Fch=850.20 (Fvco=3400.80, Nint=065, Nfrac=052)
-Fch=850.30 (Fvco=3401.20, Nint=065, Nfrac=053)
-Fch=850.40 (Fvco=3401.60, Nint=065, Nfrac=054)
-Fch=850.50 (Fvco=3402.00, Nint=065, Nfrac=055)
-Fch=850.60 (Fvco=3402.40, Nint=065, Nfrac=056)
-Fch=850.70 (Fvco=3402.80, Nint=065, Nfrac=057)
-Fch=850.80 (Fvco=3403.20, Nint=065, Nfrac=058)
-Fch=850.90 (Fvco=3403.60, Nint=065, Nfrac=059)
-Fch=851.00 (Fvco=3404.00, Nint=065, Nfrac=060)
-Fch=851.10 (Fvco=3404.40, Nint=065, Nfrac=061)
-Fch=851.20 (Fvco=3404.80, Nint=065, Nfrac=062)
-Fch=851.30 (Fvco=3405.20, Nint=065, Nfrac=063)
-Fch=851.40 (Fvco=3405.60, Nint=065, Nfrac=064)
-Fch=851.50 (Fvco=3406.00, Nint=065, Nfrac=065)
-Fch=851.60 (Fvco=3406.40, Nint=065, Nfrac=066)
-Fch=851.70 (Fvco=3406.80, Nint=065, Nfrac=067)
-Fch=851.80 (Fvco=3407.20, Nint=065, Nfrac=068)
-Fch=851.90 (Fvco=3407.60, Nint=065, Nfrac=069)
-Fch=852.00 (Fvco=3408.00, Nint=065, Nfrac=070)
-Fch=852.10 (Fvco=3408.40, Nint=065, Nfrac=071)
-Fch=852.20 (Fvco=3408.80, Nint=065, Nfrac=072)
-Fch=852.30 (Fvco=3409.20, Nint=065, Nfrac=073)
-Fch=852.40 (Fvco=3409.60, Nint=065, Nfrac=074)
-Fch=852.50 (Fvco=3410.00, Nint=065, Nfrac=075)
-Fch=852.60 (Fvco=3410.40, Nint=065, Nfrac=076)
-Fch=852.70 (Fvco=3410.80, Nint=065, Nfrac=077)
-Fch=852.80 (Fvco=3411.20, Nint=065, Nfrac=078)
-Fch=852.90 (Fvco=3411.60, Nint=065, Nfrac=079)
-Fch=853.00 (Fvco=3412.00, Nint=065, Nfrac=080)
-Fch=853.10 (Fvco=3412.40, Nint=065, Nfrac=081)
-Fch=853.20 (Fvco=3412.80, Nint=065, Nfrac=082)
-Fch=853.30 (Fvco=3413.20, Nint=065, Nfrac=083)
-Fch=853.40 (Fvco=3413.60, Nint=065, Nfrac=084)
-Fch=853.50 (Fvco=3414.00, Nint=065, Nfrac=085)
-Fch=853.60 (Fvco=3414.40, Nint=065, Nfrac=086)
-Fch=853.70 (Fvco=3414.80, Nint=065, Nfrac=087)
-Fch=853.80 (Fvco=3415.20, Nint=065, Nfrac=088)
-Fch=853.90 (Fvco=3415.60, Nint=065, Nfrac=089)
-Fch=854.00 (Fvco=3416.00, Nint=065, Nfrac=090)
-Fch=854.10 (Fvco=3416.40, Nint=065, Nfrac=091)
-Fch=854.20 (Fvco=3416.80, Nint=065, Nfrac=092)
-Fch=854.30 (Fvco=3417.20, Nint=065, Nfrac=093)
-Fch=854.40 (Fvco=3417.60, Nint=065, Nfrac=094)
-Fch=854.50 (Fvco=3418.00, Nint=065, Nfrac=095)
-Fch=854.60 (Fvco=3418.40, Nint=065, Nfrac=096)
-Fch=854.70 (Fvco=3418.80, Nint=065, Nfrac=097)
-Fch=854.80 (Fvco=3419.20, Nint=065, Nfrac=098)
-Fch=854.90 (Fvco=3419.60, Nint=065, Nfrac=099)
-Fch=855.00 (Fvco=3420.00, Nint=065, Nfrac=100)
-Fch=855.10 (Fvco=3420.40, Nint=065, Nfrac=101)
-Fch=855.20 (Fvco=3420.80, Nint=065, Nfrac=102)
-Fch=855.30 (Fvco=3421.20, Nint=065, Nfrac=103)
-Fch=855.40 (Fvco=3421.60, Nint=065, Nfrac=104)
-Fch=855.50 (Fvco=3422.00, Nint=065, Nfrac=105)
-Fch=855.60 (Fvco=3422.40, Nint=065, Nfrac=106)
-Fch=855.70 (Fvco=3422.80, Nint=065, Nfrac=107)
-Fch=855.80 (Fvco=3423.20, Nint=065, Nfrac=108)
-Fch=855.90 (Fvco=3423.60, Nint=065, Nfrac=109)
-Fch=856.00 (Fvco=3424.00, Nint=065, Nfrac=110)
-Fch=856.10 (Fvco=3424.40, Nint=065, Nfrac=111)
-Fch=856.20 (Fvco=3424.80, Nint=065, Nfrac=112)
-Fch=856.30 (Fvco=3425.20, Nint=065, Nfrac=113)
-Fch=856.40 (Fvco=3425.60, Nint=065, Nfrac=114)
-Fch=856.50 (Fvco=3426.00, Nint=065, Nfrac=115)
-Fch=856.60 (Fvco=3426.40, Nint=065, Nfrac=116)
-Fch=856.70 (Fvco=3426.80, Nint=065, Nfrac=117)
-Fch=856.80 (Fvco=3427.20, Nint=065, Nfrac=118)
-Fch=856.90 (Fvco=3427.60, Nint=065, Nfrac=119)
-Fch=857.00 (Fvco=3428.00, Nint=065, Nfrac=120)
-Fch=857.10 (Fvco=3428.40, Nint=065, Nfrac=121)
-Fch=857.20 (Fvco=3428.80, Nint=065, Nfrac=122)
-Fch=857.30 (Fvco=3429.20, Nint=065, Nfrac=123)
-Fch=857.40 (Fvco=3429.60, Nint=065, Nfrac=124)
-Fch=857.50 (Fvco=3430.00, Nint=065, Nfrac=125)
-Fch=857.60 (Fvco=3430.40, Nint=065, Nfrac=126)
-Fch=857.70 (Fvco=3430.80, Nint=065, Nfrac=127)
-Fch=857.80 (Fvco=3431.20, Nint=065, Nfrac=128)
-Fch=857.90 (Fvco=3431.60, Nint=065, Nfrac=129)
-Fch=858.00 (Fvco=3432.00, Nint=065, Nfrac=130)
-Fch=858.00 (Fvco=3432.00, Nint=066, Nfrac=000)
-Fch=858.10 (Fvco=3432.40, Nint=066, Nfrac=001)
-Fch=858.20 (Fvco=3432.80, Nint=066, Nfrac=002)
-Fch=858.30 (Fvco=3433.20, Nint=066, Nfrac=003)
-Fch=858.40 (Fvco=3433.60, Nint=066, Nfrac=004)
-Fch=858.50 (Fvco=3434.00, Nint=066, Nfrac=005)
-Fch=858.60 (Fvco=3434.40, Nint=066, Nfrac=006)
-Fch=858.70 (Fvco=3434.80, Nint=066, Nfrac=007)
-Fch=858.80 (Fvco=3435.20, Nint=066, Nfrac=008)
-Fch=858.90 (Fvco=3435.60, Nint=066, Nfrac=009)
-Fch=859.00 (Fvco=3436.00, Nint=066, Nfrac=010)
-Fch=859.10 (Fvco=3436.40, Nint=066, Nfrac=011)
-Fch=859.20 (Fvco=3436.80, Nint=066, Nfrac=012)
-Fch=859.30 (Fvco=3437.20, Nint=066, Nfrac=013)
-Fch=859.40 (Fvco=3437.60, Nint=066, Nfrac=014)
-Fch=859.50 (Fvco=3438.00, Nint=066, Nfrac=015)
-Fch=859.60 (Fvco=3438.40, Nint=066, Nfrac=016)
-Fch=859.70 (Fvco=3438.80, Nint=066, Nfrac=017)
-Fch=859.80 (Fvco=3439.20, Nint=066, Nfrac=018)
-Fch=859.90 (Fvco=3439.60, Nint=066, Nfrac=019)
-Fch=860.00 (Fvco=3440.00, Nint=066, Nfrac=020)
-Fch=860.10 (Fvco=3440.40, Nint=066, Nfrac=021)
-Fch=860.20 (Fvco=3440.80, Nint=066, Nfrac=022)
-Fch=860.30 (Fvco=3441.20, Nint=066, Nfrac=023)
-Fch=860.40 (Fvco=3441.60, Nint=066, Nfrac=024)
-Fch=860.50 (Fvco=3442.00, Nint=066, Nfrac=025)
-Fch=860.60 (Fvco=3442.40, Nint=066, Nfrac=026)
-Fch=860.70 (Fvco=3442.80, Nint=066, Nfrac=027)
-Fch=860.80 (Fvco=3443.20, Nint=066, Nfrac=028)
-Fch=860.90 (Fvco=3443.60, Nint=066, Nfrac=029)
-Fch=861.00 (Fvco=3444.00, Nint=066, Nfrac=030)
-Fch=861.10 (Fvco=3444.40, Nint=066, Nfrac=031)
-Fch=861.20 (Fvco=3444.80, Nint=066, Nfrac=032)
-Fch=861.30 (Fvco=3445.20, Nint=066, Nfrac=033)
-Fch=861.40 (Fvco=3445.60, Nint=066, Nfrac=034)
-Fch=861.50 (Fvco=3446.00, Nint=066, Nfrac=035)
-Fch=861.60 (Fvco=3446.40, Nint=066, Nfrac=036)
-Fch=861.70 (Fvco=3446.80, Nint=066, Nfrac=037)
-Fch=861.80 (Fvco=3447.20, Nint=066, Nfrac=038)
-Fch=861.90 (Fvco=3447.60, Nint=066, Nfrac=039)
-Fch=862.00 (Fvco=3448.00, Nint=066, Nfrac=040)
-Fch=862.10 (Fvco=3448.40, Nint=066, Nfrac=041)
-Fch=862.20 (Fvco=3448.80, Nint=066, Nfrac=042)
-Fch=862.30 (Fvco=3449.20, Nint=066, Nfrac=043)
-Fch=862.40 (Fvco=3449.60, Nint=066, Nfrac=044)
-Fch=862.50 (Fvco=3450.00, Nint=066, Nfrac=045)
-Fch=862.60 (Fvco=3450.40, Nint=066, Nfrac=046)
-Fch=862.70 (Fvco=3450.80, Nint=066, Nfrac=047)
-Fch=862.80 (Fvco=3451.20, Nint=066, Nfrac=048)
-Fch=862.90 (Fvco=3451.60, Nint=066, Nfrac=049)
-Fch=863.00 (Fvco=3452.00, Nint=066, Nfrac=050)
-Fch=863.10 (Fvco=3452.40, Nint=066, Nfrac=051)
-Fch=863.20 (Fvco=3452.80, Nint=066, Nfrac=052)
-Fch=863.30 (Fvco=3453.20, Nint=066, Nfrac=053)
-Fch=863.40 (Fvco=3453.60, Nint=066, Nfrac=054)
-Fch=863.50 (Fvco=3454.00, Nint=066, Nfrac=055)
-Fch=863.60 (Fvco=3454.40, Nint=066, Nfrac=056)
-Fch=863.70 (Fvco=3454.80, Nint=066, Nfrac=057)
-Fch=863.80 (Fvco=3455.20, Nint=066, Nfrac=058)
-Fch=863.90 (Fvco=3455.60, Nint=066, Nfrac=059)
-Fch=864.00 (Fvco=3456.00, Nint=066, Nfrac=060)
-Fch=864.10 (Fvco=3456.40, Nint=066, Nfrac=061)
-Fch=864.20 (Fvco=3456.80, Nint=066, Nfrac=062)
-Fch=864.30 (Fvco=3457.20, Nint=066, Nfrac=063)
-Fch=864.40 (Fvco=3457.60, Nint=066, Nfrac=064)
-Fch=864.50 (Fvco=3458.00, Nint=066, Nfrac=065)
-Fch=864.60 (Fvco=3458.40, Nint=066, Nfrac=066)
-Fch=864.70 (Fvco=3458.80, Nint=066, Nfrac=067)
-Fch=864.80 (Fvco=3459.20, Nint=066, Nfrac=068)
-Fch=864.90 (Fvco=3459.60, Nint=066, Nfrac=069)
-Fch=865.00 (Fvco=3460.00, Nint=066, Nfrac=070)
-Fch=865.10 (Fvco=3460.40, Nint=066, Nfrac=071)
-Fch=865.20 (Fvco=3460.80, Nint=066, Nfrac=072)
-Fch=865.30 (Fvco=3461.20, Nint=066, Nfrac=073)
-Fch=865.40 (Fvco=3461.60, Nint=066, Nfrac=074)
-Fch=865.50 (Fvco=3462.00, Nint=066, Nfrac=075)
-Fch=865.60 (Fvco=3462.40, Nint=066, Nfrac=076)
-Fch=865.70 (Fvco=3462.80, Nint=066, Nfrac=077)
-Fch=865.80 (Fvco=3463.20, Nint=066, Nfrac=078)
-Fch=865.90 (Fvco=3463.60, Nint=066, Nfrac=079)
-Fch=866.00 (Fvco=3464.00, Nint=066, Nfrac=080)
-Fch=866.10 (Fvco=3464.40, Nint=066, Nfrac=081)
-Fch=866.20 (Fvco=3464.80, Nint=066, Nfrac=082)
-Fch=866.30 (Fvco=3465.20, Nint=066, Nfrac=083)
-Fch=866.40 (Fvco=3465.60, Nint=066, Nfrac=084)
-Fch=866.50 (Fvco=3466.00, Nint=066, Nfrac=085)
-Fch=866.60 (Fvco=3466.40, Nint=066, Nfrac=086)
-Fch=866.70 (Fvco=3466.80, Nint=066, Nfrac=087)
-Fch=866.80 (Fvco=3467.20, Nint=066, Nfrac=088)
-Fch=866.90 (Fvco=3467.60, Nint=066, Nfrac=089)
-Fch=867.00 (Fvco=3468.00, Nint=066, Nfrac=090)
-Fch=867.10 (Fvco=3468.40, Nint=066, Nfrac=091)
-Fch=867.20 (Fvco=3468.80, Nint=066, Nfrac=092)
-Fch=867.30 (Fvco=3469.20, Nint=066, Nfrac=093)
-Fch=867.40 (Fvco=3469.60, Nint=066, Nfrac=094)
-Fch=867.50 (Fvco=3470.00, Nint=066, Nfrac=095)
-Fch=867.60 (Fvco=3470.40, Nint=066, Nfrac=096)
-Fch=867.70 (Fvco=3470.80, Nint=066, Nfrac=097)
-Fch=867.80 (Fvco=3471.20, Nint=066, Nfrac=098)
-Fch=867.90 (Fvco=3471.60, Nint=066, Nfrac=099)
-Fch=868.00 (Fvco=3472.00, Nint=066, Nfrac=100)
-Fch=868.10 (Fvco=3472.40, Nint=066, Nfrac=101)
-Fch=868.20 (Fvco=3472.80, Nint=066, Nfrac=102)
-Fch=868.30 (Fvco=3473.20, Nint=066, Nfrac=103)
-Fch=868.40 (Fvco=3473.60, Nint=066, Nfrac=104)
-Fch=868.50 (Fvco=3474.00, Nint=066, Nfrac=105)
-Fch=868.60 (Fvco=3474.40, Nint=066, Nfrac=106)
-Fch=868.70 (Fvco=3474.80, Nint=066, Nfrac=107)
-Fch=868.80 (Fvco=3475.20, Nint=066, Nfrac=108)
-Fch=868.90 (Fvco=3475.60, Nint=066, Nfrac=109)
-Fch=869.00 (Fvco=3476.00, Nint=066, Nfrac=110)
-Fch=869.10 (Fvco=3476.40, Nint=066, Nfrac=111)
-Fch=869.20 (Fvco=3476.80, Nint=066, Nfrac=112)
-Fch=869.30 (Fvco=3477.20, Nint=066, Nfrac=113)
-Fch=869.40 (Fvco=3477.60, Nint=066, Nfrac=114)
-Fch=869.50 (Fvco=3478.00, Nint=066, Nfrac=115)
-Fch=869.60 (Fvco=3478.40, Nint=066, Nfrac=116)
-Fch=869.70 (Fvco=3478.80, Nint=066, Nfrac=117)
-Fch=869.80 (Fvco=3479.20, Nint=066, Nfrac=118)
-Fch=869.90 (Fvco=3479.60, Nint=066, Nfrac=119)
-Fch=870.00 (Fvco=3480.00, Nint=066, Nfrac=120)
-Fch=870.10 (Fvco=3480.40, Nint=066, Nfrac=121)
-Fch=870.20 (Fvco=3480.80, Nint=066, Nfrac=122)
-Fch=870.30 (Fvco=3481.20, Nint=066, Nfrac=123)
-Fch=870.40 (Fvco=3481.60, Nint=066, Nfrac=124)
-Fch=870.50 (Fvco=3482.00, Nint=066, Nfrac=125)
-Fch=870.60 (Fvco=3482.40, Nint=066, Nfrac=126)
-Fch=870.70 (Fvco=3482.80, Nint=066, Nfrac=127)
-Fch=870.80 (Fvco=3483.20, Nint=066, Nfrac=128)
-Fch=870.90 (Fvco=3483.60, Nint=066, Nfrac=129)
-Fch=871.00 (Fvco=3484.00, Nint=066, Nfrac=130)
-Fch=871.00 (Fvco=3484.00, Nint=067, Nfrac=000)
-Fch=871.10 (Fvco=3484.40, Nint=067, Nfrac=001)
-Fch=871.20 (Fvco=3484.80, Nint=067, Nfrac=002)
-Fch=871.30 (Fvco=3485.20, Nint=067, Nfrac=003)
-Fch=871.40 (Fvco=3485.60, Nint=067, Nfrac=004)
-Fch=871.50 (Fvco=3486.00, Nint=067, Nfrac=005)
-Fch=871.60 (Fvco=3486.40, Nint=067, Nfrac=006)
-Fch=871.70 (Fvco=3486.80, Nint=067, Nfrac=007)
-Fch=871.80 (Fvco=3487.20, Nint=067, Nfrac=008)
-Fch=871.90 (Fvco=3487.60, Nint=067, Nfrac=009)
-Fch=872.00 (Fvco=3488.00, Nint=067, Nfrac=010)
-Fch=872.10 (Fvco=3488.40, Nint=067, Nfrac=011)
-Fch=872.20 (Fvco=3488.80, Nint=067, Nfrac=012)
-Fch=872.30 (Fvco=3489.20, Nint=067, Nfrac=013)
-Fch=872.40 (Fvco=3489.60, Nint=067, Nfrac=014)
-Fch=872.50 (Fvco=3490.00, Nint=067, Nfrac=015)
-Fch=872.60 (Fvco=3490.40, Nint=067, Nfrac=016)
-Fch=872.70 (Fvco=3490.80, Nint=067, Nfrac=017)
-Fch=872.80 (Fvco=3491.20, Nint=067, Nfrac=018)
-Fch=872.90 (Fvco=3491.60, Nint=067, Nfrac=019)
-Fch=873.00 (Fvco=3492.00, Nint=067, Nfrac=020)
-Fch=873.10 (Fvco=3492.40, Nint=067, Nfrac=021)
-Fch=873.20 (Fvco=3492.80, Nint=067, Nfrac=022)
-Fch=873.30 (Fvco=3493.20, Nint=067, Nfrac=023)
-Fch=873.40 (Fvco=3493.60, Nint=067, Nfrac=024)
-Fch=873.50 (Fvco=3494.00, Nint=067, Nfrac=025)
-Fch=873.60 (Fvco=3494.40, Nint=067, Nfrac=026)
-Fch=873.70 (Fvco=3494.80, Nint=067, Nfrac=027)
-Fch=873.80 (Fvco=3495.20, Nint=067, Nfrac=028)
-Fch=873.90 (Fvco=3495.60, Nint=067, Nfrac=029)
-Fch=874.00 (Fvco=3496.00, Nint=067, Nfrac=030)
-Fch=874.10 (Fvco=3496.40, Nint=067, Nfrac=031)
-Fch=874.20 (Fvco=3496.80, Nint=067, Nfrac=032)
-Fch=874.30 (Fvco=3497.20, Nint=067, Nfrac=033)
-Fch=874.40 (Fvco=3497.60, Nint=067, Nfrac=034)
-Fch=874.50 (Fvco=3498.00, Nint=067, Nfrac=035)
-Fch=874.60 (Fvco=3498.40, Nint=067, Nfrac=036)
-Fch=874.70 (Fvco=3498.80, Nint=067, Nfrac=037)
-Fch=874.80 (Fvco=3499.20, Nint=067, Nfrac=038)
-Fch=874.90 (Fvco=3499.60, Nint=067, Nfrac=039)
-Fch=875.00 (Fvco=3500.00, Nint=067, Nfrac=040)
-Fch=875.10 (Fvco=3500.40, Nint=067, Nfrac=041)
-Fch=875.20 (Fvco=3500.80, Nint=067, Nfrac=042)
-Fch=875.30 (Fvco=3501.20, Nint=067, Nfrac=043)
-Fch=875.40 (Fvco=3501.60, Nint=067, Nfrac=044)
-Fch=875.50 (Fvco=3502.00, Nint=067, Nfrac=045)
-Fch=875.60 (Fvco=3502.40, Nint=067, Nfrac=046)
-Fch=875.70 (Fvco=3502.80, Nint=067, Nfrac=047)
-Fch=875.80 (Fvco=3503.20, Nint=067, Nfrac=048)
-Fch=875.90 (Fvco=3503.60, Nint=067, Nfrac=049)
-Fch=876.00 (Fvco=3504.00, Nint=067, Nfrac=050)
-Fch=876.10 (Fvco=3504.40, Nint=067, Nfrac=051)
-Fch=876.20 (Fvco=3504.80, Nint=067, Nfrac=052)
-Fch=876.30 (Fvco=3505.20, Nint=067, Nfrac=053)
-Fch=876.40 (Fvco=3505.60, Nint=067, Nfrac=054)
-Fch=876.50 (Fvco=3506.00, Nint=067, Nfrac=055)
-Fch=876.60 (Fvco=3506.40, Nint=067, Nfrac=056)
-Fch=876.70 (Fvco=3506.80, Nint=067, Nfrac=057)
-Fch=876.80 (Fvco=3507.20, Nint=067, Nfrac=058)
-Fch=876.90 (Fvco=3507.60, Nint=067, Nfrac=059)
-Fch=877.00 (Fvco=3508.00, Nint=067, Nfrac=060)
-Fch=877.10 (Fvco=3508.40, Nint=067, Nfrac=061)
-Fch=877.20 (Fvco=3508.80, Nint=067, Nfrac=062)
-Fch=877.30 (Fvco=3509.20, Nint=067, Nfrac=063)
-Fch=877.40 (Fvco=3509.60, Nint=067, Nfrac=064)
-Fch=877.50 (Fvco=3510.00, Nint=067, Nfrac=065)
-Fch=877.60 (Fvco=3510.40, Nint=067, Nfrac=066)
-Fch=877.70 (Fvco=3510.80, Nint=067, Nfrac=067)
-Fch=877.80 (Fvco=3511.20, Nint=067, Nfrac=068)
-Fch=877.90 (Fvco=3511.60, Nint=067, Nfrac=069)
-Fch=878.00 (Fvco=3512.00, Nint=067, Nfrac=070)
-Fch=878.10 (Fvco=3512.40, Nint=067, Nfrac=071)
-Fch=878.20 (Fvco=3512.80, Nint=067, Nfrac=072)
-Fch=878.30 (Fvco=3513.20, Nint=067, Nfrac=073)
-Fch=878.40 (Fvco=3513.60, Nint=067, Nfrac=074)
-Fch=878.50 (Fvco=3514.00, Nint=067, Nfrac=075)
-Fch=878.60 (Fvco=3514.40, Nint=067, Nfrac=076)
-Fch=878.70 (Fvco=3514.80, Nint=067, Nfrac=077)
-Fch=878.80 (Fvco=3515.20, Nint=067, Nfrac=078)
-Fch=878.90 (Fvco=3515.60, Nint=067, Nfrac=079)
-Fch=879.00 (Fvco=3516.00, Nint=067, Nfrac=080)
-Fch=879.10 (Fvco=3516.40, Nint=067, Nfrac=081)
-Fch=879.20 (Fvco=3516.80, Nint=067, Nfrac=082)
-Fch=879.30 (Fvco=3517.20, Nint=067, Nfrac=083)
-Fch=879.40 (Fvco=3517.60, Nint=067, Nfrac=084)
-Fch=879.50 (Fvco=3518.00, Nint=067, Nfrac=085)
-Fch=879.60 (Fvco=3518.40, Nint=067, Nfrac=086)
-Fch=879.70 (Fvco=3518.80, Nint=067, Nfrac=087)
-Fch=879.80 (Fvco=3519.20, Nint=067, Nfrac=088)
-Fch=879.90 (Fvco=3519.60, Nint=067, Nfrac=089)
-Fch=880.00 (Fvco=3520.00, Nint=067, Nfrac=090)
-Fch=880.10 (Fvco=3520.40, Nint=067, Nfrac=091)
-Fch=880.20 (Fvco=3520.80, Nint=067, Nfrac=092)
-Fch=880.30 (Fvco=3521.20, Nint=067, Nfrac=093)
-Fch=880.40 (Fvco=3521.60, Nint=067, Nfrac=094)
-Fch=880.50 (Fvco=3522.00, Nint=067, Nfrac=095)
-Fch=880.60 (Fvco=3522.40, Nint=067, Nfrac=096)
-Fch=880.70 (Fvco=3522.80, Nint=067, Nfrac=097)
-Fch=880.80 (Fvco=3523.20, Nint=067, Nfrac=098)
-Fch=880.90 (Fvco=3523.60, Nint=067, Nfrac=099)
-Fch=881.00 (Fvco=3524.00, Nint=067, Nfrac=100)
-Fch=881.10 (Fvco=3524.40, Nint=067, Nfrac=101)
-Fch=881.20 (Fvco=3524.80, Nint=067, Nfrac=102)
-Fch=881.30 (Fvco=3525.20, Nint=067, Nfrac=103)
-Fch=881.40 (Fvco=3525.60, Nint=067, Nfrac=104)
-Fch=881.50 (Fvco=3526.00, Nint=067, Nfrac=105)
-Fch=881.60 (Fvco=3526.40, Nint=067, Nfrac=106)
-Fch=881.70 (Fvco=3526.80, Nint=067, Nfrac=107)
-Fch=881.80 (Fvco=3527.20, Nint=067, Nfrac=108)
-Fch=881.90 (Fvco=3527.60, Nint=067, Nfrac=109)
-Fch=882.00 (Fvco=3528.00, Nint=067, Nfrac=110)
-Fch=882.10 (Fvco=3528.40, Nint=067, Nfrac=111)
-Fch=882.20 (Fvco=3528.80, Nint=067, Nfrac=112)
-Fch=882.30 (Fvco=3529.20, Nint=067, Nfrac=113)
-Fch=882.40 (Fvco=3529.60, Nint=067, Nfrac=114)
-Fch=882.50 (Fvco=3530.00, Nint=067, Nfrac=115)
-Fch=882.60 (Fvco=3530.40, Nint=067, Nfrac=116)
-Fch=882.70 (Fvco=3530.80, Nint=067, Nfrac=117)
-Fch=882.80 (Fvco=3531.20, Nint=067, Nfrac=118)
-Fch=882.90 (Fvco=3531.60, Nint=067, Nfrac=119)
-Fch=883.00 (Fvco=3532.00, Nint=067, Nfrac=120)
-Fch=883.10 (Fvco=3532.40, Nint=067, Nfrac=121)
-Fch=883.20 (Fvco=3532.80, Nint=067, Nfrac=122)
-Fch=883.30 (Fvco=3533.20, Nint=067, Nfrac=123)
-Fch=883.40 (Fvco=3533.60, Nint=067, Nfrac=124)
-Fch=883.50 (Fvco=3534.00, Nint=067, Nfrac=125)
-Fch=883.60 (Fvco=3534.40, Nint=067, Nfrac=126)
-Fch=883.70 (Fvco=3534.80, Nint=067, Nfrac=127)
-Fch=883.80 (Fvco=3535.20, Nint=067, Nfrac=128)
-Fch=883.90 (Fvco=3535.60, Nint=067, Nfrac=129)
-Fch=884.00 (Fvco=3536.00, Nint=067, Nfrac=130)
-Fch=884.00 (Fvco=3536.00, Nint=068, Nfrac=000)
-Fch=884.10 (Fvco=3536.40, Nint=068, Nfrac=001)
-Fch=884.20 (Fvco=3536.80, Nint=068, Nfrac=002)
-Fch=884.30 (Fvco=3537.20, Nint=068, Nfrac=003)
-Fch=884.40 (Fvco=3537.60, Nint=068, Nfrac=004)
-Fch=884.50 (Fvco=3538.00, Nint=068, Nfrac=005)
-Fch=884.60 (Fvco=3538.40, Nint=068, Nfrac=006)
-Fch=884.70 (Fvco=3538.80, Nint=068, Nfrac=007)
-Fch=884.80 (Fvco=3539.20, Nint=068, Nfrac=008)
-Fch=884.90 (Fvco=3539.60, Nint=068, Nfrac=009)
-Fch=885.00 (Fvco=3540.00, Nint=068, Nfrac=010)
-Fch=885.10 (Fvco=3540.40, Nint=068, Nfrac=011)
-Fch=885.20 (Fvco=3540.80, Nint=068, Nfrac=012)
-Fch=885.30 (Fvco=3541.20, Nint=068, Nfrac=013)
-Fch=885.40 (Fvco=3541.60, Nint=068, Nfrac=014)
-Fch=885.50 (Fvco=3542.00, Nint=068, Nfrac=015)
-Fch=885.60 (Fvco=3542.40, Nint=068, Nfrac=016)
-Fch=885.70 (Fvco=3542.80, Nint=068, Nfrac=017)
-Fch=885.80 (Fvco=3543.20, Nint=068, Nfrac=018)
-Fch=885.90 (Fvco=3543.60, Nint=068, Nfrac=019)
-Fch=886.00 (Fvco=3544.00, Nint=068, Nfrac=020)
-Fch=886.10 (Fvco=3544.40, Nint=068, Nfrac=021)
-Fch=886.20 (Fvco=3544.80, Nint=068, Nfrac=022)
-Fch=886.30 (Fvco=3545.20, Nint=068, Nfrac=023)
-Fch=886.40 (Fvco=3545.60, Nint=068, Nfrac=024)
-Fch=886.50 (Fvco=3546.00, Nint=068, Nfrac=025)
-Fch=886.60 (Fvco=3546.40, Nint=068, Nfrac=026)
-Fch=886.70 (Fvco=3546.80, Nint=068, Nfrac=027)
-Fch=886.80 (Fvco=3547.20, Nint=068, Nfrac=028)
-Fch=886.90 (Fvco=3547.60, Nint=068, Nfrac=029)
-Fch=887.00 (Fvco=3548.00, Nint=068, Nfrac=030)
-Fch=887.10 (Fvco=3548.40, Nint=068, Nfrac=031)
-Fch=887.20 (Fvco=3548.80, Nint=068, Nfrac=032)
-Fch=887.30 (Fvco=3549.20, Nint=068, Nfrac=033)
-Fch=887.40 (Fvco=3549.60, Nint=068, Nfrac=034)
-Fch=887.50 (Fvco=3550.00, Nint=068, Nfrac=035)
-Fch=887.60 (Fvco=3550.40, Nint=068, Nfrac=036)
-Fch=887.70 (Fvco=3550.80, Nint=068, Nfrac=037)
-Fch=887.80 (Fvco=3551.20, Nint=068, Nfrac=038)
-Fch=887.90 (Fvco=3551.60, Nint=068, Nfrac=039)
-Fch=888.00 (Fvco=3552.00, Nint=068, Nfrac=040)
-Fch=888.10 (Fvco=3552.40, Nint=068, Nfrac=041)
-Fch=888.20 (Fvco=3552.80, Nint=068, Nfrac=042)
-Fch=888.30 (Fvco=3553.20, Nint=068, Nfrac=043)
-Fch=888.40 (Fvco=3553.60, Nint=068, Nfrac=044)
-Fch=888.50 (Fvco=3554.00, Nint=068, Nfrac=045)
-Fch=888.60 (Fvco=3554.40, Nint=068, Nfrac=046)
-Fch=888.70 (Fvco=3554.80, Nint=068, Nfrac=047)
-Fch=888.80 (Fvco=3555.20, Nint=068, Nfrac=048)
-Fch=888.90 (Fvco=3555.60, Nint=068, Nfrac=049)
-Fch=889.00 (Fvco=3556.00, Nint=068, Nfrac=050)
-Fch=889.10 (Fvco=3556.40, Nint=068, Nfrac=051)
-Fch=889.20 (Fvco=3556.80, Nint=068, Nfrac=052)
-Fch=889.30 (Fvco=3557.20, Nint=068, Nfrac=053)
-Fch=889.40 (Fvco=3557.60, Nint=068, Nfrac=054)
-Fch=889.50 (Fvco=3558.00, Nint=068, Nfrac=055)
-Fch=889.60 (Fvco=3558.40, Nint=068, Nfrac=056)
-Fch=889.70 (Fvco=3558.80, Nint=068, Nfrac=057)
-Fch=889.80 (Fvco=3559.20, Nint=068, Nfrac=058)
-Fch=889.90 (Fvco=3559.60, Nint=068, Nfrac=059)
-Fch=890.00 (Fvco=3560.00, Nint=068, Nfrac=060)
-Fch=890.10 (Fvco=3560.40, Nint=068, Nfrac=061)
-Fch=890.20 (Fvco=3560.80, Nint=068, Nfrac=062)
-Fch=890.30 (Fvco=3561.20, Nint=068, Nfrac=063)
-Fch=890.40 (Fvco=3561.60, Nint=068, Nfrac=064)
-Fch=890.50 (Fvco=3562.00, Nint=068, Nfrac=065)
-Fch=890.60 (Fvco=3562.40, Nint=068, Nfrac=066)
-Fch=890.70 (Fvco=3562.80, Nint=068, Nfrac=067)
-Fch=890.80 (Fvco=3563.20, Nint=068, Nfrac=068)
-Fch=890.90 (Fvco=3563.60, Nint=068, Nfrac=069)
-Fch=891.00 (Fvco=3564.00, Nint=068, Nfrac=070)
-Fch=891.10 (Fvco=3564.40, Nint=068, Nfrac=071)
-Fch=891.20 (Fvco=3564.80, Nint=068, Nfrac=072)
-Fch=891.30 (Fvco=3565.20, Nint=068, Nfrac=073)
-Fch=891.40 (Fvco=3565.60, Nint=068, Nfrac=074)
-Fch=891.50 (Fvco=3566.00, Nint=068, Nfrac=075)
-Fch=891.60 (Fvco=3566.40, Nint=068, Nfrac=076)
-Fch=891.70 (Fvco=3566.80, Nint=068, Nfrac=077)
-Fch=891.80 (Fvco=3567.20, Nint=068, Nfrac=078)
-Fch=891.90 (Fvco=3567.60, Nint=068, Nfrac=079)
-Fch=892.00 (Fvco=3568.00, Nint=068, Nfrac=080)
-Fch=892.10 (Fvco=3568.40, Nint=068, Nfrac=081)
-Fch=892.20 (Fvco=3568.80, Nint=068, Nfrac=082)
-Fch=892.30 (Fvco=3569.20, Nint=068, Nfrac=083)
-Fch=892.40 (Fvco=3569.60, Nint=068, Nfrac=084)
-Fch=892.50 (Fvco=3570.00, Nint=068, Nfrac=085)
-Fch=892.60 (Fvco=3570.40, Nint=068, Nfrac=086)
-Fch=892.70 (Fvco=3570.80, Nint=068, Nfrac=087)
-Fch=892.80 (Fvco=3571.20, Nint=068, Nfrac=088)
-Fch=892.90 (Fvco=3571.60, Nint=068, Nfrac=089)
-Fch=893.00 (Fvco=3572.00, Nint=068, Nfrac=090)
-Fch=893.10 (Fvco=3572.40, Nint=068, Nfrac=091)
-Fch=893.20 (Fvco=3572.80, Nint=068, Nfrac=092)
-Fch=893.30 (Fvco=3573.20, Nint=068, Nfrac=093)
-Fch=893.40 (Fvco=3573.60, Nint=068, Nfrac=094)
-Fch=893.50 (Fvco=3574.00, Nint=068, Nfrac=095)
-Fch=893.60 (Fvco=3574.40, Nint=068, Nfrac=096)
-Fch=893.70 (Fvco=3574.80, Nint=068, Nfrac=097)
-Fch=893.80 (Fvco=3575.20, Nint=068, Nfrac=098)
-Fch=893.90 (Fvco=3575.60, Nint=068, Nfrac=099)
-Fch=894.00 (Fvco=3576.00, Nint=068, Nfrac=100)
-Fch=894.10 (Fvco=3576.40, Nint=068, Nfrac=101)
-Fch=894.20 (Fvco=3576.80, Nint=068, Nfrac=102)
-Fch=894.30 (Fvco=3577.20, Nint=068, Nfrac=103)
-Fch=894.40 (Fvco=3577.60, Nint=068, Nfrac=104)
-Fch=894.50 (Fvco=3578.00, Nint=068, Nfrac=105)
-Fch=894.60 (Fvco=3578.40, Nint=068, Nfrac=106)
-Fch=894.70 (Fvco=3578.80, Nint=068, Nfrac=107)
-Fch=894.80 (Fvco=3579.20, Nint=068, Nfrac=108)
-Fch=894.90 (Fvco=3579.60, Nint=068, Nfrac=109)
-Fch=895.00 (Fvco=3580.00, Nint=068, Nfrac=110)
-Fch=895.10 (Fvco=3580.40, Nint=068, Nfrac=111)
-Fch=895.20 (Fvco=3580.80, Nint=068, Nfrac=112)
-Fch=895.30 (Fvco=3581.20, Nint=068, Nfrac=113)
-Fch=895.40 (Fvco=3581.60, Nint=068, Nfrac=114)
-Fch=895.50 (Fvco=3582.00, Nint=068, Nfrac=115)
-Fch=895.60 (Fvco=3582.40, Nint=068, Nfrac=116)
-Fch=895.70 (Fvco=3582.80, Nint=068, Nfrac=117)
-Fch=895.80 (Fvco=3583.20, Nint=068, Nfrac=118)
-Fch=895.90 (Fvco=3583.60, Nint=068, Nfrac=119)
-Fch=896.00 (Fvco=3584.00, Nint=068, Nfrac=120)
-Fch=896.10 (Fvco=3584.40, Nint=068, Nfrac=121)
-Fch=896.20 (Fvco=3584.80, Nint=068, Nfrac=122)
-Fch=896.30 (Fvco=3585.20, Nint=068, Nfrac=123)
-Fch=896.40 (Fvco=3585.60, Nint=068, Nfrac=124)
-Fch=896.50 (Fvco=3586.00, Nint=068, Nfrac=125)
-Fch=896.60 (Fvco=3586.40, Nint=068, Nfrac=126)
-Fch=896.70 (Fvco=3586.80, Nint=068, Nfrac=127)
-Fch=896.80 (Fvco=3587.20, Nint=068, Nfrac=128)
-Fch=896.90 (Fvco=3587.60, Nint=068, Nfrac=129)
-Fch=897.00 (Fvco=3588.00, Nint=068, Nfrac=130)
-Fch=897.00 (Fvco=3588.00, Nint=069, Nfrac=000)
-Fch=897.10 (Fvco=3588.40, Nint=069, Nfrac=001)
-Fch=897.20 (Fvco=3588.80, Nint=069, Nfrac=002)
-Fch=897.30 (Fvco=3589.20, Nint=069, Nfrac=003)
-Fch=897.40 (Fvco=3589.60, Nint=069, Nfrac=004)
-Fch=897.50 (Fvco=3590.00, Nint=069, Nfrac=005)
-Fch=897.60 (Fvco=3590.40, Nint=069, Nfrac=006)
-Fch=897.70 (Fvco=3590.80, Nint=069, Nfrac=007)
-Fch=897.80 (Fvco=3591.20, Nint=069, Nfrac=008)
-Fch=897.90 (Fvco=3591.60, Nint=069, Nfrac=009)
-Fch=898.00 (Fvco=3592.00, Nint=069, Nfrac=010)
-Fch=898.10 (Fvco=3592.40, Nint=069, Nfrac=011)
-Fch=898.20 (Fvco=3592.80, Nint=069, Nfrac=012)
-Fch=898.30 (Fvco=3593.20, Nint=069, Nfrac=013)
-Fch=898.40 (Fvco=3593.60, Nint=069, Nfrac=014)
-Fch=898.50 (Fvco=3594.00, Nint=069, Nfrac=015)
-Fch=898.60 (Fvco=3594.40, Nint=069, Nfrac=016)
-Fch=898.70 (Fvco=3594.80, Nint=069, Nfrac=017)
-Fch=898.80 (Fvco=3595.20, Nint=069, Nfrac=018)
-Fch=898.90 (Fvco=3595.60, Nint=069, Nfrac=019)
-Fch=899.00 (Fvco=3596.00, Nint=069, Nfrac=020)
-Fch=899.10 (Fvco=3596.40, Nint=069, Nfrac=021)
-Fch=899.20 (Fvco=3596.80, Nint=069, Nfrac=022)
-Fch=899.30 (Fvco=3597.20, Nint=069, Nfrac=023)
-Fch=899.40 (Fvco=3597.60, Nint=069, Nfrac=024)
-Fch=899.50 (Fvco=3598.00, Nint=069, Nfrac=025)
-Fch=899.60 (Fvco=3598.40, Nint=069, Nfrac=026)
-Fch=899.70 (Fvco=3598.80, Nint=069, Nfrac=027)
-Fch=899.80 (Fvco=3599.20, Nint=069, Nfrac=028)
-Fch=899.90 (Fvco=3599.60, Nint=069, Nfrac=029)
-Fch=900.00 (Fvco=3600.00, Nint=069, Nfrac=030)
-Fch=900.10 (Fvco=3600.40, Nint=069, Nfrac=031)
-Fch=900.20 (Fvco=3600.80, Nint=069, Nfrac=032)
-Fch=900.30 (Fvco=3601.20, Nint=069, Nfrac=033)
-Fch=900.40 (Fvco=3601.60, Nint=069, Nfrac=034)
-Fch=900.50 (Fvco=3602.00, Nint=069, Nfrac=035)
-Fch=900.60 (Fvco=3602.40, Nint=069, Nfrac=036)
-Fch=900.70 (Fvco=3602.80, Nint=069, Nfrac=037)
-Fch=900.80 (Fvco=3603.20, Nint=069, Nfrac=038)
-Fch=900.90 (Fvco=3603.60, Nint=069, Nfrac=039)
-Fch=901.00 (Fvco=3604.00, Nint=069, Nfrac=040)
-Fch=901.10 (Fvco=3604.40, Nint=069, Nfrac=041)
-Fch=901.20 (Fvco=3604.80, Nint=069, Nfrac=042)
-Fch=901.30 (Fvco=3605.20, Nint=069, Nfrac=043)
-Fch=901.40 (Fvco=3605.60, Nint=069, Nfrac=044)
-Fch=901.50 (Fvco=3606.00, Nint=069, Nfrac=045)
-Fch=901.60 (Fvco=3606.40, Nint=069, Nfrac=046)
-Fch=901.70 (Fvco=3606.80, Nint=069, Nfrac=047)
-Fch=901.80 (Fvco=3607.20, Nint=069, Nfrac=048)
-Fch=901.90 (Fvco=3607.60, Nint=069, Nfrac=049)
-Fch=902.00 (Fvco=3608.00, Nint=069, Nfrac=050)
-Fch=902.10 (Fvco=3608.40, Nint=069, Nfrac=051)
-Fch=902.20 (Fvco=3608.80, Nint=069, Nfrac=052)
-Fch=902.30 (Fvco=3609.20, Nint=069, Nfrac=053)
-Fch=902.40 (Fvco=3609.60, Nint=069, Nfrac=054)
-Fch=902.50 (Fvco=3610.00, Nint=069, Nfrac=055)
-Fch=902.60 (Fvco=3610.40, Nint=069, Nfrac=056)
-Fch=902.70 (Fvco=3610.80, Nint=069, Nfrac=057)
-Fch=902.80 (Fvco=3611.20, Nint=069, Nfrac=058)
-Fch=902.90 (Fvco=3611.60, Nint=069, Nfrac=059)
-Fch=903.00 (Fvco=3612.00, Nint=069, Nfrac=060)
-Fch=903.10 (Fvco=3612.40, Nint=069, Nfrac=061)
-Fch=903.20 (Fvco=3612.80, Nint=069, Nfrac=062)
-Fch=903.30 (Fvco=3613.20, Nint=069, Nfrac=063)
-Fch=903.40 (Fvco=3613.60, Nint=069, Nfrac=064)
-Fch=903.50 (Fvco=3614.00, Nint=069, Nfrac=065)
-Fch=903.60 (Fvco=3614.40, Nint=069, Nfrac=066)
-Fch=903.70 (Fvco=3614.80, Nint=069, Nfrac=067)
-Fch=903.80 (Fvco=3615.20, Nint=069, Nfrac=068)
-Fch=903.90 (Fvco=3615.60, Nint=069, Nfrac=069)
-Fch=904.00 (Fvco=3616.00, Nint=069, Nfrac=070)
-Fch=904.10 (Fvco=3616.40, Nint=069, Nfrac=071)
-Fch=904.20 (Fvco=3616.80, Nint=069, Nfrac=072)
-Fch=904.30 (Fvco=3617.20, Nint=069, Nfrac=073)
-Fch=904.40 (Fvco=3617.60, Nint=069, Nfrac=074)
-Fch=904.50 (Fvco=3618.00, Nint=069, Nfrac=075)
-Fch=904.60 (Fvco=3618.40, Nint=069, Nfrac=076)
-Fch=904.70 (Fvco=3618.80, Nint=069, Nfrac=077)
-Fch=904.80 (Fvco=3619.20, Nint=069, Nfrac=078)
-Fch=904.90 (Fvco=3619.60, Nint=069, Nfrac=079)
-Fch=905.00 (Fvco=3620.00, Nint=069, Nfrac=080)
-Fch=905.10 (Fvco=3620.40, Nint=069, Nfrac=081)
-Fch=905.20 (Fvco=3620.80, Nint=069, Nfrac=082)
-Fch=905.30 (Fvco=3621.20, Nint=069, Nfrac=083)
-Fch=905.40 (Fvco=3621.60, Nint=069, Nfrac=084)
-Fch=905.50 (Fvco=3622.00, Nint=069, Nfrac=085)
-Fch=905.60 (Fvco=3622.40, Nint=069, Nfrac=086)
-Fch=905.70 (Fvco=3622.80, Nint=069, Nfrac=087)
-Fch=905.80 (Fvco=3623.20, Nint=069, Nfrac=088)
-Fch=905.90 (Fvco=3623.60, Nint=069, Nfrac=089)
-Fch=906.00 (Fvco=3624.00, Nint=069, Nfrac=090)
-Fch=906.10 (Fvco=3624.40, Nint=069, Nfrac=091)
-Fch=906.20 (Fvco=3624.80, Nint=069, Nfrac=092)
-Fch=906.30 (Fvco=3625.20, Nint=069, Nfrac=093)
-Fch=906.40 (Fvco=3625.60, Nint=069, Nfrac=094)
-Fch=906.50 (Fvco=3626.00, Nint=069, Nfrac=095)
-Fch=906.60 (Fvco=3626.40, Nint=069, Nfrac=096)
-Fch=906.70 (Fvco=3626.80, Nint=069, Nfrac=097)
-Fch=906.80 (Fvco=3627.20, Nint=069, Nfrac=098)
-Fch=906.90 (Fvco=3627.60, Nint=069, Nfrac=099)
-Fch=907.00 (Fvco=3628.00, Nint=069, Nfrac=100)
-Fch=907.10 (Fvco=3628.40, Nint=069, Nfrac=101)
-Fch=907.20 (Fvco=3628.80, Nint=069, Nfrac=102)
-Fch=907.30 (Fvco=3629.20, Nint=069, Nfrac=103)
-Fch=907.40 (Fvco=3629.60, Nint=069, Nfrac=104)
-Fch=907.50 (Fvco=3630.00, Nint=069, Nfrac=105)
-Fch=907.60 (Fvco=3630.40, Nint=069, Nfrac=106)
-Fch=907.70 (Fvco=3630.80, Nint=069, Nfrac=107)
-Fch=907.80 (Fvco=3631.20, Nint=069, Nfrac=108)
-Fch=907.90 (Fvco=3631.60, Nint=069, Nfrac=109)
-Fch=908.00 (Fvco=3632.00, Nint=069, Nfrac=110)
-Fch=908.10 (Fvco=3632.40, Nint=069, Nfrac=111)
-Fch=908.20 (Fvco=3632.80, Nint=069, Nfrac=112)
-Fch=908.30 (Fvco=3633.20, Nint=069, Nfrac=113)
-Fch=908.40 (Fvco=3633.60, Nint=069, Nfrac=114)
-Fch=908.50 (Fvco=3634.00, Nint=069, Nfrac=115)
-Fch=908.60 (Fvco=3634.40, Nint=069, Nfrac=116)
-Fch=908.70 (Fvco=3634.80, Nint=069, Nfrac=117)
-Fch=908.80 (Fvco=3635.20, Nint=069, Nfrac=118)
-Fch=908.90 (Fvco=3635.60, Nint=069, Nfrac=119)
-Fch=909.00 (Fvco=3636.00, Nint=069, Nfrac=120)
-Fch=909.10 (Fvco=3636.40, Nint=069, Nfrac=121)
-Fch=909.20 (Fvco=3636.80, Nint=069, Nfrac=122)
-Fch=909.30 (Fvco=3637.20, Nint=069, Nfrac=123)
-Fch=909.40 (Fvco=3637.60, Nint=069, Nfrac=124)
-Fch=909.50 (Fvco=3638.00, Nint=069, Nfrac=125)
-Fch=909.60 (Fvco=3638.40, Nint=069, Nfrac=126)
-Fch=909.70 (Fvco=3638.80, Nint=069, Nfrac=127)
-Fch=909.80 (Fvco=3639.20, Nint=069, Nfrac=128)
-Fch=909.90 (Fvco=3639.60, Nint=069, Nfrac=129)
-Fch=910.00 (Fvco=3640.00, Nint=069, Nfrac=130)
-Fch=910.00 (Fvco=3640.00, Nint=070, Nfrac=000)
-Fch=910.10 (Fvco=3640.40, Nint=070, Nfrac=001)
-Fch=910.20 (Fvco=3640.80, Nint=070, Nfrac=002)
-Fch=910.30 (Fvco=3641.20, Nint=070, Nfrac=003)
-Fch=910.40 (Fvco=3641.60, Nint=070, Nfrac=004)
-Fch=910.50 (Fvco=3642.00, Nint=070, Nfrac=005)
-Fch=910.60 (Fvco=3642.40, Nint=070, Nfrac=006)
-Fch=910.70 (Fvco=3642.80, Nint=070, Nfrac=007)
-Fch=910.80 (Fvco=3643.20, Nint=070, Nfrac=008)
-Fch=910.90 (Fvco=3643.60, Nint=070, Nfrac=009)
-Fch=911.00 (Fvco=3644.00, Nint=070, Nfrac=010)
-Fch=911.10 (Fvco=3644.40, Nint=070, Nfrac=011)
-Fch=911.20 (Fvco=3644.80, Nint=070, Nfrac=012)
-Fch=911.30 (Fvco=3645.20, Nint=070, Nfrac=013)
-Fch=911.40 (Fvco=3645.60, Nint=070, Nfrac=014)
-Fch=911.50 (Fvco=3646.00, Nint=070, Nfrac=015)
-Fch=911.60 (Fvco=3646.40, Nint=070, Nfrac=016)
-Fch=911.70 (Fvco=3646.80, Nint=070, Nfrac=017)
-Fch=911.80 (Fvco=3647.20, Nint=070, Nfrac=018)
-Fch=911.90 (Fvco=3647.60, Nint=070, Nfrac=019)
-Fch=912.00 (Fvco=3648.00, Nint=070, Nfrac=020)
-Fch=912.10 (Fvco=3648.40, Nint=070, Nfrac=021)
-Fch=912.20 (Fvco=3648.80, Nint=070, Nfrac=022)
-Fch=912.30 (Fvco=3649.20, Nint=070, Nfrac=023)
-Fch=912.40 (Fvco=3649.60, Nint=070, Nfrac=024)
-Fch=912.50 (Fvco=3650.00, Nint=070, Nfrac=025)
-Fch=912.60 (Fvco=3650.40, Nint=070, Nfrac=026)
-Fch=912.70 (Fvco=3650.80, Nint=070, Nfrac=027)
-Fch=912.80 (Fvco=3651.20, Nint=070, Nfrac=028)
-Fch=912.90 (Fvco=3651.60, Nint=070, Nfrac=029)
-Fch=913.00 (Fvco=3652.00, Nint=070, Nfrac=030)
-Fch=913.10 (Fvco=3652.40, Nint=070, Nfrac=031)
-Fch=913.20 (Fvco=3652.80, Nint=070, Nfrac=032)
-Fch=913.30 (Fvco=3653.20, Nint=070, Nfrac=033)
-Fch=913.40 (Fvco=3653.60, Nint=070, Nfrac=034)
-Fch=913.50 (Fvco=3654.00, Nint=070, Nfrac=035)
-Fch=913.60 (Fvco=3654.40, Nint=070, Nfrac=036)
-Fch=913.70 (Fvco=3654.80, Nint=070, Nfrac=037)
-Fch=913.80 (Fvco=3655.20, Nint=070, Nfrac=038)
-Fch=913.90 (Fvco=3655.60, Nint=070, Nfrac=039)
-Fch=914.00 (Fvco=3656.00, Nint=070, Nfrac=040)
-Fch=914.10 (Fvco=3656.40, Nint=070, Nfrac=041)
-Fch=914.20 (Fvco=3656.80, Nint=070, Nfrac=042)
-Fch=914.30 (Fvco=3657.20, Nint=070, Nfrac=043)
-Fch=914.40 (Fvco=3657.60, Nint=070, Nfrac=044)
-Fch=914.50 (Fvco=3658.00, Nint=070, Nfrac=045)
-Fch=914.60 (Fvco=3658.40, Nint=070, Nfrac=046)
-Fch=914.70 (Fvco=3658.80, Nint=070, Nfrac=047)
-Fch=914.80 (Fvco=3659.20, Nint=070, Nfrac=048)
-Fch=914.90 (Fvco=3659.60, Nint=070, Nfrac=049)
-Fch=915.00 (Fvco=3660.00, Nint=070, Nfrac=050)
-Fch=915.10 (Fvco=3660.40, Nint=070, Nfrac=051)
-Fch=915.20 (Fvco=3660.80, Nint=070, Nfrac=052)
-Fch=915.30 (Fvco=3661.20, Nint=070, Nfrac=053)
-Fch=915.40 (Fvco=3661.60, Nint=070, Nfrac=054)
-Fch=915.50 (Fvco=3662.00, Nint=070, Nfrac=055)
-Fch=915.60 (Fvco=3662.40, Nint=070, Nfrac=056)
-Fch=915.70 (Fvco=3662.80, Nint=070, Nfrac=057)
-Fch=915.80 (Fvco=3663.20, Nint=070, Nfrac=058)
-Fch=915.90 (Fvco=3663.60, Nint=070, Nfrac=059)
-Fch=916.00 (Fvco=3664.00, Nint=070, Nfrac=060)
-Fch=916.10 (Fvco=3664.40, Nint=070, Nfrac=061)
-Fch=916.20 (Fvco=3664.80, Nint=070, Nfrac=062)
-Fch=916.30 (Fvco=3665.20, Nint=070, Nfrac=063)
-Fch=916.40 (Fvco=3665.60, Nint=070, Nfrac=064)
-Fch=916.50 (Fvco=3666.00, Nint=070, Nfrac=065)
-Fch=916.60 (Fvco=3666.40, Nint=070, Nfrac=066)
-Fch=916.70 (Fvco=3666.80, Nint=070, Nfrac=067)
-Fch=916.80 (Fvco=3667.20, Nint=070, Nfrac=068)
-Fch=916.90 (Fvco=3667.60, Nint=070, Nfrac=069)
-Fch=917.00 (Fvco=3668.00, Nint=070, Nfrac=070)
-Fch=917.10 (Fvco=3668.40, Nint=070, Nfrac=071)
-Fch=917.20 (Fvco=3668.80, Nint=070, Nfrac=072)
-Fch=917.30 (Fvco=3669.20, Nint=070, Nfrac=073)
-Fch=917.40 (Fvco=3669.60, Nint=070, Nfrac=074)
-Fch=917.50 (Fvco=3670.00, Nint=070, Nfrac=075)
-Fch=917.60 (Fvco=3670.40, Nint=070, Nfrac=076)
-Fch=917.70 (Fvco=3670.80, Nint=070, Nfrac=077)
-Fch=917.80 (Fvco=3671.20, Nint=070, Nfrac=078)
-Fch=917.90 (Fvco=3671.60, Nint=070, Nfrac=079)
-Fch=918.00 (Fvco=3672.00, Nint=070, Nfrac=080)
-Fch=918.10 (Fvco=3672.40, Nint=070, Nfrac=081)
-Fch=918.20 (Fvco=3672.80, Nint=070, Nfrac=082)
-Fch=918.30 (Fvco=3673.20, Nint=070, Nfrac=083)
-Fch=918.40 (Fvco=3673.60, Nint=070, Nfrac=084)
-Fch=918.50 (Fvco=3674.00, Nint=070, Nfrac=085)
-Fch=918.60 (Fvco=3674.40, Nint=070, Nfrac=086)
-Fch=918.70 (Fvco=3674.80, Nint=070, Nfrac=087)
-Fch=918.80 (Fvco=3675.20, Nint=070, Nfrac=088)
-Fch=918.90 (Fvco=3675.60, Nint=070, Nfrac=089)
-Fch=919.00 (Fvco=3676.00, Nint=070, Nfrac=090)
-Fch=919.10 (Fvco=3676.40, Nint=070, Nfrac=091)
-Fch=919.20 (Fvco=3676.80, Nint=070, Nfrac=092)
-Fch=919.30 (Fvco=3677.20, Nint=070, Nfrac=093)
-Fch=919.40 (Fvco=3677.60, Nint=070, Nfrac=094)
-Fch=919.50 (Fvco=3678.00, Nint=070, Nfrac=095)
-Fch=919.60 (Fvco=3678.40, Nint=070, Nfrac=096)
-Fch=919.70 (Fvco=3678.80, Nint=070, Nfrac=097)
-Fch=919.80 (Fvco=3679.20, Nint=070, Nfrac=098)
-Fch=919.90 (Fvco=3679.60, Nint=070, Nfrac=099)
-Fch=920.00 (Fvco=3680.00, Nint=070, Nfrac=100)
-Fch=920.10 (Fvco=3680.40, Nint=070, Nfrac=101)
-Fch=920.20 (Fvco=3680.80, Nint=070, Nfrac=102)
-Fch=920.30 (Fvco=3681.20, Nint=070, Nfrac=103)
-Fch=920.40 (Fvco=3681.60, Nint=070, Nfrac=104)
-Fch=920.50 (Fvco=3682.00, Nint=070, Nfrac=105)
-Fch=920.60 (Fvco=3682.40, Nint=070, Nfrac=106)
-Fch=920.70 (Fvco=3682.80, Nint=070, Nfrac=107)
-Fch=920.80 (Fvco=3683.20, Nint=070, Nfrac=108)
-Fch=920.90 (Fvco=3683.60, Nint=070, Nfrac=109)
-Fch=921.00 (Fvco=3684.00, Nint=070, Nfrac=110)
-Fch=921.10 (Fvco=3684.40, Nint=070, Nfrac=111)
-Fch=921.20 (Fvco=3684.80, Nint=070, Nfrac=112)
-Fch=921.30 (Fvco=3685.20, Nint=070, Nfrac=113)
-Fch=921.40 (Fvco=3685.60, Nint=070, Nfrac=114)
-Fch=921.50 (Fvco=3686.00, Nint=070, Nfrac=115)
-Fch=921.60 (Fvco=3686.40, Nint=070, Nfrac=116)
-Fch=921.70 (Fvco=3686.80, Nint=070, Nfrac=117)
-Fch=921.80 (Fvco=3687.20, Nint=070, Nfrac=118)
-Fch=921.90 (Fvco=3687.60, Nint=070, Nfrac=119)
-Fch=922.00 (Fvco=3688.00, Nint=070, Nfrac=120)
-Fch=922.10 (Fvco=3688.40, Nint=070, Nfrac=121)
-Fch=922.20 (Fvco=3688.80, Nint=070, Nfrac=122)
-Fch=922.30 (Fvco=3689.20, Nint=070, Nfrac=123)
-Fch=922.40 (Fvco=3689.60, Nint=070, Nfrac=124)
-Fch=922.50 (Fvco=3690.00, Nint=070, Nfrac=125)
-Fch=922.60 (Fvco=3690.40, Nint=070, Nfrac=126)
-Fch=922.70 (Fvco=3690.80, Nint=070, Nfrac=127)
-Fch=922.80 (Fvco=3691.20, Nint=070, Nfrac=128)
-Fch=922.90 (Fvco=3691.60, Nint=070, Nfrac=129)
-Fch=923.00 (Fvco=3692.00, Nint=070, Nfrac=130)
-======================================================================
-PLL Tx High Band
-Fch=1690.00 (Fvco=3380.00, Nint=065, Nfrac=000)
-Fch=1690.20 (Fvco=3380.40, Nint=065, Nfrac=001)
-Fch=1690.40 (Fvco=3380.80, Nint=065, Nfrac=002)
-Fch=1690.60 (Fvco=3381.20, Nint=065, Nfrac=003)
-Fch=1690.80 (Fvco=3381.60, Nint=065, Nfrac=004)
-Fch=1691.00 (Fvco=3382.00, Nint=065, Nfrac=005)
-Fch=1691.20 (Fvco=3382.40, Nint=065, Nfrac=006)
-Fch=1691.40 (Fvco=3382.80, Nint=065, Nfrac=007)
-Fch=1691.60 (Fvco=3383.20, Nint=065, Nfrac=008)
-Fch=1691.80 (Fvco=3383.60, Nint=065, Nfrac=009)
-Fch=1692.00 (Fvco=3384.00, Nint=065, Nfrac=010)
-Fch=1692.20 (Fvco=3384.40, Nint=065, Nfrac=011)
-Fch=1692.40 (Fvco=3384.80, Nint=065, Nfrac=012)
-Fch=1692.60 (Fvco=3385.20, Nint=065, Nfrac=013)
-Fch=1692.80 (Fvco=3385.60, Nint=065, Nfrac=014)
-Fch=1693.00 (Fvco=3386.00, Nint=065, Nfrac=015)
-Fch=1693.20 (Fvco=3386.40, Nint=065, Nfrac=016)
-Fch=1693.40 (Fvco=3386.80, Nint=065, Nfrac=017)
-Fch=1693.60 (Fvco=3387.20, Nint=065, Nfrac=018)
-Fch=1693.80 (Fvco=3387.60, Nint=065, Nfrac=019)
-Fch=1694.00 (Fvco=3388.00, Nint=065, Nfrac=020)
-Fch=1694.20 (Fvco=3388.40, Nint=065, Nfrac=021)
-Fch=1694.40 (Fvco=3388.80, Nint=065, Nfrac=022)
-Fch=1694.60 (Fvco=3389.20, Nint=065, Nfrac=023)
-Fch=1694.80 (Fvco=3389.60, Nint=065, Nfrac=024)
-Fch=1695.00 (Fvco=3390.00, Nint=065, Nfrac=025)
-Fch=1695.20 (Fvco=3390.40, Nint=065, Nfrac=026)
-Fch=1695.40 (Fvco=3390.80, Nint=065, Nfrac=027)
-Fch=1695.60 (Fvco=3391.20, Nint=065, Nfrac=028)
-Fch=1695.80 (Fvco=3391.60, Nint=065, Nfrac=029)
-Fch=1696.00 (Fvco=3392.00, Nint=065, Nfrac=030)
-Fch=1696.20 (Fvco=3392.40, Nint=065, Nfrac=031)
-Fch=1696.40 (Fvco=3392.80, Nint=065, Nfrac=032)
-Fch=1696.60 (Fvco=3393.20, Nint=065, Nfrac=033)
-Fch=1696.80 (Fvco=3393.60, Nint=065, Nfrac=034)
-Fch=1697.00 (Fvco=3394.00, Nint=065, Nfrac=035)
-Fch=1697.20 (Fvco=3394.40, Nint=065, Nfrac=036)
-Fch=1697.40 (Fvco=3394.80, Nint=065, Nfrac=037)
-Fch=1697.60 (Fvco=3395.20, Nint=065, Nfrac=038)
-Fch=1697.80 (Fvco=3395.60, Nint=065, Nfrac=039)
-Fch=1698.00 (Fvco=3396.00, Nint=065, Nfrac=040)
-Fch=1698.20 (Fvco=3396.40, Nint=065, Nfrac=041)
-Fch=1698.40 (Fvco=3396.80, Nint=065, Nfrac=042)
-Fch=1698.60 (Fvco=3397.20, Nint=065, Nfrac=043)
-Fch=1698.80 (Fvco=3397.60, Nint=065, Nfrac=044)
-Fch=1699.00 (Fvco=3398.00, Nint=065, Nfrac=045)
-Fch=1699.20 (Fvco=3398.40, Nint=065, Nfrac=046)
-Fch=1699.40 (Fvco=3398.80, Nint=065, Nfrac=047)
-Fch=1699.60 (Fvco=3399.20, Nint=065, Nfrac=048)
-Fch=1699.80 (Fvco=3399.60, Nint=065, Nfrac=049)
-Fch=1700.00 (Fvco=3400.00, Nint=065, Nfrac=050)
-Fch=1700.20 (Fvco=3400.40, Nint=065, Nfrac=051)
-Fch=1700.40 (Fvco=3400.80, Nint=065, Nfrac=052)
-Fch=1700.60 (Fvco=3401.20, Nint=065, Nfrac=053)
-Fch=1700.80 (Fvco=3401.60, Nint=065, Nfrac=054)
-Fch=1701.00 (Fvco=3402.00, Nint=065, Nfrac=055)
-Fch=1701.20 (Fvco=3402.40, Nint=065, Nfrac=056)
-Fch=1701.40 (Fvco=3402.80, Nint=065, Nfrac=057)
-Fch=1701.60 (Fvco=3403.20, Nint=065, Nfrac=058)
-Fch=1701.80 (Fvco=3403.60, Nint=065, Nfrac=059)
-Fch=1702.00 (Fvco=3404.00, Nint=065, Nfrac=060)
-Fch=1702.20 (Fvco=3404.40, Nint=065, Nfrac=061)
-Fch=1702.40 (Fvco=3404.80, Nint=065, Nfrac=062)
-Fch=1702.60 (Fvco=3405.20, Nint=065, Nfrac=063)
-Fch=1702.80 (Fvco=3405.60, Nint=065, Nfrac=064)
-Fch=1703.00 (Fvco=3406.00, Nint=065, Nfrac=065)
-Fch=1703.20 (Fvco=3406.40, Nint=065, Nfrac=066)
-Fch=1703.40 (Fvco=3406.80, Nint=065, Nfrac=067)
-Fch=1703.60 (Fvco=3407.20, Nint=065, Nfrac=068)
-Fch=1703.80 (Fvco=3407.60, Nint=065, Nfrac=069)
-Fch=1704.00 (Fvco=3408.00, Nint=065, Nfrac=070)
-Fch=1704.20 (Fvco=3408.40, Nint=065, Nfrac=071)
-Fch=1704.40 (Fvco=3408.80, Nint=065, Nfrac=072)
-Fch=1704.60 (Fvco=3409.20, Nint=065, Nfrac=073)
-Fch=1704.80 (Fvco=3409.60, Nint=065, Nfrac=074)
-Fch=1705.00 (Fvco=3410.00, Nint=065, Nfrac=075)
-Fch=1705.20 (Fvco=3410.40, Nint=065, Nfrac=076)
-Fch=1705.40 (Fvco=3410.80, Nint=065, Nfrac=077)
-Fch=1705.60 (Fvco=3411.20, Nint=065, Nfrac=078)
-Fch=1705.80 (Fvco=3411.60, Nint=065, Nfrac=079)
-Fch=1706.00 (Fvco=3412.00, Nint=065, Nfrac=080)
-Fch=1706.20 (Fvco=3412.40, Nint=065, Nfrac=081)
-Fch=1706.40 (Fvco=3412.80, Nint=065, Nfrac=082)
-Fch=1706.60 (Fvco=3413.20, Nint=065, Nfrac=083)
-Fch=1706.80 (Fvco=3413.60, Nint=065, Nfrac=084)
-Fch=1707.00 (Fvco=3414.00, Nint=065, Nfrac=085)
-Fch=1707.20 (Fvco=3414.40, Nint=065, Nfrac=086)
-Fch=1707.40 (Fvco=3414.80, Nint=065, Nfrac=087)
-Fch=1707.60 (Fvco=3415.20, Nint=065, Nfrac=088)
-Fch=1707.80 (Fvco=3415.60, Nint=065, Nfrac=089)
-Fch=1708.00 (Fvco=3416.00, Nint=065, Nfrac=090)
-Fch=1708.20 (Fvco=3416.40, Nint=065, Nfrac=091)
-Fch=1708.40 (Fvco=3416.80, Nint=065, Nfrac=092)
-Fch=1708.60 (Fvco=3417.20, Nint=065, Nfrac=093)
-Fch=1708.80 (Fvco=3417.60, Nint=065, Nfrac=094)
-Fch=1709.00 (Fvco=3418.00, Nint=065, Nfrac=095)
-Fch=1709.20 (Fvco=3418.40, Nint=065, Nfrac=096)
-Fch=1709.40 (Fvco=3418.80, Nint=065, Nfrac=097)
-Fch=1709.60 (Fvco=3419.20, Nint=065, Nfrac=098)
-Fch=1709.80 (Fvco=3419.60, Nint=065, Nfrac=099)
-Fch=1710.00 (Fvco=3420.00, Nint=065, Nfrac=100)
-Fch=1710.20 (Fvco=3420.40, Nint=065, Nfrac=101)
-Fch=1710.40 (Fvco=3420.80, Nint=065, Nfrac=102)
-Fch=1710.60 (Fvco=3421.20, Nint=065, Nfrac=103)
-Fch=1710.80 (Fvco=3421.60, Nint=065, Nfrac=104)
-Fch=1711.00 (Fvco=3422.00, Nint=065, Nfrac=105)
-Fch=1711.20 (Fvco=3422.40, Nint=065, Nfrac=106)
-Fch=1711.40 (Fvco=3422.80, Nint=065, Nfrac=107)
-Fch=1711.60 (Fvco=3423.20, Nint=065, Nfrac=108)
-Fch=1711.80 (Fvco=3423.60, Nint=065, Nfrac=109)
-Fch=1712.00 (Fvco=3424.00, Nint=065, Nfrac=110)
-Fch=1712.20 (Fvco=3424.40, Nint=065, Nfrac=111)
-Fch=1712.40 (Fvco=3424.80, Nint=065, Nfrac=112)
-Fch=1712.60 (Fvco=3425.20, Nint=065, Nfrac=113)
-Fch=1712.80 (Fvco=3425.60, Nint=065, Nfrac=114)
-Fch=1713.00 (Fvco=3426.00, Nint=065, Nfrac=115)
-Fch=1713.20 (Fvco=3426.40, Nint=065, Nfrac=116)
-Fch=1713.40 (Fvco=3426.80, Nint=065, Nfrac=117)
-Fch=1713.60 (Fvco=3427.20, Nint=065, Nfrac=118)
-Fch=1713.80 (Fvco=3427.60, Nint=065, Nfrac=119)
-Fch=1714.00 (Fvco=3428.00, Nint=065, Nfrac=120)
-Fch=1714.20 (Fvco=3428.40, Nint=065, Nfrac=121)
-Fch=1714.40 (Fvco=3428.80, Nint=065, Nfrac=122)
-Fch=1714.60 (Fvco=3429.20, Nint=065, Nfrac=123)
-Fch=1714.80 (Fvco=3429.60, Nint=065, Nfrac=124)
-Fch=1715.00 (Fvco=3430.00, Nint=065, Nfrac=125)
-Fch=1715.20 (Fvco=3430.40, Nint=065, Nfrac=126)
-Fch=1715.40 (Fvco=3430.80, Nint=065, Nfrac=127)
-Fch=1715.60 (Fvco=3431.20, Nint=065, Nfrac=128)
-Fch=1715.80 (Fvco=3431.60, Nint=065, Nfrac=129)
-Fch=1716.00 (Fvco=3432.00, Nint=065, Nfrac=130)
-Fch=1716.00 (Fvco=3432.00, Nint=066, Nfrac=000)
-Fch=1716.20 (Fvco=3432.40, Nint=066, Nfrac=001)
-Fch=1716.40 (Fvco=3432.80, Nint=066, Nfrac=002)
-Fch=1716.60 (Fvco=3433.20, Nint=066, Nfrac=003)
-Fch=1716.80 (Fvco=3433.60, Nint=066, Nfrac=004)
-Fch=1717.00 (Fvco=3434.00, Nint=066, Nfrac=005)
-Fch=1717.20 (Fvco=3434.40, Nint=066, Nfrac=006)
-Fch=1717.40 (Fvco=3434.80, Nint=066, Nfrac=007)
-Fch=1717.60 (Fvco=3435.20, Nint=066, Nfrac=008)
-Fch=1717.80 (Fvco=3435.60, Nint=066, Nfrac=009)
-Fch=1718.00 (Fvco=3436.00, Nint=066, Nfrac=010)
-Fch=1718.20 (Fvco=3436.40, Nint=066, Nfrac=011)
-Fch=1718.40 (Fvco=3436.80, Nint=066, Nfrac=012)
-Fch=1718.60 (Fvco=3437.20, Nint=066, Nfrac=013)
-Fch=1718.80 (Fvco=3437.60, Nint=066, Nfrac=014)
-Fch=1719.00 (Fvco=3438.00, Nint=066, Nfrac=015)
-Fch=1719.20 (Fvco=3438.40, Nint=066, Nfrac=016)
-Fch=1719.40 (Fvco=3438.80, Nint=066, Nfrac=017)
-Fch=1719.60 (Fvco=3439.20, Nint=066, Nfrac=018)
-Fch=1719.80 (Fvco=3439.60, Nint=066, Nfrac=019)
-Fch=1720.00 (Fvco=3440.00, Nint=066, Nfrac=020)
-Fch=1720.20 (Fvco=3440.40, Nint=066, Nfrac=021)
-Fch=1720.40 (Fvco=3440.80, Nint=066, Nfrac=022)
-Fch=1720.60 (Fvco=3441.20, Nint=066, Nfrac=023)
-Fch=1720.80 (Fvco=3441.60, Nint=066, Nfrac=024)
-Fch=1721.00 (Fvco=3442.00, Nint=066, Nfrac=025)
-Fch=1721.20 (Fvco=3442.40, Nint=066, Nfrac=026)
-Fch=1721.40 (Fvco=3442.80, Nint=066, Nfrac=027)
-Fch=1721.60 (Fvco=3443.20, Nint=066, Nfrac=028)
-Fch=1721.80 (Fvco=3443.60, Nint=066, Nfrac=029)
-Fch=1722.00 (Fvco=3444.00, Nint=066, Nfrac=030)
-Fch=1722.20 (Fvco=3444.40, Nint=066, Nfrac=031)
-Fch=1722.40 (Fvco=3444.80, Nint=066, Nfrac=032)
-Fch=1722.60 (Fvco=3445.20, Nint=066, Nfrac=033)
-Fch=1722.80 (Fvco=3445.60, Nint=066, Nfrac=034)
-Fch=1723.00 (Fvco=3446.00, Nint=066, Nfrac=035)
-Fch=1723.20 (Fvco=3446.40, Nint=066, Nfrac=036)
-Fch=1723.40 (Fvco=3446.80, Nint=066, Nfrac=037)
-Fch=1723.60 (Fvco=3447.20, Nint=066, Nfrac=038)
-Fch=1723.80 (Fvco=3447.60, Nint=066, Nfrac=039)
-Fch=1724.00 (Fvco=3448.00, Nint=066, Nfrac=040)
-Fch=1724.20 (Fvco=3448.40, Nint=066, Nfrac=041)
-Fch=1724.40 (Fvco=3448.80, Nint=066, Nfrac=042)
-Fch=1724.60 (Fvco=3449.20, Nint=066, Nfrac=043)
-Fch=1724.80 (Fvco=3449.60, Nint=066, Nfrac=044)
-Fch=1725.00 (Fvco=3450.00, Nint=066, Nfrac=045)
-Fch=1725.20 (Fvco=3450.40, Nint=066, Nfrac=046)
-Fch=1725.40 (Fvco=3450.80, Nint=066, Nfrac=047)
-Fch=1725.60 (Fvco=3451.20, Nint=066, Nfrac=048)
-Fch=1725.80 (Fvco=3451.60, Nint=066, Nfrac=049)
-Fch=1726.00 (Fvco=3452.00, Nint=066, Nfrac=050)
-Fch=1726.20 (Fvco=3452.40, Nint=066, Nfrac=051)
-Fch=1726.40 (Fvco=3452.80, Nint=066, Nfrac=052)
-Fch=1726.60 (Fvco=3453.20, Nint=066, Nfrac=053)
-Fch=1726.80 (Fvco=3453.60, Nint=066, Nfrac=054)
-Fch=1727.00 (Fvco=3454.00, Nint=066, Nfrac=055)
-Fch=1727.20 (Fvco=3454.40, Nint=066, Nfrac=056)
-Fch=1727.40 (Fvco=3454.80, Nint=066, Nfrac=057)
-Fch=1727.60 (Fvco=3455.20, Nint=066, Nfrac=058)
-Fch=1727.80 (Fvco=3455.60, Nint=066, Nfrac=059)
-Fch=1728.00 (Fvco=3456.00, Nint=066, Nfrac=060)
-Fch=1728.20 (Fvco=3456.40, Nint=066, Nfrac=061)
-Fch=1728.40 (Fvco=3456.80, Nint=066, Nfrac=062)
-Fch=1728.60 (Fvco=3457.20, Nint=066, Nfrac=063)
-Fch=1728.80 (Fvco=3457.60, Nint=066, Nfrac=064)
-Fch=1729.00 (Fvco=3458.00, Nint=066, Nfrac=065)
-Fch=1729.20 (Fvco=3458.40, Nint=066, Nfrac=066)
-Fch=1729.40 (Fvco=3458.80, Nint=066, Nfrac=067)
-Fch=1729.60 (Fvco=3459.20, Nint=066, Nfrac=068)
-Fch=1729.80 (Fvco=3459.60, Nint=066, Nfrac=069)
-Fch=1730.00 (Fvco=3460.00, Nint=066, Nfrac=070)
-Fch=1730.20 (Fvco=3460.40, Nint=066, Nfrac=071)
-Fch=1730.40 (Fvco=3460.80, Nint=066, Nfrac=072)
-Fch=1730.60 (Fvco=3461.20, Nint=066, Nfrac=073)
-Fch=1730.80 (Fvco=3461.60, Nint=066, Nfrac=074)
-Fch=1731.00 (Fvco=3462.00, Nint=066, Nfrac=075)
-Fch=1731.20 (Fvco=3462.40, Nint=066, Nfrac=076)
-Fch=1731.40 (Fvco=3462.80, Nint=066, Nfrac=077)
-Fch=1731.60 (Fvco=3463.20, Nint=066, Nfrac=078)
-Fch=1731.80 (Fvco=3463.60, Nint=066, Nfrac=079)
-Fch=1732.00 (Fvco=3464.00, Nint=066, Nfrac=080)
-Fch=1732.20 (Fvco=3464.40, Nint=066, Nfrac=081)
-Fch=1732.40 (Fvco=3464.80, Nint=066, Nfrac=082)
-Fch=1732.60 (Fvco=3465.20, Nint=066, Nfrac=083)
-Fch=1732.80 (Fvco=3465.60, Nint=066, Nfrac=084)
-Fch=1733.00 (Fvco=3466.00, Nint=066, Nfrac=085)
-Fch=1733.20 (Fvco=3466.40, Nint=066, Nfrac=086)
-Fch=1733.40 (Fvco=3466.80, Nint=066, Nfrac=087)
-Fch=1733.60 (Fvco=3467.20, Nint=066, Nfrac=088)
-Fch=1733.80 (Fvco=3467.60, Nint=066, Nfrac=089)
-Fch=1734.00 (Fvco=3468.00, Nint=066, Nfrac=090)
-Fch=1734.20 (Fvco=3468.40, Nint=066, Nfrac=091)
-Fch=1734.40 (Fvco=3468.80, Nint=066, Nfrac=092)
-Fch=1734.60 (Fvco=3469.20, Nint=066, Nfrac=093)
-Fch=1734.80 (Fvco=3469.60, Nint=066, Nfrac=094)
-Fch=1735.00 (Fvco=3470.00, Nint=066, Nfrac=095)
-Fch=1735.20 (Fvco=3470.40, Nint=066, Nfrac=096)
-Fch=1735.40 (Fvco=3470.80, Nint=066, Nfrac=097)
-Fch=1735.60 (Fvco=3471.20, Nint=066, Nfrac=098)
-Fch=1735.80 (Fvco=3471.60, Nint=066, Nfrac=099)
-Fch=1736.00 (Fvco=3472.00, Nint=066, Nfrac=100)
-Fch=1736.20 (Fvco=3472.40, Nint=066, Nfrac=101)
-Fch=1736.40 (Fvco=3472.80, Nint=066, Nfrac=102)
-Fch=1736.60 (Fvco=3473.20, Nint=066, Nfrac=103)
-Fch=1736.80 (Fvco=3473.60, Nint=066, Nfrac=104)
-Fch=1737.00 (Fvco=3474.00, Nint=066, Nfrac=105)
-Fch=1737.20 (Fvco=3474.40, Nint=066, Nfrac=106)
-Fch=1737.40 (Fvco=3474.80, Nint=066, Nfrac=107)
-Fch=1737.60 (Fvco=3475.20, Nint=066, Nfrac=108)
-Fch=1737.80 (Fvco=3475.60, Nint=066, Nfrac=109)
-Fch=1738.00 (Fvco=3476.00, Nint=066, Nfrac=110)
-Fch=1738.20 (Fvco=3476.40, Nint=066, Nfrac=111)
-Fch=1738.40 (Fvco=3476.80, Nint=066, Nfrac=112)
-Fch=1738.60 (Fvco=3477.20, Nint=066, Nfrac=113)
-Fch=1738.80 (Fvco=3477.60, Nint=066, Nfrac=114)
-Fch=1739.00 (Fvco=3478.00, Nint=066, Nfrac=115)
-Fch=1739.20 (Fvco=3478.40, Nint=066, Nfrac=116)
-Fch=1739.40 (Fvco=3478.80, Nint=066, Nfrac=117)
-Fch=1739.60 (Fvco=3479.20, Nint=066, Nfrac=118)
-Fch=1739.80 (Fvco=3479.60, Nint=066, Nfrac=119)
-Fch=1740.00 (Fvco=3480.00, Nint=066, Nfrac=120)
-Fch=1740.20 (Fvco=3480.40, Nint=066, Nfrac=121)
-Fch=1740.40 (Fvco=3480.80, Nint=066, Nfrac=122)
-Fch=1740.60 (Fvco=3481.20, Nint=066, Nfrac=123)
-Fch=1740.80 (Fvco=3481.60, Nint=066, Nfrac=124)
-Fch=1741.00 (Fvco=3482.00, Nint=066, Nfrac=125)
-Fch=1741.20 (Fvco=3482.40, Nint=066, Nfrac=126)
-Fch=1741.40 (Fvco=3482.80, Nint=066, Nfrac=127)
-Fch=1741.60 (Fvco=3483.20, Nint=066, Nfrac=128)
-Fch=1741.80 (Fvco=3483.60, Nint=066, Nfrac=129)
-Fch=1742.00 (Fvco=3484.00, Nint=066, Nfrac=130)
-Fch=1742.00 (Fvco=3484.00, Nint=067, Nfrac=000)
-Fch=1742.20 (Fvco=3484.40, Nint=067, Nfrac=001)
-Fch=1742.40 (Fvco=3484.80, Nint=067, Nfrac=002)
-Fch=1742.60 (Fvco=3485.20, Nint=067, Nfrac=003)
-Fch=1742.80 (Fvco=3485.60, Nint=067, Nfrac=004)
-Fch=1743.00 (Fvco=3486.00, Nint=067, Nfrac=005)
-Fch=1743.20 (Fvco=3486.40, Nint=067, Nfrac=006)
-Fch=1743.40 (Fvco=3486.80, Nint=067, Nfrac=007)
-Fch=1743.60 (Fvco=3487.20, Nint=067, Nfrac=008)
-Fch=1743.80 (Fvco=3487.60, Nint=067, Nfrac=009)
-Fch=1744.00 (Fvco=3488.00, Nint=067, Nfrac=010)
-Fch=1744.20 (Fvco=3488.40, Nint=067, Nfrac=011)
-Fch=1744.40 (Fvco=3488.80, Nint=067, Nfrac=012)
-Fch=1744.60 (Fvco=3489.20, Nint=067, Nfrac=013)
-Fch=1744.80 (Fvco=3489.60, Nint=067, Nfrac=014)
-Fch=1745.00 (Fvco=3490.00, Nint=067, Nfrac=015)
-Fch=1745.20 (Fvco=3490.40, Nint=067, Nfrac=016)
-Fch=1745.40 (Fvco=3490.80, Nint=067, Nfrac=017)
-Fch=1745.60 (Fvco=3491.20, Nint=067, Nfrac=018)
-Fch=1745.80 (Fvco=3491.60, Nint=067, Nfrac=019)
-Fch=1746.00 (Fvco=3492.00, Nint=067, Nfrac=020)
-Fch=1746.20 (Fvco=3492.40, Nint=067, Nfrac=021)
-Fch=1746.40 (Fvco=3492.80, Nint=067, Nfrac=022)
-Fch=1746.60 (Fvco=3493.20, Nint=067, Nfrac=023)
-Fch=1746.80 (Fvco=3493.60, Nint=067, Nfrac=024)
-Fch=1747.00 (Fvco=3494.00, Nint=067, Nfrac=025)
-Fch=1747.20 (Fvco=3494.40, Nint=067, Nfrac=026)
-Fch=1747.40 (Fvco=3494.80, Nint=067, Nfrac=027)
-Fch=1747.60 (Fvco=3495.20, Nint=067, Nfrac=028)
-Fch=1747.80 (Fvco=3495.60, Nint=067, Nfrac=029)
-Fch=1748.00 (Fvco=3496.00, Nint=067, Nfrac=030)
-Fch=1748.20 (Fvco=3496.40, Nint=067, Nfrac=031)
-Fch=1748.40 (Fvco=3496.80, Nint=067, Nfrac=032)
-Fch=1748.60 (Fvco=3497.20, Nint=067, Nfrac=033)
-Fch=1748.80 (Fvco=3497.60, Nint=067, Nfrac=034)
-Fch=1749.00 (Fvco=3498.00, Nint=067, Nfrac=035)
-Fch=1749.20 (Fvco=3498.40, Nint=067, Nfrac=036)
-Fch=1749.40 (Fvco=3498.80, Nint=067, Nfrac=037)
-Fch=1749.60 (Fvco=3499.20, Nint=067, Nfrac=038)
-Fch=1749.80 (Fvco=3499.60, Nint=067, Nfrac=039)
-Fch=1750.00 (Fvco=3500.00, Nint=067, Nfrac=040)
-Fch=1750.20 (Fvco=3500.40, Nint=067, Nfrac=041)
-Fch=1750.40 (Fvco=3500.80, Nint=067, Nfrac=042)
-Fch=1750.60 (Fvco=3501.20, Nint=067, Nfrac=043)
-Fch=1750.80 (Fvco=3501.60, Nint=067, Nfrac=044)
-Fch=1751.00 (Fvco=3502.00, Nint=067, Nfrac=045)
-Fch=1751.20 (Fvco=3502.40, Nint=067, Nfrac=046)
-Fch=1751.40 (Fvco=3502.80, Nint=067, Nfrac=047)
-Fch=1751.60 (Fvco=3503.20, Nint=067, Nfrac=048)
-Fch=1751.80 (Fvco=3503.60, Nint=067, Nfrac=049)
-Fch=1752.00 (Fvco=3504.00, Nint=067, Nfrac=050)
-Fch=1752.20 (Fvco=3504.40, Nint=067, Nfrac=051)
-Fch=1752.40 (Fvco=3504.80, Nint=067, Nfrac=052)
-Fch=1752.60 (Fvco=3505.20, Nint=067, Nfrac=053)
-Fch=1752.80 (Fvco=3505.60, Nint=067, Nfrac=054)
-Fch=1753.00 (Fvco=3506.00, Nint=067, Nfrac=055)
-Fch=1753.20 (Fvco=3506.40, Nint=067, Nfrac=056)
-Fch=1753.40 (Fvco=3506.80, Nint=067, Nfrac=057)
-Fch=1753.60 (Fvco=3507.20, Nint=067, Nfrac=058)
-Fch=1753.80 (Fvco=3507.60, Nint=067, Nfrac=059)
-Fch=1754.00 (Fvco=3508.00, Nint=067, Nfrac=060)
-Fch=1754.20 (Fvco=3508.40, Nint=067, Nfrac=061)
-Fch=1754.40 (Fvco=3508.80, Nint=067, Nfrac=062)
-Fch=1754.60 (Fvco=3509.20, Nint=067, Nfrac=063)
-Fch=1754.80 (Fvco=3509.60, Nint=067, Nfrac=064)
-Fch=1755.00 (Fvco=3510.00, Nint=067, Nfrac=065)
-Fch=1755.20 (Fvco=3510.40, Nint=067, Nfrac=066)
-Fch=1755.40 (Fvco=3510.80, Nint=067, Nfrac=067)
-Fch=1755.60 (Fvco=3511.20, Nint=067, Nfrac=068)
-Fch=1755.80 (Fvco=3511.60, Nint=067, Nfrac=069)
-Fch=1756.00 (Fvco=3512.00, Nint=067, Nfrac=070)
-Fch=1756.20 (Fvco=3512.40, Nint=067, Nfrac=071)
-Fch=1756.40 (Fvco=3512.80, Nint=067, Nfrac=072)
-Fch=1756.60 (Fvco=3513.20, Nint=067, Nfrac=073)
-Fch=1756.80 (Fvco=3513.60, Nint=067, Nfrac=074)
-Fch=1757.00 (Fvco=3514.00, Nint=067, Nfrac=075)
-Fch=1757.20 (Fvco=3514.40, Nint=067, Nfrac=076)
-Fch=1757.40 (Fvco=3514.80, Nint=067, Nfrac=077)
-Fch=1757.60 (Fvco=3515.20, Nint=067, Nfrac=078)
-Fch=1757.80 (Fvco=3515.60, Nint=067, Nfrac=079)
-Fch=1758.00 (Fvco=3516.00, Nint=067, Nfrac=080)
-Fch=1758.20 (Fvco=3516.40, Nint=067, Nfrac=081)
-Fch=1758.40 (Fvco=3516.80, Nint=067, Nfrac=082)
-Fch=1758.60 (Fvco=3517.20, Nint=067, Nfrac=083)
-Fch=1758.80 (Fvco=3517.60, Nint=067, Nfrac=084)
-Fch=1759.00 (Fvco=3518.00, Nint=067, Nfrac=085)
-Fch=1759.20 (Fvco=3518.40, Nint=067, Nfrac=086)
-Fch=1759.40 (Fvco=3518.80, Nint=067, Nfrac=087)
-Fch=1759.60 (Fvco=3519.20, Nint=067, Nfrac=088)
-Fch=1759.80 (Fvco=3519.60, Nint=067, Nfrac=089)
-Fch=1760.00 (Fvco=3520.00, Nint=067, Nfrac=090)
-Fch=1760.20 (Fvco=3520.40, Nint=067, Nfrac=091)
-Fch=1760.40 (Fvco=3520.80, Nint=067, Nfrac=092)
-Fch=1760.60 (Fvco=3521.20, Nint=067, Nfrac=093)
-Fch=1760.80 (Fvco=3521.60, Nint=067, Nfrac=094)
-Fch=1761.00 (Fvco=3522.00, Nint=067, Nfrac=095)
-Fch=1761.20 (Fvco=3522.40, Nint=067, Nfrac=096)
-Fch=1761.40 (Fvco=3522.80, Nint=067, Nfrac=097)
-Fch=1761.60 (Fvco=3523.20, Nint=067, Nfrac=098)
-Fch=1761.80 (Fvco=3523.60, Nint=067, Nfrac=099)
-Fch=1762.00 (Fvco=3524.00, Nint=067, Nfrac=100)
-Fch=1762.20 (Fvco=3524.40, Nint=067, Nfrac=101)
-Fch=1762.40 (Fvco=3524.80, Nint=067, Nfrac=102)
-Fch=1762.60 (Fvco=3525.20, Nint=067, Nfrac=103)
-Fch=1762.80 (Fvco=3525.60, Nint=067, Nfrac=104)
-Fch=1763.00 (Fvco=3526.00, Nint=067, Nfrac=105)
-Fch=1763.20 (Fvco=3526.40, Nint=067, Nfrac=106)
-Fch=1763.40 (Fvco=3526.80, Nint=067, Nfrac=107)
-Fch=1763.60 (Fvco=3527.20, Nint=067, Nfrac=108)
-Fch=1763.80 (Fvco=3527.60, Nint=067, Nfrac=109)
-Fch=1764.00 (Fvco=3528.00, Nint=067, Nfrac=110)
-Fch=1764.20 (Fvco=3528.40, Nint=067, Nfrac=111)
-Fch=1764.40 (Fvco=3528.80, Nint=067, Nfrac=112)
-Fch=1764.60 (Fvco=3529.20, Nint=067, Nfrac=113)
-Fch=1764.80 (Fvco=3529.60, Nint=067, Nfrac=114)
-Fch=1765.00 (Fvco=3530.00, Nint=067, Nfrac=115)
-Fch=1765.20 (Fvco=3530.40, Nint=067, Nfrac=116)
-Fch=1765.40 (Fvco=3530.80, Nint=067, Nfrac=117)
-Fch=1765.60 (Fvco=3531.20, Nint=067, Nfrac=118)
-Fch=1765.80 (Fvco=3531.60, Nint=067, Nfrac=119)
-Fch=1766.00 (Fvco=3532.00, Nint=067, Nfrac=120)
-Fch=1766.20 (Fvco=3532.40, Nint=067, Nfrac=121)
-Fch=1766.40 (Fvco=3532.80, Nint=067, Nfrac=122)
-Fch=1766.60 (Fvco=3533.20, Nint=067, Nfrac=123)
-Fch=1766.80 (Fvco=3533.60, Nint=067, Nfrac=124)
-Fch=1767.00 (Fvco=3534.00, Nint=067, Nfrac=125)
-Fch=1767.20 (Fvco=3534.40, Nint=067, Nfrac=126)
-Fch=1767.40 (Fvco=3534.80, Nint=067, Nfrac=127)
-Fch=1767.60 (Fvco=3535.20, Nint=067, Nfrac=128)
-Fch=1767.80 (Fvco=3535.60, Nint=067, Nfrac=129)
-Fch=1768.00 (Fvco=3536.00, Nint=067, Nfrac=130)
-Fch=1768.00 (Fvco=3536.00, Nint=068, Nfrac=000)
-Fch=1768.20 (Fvco=3536.40, Nint=068, Nfrac=001)
-Fch=1768.40 (Fvco=3536.80, Nint=068, Nfrac=002)
-Fch=1768.60 (Fvco=3537.20, Nint=068, Nfrac=003)
-Fch=1768.80 (Fvco=3537.60, Nint=068, Nfrac=004)
-Fch=1769.00 (Fvco=3538.00, Nint=068, Nfrac=005)
-Fch=1769.20 (Fvco=3538.40, Nint=068, Nfrac=006)
-Fch=1769.40 (Fvco=3538.80, Nint=068, Nfrac=007)
-Fch=1769.60 (Fvco=3539.20, Nint=068, Nfrac=008)
-Fch=1769.80 (Fvco=3539.60, Nint=068, Nfrac=009)
-Fch=1770.00 (Fvco=3540.00, Nint=068, Nfrac=010)
-Fch=1770.20 (Fvco=3540.40, Nint=068, Nfrac=011)
-Fch=1770.40 (Fvco=3540.80, Nint=068, Nfrac=012)
-Fch=1770.60 (Fvco=3541.20, Nint=068, Nfrac=013)
-Fch=1770.80 (Fvco=3541.60, Nint=068, Nfrac=014)
-Fch=1771.00 (Fvco=3542.00, Nint=068, Nfrac=015)
-Fch=1771.20 (Fvco=3542.40, Nint=068, Nfrac=016)
-Fch=1771.40 (Fvco=3542.80, Nint=068, Nfrac=017)
-Fch=1771.60 (Fvco=3543.20, Nint=068, Nfrac=018)
-Fch=1771.80 (Fvco=3543.60, Nint=068, Nfrac=019)
-Fch=1772.00 (Fvco=3544.00, Nint=068, Nfrac=020)
-Fch=1772.20 (Fvco=3544.40, Nint=068, Nfrac=021)
-Fch=1772.40 (Fvco=3544.80, Nint=068, Nfrac=022)
-Fch=1772.60 (Fvco=3545.20, Nint=068, Nfrac=023)
-Fch=1772.80 (Fvco=3545.60, Nint=068, Nfrac=024)
-Fch=1773.00 (Fvco=3546.00, Nint=068, Nfrac=025)
-Fch=1773.20 (Fvco=3546.40, Nint=068, Nfrac=026)
-Fch=1773.40 (Fvco=3546.80, Nint=068, Nfrac=027)
-Fch=1773.60 (Fvco=3547.20, Nint=068, Nfrac=028)
-Fch=1773.80 (Fvco=3547.60, Nint=068, Nfrac=029)
-Fch=1774.00 (Fvco=3548.00, Nint=068, Nfrac=030)
-Fch=1774.20 (Fvco=3548.40, Nint=068, Nfrac=031)
-Fch=1774.40 (Fvco=3548.80, Nint=068, Nfrac=032)
-Fch=1774.60 (Fvco=3549.20, Nint=068, Nfrac=033)
-Fch=1774.80 (Fvco=3549.60, Nint=068, Nfrac=034)
-Fch=1775.00 (Fvco=3550.00, Nint=068, Nfrac=035)
-Fch=1775.20 (Fvco=3550.40, Nint=068, Nfrac=036)
-Fch=1775.40 (Fvco=3550.80, Nint=068, Nfrac=037)
-Fch=1775.60 (Fvco=3551.20, Nint=068, Nfrac=038)
-Fch=1775.80 (Fvco=3551.60, Nint=068, Nfrac=039)
-Fch=1776.00 (Fvco=3552.00, Nint=068, Nfrac=040)
-Fch=1776.20 (Fvco=3552.40, Nint=068, Nfrac=041)
-Fch=1776.40 (Fvco=3552.80, Nint=068, Nfrac=042)
-Fch=1776.60 (Fvco=3553.20, Nint=068, Nfrac=043)
-Fch=1776.80 (Fvco=3553.60, Nint=068, Nfrac=044)
-Fch=1777.00 (Fvco=3554.00, Nint=068, Nfrac=045)
-Fch=1777.20 (Fvco=3554.40, Nint=068, Nfrac=046)
-Fch=1777.40 (Fvco=3554.80, Nint=068, Nfrac=047)
-Fch=1777.60 (Fvco=3555.20, Nint=068, Nfrac=048)
-Fch=1777.80 (Fvco=3555.60, Nint=068, Nfrac=049)
-Fch=1778.00 (Fvco=3556.00, Nint=068, Nfrac=050)
-Fch=1778.20 (Fvco=3556.40, Nint=068, Nfrac=051)
-Fch=1778.40 (Fvco=3556.80, Nint=068, Nfrac=052)
-Fch=1778.60 (Fvco=3557.20, Nint=068, Nfrac=053)
-Fch=1778.80 (Fvco=3557.60, Nint=068, Nfrac=054)
-Fch=1779.00 (Fvco=3558.00, Nint=068, Nfrac=055)
-Fch=1779.20 (Fvco=3558.40, Nint=068, Nfrac=056)
-Fch=1779.40 (Fvco=3558.80, Nint=068, Nfrac=057)
-Fch=1779.60 (Fvco=3559.20, Nint=068, Nfrac=058)
-Fch=1779.80 (Fvco=3559.60, Nint=068, Nfrac=059)
-Fch=1780.00 (Fvco=3560.00, Nint=068, Nfrac=060)
-Fch=1780.20 (Fvco=3560.40, Nint=068, Nfrac=061)
-Fch=1780.40 (Fvco=3560.80, Nint=068, Nfrac=062)
-Fch=1780.60 (Fvco=3561.20, Nint=068, Nfrac=063)
-Fch=1780.80 (Fvco=3561.60, Nint=068, Nfrac=064)
-Fch=1781.00 (Fvco=3562.00, Nint=068, Nfrac=065)
-Fch=1781.20 (Fvco=3562.40, Nint=068, Nfrac=066)
-Fch=1781.40 (Fvco=3562.80, Nint=068, Nfrac=067)
-Fch=1781.60 (Fvco=3563.20, Nint=068, Nfrac=068)
-Fch=1781.80 (Fvco=3563.60, Nint=068, Nfrac=069)
-Fch=1782.00 (Fvco=3564.00, Nint=068, Nfrac=070)
-Fch=1782.20 (Fvco=3564.40, Nint=068, Nfrac=071)
-Fch=1782.40 (Fvco=3564.80, Nint=068, Nfrac=072)
-Fch=1782.60 (Fvco=3565.20, Nint=068, Nfrac=073)
-Fch=1782.80 (Fvco=3565.60, Nint=068, Nfrac=074)
-Fch=1783.00 (Fvco=3566.00, Nint=068, Nfrac=075)
-Fch=1783.20 (Fvco=3566.40, Nint=068, Nfrac=076)
-Fch=1783.40 (Fvco=3566.80, Nint=068, Nfrac=077)
-Fch=1783.60 (Fvco=3567.20, Nint=068, Nfrac=078)
-Fch=1783.80 (Fvco=3567.60, Nint=068, Nfrac=079)
-Fch=1784.00 (Fvco=3568.00, Nint=068, Nfrac=080)
-Fch=1784.20 (Fvco=3568.40, Nint=068, Nfrac=081)
-Fch=1784.40 (Fvco=3568.80, Nint=068, Nfrac=082)
-Fch=1784.60 (Fvco=3569.20, Nint=068, Nfrac=083)
-Fch=1784.80 (Fvco=3569.60, Nint=068, Nfrac=084)
-Fch=1785.00 (Fvco=3570.00, Nint=068, Nfrac=085)
-Fch=1785.20 (Fvco=3570.40, Nint=068, Nfrac=086)
-Fch=1785.40 (Fvco=3570.80, Nint=068, Nfrac=087)
-Fch=1785.60 (Fvco=3571.20, Nint=068, Nfrac=088)
-Fch=1785.80 (Fvco=3571.60, Nint=068, Nfrac=089)
-Fch=1786.00 (Fvco=3572.00, Nint=068, Nfrac=090)
-Fch=1786.20 (Fvco=3572.40, Nint=068, Nfrac=091)
-Fch=1786.40 (Fvco=3572.80, Nint=068, Nfrac=092)
-Fch=1786.60 (Fvco=3573.20, Nint=068, Nfrac=093)
-Fch=1786.80 (Fvco=3573.60, Nint=068, Nfrac=094)
-Fch=1787.00 (Fvco=3574.00, Nint=068, Nfrac=095)
-Fch=1787.20 (Fvco=3574.40, Nint=068, Nfrac=096)
-Fch=1787.40 (Fvco=3574.80, Nint=068, Nfrac=097)
-Fch=1787.60 (Fvco=3575.20, Nint=068, Nfrac=098)
-Fch=1787.80 (Fvco=3575.60, Nint=068, Nfrac=099)
-Fch=1788.00 (Fvco=3576.00, Nint=068, Nfrac=100)
-Fch=1788.20 (Fvco=3576.40, Nint=068, Nfrac=101)
-Fch=1788.40 (Fvco=3576.80, Nint=068, Nfrac=102)
-Fch=1788.60 (Fvco=3577.20, Nint=068, Nfrac=103)
-Fch=1788.80 (Fvco=3577.60, Nint=068, Nfrac=104)
-Fch=1789.00 (Fvco=3578.00, Nint=068, Nfrac=105)
-Fch=1789.20 (Fvco=3578.40, Nint=068, Nfrac=106)
-Fch=1789.40 (Fvco=3578.80, Nint=068, Nfrac=107)
-Fch=1789.60 (Fvco=3579.20, Nint=068, Nfrac=108)
-Fch=1789.80 (Fvco=3579.60, Nint=068, Nfrac=109)
-Fch=1790.00 (Fvco=3580.00, Nint=068, Nfrac=110)
-Fch=1790.20 (Fvco=3580.40, Nint=068, Nfrac=111)
-Fch=1790.40 (Fvco=3580.80, Nint=068, Nfrac=112)
-Fch=1790.60 (Fvco=3581.20, Nint=068, Nfrac=113)
-Fch=1790.80 (Fvco=3581.60, Nint=068, Nfrac=114)
-Fch=1791.00 (Fvco=3582.00, Nint=068, Nfrac=115)
-Fch=1791.20 (Fvco=3582.40, Nint=068, Nfrac=116)
-Fch=1791.40 (Fvco=3582.80, Nint=068, Nfrac=117)
-Fch=1791.60 (Fvco=3583.20, Nint=068, Nfrac=118)
-Fch=1791.80 (Fvco=3583.60, Nint=068, Nfrac=119)
-Fch=1792.00 (Fvco=3584.00, Nint=068, Nfrac=120)
-Fch=1792.20 (Fvco=3584.40, Nint=068, Nfrac=121)
-Fch=1792.40 (Fvco=3584.80, Nint=068, Nfrac=122)
-Fch=1792.60 (Fvco=3585.20, Nint=068, Nfrac=123)
-Fch=1792.80 (Fvco=3585.60, Nint=068, Nfrac=124)
-Fch=1793.00 (Fvco=3586.00, Nint=068, Nfrac=125)
-Fch=1793.20 (Fvco=3586.40, Nint=068, Nfrac=126)
-Fch=1793.40 (Fvco=3586.80, Nint=068, Nfrac=127)
-Fch=1793.60 (Fvco=3587.20, Nint=068, Nfrac=128)
-Fch=1793.80 (Fvco=3587.60, Nint=068, Nfrac=129)
-Fch=1794.00 (Fvco=3588.00, Nint=068, Nfrac=130)
-Fch=1794.00 (Fvco=3588.00, Nint=069, Nfrac=000)
-Fch=1794.20 (Fvco=3588.40, Nint=069, Nfrac=001)
-Fch=1794.40 (Fvco=3588.80, Nint=069, Nfrac=002)
-Fch=1794.60 (Fvco=3589.20, Nint=069, Nfrac=003)
-Fch=1794.80 (Fvco=3589.60, Nint=069, Nfrac=004)
-Fch=1795.00 (Fvco=3590.00, Nint=069, Nfrac=005)
-Fch=1795.20 (Fvco=3590.40, Nint=069, Nfrac=006)
-Fch=1795.40 (Fvco=3590.80, Nint=069, Nfrac=007)
-Fch=1795.60 (Fvco=3591.20, Nint=069, Nfrac=008)
-Fch=1795.80 (Fvco=3591.60, Nint=069, Nfrac=009)
-Fch=1796.00 (Fvco=3592.00, Nint=069, Nfrac=010)
-Fch=1796.20 (Fvco=3592.40, Nint=069, Nfrac=011)
-Fch=1796.40 (Fvco=3592.80, Nint=069, Nfrac=012)
-Fch=1796.60 (Fvco=3593.20, Nint=069, Nfrac=013)
-Fch=1796.80 (Fvco=3593.60, Nint=069, Nfrac=014)
-Fch=1797.00 (Fvco=3594.00, Nint=069, Nfrac=015)
-Fch=1797.20 (Fvco=3594.40, Nint=069, Nfrac=016)
-Fch=1797.40 (Fvco=3594.80, Nint=069, Nfrac=017)
-Fch=1797.60 (Fvco=3595.20, Nint=069, Nfrac=018)
-Fch=1797.80 (Fvco=3595.60, Nint=069, Nfrac=019)
-Fch=1798.00 (Fvco=3596.00, Nint=069, Nfrac=020)
-Fch=1798.20 (Fvco=3596.40, Nint=069, Nfrac=021)
-Fch=1798.40 (Fvco=3596.80, Nint=069, Nfrac=022)
-Fch=1798.60 (Fvco=3597.20, Nint=069, Nfrac=023)
-Fch=1798.80 (Fvco=3597.60, Nint=069, Nfrac=024)
-Fch=1799.00 (Fvco=3598.00, Nint=069, Nfrac=025)
-Fch=1799.20 (Fvco=3598.40, Nint=069, Nfrac=026)
-Fch=1799.40 (Fvco=3598.80, Nint=069, Nfrac=027)
-Fch=1799.60 (Fvco=3599.20, Nint=069, Nfrac=028)
-Fch=1799.80 (Fvco=3599.60, Nint=069, Nfrac=029)
-Fch=1800.00 (Fvco=3600.00, Nint=069, Nfrac=030)
-Fch=1800.20 (Fvco=3600.40, Nint=069, Nfrac=031)
-Fch=1800.40 (Fvco=3600.80, Nint=069, Nfrac=032)
-Fch=1800.60 (Fvco=3601.20, Nint=069, Nfrac=033)
-Fch=1800.80 (Fvco=3601.60, Nint=069, Nfrac=034)
-Fch=1801.00 (Fvco=3602.00, Nint=069, Nfrac=035)
-Fch=1801.20 (Fvco=3602.40, Nint=069, Nfrac=036)
-Fch=1801.40 (Fvco=3602.80, Nint=069, Nfrac=037)
-Fch=1801.60 (Fvco=3603.20, Nint=069, Nfrac=038)
-Fch=1801.80 (Fvco=3603.60, Nint=069, Nfrac=039)
-Fch=1802.00 (Fvco=3604.00, Nint=069, Nfrac=040)
-Fch=1802.20 (Fvco=3604.40, Nint=069, Nfrac=041)
-Fch=1802.40 (Fvco=3604.80, Nint=069, Nfrac=042)
-Fch=1802.60 (Fvco=3605.20, Nint=069, Nfrac=043)
-Fch=1802.80 (Fvco=3605.60, Nint=069, Nfrac=044)
-Fch=1803.00 (Fvco=3606.00, Nint=069, Nfrac=045)
-Fch=1803.20 (Fvco=3606.40, Nint=069, Nfrac=046)
-Fch=1803.40 (Fvco=3606.80, Nint=069, Nfrac=047)
-Fch=1803.60 (Fvco=3607.20, Nint=069, Nfrac=048)
-Fch=1803.80 (Fvco=3607.60, Nint=069, Nfrac=049)
-Fch=1804.00 (Fvco=3608.00, Nint=069, Nfrac=050)
-Fch=1804.20 (Fvco=3608.40, Nint=069, Nfrac=051)
-Fch=1804.40 (Fvco=3608.80, Nint=069, Nfrac=052)
-Fch=1804.60 (Fvco=3609.20, Nint=069, Nfrac=053)
-Fch=1804.80 (Fvco=3609.60, Nint=069, Nfrac=054)
-Fch=1805.00 (Fvco=3610.00, Nint=069, Nfrac=055)
-Fch=1805.20 (Fvco=3610.40, Nint=069, Nfrac=056)
-Fch=1805.40 (Fvco=3610.80, Nint=069, Nfrac=057)
-Fch=1805.60 (Fvco=3611.20, Nint=069, Nfrac=058)
-Fch=1805.80 (Fvco=3611.60, Nint=069, Nfrac=059)
-Fch=1806.00 (Fvco=3612.00, Nint=069, Nfrac=060)
-Fch=1806.20 (Fvco=3612.40, Nint=069, Nfrac=061)
-Fch=1806.40 (Fvco=3612.80, Nint=069, Nfrac=062)
-Fch=1806.60 (Fvco=3613.20, Nint=069, Nfrac=063)
-Fch=1806.80 (Fvco=3613.60, Nint=069, Nfrac=064)
-Fch=1807.00 (Fvco=3614.00, Nint=069, Nfrac=065)
-Fch=1807.20 (Fvco=3614.40, Nint=069, Nfrac=066)
-Fch=1807.40 (Fvco=3614.80, Nint=069, Nfrac=067)
-Fch=1807.60 (Fvco=3615.20, Nint=069, Nfrac=068)
-Fch=1807.80 (Fvco=3615.60, Nint=069, Nfrac=069)
-Fch=1808.00 (Fvco=3616.00, Nint=069, Nfrac=070)
-Fch=1808.20 (Fvco=3616.40, Nint=069, Nfrac=071)
-Fch=1808.40 (Fvco=3616.80, Nint=069, Nfrac=072)
-Fch=1808.60 (Fvco=3617.20, Nint=069, Nfrac=073)
-Fch=1808.80 (Fvco=3617.60, Nint=069, Nfrac=074)
-Fch=1809.00 (Fvco=3618.00, Nint=069, Nfrac=075)
-Fch=1809.20 (Fvco=3618.40, Nint=069, Nfrac=076)
-Fch=1809.40 (Fvco=3618.80, Nint=069, Nfrac=077)
-Fch=1809.60 (Fvco=3619.20, Nint=069, Nfrac=078)
-Fch=1809.80 (Fvco=3619.60, Nint=069, Nfrac=079)
-Fch=1810.00 (Fvco=3620.00, Nint=069, Nfrac=080)
-Fch=1810.20 (Fvco=3620.40, Nint=069, Nfrac=081)
-Fch=1810.40 (Fvco=3620.80, Nint=069, Nfrac=082)
-Fch=1810.60 (Fvco=3621.20, Nint=069, Nfrac=083)
-Fch=1810.80 (Fvco=3621.60, Nint=069, Nfrac=084)
-Fch=1811.00 (Fvco=3622.00, Nint=069, Nfrac=085)
-Fch=1811.20 (Fvco=3622.40, Nint=069, Nfrac=086)
-Fch=1811.40 (Fvco=3622.80, Nint=069, Nfrac=087)
-Fch=1811.60 (Fvco=3623.20, Nint=069, Nfrac=088)
-Fch=1811.80 (Fvco=3623.60, Nint=069, Nfrac=089)
-Fch=1812.00 (Fvco=3624.00, Nint=069, Nfrac=090)
-Fch=1812.20 (Fvco=3624.40, Nint=069, Nfrac=091)
-Fch=1812.40 (Fvco=3624.80, Nint=069, Nfrac=092)
-Fch=1812.60 (Fvco=3625.20, Nint=069, Nfrac=093)
-Fch=1812.80 (Fvco=3625.60, Nint=069, Nfrac=094)
-Fch=1813.00 (Fvco=3626.00, Nint=069, Nfrac=095)
-Fch=1813.20 (Fvco=3626.40, Nint=069, Nfrac=096)
-Fch=1813.40 (Fvco=3626.80, Nint=069, Nfrac=097)
-Fch=1813.60 (Fvco=3627.20, Nint=069, Nfrac=098)
-Fch=1813.80 (Fvco=3627.60, Nint=069, Nfrac=099)
-Fch=1814.00 (Fvco=3628.00, Nint=069, Nfrac=100)
-Fch=1814.20 (Fvco=3628.40, Nint=069, Nfrac=101)
-Fch=1814.40 (Fvco=3628.80, Nint=069, Nfrac=102)
-Fch=1814.60 (Fvco=3629.20, Nint=069, Nfrac=103)
-Fch=1814.80 (Fvco=3629.60, Nint=069, Nfrac=104)
-Fch=1815.00 (Fvco=3630.00, Nint=069, Nfrac=105)
-Fch=1815.20 (Fvco=3630.40, Nint=069, Nfrac=106)
-Fch=1815.40 (Fvco=3630.80, Nint=069, Nfrac=107)
-Fch=1815.60 (Fvco=3631.20, Nint=069, Nfrac=108)
-Fch=1815.80 (Fvco=3631.60, Nint=069, Nfrac=109)
-Fch=1816.00 (Fvco=3632.00, Nint=069, Nfrac=110)
-Fch=1816.20 (Fvco=3632.40, Nint=069, Nfrac=111)
-Fch=1816.40 (Fvco=3632.80, Nint=069, Nfrac=112)
-Fch=1816.60 (Fvco=3633.20, Nint=069, Nfrac=113)
-Fch=1816.80 (Fvco=3633.60, Nint=069, Nfrac=114)
-Fch=1817.00 (Fvco=3634.00, Nint=069, Nfrac=115)
-Fch=1817.20 (Fvco=3634.40, Nint=069, Nfrac=116)
-Fch=1817.40 (Fvco=3634.80, Nint=069, Nfrac=117)
-Fch=1817.60 (Fvco=3635.20, Nint=069, Nfrac=118)
-Fch=1817.80 (Fvco=3635.60, Nint=069, Nfrac=119)
-Fch=1818.00 (Fvco=3636.00, Nint=069, Nfrac=120)
-Fch=1818.20 (Fvco=3636.40, Nint=069, Nfrac=121)
-Fch=1818.40 (Fvco=3636.80, Nint=069, Nfrac=122)
-Fch=1818.60 (Fvco=3637.20, Nint=069, Nfrac=123)
-Fch=1818.80 (Fvco=3637.60, Nint=069, Nfrac=124)
-Fch=1819.00 (Fvco=3638.00, Nint=069, Nfrac=125)
-Fch=1819.20 (Fvco=3638.40, Nint=069, Nfrac=126)
-Fch=1819.40 (Fvco=3638.80, Nint=069, Nfrac=127)
-Fch=1819.60 (Fvco=3639.20, Nint=069, Nfrac=128)
-Fch=1819.80 (Fvco=3639.60, Nint=069, Nfrac=129)
-Fch=1820.00 (Fvco=3640.00, Nint=069, Nfrac=130)
-Fch=1820.00 (Fvco=3640.00, Nint=070, Nfrac=000)
-Fch=1820.20 (Fvco=3640.40, Nint=070, Nfrac=001)
-Fch=1820.40 (Fvco=3640.80, Nint=070, Nfrac=002)
-Fch=1820.60 (Fvco=3641.20, Nint=070, Nfrac=003)
-Fch=1820.80 (Fvco=3641.60, Nint=070, Nfrac=004)
-Fch=1821.00 (Fvco=3642.00, Nint=070, Nfrac=005)
-Fch=1821.20 (Fvco=3642.40, Nint=070, Nfrac=006)
-Fch=1821.40 (Fvco=3642.80, Nint=070, Nfrac=007)
-Fch=1821.60 (Fvco=3643.20, Nint=070, Nfrac=008)
-Fch=1821.80 (Fvco=3643.60, Nint=070, Nfrac=009)
-Fch=1822.00 (Fvco=3644.00, Nint=070, Nfrac=010)
-Fch=1822.20 (Fvco=3644.40, Nint=070, Nfrac=011)
-Fch=1822.40 (Fvco=3644.80, Nint=070, Nfrac=012)
-Fch=1822.60 (Fvco=3645.20, Nint=070, Nfrac=013)
-Fch=1822.80 (Fvco=3645.60, Nint=070, Nfrac=014)
-Fch=1823.00 (Fvco=3646.00, Nint=070, Nfrac=015)
-Fch=1823.20 (Fvco=3646.40, Nint=070, Nfrac=016)
-Fch=1823.40 (Fvco=3646.80, Nint=070, Nfrac=017)
-Fch=1823.60 (Fvco=3647.20, Nint=070, Nfrac=018)
-Fch=1823.80 (Fvco=3647.60, Nint=070, Nfrac=019)
-Fch=1824.00 (Fvco=3648.00, Nint=070, Nfrac=020)
-Fch=1824.20 (Fvco=3648.40, Nint=070, Nfrac=021)
-Fch=1824.40 (Fvco=3648.80, Nint=070, Nfrac=022)
-Fch=1824.60 (Fvco=3649.20, Nint=070, Nfrac=023)
-Fch=1824.80 (Fvco=3649.60, Nint=070, Nfrac=024)
-Fch=1825.00 (Fvco=3650.00, Nint=070, Nfrac=025)
-Fch=1825.20 (Fvco=3650.40, Nint=070, Nfrac=026)
-Fch=1825.40 (Fvco=3650.80, Nint=070, Nfrac=027)
-Fch=1825.60 (Fvco=3651.20, Nint=070, Nfrac=028)
-Fch=1825.80 (Fvco=3651.60, Nint=070, Nfrac=029)
-Fch=1826.00 (Fvco=3652.00, Nint=070, Nfrac=030)
-Fch=1826.20 (Fvco=3652.40, Nint=070, Nfrac=031)
-Fch=1826.40 (Fvco=3652.80, Nint=070, Nfrac=032)
-Fch=1826.60 (Fvco=3653.20, Nint=070, Nfrac=033)
-Fch=1826.80 (Fvco=3653.60, Nint=070, Nfrac=034)
-Fch=1827.00 (Fvco=3654.00, Nint=070, Nfrac=035)
-Fch=1827.20 (Fvco=3654.40, Nint=070, Nfrac=036)
-Fch=1827.40 (Fvco=3654.80, Nint=070, Nfrac=037)
-Fch=1827.60 (Fvco=3655.20, Nint=070, Nfrac=038)
-Fch=1827.80 (Fvco=3655.60, Nint=070, Nfrac=039)
-Fch=1828.00 (Fvco=3656.00, Nint=070, Nfrac=040)
-Fch=1828.20 (Fvco=3656.40, Nint=070, Nfrac=041)
-Fch=1828.40 (Fvco=3656.80, Nint=070, Nfrac=042)
-Fch=1828.60 (Fvco=3657.20, Nint=070, Nfrac=043)
-Fch=1828.80 (Fvco=3657.60, Nint=070, Nfrac=044)
-Fch=1829.00 (Fvco=3658.00, Nint=070, Nfrac=045)
-Fch=1829.20 (Fvco=3658.40, Nint=070, Nfrac=046)
-Fch=1829.40 (Fvco=3658.80, Nint=070, Nfrac=047)
-Fch=1829.60 (Fvco=3659.20, Nint=070, Nfrac=048)
-Fch=1829.80 (Fvco=3659.60, Nint=070, Nfrac=049)
-Fch=1830.00 (Fvco=3660.00, Nint=070, Nfrac=050)
-Fch=1830.20 (Fvco=3660.40, Nint=070, Nfrac=051)
-Fch=1830.40 (Fvco=3660.80, Nint=070, Nfrac=052)
-Fch=1830.60 (Fvco=3661.20, Nint=070, Nfrac=053)
-Fch=1830.80 (Fvco=3661.60, Nint=070, Nfrac=054)
-Fch=1831.00 (Fvco=3662.00, Nint=070, Nfrac=055)
-Fch=1831.20 (Fvco=3662.40, Nint=070, Nfrac=056)
-Fch=1831.40 (Fvco=3662.80, Nint=070, Nfrac=057)
-Fch=1831.60 (Fvco=3663.20, Nint=070, Nfrac=058)
-Fch=1831.80 (Fvco=3663.60, Nint=070, Nfrac=059)
-Fch=1832.00 (Fvco=3664.00, Nint=070, Nfrac=060)
-Fch=1832.20 (Fvco=3664.40, Nint=070, Nfrac=061)
-Fch=1832.40 (Fvco=3664.80, Nint=070, Nfrac=062)
-Fch=1832.60 (Fvco=3665.20, Nint=070, Nfrac=063)
-Fch=1832.80 (Fvco=3665.60, Nint=070, Nfrac=064)
-Fch=1833.00 (Fvco=3666.00, Nint=070, Nfrac=065)
-Fch=1833.20 (Fvco=3666.40, Nint=070, Nfrac=066)
-Fch=1833.40 (Fvco=3666.80, Nint=070, Nfrac=067)
-Fch=1833.60 (Fvco=3667.20, Nint=070, Nfrac=068)
-Fch=1833.80 (Fvco=3667.60, Nint=070, Nfrac=069)
-Fch=1834.00 (Fvco=3668.00, Nint=070, Nfrac=070)
-Fch=1834.20 (Fvco=3668.40, Nint=070, Nfrac=071)
-Fch=1834.40 (Fvco=3668.80, Nint=070, Nfrac=072)
-Fch=1834.60 (Fvco=3669.20, Nint=070, Nfrac=073)
-Fch=1834.80 (Fvco=3669.60, Nint=070, Nfrac=074)
-Fch=1835.00 (Fvco=3670.00, Nint=070, Nfrac=075)
-Fch=1835.20 (Fvco=3670.40, Nint=070, Nfrac=076)
-Fch=1835.40 (Fvco=3670.80, Nint=070, Nfrac=077)
-Fch=1835.60 (Fvco=3671.20, Nint=070, Nfrac=078)
-Fch=1835.80 (Fvco=3671.60, Nint=070, Nfrac=079)
-Fch=1836.00 (Fvco=3672.00, Nint=070, Nfrac=080)
-Fch=1836.20 (Fvco=3672.40, Nint=070, Nfrac=081)
-Fch=1836.40 (Fvco=3672.80, Nint=070, Nfrac=082)
-Fch=1836.60 (Fvco=3673.20, Nint=070, Nfrac=083)
-Fch=1836.80 (Fvco=3673.60, Nint=070, Nfrac=084)
-Fch=1837.00 (Fvco=3674.00, Nint=070, Nfrac=085)
-Fch=1837.20 (Fvco=3674.40, Nint=070, Nfrac=086)
-Fch=1837.40 (Fvco=3674.80, Nint=070, Nfrac=087)
-Fch=1837.60 (Fvco=3675.20, Nint=070, Nfrac=088)
-Fch=1837.80 (Fvco=3675.60, Nint=070, Nfrac=089)
-Fch=1838.00 (Fvco=3676.00, Nint=070, Nfrac=090)
-Fch=1838.20 (Fvco=3676.40, Nint=070, Nfrac=091)
-Fch=1838.40 (Fvco=3676.80, Nint=070, Nfrac=092)
-Fch=1838.60 (Fvco=3677.20, Nint=070, Nfrac=093)
-Fch=1838.80 (Fvco=3677.60, Nint=070, Nfrac=094)
-Fch=1839.00 (Fvco=3678.00, Nint=070, Nfrac=095)
-Fch=1839.20 (Fvco=3678.40, Nint=070, Nfrac=096)
-Fch=1839.40 (Fvco=3678.80, Nint=070, Nfrac=097)
-Fch=1839.60 (Fvco=3679.20, Nint=070, Nfrac=098)
-Fch=1839.80 (Fvco=3679.60, Nint=070, Nfrac=099)
-Fch=1840.00 (Fvco=3680.00, Nint=070, Nfrac=100)
-Fch=1840.20 (Fvco=3680.40, Nint=070, Nfrac=101)
-Fch=1840.40 (Fvco=3680.80, Nint=070, Nfrac=102)
-Fch=1840.60 (Fvco=3681.20, Nint=070, Nfrac=103)
-Fch=1840.80 (Fvco=3681.60, Nint=070, Nfrac=104)
-Fch=1841.00 (Fvco=3682.00, Nint=070, Nfrac=105)
-Fch=1841.20 (Fvco=3682.40, Nint=070, Nfrac=106)
-Fch=1841.40 (Fvco=3682.80, Nint=070, Nfrac=107)
-Fch=1841.60 (Fvco=3683.20, Nint=070, Nfrac=108)
-Fch=1841.80 (Fvco=3683.60, Nint=070, Nfrac=109)
-Fch=1842.00 (Fvco=3684.00, Nint=070, Nfrac=110)
-Fch=1842.20 (Fvco=3684.40, Nint=070, Nfrac=111)
-Fch=1842.40 (Fvco=3684.80, Nint=070, Nfrac=112)
-Fch=1842.60 (Fvco=3685.20, Nint=070, Nfrac=113)
-Fch=1842.80 (Fvco=3685.60, Nint=070, Nfrac=114)
-Fch=1843.00 (Fvco=3686.00, Nint=070, Nfrac=115)
-Fch=1843.20 (Fvco=3686.40, Nint=070, Nfrac=116)
-Fch=1843.40 (Fvco=3686.80, Nint=070, Nfrac=117)
-Fch=1843.60 (Fvco=3687.20, Nint=070, Nfrac=118)
-Fch=1843.80 (Fvco=3687.60, Nint=070, Nfrac=119)
-Fch=1844.00 (Fvco=3688.00, Nint=070, Nfrac=120)
-Fch=1844.20 (Fvco=3688.40, Nint=070, Nfrac=121)
-Fch=1844.40 (Fvco=3688.80, Nint=070, Nfrac=122)
-Fch=1844.60 (Fvco=3689.20, Nint=070, Nfrac=123)
-Fch=1844.80 (Fvco=3689.60, Nint=070, Nfrac=124)
-Fch=1845.00 (Fvco=3690.00, Nint=070, Nfrac=125)
-Fch=1845.20 (Fvco=3690.40, Nint=070, Nfrac=126)
-Fch=1845.40 (Fvco=3690.80, Nint=070, Nfrac=127)
-Fch=1845.60 (Fvco=3691.20, Nint=070, Nfrac=128)
-Fch=1845.80 (Fvco=3691.60, Nint=070, Nfrac=129)
-Fch=1846.00 (Fvco=3692.00, Nint=070, Nfrac=130)
-Fch=1846.00 (Fvco=3692.00, Nint=071, Nfrac=000)
-Fch=1846.20 (Fvco=3692.40, Nint=071, Nfrac=001)
-Fch=1846.40 (Fvco=3692.80, Nint=071, Nfrac=002)
-Fch=1846.60 (Fvco=3693.20, Nint=071, Nfrac=003)
-Fch=1846.80 (Fvco=3693.60, Nint=071, Nfrac=004)
-Fch=1847.00 (Fvco=3694.00, Nint=071, Nfrac=005)
-Fch=1847.20 (Fvco=3694.40, Nint=071, Nfrac=006)
-Fch=1847.40 (Fvco=3694.80, Nint=071, Nfrac=007)
-Fch=1847.60 (Fvco=3695.20, Nint=071, Nfrac=008)
-Fch=1847.80 (Fvco=3695.60, Nint=071, Nfrac=009)
-Fch=1848.00 (Fvco=3696.00, Nint=071, Nfrac=010)
-Fch=1848.20 (Fvco=3696.40, Nint=071, Nfrac=011)
-Fch=1848.40 (Fvco=3696.80, Nint=071, Nfrac=012)
-Fch=1848.60 (Fvco=3697.20, Nint=071, Nfrac=013)
-Fch=1848.80 (Fvco=3697.60, Nint=071, Nfrac=014)
-Fch=1849.00 (Fvco=3698.00, Nint=071, Nfrac=015)
-Fch=1849.20 (Fvco=3698.40, Nint=071, Nfrac=016)
-Fch=1849.40 (Fvco=3698.80, Nint=071, Nfrac=017)
-Fch=1849.60 (Fvco=3699.20, Nint=071, Nfrac=018)
-Fch=1849.80 (Fvco=3699.60, Nint=071, Nfrac=019)
-Fch=1850.00 (Fvco=3700.00, Nint=071, Nfrac=020)
-Fch=1850.20 (Fvco=3700.40, Nint=071, Nfrac=021)
-Fch=1850.40 (Fvco=3700.80, Nint=071, Nfrac=022)
-Fch=1850.60 (Fvco=3701.20, Nint=071, Nfrac=023)
-Fch=1850.80 (Fvco=3701.60, Nint=071, Nfrac=024)
-Fch=1851.00 (Fvco=3702.00, Nint=071, Nfrac=025)
-Fch=1851.20 (Fvco=3702.40, Nint=071, Nfrac=026)
-Fch=1851.40 (Fvco=3702.80, Nint=071, Nfrac=027)
-Fch=1851.60 (Fvco=3703.20, Nint=071, Nfrac=028)
-Fch=1851.80 (Fvco=3703.60, Nint=071, Nfrac=029)
-Fch=1852.00 (Fvco=3704.00, Nint=071, Nfrac=030)
-Fch=1852.20 (Fvco=3704.40, Nint=071, Nfrac=031)
-Fch=1852.40 (Fvco=3704.80, Nint=071, Nfrac=032)
-Fch=1852.60 (Fvco=3705.20, Nint=071, Nfrac=033)
-Fch=1852.80 (Fvco=3705.60, Nint=071, Nfrac=034)
-Fch=1853.00 (Fvco=3706.00, Nint=071, Nfrac=035)
-Fch=1853.20 (Fvco=3706.40, Nint=071, Nfrac=036)
-Fch=1853.40 (Fvco=3706.80, Nint=071, Nfrac=037)
-Fch=1853.60 (Fvco=3707.20, Nint=071, Nfrac=038)
-Fch=1853.80 (Fvco=3707.60, Nint=071, Nfrac=039)
-Fch=1854.00 (Fvco=3708.00, Nint=071, Nfrac=040)
-Fch=1854.20 (Fvco=3708.40, Nint=071, Nfrac=041)
-Fch=1854.40 (Fvco=3708.80, Nint=071, Nfrac=042)
-Fch=1854.60 (Fvco=3709.20, Nint=071, Nfrac=043)
-Fch=1854.80 (Fvco=3709.60, Nint=071, Nfrac=044)
-Fch=1855.00 (Fvco=3710.00, Nint=071, Nfrac=045)
-Fch=1855.20 (Fvco=3710.40, Nint=071, Nfrac=046)
-Fch=1855.40 (Fvco=3710.80, Nint=071, Nfrac=047)
-Fch=1855.60 (Fvco=3711.20, Nint=071, Nfrac=048)
-Fch=1855.80 (Fvco=3711.60, Nint=071, Nfrac=049)
-Fch=1856.00 (Fvco=3712.00, Nint=071, Nfrac=050)
-Fch=1856.20 (Fvco=3712.40, Nint=071, Nfrac=051)
-Fch=1856.40 (Fvco=3712.80, Nint=071, Nfrac=052)
-Fch=1856.60 (Fvco=3713.20, Nint=071, Nfrac=053)
-Fch=1856.80 (Fvco=3713.60, Nint=071, Nfrac=054)
-Fch=1857.00 (Fvco=3714.00, Nint=071, Nfrac=055)
-Fch=1857.20 (Fvco=3714.40, Nint=071, Nfrac=056)
-Fch=1857.40 (Fvco=3714.80, Nint=071, Nfrac=057)
-Fch=1857.60 (Fvco=3715.20, Nint=071, Nfrac=058)
-Fch=1857.80 (Fvco=3715.60, Nint=071, Nfrac=059)
-Fch=1858.00 (Fvco=3716.00, Nint=071, Nfrac=060)
-Fch=1858.20 (Fvco=3716.40, Nint=071, Nfrac=061)
-Fch=1858.40 (Fvco=3716.80, Nint=071, Nfrac=062)
-Fch=1858.60 (Fvco=3717.20, Nint=071, Nfrac=063)
-Fch=1858.80 (Fvco=3717.60, Nint=071, Nfrac=064)
-Fch=1859.00 (Fvco=3718.00, Nint=071, Nfrac=065)
-Fch=1859.20 (Fvco=3718.40, Nint=071, Nfrac=066)
-Fch=1859.40 (Fvco=3718.80, Nint=071, Nfrac=067)
-Fch=1859.60 (Fvco=3719.20, Nint=071, Nfrac=068)
-Fch=1859.80 (Fvco=3719.60, Nint=071, Nfrac=069)
-Fch=1860.00 (Fvco=3720.00, Nint=071, Nfrac=070)
-Fch=1860.20 (Fvco=3720.40, Nint=071, Nfrac=071)
-Fch=1860.40 (Fvco=3720.80, Nint=071, Nfrac=072)
-Fch=1860.60 (Fvco=3721.20, Nint=071, Nfrac=073)
-Fch=1860.80 (Fvco=3721.60, Nint=071, Nfrac=074)
-Fch=1861.00 (Fvco=3722.00, Nint=071, Nfrac=075)
-Fch=1861.20 (Fvco=3722.40, Nint=071, Nfrac=076)
-Fch=1861.40 (Fvco=3722.80, Nint=071, Nfrac=077)
-Fch=1861.60 (Fvco=3723.20, Nint=071, Nfrac=078)
-Fch=1861.80 (Fvco=3723.60, Nint=071, Nfrac=079)
-Fch=1862.00 (Fvco=3724.00, Nint=071, Nfrac=080)
-Fch=1862.20 (Fvco=3724.40, Nint=071, Nfrac=081)
-Fch=1862.40 (Fvco=3724.80, Nint=071, Nfrac=082)
-Fch=1862.60 (Fvco=3725.20, Nint=071, Nfrac=083)
-Fch=1862.80 (Fvco=3725.60, Nint=071, Nfrac=084)
-Fch=1863.00 (Fvco=3726.00, Nint=071, Nfrac=085)
-Fch=1863.20 (Fvco=3726.40, Nint=071, Nfrac=086)
-Fch=1863.40 (Fvco=3726.80, Nint=071, Nfrac=087)
-Fch=1863.60 (Fvco=3727.20, Nint=071, Nfrac=088)
-Fch=1863.80 (Fvco=3727.60, Nint=071, Nfrac=089)
-Fch=1864.00 (Fvco=3728.00, Nint=071, Nfrac=090)
-Fch=1864.20 (Fvco=3728.40, Nint=071, Nfrac=091)
-Fch=1864.40 (Fvco=3728.80, Nint=071, Nfrac=092)
-Fch=1864.60 (Fvco=3729.20, Nint=071, Nfrac=093)
-Fch=1864.80 (Fvco=3729.60, Nint=071, Nfrac=094)
-Fch=1865.00 (Fvco=3730.00, Nint=071, Nfrac=095)
-Fch=1865.20 (Fvco=3730.40, Nint=071, Nfrac=096)
-Fch=1865.40 (Fvco=3730.80, Nint=071, Nfrac=097)
-Fch=1865.60 (Fvco=3731.20, Nint=071, Nfrac=098)
-Fch=1865.80 (Fvco=3731.60, Nint=071, Nfrac=099)
-Fch=1866.00 (Fvco=3732.00, Nint=071, Nfrac=100)
-Fch=1866.20 (Fvco=3732.40, Nint=071, Nfrac=101)
-Fch=1866.40 (Fvco=3732.80, Nint=071, Nfrac=102)
-Fch=1866.60 (Fvco=3733.20, Nint=071, Nfrac=103)
-Fch=1866.80 (Fvco=3733.60, Nint=071, Nfrac=104)
-Fch=1867.00 (Fvco=3734.00, Nint=071, Nfrac=105)
-Fch=1867.20 (Fvco=3734.40, Nint=071, Nfrac=106)
-Fch=1867.40 (Fvco=3734.80, Nint=071, Nfrac=107)
-Fch=1867.60 (Fvco=3735.20, Nint=071, Nfrac=108)
-Fch=1867.80 (Fvco=3735.60, Nint=071, Nfrac=109)
-Fch=1868.00 (Fvco=3736.00, Nint=071, Nfrac=110)
-Fch=1868.20 (Fvco=3736.40, Nint=071, Nfrac=111)
-Fch=1868.40 (Fvco=3736.80, Nint=071, Nfrac=112)
-Fch=1868.60 (Fvco=3737.20, Nint=071, Nfrac=113)
-Fch=1868.80 (Fvco=3737.60, Nint=071, Nfrac=114)
-Fch=1869.00 (Fvco=3738.00, Nint=071, Nfrac=115)
-Fch=1869.20 (Fvco=3738.40, Nint=071, Nfrac=116)
-Fch=1869.40 (Fvco=3738.80, Nint=071, Nfrac=117)
-Fch=1869.60 (Fvco=3739.20, Nint=071, Nfrac=118)
-Fch=1869.80 (Fvco=3739.60, Nint=071, Nfrac=119)
-Fch=1870.00 (Fvco=3740.00, Nint=071, Nfrac=120)
-Fch=1870.20 (Fvco=3740.40, Nint=071, Nfrac=121)
-Fch=1870.40 (Fvco=3740.80, Nint=071, Nfrac=122)
-Fch=1870.60 (Fvco=3741.20, Nint=071, Nfrac=123)
-Fch=1870.80 (Fvco=3741.60, Nint=071, Nfrac=124)
-Fch=1871.00 (Fvco=3742.00, Nint=071, Nfrac=125)
-Fch=1871.20 (Fvco=3742.40, Nint=071, Nfrac=126)
-Fch=1871.40 (Fvco=3742.80, Nint=071, Nfrac=127)
-Fch=1871.60 (Fvco=3743.20, Nint=071, Nfrac=128)
-Fch=1871.80 (Fvco=3743.60, Nint=071, Nfrac=129)
-Fch=1872.00 (Fvco=3744.00, Nint=071, Nfrac=130)
-Fch=1872.00 (Fvco=3744.00, Nint=072, Nfrac=000)
-Fch=1872.20 (Fvco=3744.40, Nint=072, Nfrac=001)
-Fch=1872.40 (Fvco=3744.80, Nint=072, Nfrac=002)
-Fch=1872.60 (Fvco=3745.20, Nint=072, Nfrac=003)
-Fch=1872.80 (Fvco=3745.60, Nint=072, Nfrac=004)
-Fch=1873.00 (Fvco=3746.00, Nint=072, Nfrac=005)
-Fch=1873.20 (Fvco=3746.40, Nint=072, Nfrac=006)
-Fch=1873.40 (Fvco=3746.80, Nint=072, Nfrac=007)
-Fch=1873.60 (Fvco=3747.20, Nint=072, Nfrac=008)
-Fch=1873.80 (Fvco=3747.60, Nint=072, Nfrac=009)
-Fch=1874.00 (Fvco=3748.00, Nint=072, Nfrac=010)
-Fch=1874.20 (Fvco=3748.40, Nint=072, Nfrac=011)
-Fch=1874.40 (Fvco=3748.80, Nint=072, Nfrac=012)
-Fch=1874.60 (Fvco=3749.20, Nint=072, Nfrac=013)
-Fch=1874.80 (Fvco=3749.60, Nint=072, Nfrac=014)
-Fch=1875.00 (Fvco=3750.00, Nint=072, Nfrac=015)
-Fch=1875.20 (Fvco=3750.40, Nint=072, Nfrac=016)
-Fch=1875.40 (Fvco=3750.80, Nint=072, Nfrac=017)
-Fch=1875.60 (Fvco=3751.20, Nint=072, Nfrac=018)
-Fch=1875.80 (Fvco=3751.60, Nint=072, Nfrac=019)
-Fch=1876.00 (Fvco=3752.00, Nint=072, Nfrac=020)
-Fch=1876.20 (Fvco=3752.40, Nint=072, Nfrac=021)
-Fch=1876.40 (Fvco=3752.80, Nint=072, Nfrac=022)
-Fch=1876.60 (Fvco=3753.20, Nint=072, Nfrac=023)
-Fch=1876.80 (Fvco=3753.60, Nint=072, Nfrac=024)
-Fch=1877.00 (Fvco=3754.00, Nint=072, Nfrac=025)
-Fch=1877.20 (Fvco=3754.40, Nint=072, Nfrac=026)
-Fch=1877.40 (Fvco=3754.80, Nint=072, Nfrac=027)
-Fch=1877.60 (Fvco=3755.20, Nint=072, Nfrac=028)
-Fch=1877.80 (Fvco=3755.60, Nint=072, Nfrac=029)
-Fch=1878.00 (Fvco=3756.00, Nint=072, Nfrac=030)
-Fch=1878.20 (Fvco=3756.40, Nint=072, Nfrac=031)
-Fch=1878.40 (Fvco=3756.80, Nint=072, Nfrac=032)
-Fch=1878.60 (Fvco=3757.20, Nint=072, Nfrac=033)
-Fch=1878.80 (Fvco=3757.60, Nint=072, Nfrac=034)
-Fch=1879.00 (Fvco=3758.00, Nint=072, Nfrac=035)
-Fch=1879.20 (Fvco=3758.40, Nint=072, Nfrac=036)
-Fch=1879.40 (Fvco=3758.80, Nint=072, Nfrac=037)
-Fch=1879.60 (Fvco=3759.20, Nint=072, Nfrac=038)
-Fch=1879.80 (Fvco=3759.60, Nint=072, Nfrac=039)
-Fch=1880.00 (Fvco=3760.00, Nint=072, Nfrac=040)
-Fch=1880.20 (Fvco=3760.40, Nint=072, Nfrac=041)
-Fch=1880.40 (Fvco=3760.80, Nint=072, Nfrac=042)
-Fch=1880.60 (Fvco=3761.20, Nint=072, Nfrac=043)
-Fch=1880.80 (Fvco=3761.60, Nint=072, Nfrac=044)
-Fch=1881.00 (Fvco=3762.00, Nint=072, Nfrac=045)
-Fch=1881.20 (Fvco=3762.40, Nint=072, Nfrac=046)
-Fch=1881.40 (Fvco=3762.80, Nint=072, Nfrac=047)
-Fch=1881.60 (Fvco=3763.20, Nint=072, Nfrac=048)
-Fch=1881.80 (Fvco=3763.60, Nint=072, Nfrac=049)
-Fch=1882.00 (Fvco=3764.00, Nint=072, Nfrac=050)
-Fch=1882.20 (Fvco=3764.40, Nint=072, Nfrac=051)
-Fch=1882.40 (Fvco=3764.80, Nint=072, Nfrac=052)
-Fch=1882.60 (Fvco=3765.20, Nint=072, Nfrac=053)
-Fch=1882.80 (Fvco=3765.60, Nint=072, Nfrac=054)
-Fch=1883.00 (Fvco=3766.00, Nint=072, Nfrac=055)
-Fch=1883.20 (Fvco=3766.40, Nint=072, Nfrac=056)
-Fch=1883.40 (Fvco=3766.80, Nint=072, Nfrac=057)
-Fch=1883.60 (Fvco=3767.20, Nint=072, Nfrac=058)
-Fch=1883.80 (Fvco=3767.60, Nint=072, Nfrac=059)
-Fch=1884.00 (Fvco=3768.00, Nint=072, Nfrac=060)
-Fch=1884.20 (Fvco=3768.40, Nint=072, Nfrac=061)
-Fch=1884.40 (Fvco=3768.80, Nint=072, Nfrac=062)
-Fch=1884.60 (Fvco=3769.20, Nint=072, Nfrac=063)
-Fch=1884.80 (Fvco=3769.60, Nint=072, Nfrac=064)
-Fch=1885.00 (Fvco=3770.00, Nint=072, Nfrac=065)
-Fch=1885.20 (Fvco=3770.40, Nint=072, Nfrac=066)
-Fch=1885.40 (Fvco=3770.80, Nint=072, Nfrac=067)
-Fch=1885.60 (Fvco=3771.20, Nint=072, Nfrac=068)
-Fch=1885.80 (Fvco=3771.60, Nint=072, Nfrac=069)
-Fch=1886.00 (Fvco=3772.00, Nint=072, Nfrac=070)
-Fch=1886.20 (Fvco=3772.40, Nint=072, Nfrac=071)
-Fch=1886.40 (Fvco=3772.80, Nint=072, Nfrac=072)
-Fch=1886.60 (Fvco=3773.20, Nint=072, Nfrac=073)
-Fch=1886.80 (Fvco=3773.60, Nint=072, Nfrac=074)
-Fch=1887.00 (Fvco=3774.00, Nint=072, Nfrac=075)
-Fch=1887.20 (Fvco=3774.40, Nint=072, Nfrac=076)
-Fch=1887.40 (Fvco=3774.80, Nint=072, Nfrac=077)
-Fch=1887.60 (Fvco=3775.20, Nint=072, Nfrac=078)
-Fch=1887.80 (Fvco=3775.60, Nint=072, Nfrac=079)
-Fch=1888.00 (Fvco=3776.00, Nint=072, Nfrac=080)
-Fch=1888.20 (Fvco=3776.40, Nint=072, Nfrac=081)
-Fch=1888.40 (Fvco=3776.80, Nint=072, Nfrac=082)
-Fch=1888.60 (Fvco=3777.20, Nint=072, Nfrac=083)
-Fch=1888.80 (Fvco=3777.60, Nint=072, Nfrac=084)
-Fch=1889.00 (Fvco=3778.00, Nint=072, Nfrac=085)
-Fch=1889.20 (Fvco=3778.40, Nint=072, Nfrac=086)
-Fch=1889.40 (Fvco=3778.80, Nint=072, Nfrac=087)
-Fch=1889.60 (Fvco=3779.20, Nint=072, Nfrac=088)
-Fch=1889.80 (Fvco=3779.60, Nint=072, Nfrac=089)
-Fch=1890.00 (Fvco=3780.00, Nint=072, Nfrac=090)
-Fch=1890.20 (Fvco=3780.40, Nint=072, Nfrac=091)
-Fch=1890.40 (Fvco=3780.80, Nint=072, Nfrac=092)
-Fch=1890.60 (Fvco=3781.20, Nint=072, Nfrac=093)
-Fch=1890.80 (Fvco=3781.60, Nint=072, Nfrac=094)
-Fch=1891.00 (Fvco=3782.00, Nint=072, Nfrac=095)
-Fch=1891.20 (Fvco=3782.40, Nint=072, Nfrac=096)
-Fch=1891.40 (Fvco=3782.80, Nint=072, Nfrac=097)
-Fch=1891.60 (Fvco=3783.20, Nint=072, Nfrac=098)
-Fch=1891.80 (Fvco=3783.60, Nint=072, Nfrac=099)
-Fch=1892.00 (Fvco=3784.00, Nint=072, Nfrac=100)
-Fch=1892.20 (Fvco=3784.40, Nint=072, Nfrac=101)
-Fch=1892.40 (Fvco=3784.80, Nint=072, Nfrac=102)
-Fch=1892.60 (Fvco=3785.20, Nint=072, Nfrac=103)
-Fch=1892.80 (Fvco=3785.60, Nint=072, Nfrac=104)
-Fch=1893.00 (Fvco=3786.00, Nint=072, Nfrac=105)
-Fch=1893.20 (Fvco=3786.40, Nint=072, Nfrac=106)
-Fch=1893.40 (Fvco=3786.80, Nint=072, Nfrac=107)
-Fch=1893.60 (Fvco=3787.20, Nint=072, Nfrac=108)
-Fch=1893.80 (Fvco=3787.60, Nint=072, Nfrac=109)
-Fch=1894.00 (Fvco=3788.00, Nint=072, Nfrac=110)
-Fch=1894.20 (Fvco=3788.40, Nint=072, Nfrac=111)
-Fch=1894.40 (Fvco=3788.80, Nint=072, Nfrac=112)
-Fch=1894.60 (Fvco=3789.20, Nint=072, Nfrac=113)
-Fch=1894.80 (Fvco=3789.60, Nint=072, Nfrac=114)
-Fch=1895.00 (Fvco=3790.00, Nint=072, Nfrac=115)
-Fch=1895.20 (Fvco=3790.40, Nint=072, Nfrac=116)
-Fch=1895.40 (Fvco=3790.80, Nint=072, Nfrac=117)
-Fch=1895.60 (Fvco=3791.20, Nint=072, Nfrac=118)
-Fch=1895.80 (Fvco=3791.60, Nint=072, Nfrac=119)
-Fch=1896.00 (Fvco=3792.00, Nint=072, Nfrac=120)
-Fch=1896.20 (Fvco=3792.40, Nint=072, Nfrac=121)
-Fch=1896.40 (Fvco=3792.80, Nint=072, Nfrac=122)
-Fch=1896.60 (Fvco=3793.20, Nint=072, Nfrac=123)
-Fch=1896.80 (Fvco=3793.60, Nint=072, Nfrac=124)
-Fch=1897.00 (Fvco=3794.00, Nint=072, Nfrac=125)
-Fch=1897.20 (Fvco=3794.40, Nint=072, Nfrac=126)
-Fch=1897.40 (Fvco=3794.80, Nint=072, Nfrac=127)
-Fch=1897.60 (Fvco=3795.20, Nint=072, Nfrac=128)
-Fch=1897.80 (Fvco=3795.60, Nint=072, Nfrac=129)
-Fch=1898.00 (Fvco=3796.00, Nint=072, Nfrac=130)
-Fch=1898.00 (Fvco=3796.00, Nint=073, Nfrac=000)
-Fch=1898.20 (Fvco=3796.40, Nint=073, Nfrac=001)
-Fch=1898.40 (Fvco=3796.80, Nint=073, Nfrac=002)
-Fch=1898.60 (Fvco=3797.20, Nint=073, Nfrac=003)
-Fch=1898.80 (Fvco=3797.60, Nint=073, Nfrac=004)
-Fch=1899.00 (Fvco=3798.00, Nint=073, Nfrac=005)
-Fch=1899.20 (Fvco=3798.40, Nint=073, Nfrac=006)
-Fch=1899.40 (Fvco=3798.80, Nint=073, Nfrac=007)
-Fch=1899.60 (Fvco=3799.20, Nint=073, Nfrac=008)
-Fch=1899.80 (Fvco=3799.60, Nint=073, Nfrac=009)
-Fch=1900.00 (Fvco=3800.00, Nint=073, Nfrac=010)
-Fch=1900.20 (Fvco=3800.40, Nint=073, Nfrac=011)
-Fch=1900.40 (Fvco=3800.80, Nint=073, Nfrac=012)
-Fch=1900.60 (Fvco=3801.20, Nint=073, Nfrac=013)
-Fch=1900.80 (Fvco=3801.60, Nint=073, Nfrac=014)
-Fch=1901.00 (Fvco=3802.00, Nint=073, Nfrac=015)
-Fch=1901.20 (Fvco=3802.40, Nint=073, Nfrac=016)
-Fch=1901.40 (Fvco=3802.80, Nint=073, Nfrac=017)
-Fch=1901.60 (Fvco=3803.20, Nint=073, Nfrac=018)
-Fch=1901.80 (Fvco=3803.60, Nint=073, Nfrac=019)
-Fch=1902.00 (Fvco=3804.00, Nint=073, Nfrac=020)
-Fch=1902.20 (Fvco=3804.40, Nint=073, Nfrac=021)
-Fch=1902.40 (Fvco=3804.80, Nint=073, Nfrac=022)
-Fch=1902.60 (Fvco=3805.20, Nint=073, Nfrac=023)
-Fch=1902.80 (Fvco=3805.60, Nint=073, Nfrac=024)
-Fch=1903.00 (Fvco=3806.00, Nint=073, Nfrac=025)
-Fch=1903.20 (Fvco=3806.40, Nint=073, Nfrac=026)
-Fch=1903.40 (Fvco=3806.80, Nint=073, Nfrac=027)
-Fch=1903.60 (Fvco=3807.20, Nint=073, Nfrac=028)
-Fch=1903.80 (Fvco=3807.60, Nint=073, Nfrac=029)
-Fch=1904.00 (Fvco=3808.00, Nint=073, Nfrac=030)
-Fch=1904.20 (Fvco=3808.40, Nint=073, Nfrac=031)
-Fch=1904.40 (Fvco=3808.80, Nint=073, Nfrac=032)
-Fch=1904.60 (Fvco=3809.20, Nint=073, Nfrac=033)
-Fch=1904.80 (Fvco=3809.60, Nint=073, Nfrac=034)
-Fch=1905.00 (Fvco=3810.00, Nint=073, Nfrac=035)
-Fch=1905.20 (Fvco=3810.40, Nint=073, Nfrac=036)
-Fch=1905.40 (Fvco=3810.80, Nint=073, Nfrac=037)
-Fch=1905.60 (Fvco=3811.20, Nint=073, Nfrac=038)
-Fch=1905.80 (Fvco=3811.60, Nint=073, Nfrac=039)
-Fch=1906.00 (Fvco=3812.00, Nint=073, Nfrac=040)
-Fch=1906.20 (Fvco=3812.40, Nint=073, Nfrac=041)
-Fch=1906.40 (Fvco=3812.80, Nint=073, Nfrac=042)
-Fch=1906.60 (Fvco=3813.20, Nint=073, Nfrac=043)
-Fch=1906.80 (Fvco=3813.60, Nint=073, Nfrac=044)
-Fch=1907.00 (Fvco=3814.00, Nint=073, Nfrac=045)
-Fch=1907.20 (Fvco=3814.40, Nint=073, Nfrac=046)
-Fch=1907.40 (Fvco=3814.80, Nint=073, Nfrac=047)
-Fch=1907.60 (Fvco=3815.20, Nint=073, Nfrac=048)
-Fch=1907.80 (Fvco=3815.60, Nint=073, Nfrac=049)
-Fch=1908.00 (Fvco=3816.00, Nint=073, Nfrac=050)
-Fch=1908.20 (Fvco=3816.40, Nint=073, Nfrac=051)
-Fch=1908.40 (Fvco=3816.80, Nint=073, Nfrac=052)
-Fch=1908.60 (Fvco=3817.20, Nint=073, Nfrac=053)
-Fch=1908.80 (Fvco=3817.60, Nint=073, Nfrac=054)
-Fch=1909.00 (Fvco=3818.00, Nint=073, Nfrac=055)
-Fch=1909.20 (Fvco=3818.40, Nint=073, Nfrac=056)
-Fch=1909.40 (Fvco=3818.80, Nint=073, Nfrac=057)
-Fch=1909.60 (Fvco=3819.20, Nint=073, Nfrac=058)
-Fch=1909.80 (Fvco=3819.60, Nint=073, Nfrac=059)
-Fch=1910.00 (Fvco=3820.00, Nint=073, Nfrac=060)
-Fch=1910.20 (Fvco=3820.40, Nint=073, Nfrac=061)
-Fch=1910.40 (Fvco=3820.80, Nint=073, Nfrac=062)
-Fch=1910.60 (Fvco=3821.20, Nint=073, Nfrac=063)
-Fch=1910.80 (Fvco=3821.60, Nint=073, Nfrac=064)
-Fch=1911.00 (Fvco=3822.00, Nint=073, Nfrac=065)
-Fch=1911.20 (Fvco=3822.40, Nint=073, Nfrac=066)
-Fch=1911.40 (Fvco=3822.80, Nint=073, Nfrac=067)
-Fch=1911.60 (Fvco=3823.20, Nint=073, Nfrac=068)
-Fch=1911.80 (Fvco=3823.60, Nint=073, Nfrac=069)
-Fch=1912.00 (Fvco=3824.00, Nint=073, Nfrac=070)
-Fch=1912.20 (Fvco=3824.40, Nint=073, Nfrac=071)
-Fch=1912.40 (Fvco=3824.80, Nint=073, Nfrac=072)
-Fch=1912.60 (Fvco=3825.20, Nint=073, Nfrac=073)
-Fch=1912.80 (Fvco=3825.60, Nint=073, Nfrac=074)
-Fch=1913.00 (Fvco=3826.00, Nint=073, Nfrac=075)
-Fch=1913.20 (Fvco=3826.40, Nint=073, Nfrac=076)
-Fch=1913.40 (Fvco=3826.80, Nint=073, Nfrac=077)
-Fch=1913.60 (Fvco=3827.20, Nint=073, Nfrac=078)
-Fch=1913.80 (Fvco=3827.60, Nint=073, Nfrac=079)
-Fch=1914.00 (Fvco=3828.00, Nint=073, Nfrac=080)
-Fch=1914.20 (Fvco=3828.40, Nint=073, Nfrac=081)
-Fch=1914.40 (Fvco=3828.80, Nint=073, Nfrac=082)
-Fch=1914.60 (Fvco=3829.20, Nint=073, Nfrac=083)
-Fch=1914.80 (Fvco=3829.60, Nint=073, Nfrac=084)
-Fch=1915.00 (Fvco=3830.00, Nint=073, Nfrac=085)
-Fch=1915.20 (Fvco=3830.40, Nint=073, Nfrac=086)
-Fch=1915.40 (Fvco=3830.80, Nint=073, Nfrac=087)
-Fch=1915.60 (Fvco=3831.20, Nint=073, Nfrac=088)
-Fch=1915.80 (Fvco=3831.60, Nint=073, Nfrac=089)
-Fch=1916.00 (Fvco=3832.00, Nint=073, Nfrac=090)
-Fch=1916.20 (Fvco=3832.40, Nint=073, Nfrac=091)
-Fch=1916.40 (Fvco=3832.80, Nint=073, Nfrac=092)
-Fch=1916.60 (Fvco=3833.20, Nint=073, Nfrac=093)
-Fch=1916.80 (Fvco=3833.60, Nint=073, Nfrac=094)
-Fch=1917.00 (Fvco=3834.00, Nint=073, Nfrac=095)
-Fch=1917.20 (Fvco=3834.40, Nint=073, Nfrac=096)
-Fch=1917.40 (Fvco=3834.80, Nint=073, Nfrac=097)
-Fch=1917.60 (Fvco=3835.20, Nint=073, Nfrac=098)
-Fch=1917.80 (Fvco=3835.60, Nint=073, Nfrac=099)
-Fch=1918.00 (Fvco=3836.00, Nint=073, Nfrac=100)
-Fch=1918.20 (Fvco=3836.40, Nint=073, Nfrac=101)
-Fch=1918.40 (Fvco=3836.80, Nint=073, Nfrac=102)
-Fch=1918.60 (Fvco=3837.20, Nint=073, Nfrac=103)
-Fch=1918.80 (Fvco=3837.60, Nint=073, Nfrac=104)
-Fch=1919.00 (Fvco=3838.00, Nint=073, Nfrac=105)
-Fch=1919.20 (Fvco=3838.40, Nint=073, Nfrac=106)
-Fch=1919.40 (Fvco=3838.80, Nint=073, Nfrac=107)
-Fch=1919.60 (Fvco=3839.20, Nint=073, Nfrac=108)
-Fch=1919.80 (Fvco=3839.60, Nint=073, Nfrac=109)
-Fch=1920.00 (Fvco=3840.00, Nint=073, Nfrac=110)
-Fch=1920.20 (Fvco=3840.40, Nint=073, Nfrac=111)
-Fch=1920.40 (Fvco=3840.80, Nint=073, Nfrac=112)
-Fch=1920.60 (Fvco=3841.20, Nint=073, Nfrac=113)
-Fch=1920.80 (Fvco=3841.60, Nint=073, Nfrac=114)
-Fch=1921.00 (Fvco=3842.00, Nint=073, Nfrac=115)
-Fch=1921.20 (Fvco=3842.40, Nint=073, Nfrac=116)
-Fch=1921.40 (Fvco=3842.80, Nint=073, Nfrac=117)
-Fch=1921.60 (Fvco=3843.20, Nint=073, Nfrac=118)
-Fch=1921.80 (Fvco=3843.60, Nint=073, Nfrac=119)
-Fch=1922.00 (Fvco=3844.00, Nint=073, Nfrac=120)
-Fch=1922.20 (Fvco=3844.40, Nint=073, Nfrac=121)
-Fch=1922.40 (Fvco=3844.80, Nint=073, Nfrac=122)
-Fch=1922.60 (Fvco=3845.20, Nint=073, Nfrac=123)
-Fch=1922.80 (Fvco=3845.60, Nint=073, Nfrac=124)
-Fch=1923.00 (Fvco=3846.00, Nint=073, Nfrac=125)
-Fch=1923.20 (Fvco=3846.40, Nint=073, Nfrac=126)
-Fch=1923.40 (Fvco=3846.80, Nint=073, Nfrac=127)
-Fch=1923.60 (Fvco=3847.20, Nint=073, Nfrac=128)
-Fch=1923.80 (Fvco=3847.60, Nint=073, Nfrac=129)
-Fch=1924.00 (Fvco=3848.00, Nint=073, Nfrac=130)
diff --git a/Src/osmoconbb/src/host/rita_pll/rita_pll.pl b/Src/osmoconbb/src/host/rita_pll/rita_pll.pl
deleted file mode 100755
index b5b0944..0000000
--- a/Src/osmoconbb/src/host/rita_pll/rita_pll.pl
+++ /dev/null
@@ -1,115 +0,0 @@
-#!/usr/bin/perl
-
-sub pll_rx($$$$$) {
- my ($a, $b, $p, $r, $l) = @_;
-
- return (($b*$p+$a)/($r*$l))*26;
-}
-
-sub pll_rx_low_band($$) {
- my ($a, $b) = @_;
- my $p = 64; my $r = 65; my $l = 4;
- return pll_rx($a, $b, $p, $r, $l);
-}
-
-sub pll_rx_high_band($$) {
- my ($a, $b) = @_;
- my $p = 64; my $r = 65; my $l = 2;
- return pll_rx($a, $b, $p, $r, $l);
-}
-
-sub pll_tx_gsm850_1($$) {
- my ($a, $b) = @_;
- my $p = 64; my $r = 55; my $l = 4; my $m = 26;
-
- my $left = ((1/$l) - (1/$m));
- my $right = (($b*$p+$a)/$r);
-
- return $left * $right * 26;
-}
-
-sub pll_tx_gsm850_2($$) {
- my ($a, $b) = @_;
- my $p = 64; my $r = 30; my $l = 4; my $m = 52;
-
- my $left = ((1/$l) - (1/$m));
- my $right = (($b*$p+$a)/$r);
-
- return $left * $right * 26;
-}
-
-sub pll_tx_gsm900($$) {
- my ($a, $b) = @_;
- my $p = 64; my $r = 35; my $l = 4; my $m = 52;
-
- my $left = ((1/$l) + (1/$m));
- my $right = (($b*$p+$a)/$r);
-
- return $left * $right * 26;
-}
-
-sub pll_tx_high($$) {
- my ($a, $b) = @_;
- my $p = 64; my $r = 70; my $l = 2; my $m = 26;
-
- my $left = ((1/$l) + (1/$m));
- my $right = (($b*$p+$a)/$r);
-
- return $left * $right * 26;
-}
-
-sub hr() {
- printf("======================================================================\n");
-}
-
-printf("PLL Rx Low Band:\n");
-for (my $b = 135; $b <= 150; $b++) {
-#for GSM 810
-#for (my $b = 132; $b <= 150; $b++) {
- for (my $a = 0; $a <= 62; $a++) {
- printf("Fout=%4.2f (A=%03u, B=%03u)\n", pll_rx_low_band($a, $b), $a, $b);
- }
-}
-
-hr();
-printf("PLL Rx High Band:\n");
-for (my $b = 141; $b <= 155; $b++) {
- for (my $a = 0; $a <= 62; $a++) {
- printf("Fout=%4.2f (A=%03u, B=%03u)\n", pll_rx_high_band($a, $b), $a, $b);
- }
-}
-
-hr();
-printf("PLL Tx GSM850_1\n");
-for (my $b = 128; $b <= 130; $b++) {
-#for GSM 810
-#for (my $b = 125; $b <= 130; $b++) {
- for (my $a = 0; $a <= 62; $a++) {
- printf("Fout=%4.2f (A=%03u, B=%03u)\n", pll_tx_gsm850_1($a, $b), $a, $b);
- }
-}
-
-hr();
-printf("PLL Tx GSM850_2\n");
-for (my $b = 65; $b <= 66; $b++) {
- for (my $a = 0; $a <= 63; $a++) {
- printf("Fout=%4.2f (A=%03u, B=%03u)\n", pll_tx_gsm850_2($a, $b), $a, $b);
- }
-}
-
-hr();
-printf("PLL Tx GSM900\n");
-for (my $b = 68; $b <= 71; $b++) {
- for (my $a = 0; $a <= 63; $a++) {
- printf("Fout=%4.2f (A=%03u, B=%03u)\n", pll_tx_gsm900($a, $b), $a, $b);
- }
-}
-
-hr();
-printf("PLL Tx GSM1800/1900\n");
-for (my $b = 133; $b <= 149; $b++) {
- for (my $a = 0; $a <= 63; $a++) {
- printf("Fout=%4.2f (A=%03u, B=%03u)\n", pll_tx_high($a, $b), $a, $b);
- }
-}
-
diff --git a/Src/osmoconbb/src/host/rita_pll/rita_pll.txt b/Src/osmoconbb/src/host/rita_pll/rita_pll.txt
deleted file mode 100644
index cac2cac..0000000
--- a/Src/osmoconbb/src/host/rita_pll/rita_pll.txt
+++ /dev/null
@@ -1,3625 +0,0 @@
-PLL Rx Low Band:
-Fout=864.00 (A=000, B=135)
-Fout=864.10 (A=001, B=135)
-Fout=864.20 (A=002, B=135)
-Fout=864.30 (A=003, B=135)
-Fout=864.40 (A=004, B=135)
-Fout=864.50 (A=005, B=135)
-Fout=864.60 (A=006, B=135)
-Fout=864.70 (A=007, B=135)
-Fout=864.80 (A=008, B=135)
-Fout=864.90 (A=009, B=135)
-Fout=865.00 (A=010, B=135)
-Fout=865.10 (A=011, B=135)
-Fout=865.20 (A=012, B=135)
-Fout=865.30 (A=013, B=135)
-Fout=865.40 (A=014, B=135)
-Fout=865.50 (A=015, B=135)
-Fout=865.60 (A=016, B=135)
-Fout=865.70 (A=017, B=135)
-Fout=865.80 (A=018, B=135)
-Fout=865.90 (A=019, B=135)
-Fout=866.00 (A=020, B=135)
-Fout=866.10 (A=021, B=135)
-Fout=866.20 (A=022, B=135)
-Fout=866.30 (A=023, B=135)
-Fout=866.40 (A=024, B=135)
-Fout=866.50 (A=025, B=135)
-Fout=866.60 (A=026, B=135)
-Fout=866.70 (A=027, B=135)
-Fout=866.80 (A=028, B=135)
-Fout=866.90 (A=029, B=135)
-Fout=867.00 (A=030, B=135)
-Fout=867.10 (A=031, B=135)
-Fout=867.20 (A=032, B=135)
-Fout=867.30 (A=033, B=135)
-Fout=867.40 (A=034, B=135)
-Fout=867.50 (A=035, B=135)
-Fout=867.60 (A=036, B=135)
-Fout=867.70 (A=037, B=135)
-Fout=867.80 (A=038, B=135)
-Fout=867.90 (A=039, B=135)
-Fout=868.00 (A=040, B=135)
-Fout=868.10 (A=041, B=135)
-Fout=868.20 (A=042, B=135)
-Fout=868.30 (A=043, B=135)
-Fout=868.40 (A=044, B=135)
-Fout=868.50 (A=045, B=135)
-Fout=868.60 (A=046, B=135)
-Fout=868.70 (A=047, B=135)
-Fout=868.80 (A=048, B=135)
-Fout=868.90 (A=049, B=135)
-Fout=869.00 (A=050, B=135)
-Fout=869.10 (A=051, B=135)
-Fout=869.20 (A=052, B=135)
-Fout=869.30 (A=053, B=135)
-Fout=869.40 (A=054, B=135)
-Fout=869.50 (A=055, B=135)
-Fout=869.60 (A=056, B=135)
-Fout=869.70 (A=057, B=135)
-Fout=869.80 (A=058, B=135)
-Fout=869.90 (A=059, B=135)
-Fout=870.00 (A=060, B=135)
-Fout=870.10 (A=061, B=135)
-Fout=870.20 (A=062, B=135)
-Fout=870.40 (A=000, B=136)
-Fout=870.50 (A=001, B=136)
-Fout=870.60 (A=002, B=136)
-Fout=870.70 (A=003, B=136)
-Fout=870.80 (A=004, B=136)
-Fout=870.90 (A=005, B=136)
-Fout=871.00 (A=006, B=136)
-Fout=871.10 (A=007, B=136)
-Fout=871.20 (A=008, B=136)
-Fout=871.30 (A=009, B=136)
-Fout=871.40 (A=010, B=136)
-Fout=871.50 (A=011, B=136)
-Fout=871.60 (A=012, B=136)
-Fout=871.70 (A=013, B=136)
-Fout=871.80 (A=014, B=136)
-Fout=871.90 (A=015, B=136)
-Fout=872.00 (A=016, B=136)
-Fout=872.10 (A=017, B=136)
-Fout=872.20 (A=018, B=136)
-Fout=872.30 (A=019, B=136)
-Fout=872.40 (A=020, B=136)
-Fout=872.50 (A=021, B=136)
-Fout=872.60 (A=022, B=136)
-Fout=872.70 (A=023, B=136)
-Fout=872.80 (A=024, B=136)
-Fout=872.90 (A=025, B=136)
-Fout=873.00 (A=026, B=136)
-Fout=873.10 (A=027, B=136)
-Fout=873.20 (A=028, B=136)
-Fout=873.30 (A=029, B=136)
-Fout=873.40 (A=030, B=136)
-Fout=873.50 (A=031, B=136)
-Fout=873.60 (A=032, B=136)
-Fout=873.70 (A=033, B=136)
-Fout=873.80 (A=034, B=136)
-Fout=873.90 (A=035, B=136)
-Fout=874.00 (A=036, B=136)
-Fout=874.10 (A=037, B=136)
-Fout=874.20 (A=038, B=136)
-Fout=874.30 (A=039, B=136)
-Fout=874.40 (A=040, B=136)
-Fout=874.50 (A=041, B=136)
-Fout=874.60 (A=042, B=136)
-Fout=874.70 (A=043, B=136)
-Fout=874.80 (A=044, B=136)
-Fout=874.90 (A=045, B=136)
-Fout=875.00 (A=046, B=136)
-Fout=875.10 (A=047, B=136)
-Fout=875.20 (A=048, B=136)
-Fout=875.30 (A=049, B=136)
-Fout=875.40 (A=050, B=136)
-Fout=875.50 (A=051, B=136)
-Fout=875.60 (A=052, B=136)
-Fout=875.70 (A=053, B=136)
-Fout=875.80 (A=054, B=136)
-Fout=875.90 (A=055, B=136)
-Fout=876.00 (A=056, B=136)
-Fout=876.10 (A=057, B=136)
-Fout=876.20 (A=058, B=136)
-Fout=876.30 (A=059, B=136)
-Fout=876.40 (A=060, B=136)
-Fout=876.50 (A=061, B=136)
-Fout=876.60 (A=062, B=136)
-Fout=876.80 (A=000, B=137)
-Fout=876.90 (A=001, B=137)
-Fout=877.00 (A=002, B=137)
-Fout=877.10 (A=003, B=137)
-Fout=877.20 (A=004, B=137)
-Fout=877.30 (A=005, B=137)
-Fout=877.40 (A=006, B=137)
-Fout=877.50 (A=007, B=137)
-Fout=877.60 (A=008, B=137)
-Fout=877.70 (A=009, B=137)
-Fout=877.80 (A=010, B=137)
-Fout=877.90 (A=011, B=137)
-Fout=878.00 (A=012, B=137)
-Fout=878.10 (A=013, B=137)
-Fout=878.20 (A=014, B=137)
-Fout=878.30 (A=015, B=137)
-Fout=878.40 (A=016, B=137)
-Fout=878.50 (A=017, B=137)
-Fout=878.60 (A=018, B=137)
-Fout=878.70 (A=019, B=137)
-Fout=878.80 (A=020, B=137)
-Fout=878.90 (A=021, B=137)
-Fout=879.00 (A=022, B=137)
-Fout=879.10 (A=023, B=137)
-Fout=879.20 (A=024, B=137)
-Fout=879.30 (A=025, B=137)
-Fout=879.40 (A=026, B=137)
-Fout=879.50 (A=027, B=137)
-Fout=879.60 (A=028, B=137)
-Fout=879.70 (A=029, B=137)
-Fout=879.80 (A=030, B=137)
-Fout=879.90 (A=031, B=137)
-Fout=880.00 (A=032, B=137)
-Fout=880.10 (A=033, B=137)
-Fout=880.20 (A=034, B=137)
-Fout=880.30 (A=035, B=137)
-Fout=880.40 (A=036, B=137)
-Fout=880.50 (A=037, B=137)
-Fout=880.60 (A=038, B=137)
-Fout=880.70 (A=039, B=137)
-Fout=880.80 (A=040, B=137)
-Fout=880.90 (A=041, B=137)
-Fout=881.00 (A=042, B=137)
-Fout=881.10 (A=043, B=137)
-Fout=881.20 (A=044, B=137)
-Fout=881.30 (A=045, B=137)
-Fout=881.40 (A=046, B=137)
-Fout=881.50 (A=047, B=137)
-Fout=881.60 (A=048, B=137)
-Fout=881.70 (A=049, B=137)
-Fout=881.80 (A=050, B=137)
-Fout=881.90 (A=051, B=137)
-Fout=882.00 (A=052, B=137)
-Fout=882.10 (A=053, B=137)
-Fout=882.20 (A=054, B=137)
-Fout=882.30 (A=055, B=137)
-Fout=882.40 (A=056, B=137)
-Fout=882.50 (A=057, B=137)
-Fout=882.60 (A=058, B=137)
-Fout=882.70 (A=059, B=137)
-Fout=882.80 (A=060, B=137)
-Fout=882.90 (A=061, B=137)
-Fout=883.00 (A=062, B=137)
-Fout=883.20 (A=000, B=138)
-Fout=883.30 (A=001, B=138)
-Fout=883.40 (A=002, B=138)
-Fout=883.50 (A=003, B=138)
-Fout=883.60 (A=004, B=138)
-Fout=883.70 (A=005, B=138)
-Fout=883.80 (A=006, B=138)
-Fout=883.90 (A=007, B=138)
-Fout=884.00 (A=008, B=138)
-Fout=884.10 (A=009, B=138)
-Fout=884.20 (A=010, B=138)
-Fout=884.30 (A=011, B=138)
-Fout=884.40 (A=012, B=138)
-Fout=884.50 (A=013, B=138)
-Fout=884.60 (A=014, B=138)
-Fout=884.70 (A=015, B=138)
-Fout=884.80 (A=016, B=138)
-Fout=884.90 (A=017, B=138)
-Fout=885.00 (A=018, B=138)
-Fout=885.10 (A=019, B=138)
-Fout=885.20 (A=020, B=138)
-Fout=885.30 (A=021, B=138)
-Fout=885.40 (A=022, B=138)
-Fout=885.50 (A=023, B=138)
-Fout=885.60 (A=024, B=138)
-Fout=885.70 (A=025, B=138)
-Fout=885.80 (A=026, B=138)
-Fout=885.90 (A=027, B=138)
-Fout=886.00 (A=028, B=138)
-Fout=886.10 (A=029, B=138)
-Fout=886.20 (A=030, B=138)
-Fout=886.30 (A=031, B=138)
-Fout=886.40 (A=032, B=138)
-Fout=886.50 (A=033, B=138)
-Fout=886.60 (A=034, B=138)
-Fout=886.70 (A=035, B=138)
-Fout=886.80 (A=036, B=138)
-Fout=886.90 (A=037, B=138)
-Fout=887.00 (A=038, B=138)
-Fout=887.10 (A=039, B=138)
-Fout=887.20 (A=040, B=138)
-Fout=887.30 (A=041, B=138)
-Fout=887.40 (A=042, B=138)
-Fout=887.50 (A=043, B=138)
-Fout=887.60 (A=044, B=138)
-Fout=887.70 (A=045, B=138)
-Fout=887.80 (A=046, B=138)
-Fout=887.90 (A=047, B=138)
-Fout=888.00 (A=048, B=138)
-Fout=888.10 (A=049, B=138)
-Fout=888.20 (A=050, B=138)
-Fout=888.30 (A=051, B=138)
-Fout=888.40 (A=052, B=138)
-Fout=888.50 (A=053, B=138)
-Fout=888.60 (A=054, B=138)
-Fout=888.70 (A=055, B=138)
-Fout=888.80 (A=056, B=138)
-Fout=888.90 (A=057, B=138)
-Fout=889.00 (A=058, B=138)
-Fout=889.10 (A=059, B=138)
-Fout=889.20 (A=060, B=138)
-Fout=889.30 (A=061, B=138)
-Fout=889.40 (A=062, B=138)
-Fout=889.60 (A=000, B=139)
-Fout=889.70 (A=001, B=139)
-Fout=889.80 (A=002, B=139)
-Fout=889.90 (A=003, B=139)
-Fout=890.00 (A=004, B=139)
-Fout=890.10 (A=005, B=139)
-Fout=890.20 (A=006, B=139)
-Fout=890.30 (A=007, B=139)
-Fout=890.40 (A=008, B=139)
-Fout=890.50 (A=009, B=139)
-Fout=890.60 (A=010, B=139)
-Fout=890.70 (A=011, B=139)
-Fout=890.80 (A=012, B=139)
-Fout=890.90 (A=013, B=139)
-Fout=891.00 (A=014, B=139)
-Fout=891.10 (A=015, B=139)
-Fout=891.20 (A=016, B=139)
-Fout=891.30 (A=017, B=139)
-Fout=891.40 (A=018, B=139)
-Fout=891.50 (A=019, B=139)
-Fout=891.60 (A=020, B=139)
-Fout=891.70 (A=021, B=139)
-Fout=891.80 (A=022, B=139)
-Fout=891.90 (A=023, B=139)
-Fout=892.00 (A=024, B=139)
-Fout=892.10 (A=025, B=139)
-Fout=892.20 (A=026, B=139)
-Fout=892.30 (A=027, B=139)
-Fout=892.40 (A=028, B=139)
-Fout=892.50 (A=029, B=139)
-Fout=892.60 (A=030, B=139)
-Fout=892.70 (A=031, B=139)
-Fout=892.80 (A=032, B=139)
-Fout=892.90 (A=033, B=139)
-Fout=893.00 (A=034, B=139)
-Fout=893.10 (A=035, B=139)
-Fout=893.20 (A=036, B=139)
-Fout=893.30 (A=037, B=139)
-Fout=893.40 (A=038, B=139)
-Fout=893.50 (A=039, B=139)
-Fout=893.60 (A=040, B=139)
-Fout=893.70 (A=041, B=139)
-Fout=893.80 (A=042, B=139)
-Fout=893.90 (A=043, B=139)
-Fout=894.00 (A=044, B=139)
-Fout=894.10 (A=045, B=139)
-Fout=894.20 (A=046, B=139)
-Fout=894.30 (A=047, B=139)
-Fout=894.40 (A=048, B=139)
-Fout=894.50 (A=049, B=139)
-Fout=894.60 (A=050, B=139)
-Fout=894.70 (A=051, B=139)
-Fout=894.80 (A=052, B=139)
-Fout=894.90 (A=053, B=139)
-Fout=895.00 (A=054, B=139)
-Fout=895.10 (A=055, B=139)
-Fout=895.20 (A=056, B=139)
-Fout=895.30 (A=057, B=139)
-Fout=895.40 (A=058, B=139)
-Fout=895.50 (A=059, B=139)
-Fout=895.60 (A=060, B=139)
-Fout=895.70 (A=061, B=139)
-Fout=895.80 (A=062, B=139)
-Fout=896.00 (A=000, B=140)
-Fout=896.10 (A=001, B=140)
-Fout=896.20 (A=002, B=140)
-Fout=896.30 (A=003, B=140)
-Fout=896.40 (A=004, B=140)
-Fout=896.50 (A=005, B=140)
-Fout=896.60 (A=006, B=140)
-Fout=896.70 (A=007, B=140)
-Fout=896.80 (A=008, B=140)
-Fout=896.90 (A=009, B=140)
-Fout=897.00 (A=010, B=140)
-Fout=897.10 (A=011, B=140)
-Fout=897.20 (A=012, B=140)
-Fout=897.30 (A=013, B=140)
-Fout=897.40 (A=014, B=140)
-Fout=897.50 (A=015, B=140)
-Fout=897.60 (A=016, B=140)
-Fout=897.70 (A=017, B=140)
-Fout=897.80 (A=018, B=140)
-Fout=897.90 (A=019, B=140)
-Fout=898.00 (A=020, B=140)
-Fout=898.10 (A=021, B=140)
-Fout=898.20 (A=022, B=140)
-Fout=898.30 (A=023, B=140)
-Fout=898.40 (A=024, B=140)
-Fout=898.50 (A=025, B=140)
-Fout=898.60 (A=026, B=140)
-Fout=898.70 (A=027, B=140)
-Fout=898.80 (A=028, B=140)
-Fout=898.90 (A=029, B=140)
-Fout=899.00 (A=030, B=140)
-Fout=899.10 (A=031, B=140)
-Fout=899.20 (A=032, B=140)
-Fout=899.30 (A=033, B=140)
-Fout=899.40 (A=034, B=140)
-Fout=899.50 (A=035, B=140)
-Fout=899.60 (A=036, B=140)
-Fout=899.70 (A=037, B=140)
-Fout=899.80 (A=038, B=140)
-Fout=899.90 (A=039, B=140)
-Fout=900.00 (A=040, B=140)
-Fout=900.10 (A=041, B=140)
-Fout=900.20 (A=042, B=140)
-Fout=900.30 (A=043, B=140)
-Fout=900.40 (A=044, B=140)
-Fout=900.50 (A=045, B=140)
-Fout=900.60 (A=046, B=140)
-Fout=900.70 (A=047, B=140)
-Fout=900.80 (A=048, B=140)
-Fout=900.90 (A=049, B=140)
-Fout=901.00 (A=050, B=140)
-Fout=901.10 (A=051, B=140)
-Fout=901.20 (A=052, B=140)
-Fout=901.30 (A=053, B=140)
-Fout=901.40 (A=054, B=140)
-Fout=901.50 (A=055, B=140)
-Fout=901.60 (A=056, B=140)
-Fout=901.70 (A=057, B=140)
-Fout=901.80 (A=058, B=140)
-Fout=901.90 (A=059, B=140)
-Fout=902.00 (A=060, B=140)
-Fout=902.10 (A=061, B=140)
-Fout=902.20 (A=062, B=140)
-Fout=902.40 (A=000, B=141)
-Fout=902.50 (A=001, B=141)
-Fout=902.60 (A=002, B=141)
-Fout=902.70 (A=003, B=141)
-Fout=902.80 (A=004, B=141)
-Fout=902.90 (A=005, B=141)
-Fout=903.00 (A=006, B=141)
-Fout=903.10 (A=007, B=141)
-Fout=903.20 (A=008, B=141)
-Fout=903.30 (A=009, B=141)
-Fout=903.40 (A=010, B=141)
-Fout=903.50 (A=011, B=141)
-Fout=903.60 (A=012, B=141)
-Fout=903.70 (A=013, B=141)
-Fout=903.80 (A=014, B=141)
-Fout=903.90 (A=015, B=141)
-Fout=904.00 (A=016, B=141)
-Fout=904.10 (A=017, B=141)
-Fout=904.20 (A=018, B=141)
-Fout=904.30 (A=019, B=141)
-Fout=904.40 (A=020, B=141)
-Fout=904.50 (A=021, B=141)
-Fout=904.60 (A=022, B=141)
-Fout=904.70 (A=023, B=141)
-Fout=904.80 (A=024, B=141)
-Fout=904.90 (A=025, B=141)
-Fout=905.00 (A=026, B=141)
-Fout=905.10 (A=027, B=141)
-Fout=905.20 (A=028, B=141)
-Fout=905.30 (A=029, B=141)
-Fout=905.40 (A=030, B=141)
-Fout=905.50 (A=031, B=141)
-Fout=905.60 (A=032, B=141)
-Fout=905.70 (A=033, B=141)
-Fout=905.80 (A=034, B=141)
-Fout=905.90 (A=035, B=141)
-Fout=906.00 (A=036, B=141)
-Fout=906.10 (A=037, B=141)
-Fout=906.20 (A=038, B=141)
-Fout=906.30 (A=039, B=141)
-Fout=906.40 (A=040, B=141)
-Fout=906.50 (A=041, B=141)
-Fout=906.60 (A=042, B=141)
-Fout=906.70 (A=043, B=141)
-Fout=906.80 (A=044, B=141)
-Fout=906.90 (A=045, B=141)
-Fout=907.00 (A=046, B=141)
-Fout=907.10 (A=047, B=141)
-Fout=907.20 (A=048, B=141)
-Fout=907.30 (A=049, B=141)
-Fout=907.40 (A=050, B=141)
-Fout=907.50 (A=051, B=141)
-Fout=907.60 (A=052, B=141)
-Fout=907.70 (A=053, B=141)
-Fout=907.80 (A=054, B=141)
-Fout=907.90 (A=055, B=141)
-Fout=908.00 (A=056, B=141)
-Fout=908.10 (A=057, B=141)
-Fout=908.20 (A=058, B=141)
-Fout=908.30 (A=059, B=141)
-Fout=908.40 (A=060, B=141)
-Fout=908.50 (A=061, B=141)
-Fout=908.60 (A=062, B=141)
-Fout=908.80 (A=000, B=142)
-Fout=908.90 (A=001, B=142)
-Fout=909.00 (A=002, B=142)
-Fout=909.10 (A=003, B=142)
-Fout=909.20 (A=004, B=142)
-Fout=909.30 (A=005, B=142)
-Fout=909.40 (A=006, B=142)
-Fout=909.50 (A=007, B=142)
-Fout=909.60 (A=008, B=142)
-Fout=909.70 (A=009, B=142)
-Fout=909.80 (A=010, B=142)
-Fout=909.90 (A=011, B=142)
-Fout=910.00 (A=012, B=142)
-Fout=910.10 (A=013, B=142)
-Fout=910.20 (A=014, B=142)
-Fout=910.30 (A=015, B=142)
-Fout=910.40 (A=016, B=142)
-Fout=910.50 (A=017, B=142)
-Fout=910.60 (A=018, B=142)
-Fout=910.70 (A=019, B=142)
-Fout=910.80 (A=020, B=142)
-Fout=910.90 (A=021, B=142)
-Fout=911.00 (A=022, B=142)
-Fout=911.10 (A=023, B=142)
-Fout=911.20 (A=024, B=142)
-Fout=911.30 (A=025, B=142)
-Fout=911.40 (A=026, B=142)
-Fout=911.50 (A=027, B=142)
-Fout=911.60 (A=028, B=142)
-Fout=911.70 (A=029, B=142)
-Fout=911.80 (A=030, B=142)
-Fout=911.90 (A=031, B=142)
-Fout=912.00 (A=032, B=142)
-Fout=912.10 (A=033, B=142)
-Fout=912.20 (A=034, B=142)
-Fout=912.30 (A=035, B=142)
-Fout=912.40 (A=036, B=142)
-Fout=912.50 (A=037, B=142)
-Fout=912.60 (A=038, B=142)
-Fout=912.70 (A=039, B=142)
-Fout=912.80 (A=040, B=142)
-Fout=912.90 (A=041, B=142)
-Fout=913.00 (A=042, B=142)
-Fout=913.10 (A=043, B=142)
-Fout=913.20 (A=044, B=142)
-Fout=913.30 (A=045, B=142)
-Fout=913.40 (A=046, B=142)
-Fout=913.50 (A=047, B=142)
-Fout=913.60 (A=048, B=142)
-Fout=913.70 (A=049, B=142)
-Fout=913.80 (A=050, B=142)
-Fout=913.90 (A=051, B=142)
-Fout=914.00 (A=052, B=142)
-Fout=914.10 (A=053, B=142)
-Fout=914.20 (A=054, B=142)
-Fout=914.30 (A=055, B=142)
-Fout=914.40 (A=056, B=142)
-Fout=914.50 (A=057, B=142)
-Fout=914.60 (A=058, B=142)
-Fout=914.70 (A=059, B=142)
-Fout=914.80 (A=060, B=142)
-Fout=914.90 (A=061, B=142)
-Fout=915.00 (A=062, B=142)
-Fout=915.20 (A=000, B=143)
-Fout=915.30 (A=001, B=143)
-Fout=915.40 (A=002, B=143)
-Fout=915.50 (A=003, B=143)
-Fout=915.60 (A=004, B=143)
-Fout=915.70 (A=005, B=143)
-Fout=915.80 (A=006, B=143)
-Fout=915.90 (A=007, B=143)
-Fout=916.00 (A=008, B=143)
-Fout=916.10 (A=009, B=143)
-Fout=916.20 (A=010, B=143)
-Fout=916.30 (A=011, B=143)
-Fout=916.40 (A=012, B=143)
-Fout=916.50 (A=013, B=143)
-Fout=916.60 (A=014, B=143)
-Fout=916.70 (A=015, B=143)
-Fout=916.80 (A=016, B=143)
-Fout=916.90 (A=017, B=143)
-Fout=917.00 (A=018, B=143)
-Fout=917.10 (A=019, B=143)
-Fout=917.20 (A=020, B=143)
-Fout=917.30 (A=021, B=143)
-Fout=917.40 (A=022, B=143)
-Fout=917.50 (A=023, B=143)
-Fout=917.60 (A=024, B=143)
-Fout=917.70 (A=025, B=143)
-Fout=917.80 (A=026, B=143)
-Fout=917.90 (A=027, B=143)
-Fout=918.00 (A=028, B=143)
-Fout=918.10 (A=029, B=143)
-Fout=918.20 (A=030, B=143)
-Fout=918.30 (A=031, B=143)
-Fout=918.40 (A=032, B=143)
-Fout=918.50 (A=033, B=143)
-Fout=918.60 (A=034, B=143)
-Fout=918.70 (A=035, B=143)
-Fout=918.80 (A=036, B=143)
-Fout=918.90 (A=037, B=143)
-Fout=919.00 (A=038, B=143)
-Fout=919.10 (A=039, B=143)
-Fout=919.20 (A=040, B=143)
-Fout=919.30 (A=041, B=143)
-Fout=919.40 (A=042, B=143)
-Fout=919.50 (A=043, B=143)
-Fout=919.60 (A=044, B=143)
-Fout=919.70 (A=045, B=143)
-Fout=919.80 (A=046, B=143)
-Fout=919.90 (A=047, B=143)
-Fout=920.00 (A=048, B=143)
-Fout=920.10 (A=049, B=143)
-Fout=920.20 (A=050, B=143)
-Fout=920.30 (A=051, B=143)
-Fout=920.40 (A=052, B=143)
-Fout=920.50 (A=053, B=143)
-Fout=920.60 (A=054, B=143)
-Fout=920.70 (A=055, B=143)
-Fout=920.80 (A=056, B=143)
-Fout=920.90 (A=057, B=143)
-Fout=921.00 (A=058, B=143)
-Fout=921.10 (A=059, B=143)
-Fout=921.20 (A=060, B=143)
-Fout=921.30 (A=061, B=143)
-Fout=921.40 (A=062, B=143)
-Fout=921.60 (A=000, B=144)
-Fout=921.70 (A=001, B=144)
-Fout=921.80 (A=002, B=144)
-Fout=921.90 (A=003, B=144)
-Fout=922.00 (A=004, B=144)
-Fout=922.10 (A=005, B=144)
-Fout=922.20 (A=006, B=144)
-Fout=922.30 (A=007, B=144)
-Fout=922.40 (A=008, B=144)
-Fout=922.50 (A=009, B=144)
-Fout=922.60 (A=010, B=144)
-Fout=922.70 (A=011, B=144)
-Fout=922.80 (A=012, B=144)
-Fout=922.90 (A=013, B=144)
-Fout=923.00 (A=014, B=144)
-Fout=923.10 (A=015, B=144)
-Fout=923.20 (A=016, B=144)
-Fout=923.30 (A=017, B=144)
-Fout=923.40 (A=018, B=144)
-Fout=923.50 (A=019, B=144)
-Fout=923.60 (A=020, B=144)
-Fout=923.70 (A=021, B=144)
-Fout=923.80 (A=022, B=144)
-Fout=923.90 (A=023, B=144)
-Fout=924.00 (A=024, B=144)
-Fout=924.10 (A=025, B=144)
-Fout=924.20 (A=026, B=144)
-Fout=924.30 (A=027, B=144)
-Fout=924.40 (A=028, B=144)
-Fout=924.50 (A=029, B=144)
-Fout=924.60 (A=030, B=144)
-Fout=924.70 (A=031, B=144)
-Fout=924.80 (A=032, B=144)
-Fout=924.90 (A=033, B=144)
-Fout=925.00 (A=034, B=144)
-Fout=925.10 (A=035, B=144)
-Fout=925.20 (A=036, B=144)
-Fout=925.30 (A=037, B=144)
-Fout=925.40 (A=038, B=144)
-Fout=925.50 (A=039, B=144)
-Fout=925.60 (A=040, B=144)
-Fout=925.70 (A=041, B=144)
-Fout=925.80 (A=042, B=144)
-Fout=925.90 (A=043, B=144)
-Fout=926.00 (A=044, B=144)
-Fout=926.10 (A=045, B=144)
-Fout=926.20 (A=046, B=144)
-Fout=926.30 (A=047, B=144)
-Fout=926.40 (A=048, B=144)
-Fout=926.50 (A=049, B=144)
-Fout=926.60 (A=050, B=144)
-Fout=926.70 (A=051, B=144)
-Fout=926.80 (A=052, B=144)
-Fout=926.90 (A=053, B=144)
-Fout=927.00 (A=054, B=144)
-Fout=927.10 (A=055, B=144)
-Fout=927.20 (A=056, B=144)
-Fout=927.30 (A=057, B=144)
-Fout=927.40 (A=058, B=144)
-Fout=927.50 (A=059, B=144)
-Fout=927.60 (A=060, B=144)
-Fout=927.70 (A=061, B=144)
-Fout=927.80 (A=062, B=144)
-Fout=928.00 (A=000, B=145)
-Fout=928.10 (A=001, B=145)
-Fout=928.20 (A=002, B=145)
-Fout=928.30 (A=003, B=145)
-Fout=928.40 (A=004, B=145)
-Fout=928.50 (A=005, B=145)
-Fout=928.60 (A=006, B=145)
-Fout=928.70 (A=007, B=145)
-Fout=928.80 (A=008, B=145)
-Fout=928.90 (A=009, B=145)
-Fout=929.00 (A=010, B=145)
-Fout=929.10 (A=011, B=145)
-Fout=929.20 (A=012, B=145)
-Fout=929.30 (A=013, B=145)
-Fout=929.40 (A=014, B=145)
-Fout=929.50 (A=015, B=145)
-Fout=929.60 (A=016, B=145)
-Fout=929.70 (A=017, B=145)
-Fout=929.80 (A=018, B=145)
-Fout=929.90 (A=019, B=145)
-Fout=930.00 (A=020, B=145)
-Fout=930.10 (A=021, B=145)
-Fout=930.20 (A=022, B=145)
-Fout=930.30 (A=023, B=145)
-Fout=930.40 (A=024, B=145)
-Fout=930.50 (A=025, B=145)
-Fout=930.60 (A=026, B=145)
-Fout=930.70 (A=027, B=145)
-Fout=930.80 (A=028, B=145)
-Fout=930.90 (A=029, B=145)
-Fout=931.00 (A=030, B=145)
-Fout=931.10 (A=031, B=145)
-Fout=931.20 (A=032, B=145)
-Fout=931.30 (A=033, B=145)
-Fout=931.40 (A=034, B=145)
-Fout=931.50 (A=035, B=145)
-Fout=931.60 (A=036, B=145)
-Fout=931.70 (A=037, B=145)
-Fout=931.80 (A=038, B=145)
-Fout=931.90 (A=039, B=145)
-Fout=932.00 (A=040, B=145)
-Fout=932.10 (A=041, B=145)
-Fout=932.20 (A=042, B=145)
-Fout=932.30 (A=043, B=145)
-Fout=932.40 (A=044, B=145)
-Fout=932.50 (A=045, B=145)
-Fout=932.60 (A=046, B=145)
-Fout=932.70 (A=047, B=145)
-Fout=932.80 (A=048, B=145)
-Fout=932.90 (A=049, B=145)
-Fout=933.00 (A=050, B=145)
-Fout=933.10 (A=051, B=145)
-Fout=933.20 (A=052, B=145)
-Fout=933.30 (A=053, B=145)
-Fout=933.40 (A=054, B=145)
-Fout=933.50 (A=055, B=145)
-Fout=933.60 (A=056, B=145)
-Fout=933.70 (A=057, B=145)
-Fout=933.80 (A=058, B=145)
-Fout=933.90 (A=059, B=145)
-Fout=934.00 (A=060, B=145)
-Fout=934.10 (A=061, B=145)
-Fout=934.20 (A=062, B=145)
-Fout=934.40 (A=000, B=146)
-Fout=934.50 (A=001, B=146)
-Fout=934.60 (A=002, B=146)
-Fout=934.70 (A=003, B=146)
-Fout=934.80 (A=004, B=146)
-Fout=934.90 (A=005, B=146)
-Fout=935.00 (A=006, B=146)
-Fout=935.10 (A=007, B=146)
-Fout=935.20 (A=008, B=146)
-Fout=935.30 (A=009, B=146)
-Fout=935.40 (A=010, B=146)
-Fout=935.50 (A=011, B=146)
-Fout=935.60 (A=012, B=146)
-Fout=935.70 (A=013, B=146)
-Fout=935.80 (A=014, B=146)
-Fout=935.90 (A=015, B=146)
-Fout=936.00 (A=016, B=146)
-Fout=936.10 (A=017, B=146)
-Fout=936.20 (A=018, B=146)
-Fout=936.30 (A=019, B=146)
-Fout=936.40 (A=020, B=146)
-Fout=936.50 (A=021, B=146)
-Fout=936.60 (A=022, B=146)
-Fout=936.70 (A=023, B=146)
-Fout=936.80 (A=024, B=146)
-Fout=936.90 (A=025, B=146)
-Fout=937.00 (A=026, B=146)
-Fout=937.10 (A=027, B=146)
-Fout=937.20 (A=028, B=146)
-Fout=937.30 (A=029, B=146)
-Fout=937.40 (A=030, B=146)
-Fout=937.50 (A=031, B=146)
-Fout=937.60 (A=032, B=146)
-Fout=937.70 (A=033, B=146)
-Fout=937.80 (A=034, B=146)
-Fout=937.90 (A=035, B=146)
-Fout=938.00 (A=036, B=146)
-Fout=938.10 (A=037, B=146)
-Fout=938.20 (A=038, B=146)
-Fout=938.30 (A=039, B=146)
-Fout=938.40 (A=040, B=146)
-Fout=938.50 (A=041, B=146)
-Fout=938.60 (A=042, B=146)
-Fout=938.70 (A=043, B=146)
-Fout=938.80 (A=044, B=146)
-Fout=938.90 (A=045, B=146)
-Fout=939.00 (A=046, B=146)
-Fout=939.10 (A=047, B=146)
-Fout=939.20 (A=048, B=146)
-Fout=939.30 (A=049, B=146)
-Fout=939.40 (A=050, B=146)
-Fout=939.50 (A=051, B=146)
-Fout=939.60 (A=052, B=146)
-Fout=939.70 (A=053, B=146)
-Fout=939.80 (A=054, B=146)
-Fout=939.90 (A=055, B=146)
-Fout=940.00 (A=056, B=146)
-Fout=940.10 (A=057, B=146)
-Fout=940.20 (A=058, B=146)
-Fout=940.30 (A=059, B=146)
-Fout=940.40 (A=060, B=146)
-Fout=940.50 (A=061, B=146)
-Fout=940.60 (A=062, B=146)
-Fout=940.80 (A=000, B=147)
-Fout=940.90 (A=001, B=147)
-Fout=941.00 (A=002, B=147)
-Fout=941.10 (A=003, B=147)
-Fout=941.20 (A=004, B=147)
-Fout=941.30 (A=005, B=147)
-Fout=941.40 (A=006, B=147)
-Fout=941.50 (A=007, B=147)
-Fout=941.60 (A=008, B=147)
-Fout=941.70 (A=009, B=147)
-Fout=941.80 (A=010, B=147)
-Fout=941.90 (A=011, B=147)
-Fout=942.00 (A=012, B=147)
-Fout=942.10 (A=013, B=147)
-Fout=942.20 (A=014, B=147)
-Fout=942.30 (A=015, B=147)
-Fout=942.40 (A=016, B=147)
-Fout=942.50 (A=017, B=147)
-Fout=942.60 (A=018, B=147)
-Fout=942.70 (A=019, B=147)
-Fout=942.80 (A=020, B=147)
-Fout=942.90 (A=021, B=147)
-Fout=943.00 (A=022, B=147)
-Fout=943.10 (A=023, B=147)
-Fout=943.20 (A=024, B=147)
-Fout=943.30 (A=025, B=147)
-Fout=943.40 (A=026, B=147)
-Fout=943.50 (A=027, B=147)
-Fout=943.60 (A=028, B=147)
-Fout=943.70 (A=029, B=147)
-Fout=943.80 (A=030, B=147)
-Fout=943.90 (A=031, B=147)
-Fout=944.00 (A=032, B=147)
-Fout=944.10 (A=033, B=147)
-Fout=944.20 (A=034, B=147)
-Fout=944.30 (A=035, B=147)
-Fout=944.40 (A=036, B=147)
-Fout=944.50 (A=037, B=147)
-Fout=944.60 (A=038, B=147)
-Fout=944.70 (A=039, B=147)
-Fout=944.80 (A=040, B=147)
-Fout=944.90 (A=041, B=147)
-Fout=945.00 (A=042, B=147)
-Fout=945.10 (A=043, B=147)
-Fout=945.20 (A=044, B=147)
-Fout=945.30 (A=045, B=147)
-Fout=945.40 (A=046, B=147)
-Fout=945.50 (A=047, B=147)
-Fout=945.60 (A=048, B=147)
-Fout=945.70 (A=049, B=147)
-Fout=945.80 (A=050, B=147)
-Fout=945.90 (A=051, B=147)
-Fout=946.00 (A=052, B=147)
-Fout=946.10 (A=053, B=147)
-Fout=946.20 (A=054, B=147)
-Fout=946.30 (A=055, B=147)
-Fout=946.40 (A=056, B=147)
-Fout=946.50 (A=057, B=147)
-Fout=946.60 (A=058, B=147)
-Fout=946.70 (A=059, B=147)
-Fout=946.80 (A=060, B=147)
-Fout=946.90 (A=061, B=147)
-Fout=947.00 (A=062, B=147)
-Fout=947.20 (A=000, B=148)
-Fout=947.30 (A=001, B=148)
-Fout=947.40 (A=002, B=148)
-Fout=947.50 (A=003, B=148)
-Fout=947.60 (A=004, B=148)
-Fout=947.70 (A=005, B=148)
-Fout=947.80 (A=006, B=148)
-Fout=947.90 (A=007, B=148)
-Fout=948.00 (A=008, B=148)
-Fout=948.10 (A=009, B=148)
-Fout=948.20 (A=010, B=148)
-Fout=948.30 (A=011, B=148)
-Fout=948.40 (A=012, B=148)
-Fout=948.50 (A=013, B=148)
-Fout=948.60 (A=014, B=148)
-Fout=948.70 (A=015, B=148)
-Fout=948.80 (A=016, B=148)
-Fout=948.90 (A=017, B=148)
-Fout=949.00 (A=018, B=148)
-Fout=949.10 (A=019, B=148)
-Fout=949.20 (A=020, B=148)
-Fout=949.30 (A=021, B=148)
-Fout=949.40 (A=022, B=148)
-Fout=949.50 (A=023, B=148)
-Fout=949.60 (A=024, B=148)
-Fout=949.70 (A=025, B=148)
-Fout=949.80 (A=026, B=148)
-Fout=949.90 (A=027, B=148)
-Fout=950.00 (A=028, B=148)
-Fout=950.10 (A=029, B=148)
-Fout=950.20 (A=030, B=148)
-Fout=950.30 (A=031, B=148)
-Fout=950.40 (A=032, B=148)
-Fout=950.50 (A=033, B=148)
-Fout=950.60 (A=034, B=148)
-Fout=950.70 (A=035, B=148)
-Fout=950.80 (A=036, B=148)
-Fout=950.90 (A=037, B=148)
-Fout=951.00 (A=038, B=148)
-Fout=951.10 (A=039, B=148)
-Fout=951.20 (A=040, B=148)
-Fout=951.30 (A=041, B=148)
-Fout=951.40 (A=042, B=148)
-Fout=951.50 (A=043, B=148)
-Fout=951.60 (A=044, B=148)
-Fout=951.70 (A=045, B=148)
-Fout=951.80 (A=046, B=148)
-Fout=951.90 (A=047, B=148)
-Fout=952.00 (A=048, B=148)
-Fout=952.10 (A=049, B=148)
-Fout=952.20 (A=050, B=148)
-Fout=952.30 (A=051, B=148)
-Fout=952.40 (A=052, B=148)
-Fout=952.50 (A=053, B=148)
-Fout=952.60 (A=054, B=148)
-Fout=952.70 (A=055, B=148)
-Fout=952.80 (A=056, B=148)
-Fout=952.90 (A=057, B=148)
-Fout=953.00 (A=058, B=148)
-Fout=953.10 (A=059, B=148)
-Fout=953.20 (A=060, B=148)
-Fout=953.30 (A=061, B=148)
-Fout=953.40 (A=062, B=148)
-Fout=953.60 (A=000, B=149)
-Fout=953.70 (A=001, B=149)
-Fout=953.80 (A=002, B=149)
-Fout=953.90 (A=003, B=149)
-Fout=954.00 (A=004, B=149)
-Fout=954.10 (A=005, B=149)
-Fout=954.20 (A=006, B=149)
-Fout=954.30 (A=007, B=149)
-Fout=954.40 (A=008, B=149)
-Fout=954.50 (A=009, B=149)
-Fout=954.60 (A=010, B=149)
-Fout=954.70 (A=011, B=149)
-Fout=954.80 (A=012, B=149)
-Fout=954.90 (A=013, B=149)
-Fout=955.00 (A=014, B=149)
-Fout=955.10 (A=015, B=149)
-Fout=955.20 (A=016, B=149)
-Fout=955.30 (A=017, B=149)
-Fout=955.40 (A=018, B=149)
-Fout=955.50 (A=019, B=149)
-Fout=955.60 (A=020, B=149)
-Fout=955.70 (A=021, B=149)
-Fout=955.80 (A=022, B=149)
-Fout=955.90 (A=023, B=149)
-Fout=956.00 (A=024, B=149)
-Fout=956.10 (A=025, B=149)
-Fout=956.20 (A=026, B=149)
-Fout=956.30 (A=027, B=149)
-Fout=956.40 (A=028, B=149)
-Fout=956.50 (A=029, B=149)
-Fout=956.60 (A=030, B=149)
-Fout=956.70 (A=031, B=149)
-Fout=956.80 (A=032, B=149)
-Fout=956.90 (A=033, B=149)
-Fout=957.00 (A=034, B=149)
-Fout=957.10 (A=035, B=149)
-Fout=957.20 (A=036, B=149)
-Fout=957.30 (A=037, B=149)
-Fout=957.40 (A=038, B=149)
-Fout=957.50 (A=039, B=149)
-Fout=957.60 (A=040, B=149)
-Fout=957.70 (A=041, B=149)
-Fout=957.80 (A=042, B=149)
-Fout=957.90 (A=043, B=149)
-Fout=958.00 (A=044, B=149)
-Fout=958.10 (A=045, B=149)
-Fout=958.20 (A=046, B=149)
-Fout=958.30 (A=047, B=149)
-Fout=958.40 (A=048, B=149)
-Fout=958.50 (A=049, B=149)
-Fout=958.60 (A=050, B=149)
-Fout=958.70 (A=051, B=149)
-Fout=958.80 (A=052, B=149)
-Fout=958.90 (A=053, B=149)
-Fout=959.00 (A=054, B=149)
-Fout=959.10 (A=055, B=149)
-Fout=959.20 (A=056, B=149)
-Fout=959.30 (A=057, B=149)
-Fout=959.40 (A=058, B=149)
-Fout=959.50 (A=059, B=149)
-Fout=959.60 (A=060, B=149)
-Fout=959.70 (A=061, B=149)
-Fout=959.80 (A=062, B=149)
-Fout=960.00 (A=000, B=150)
-Fout=960.10 (A=001, B=150)
-Fout=960.20 (A=002, B=150)
-Fout=960.30 (A=003, B=150)
-Fout=960.40 (A=004, B=150)
-Fout=960.50 (A=005, B=150)
-Fout=960.60 (A=006, B=150)
-Fout=960.70 (A=007, B=150)
-Fout=960.80 (A=008, B=150)
-Fout=960.90 (A=009, B=150)
-Fout=961.00 (A=010, B=150)
-Fout=961.10 (A=011, B=150)
-Fout=961.20 (A=012, B=150)
-Fout=961.30 (A=013, B=150)
-Fout=961.40 (A=014, B=150)
-Fout=961.50 (A=015, B=150)
-Fout=961.60 (A=016, B=150)
-Fout=961.70 (A=017, B=150)
-Fout=961.80 (A=018, B=150)
-Fout=961.90 (A=019, B=150)
-Fout=962.00 (A=020, B=150)
-Fout=962.10 (A=021, B=150)
-Fout=962.20 (A=022, B=150)
-Fout=962.30 (A=023, B=150)
-Fout=962.40 (A=024, B=150)
-Fout=962.50 (A=025, B=150)
-Fout=962.60 (A=026, B=150)
-Fout=962.70 (A=027, B=150)
-Fout=962.80 (A=028, B=150)
-Fout=962.90 (A=029, B=150)
-Fout=963.00 (A=030, B=150)
-Fout=963.10 (A=031, B=150)
-Fout=963.20 (A=032, B=150)
-Fout=963.30 (A=033, B=150)
-Fout=963.40 (A=034, B=150)
-Fout=963.50 (A=035, B=150)
-Fout=963.60 (A=036, B=150)
-Fout=963.70 (A=037, B=150)
-Fout=963.80 (A=038, B=150)
-Fout=963.90 (A=039, B=150)
-Fout=964.00 (A=040, B=150)
-Fout=964.10 (A=041, B=150)
-Fout=964.20 (A=042, B=150)
-Fout=964.30 (A=043, B=150)
-Fout=964.40 (A=044, B=150)
-Fout=964.50 (A=045, B=150)
-Fout=964.60 (A=046, B=150)
-Fout=964.70 (A=047, B=150)
-Fout=964.80 (A=048, B=150)
-Fout=964.90 (A=049, B=150)
-Fout=965.00 (A=050, B=150)
-Fout=965.10 (A=051, B=150)
-Fout=965.20 (A=052, B=150)
-Fout=965.30 (A=053, B=150)
-Fout=965.40 (A=054, B=150)
-Fout=965.50 (A=055, B=150)
-Fout=965.60 (A=056, B=150)
-Fout=965.70 (A=057, B=150)
-Fout=965.80 (A=058, B=150)
-Fout=965.90 (A=059, B=150)
-Fout=966.00 (A=060, B=150)
-Fout=966.10 (A=061, B=150)
-Fout=966.20 (A=062, B=150)
-======================================================================
-PLL Rx High Band:
-Fout=1804.80 (A=000, B=141)
-Fout=1805.00 (A=001, B=141)
-Fout=1805.20 (A=002, B=141)
-Fout=1805.40 (A=003, B=141)
-Fout=1805.60 (A=004, B=141)
-Fout=1805.80 (A=005, B=141)
-Fout=1806.00 (A=006, B=141)
-Fout=1806.20 (A=007, B=141)
-Fout=1806.40 (A=008, B=141)
-Fout=1806.60 (A=009, B=141)
-Fout=1806.80 (A=010, B=141)
-Fout=1807.00 (A=011, B=141)
-Fout=1807.20 (A=012, B=141)
-Fout=1807.40 (A=013, B=141)
-Fout=1807.60 (A=014, B=141)
-Fout=1807.80 (A=015, B=141)
-Fout=1808.00 (A=016, B=141)
-Fout=1808.20 (A=017, B=141)
-Fout=1808.40 (A=018, B=141)
-Fout=1808.60 (A=019, B=141)
-Fout=1808.80 (A=020, B=141)
-Fout=1809.00 (A=021, B=141)
-Fout=1809.20 (A=022, B=141)
-Fout=1809.40 (A=023, B=141)
-Fout=1809.60 (A=024, B=141)
-Fout=1809.80 (A=025, B=141)
-Fout=1810.00 (A=026, B=141)
-Fout=1810.20 (A=027, B=141)
-Fout=1810.40 (A=028, B=141)
-Fout=1810.60 (A=029, B=141)
-Fout=1810.80 (A=030, B=141)
-Fout=1811.00 (A=031, B=141)
-Fout=1811.20 (A=032, B=141)
-Fout=1811.40 (A=033, B=141)
-Fout=1811.60 (A=034, B=141)
-Fout=1811.80 (A=035, B=141)
-Fout=1812.00 (A=036, B=141)
-Fout=1812.20 (A=037, B=141)
-Fout=1812.40 (A=038, B=141)
-Fout=1812.60 (A=039, B=141)
-Fout=1812.80 (A=040, B=141)
-Fout=1813.00 (A=041, B=141)
-Fout=1813.20 (A=042, B=141)
-Fout=1813.40 (A=043, B=141)
-Fout=1813.60 (A=044, B=141)
-Fout=1813.80 (A=045, B=141)
-Fout=1814.00 (A=046, B=141)
-Fout=1814.20 (A=047, B=141)
-Fout=1814.40 (A=048, B=141)
-Fout=1814.60 (A=049, B=141)
-Fout=1814.80 (A=050, B=141)
-Fout=1815.00 (A=051, B=141)
-Fout=1815.20 (A=052, B=141)
-Fout=1815.40 (A=053, B=141)
-Fout=1815.60 (A=054, B=141)
-Fout=1815.80 (A=055, B=141)
-Fout=1816.00 (A=056, B=141)
-Fout=1816.20 (A=057, B=141)
-Fout=1816.40 (A=058, B=141)
-Fout=1816.60 (A=059, B=141)
-Fout=1816.80 (A=060, B=141)
-Fout=1817.00 (A=061, B=141)
-Fout=1817.20 (A=062, B=141)
-Fout=1817.60 (A=000, B=142)
-Fout=1817.80 (A=001, B=142)
-Fout=1818.00 (A=002, B=142)
-Fout=1818.20 (A=003, B=142)
-Fout=1818.40 (A=004, B=142)
-Fout=1818.60 (A=005, B=142)
-Fout=1818.80 (A=006, B=142)
-Fout=1819.00 (A=007, B=142)
-Fout=1819.20 (A=008, B=142)
-Fout=1819.40 (A=009, B=142)
-Fout=1819.60 (A=010, B=142)
-Fout=1819.80 (A=011, B=142)
-Fout=1820.00 (A=012, B=142)
-Fout=1820.20 (A=013, B=142)
-Fout=1820.40 (A=014, B=142)
-Fout=1820.60 (A=015, B=142)
-Fout=1820.80 (A=016, B=142)
-Fout=1821.00 (A=017, B=142)
-Fout=1821.20 (A=018, B=142)
-Fout=1821.40 (A=019, B=142)
-Fout=1821.60 (A=020, B=142)
-Fout=1821.80 (A=021, B=142)
-Fout=1822.00 (A=022, B=142)
-Fout=1822.20 (A=023, B=142)
-Fout=1822.40 (A=024, B=142)
-Fout=1822.60 (A=025, B=142)
-Fout=1822.80 (A=026, B=142)
-Fout=1823.00 (A=027, B=142)
-Fout=1823.20 (A=028, B=142)
-Fout=1823.40 (A=029, B=142)
-Fout=1823.60 (A=030, B=142)
-Fout=1823.80 (A=031, B=142)
-Fout=1824.00 (A=032, B=142)
-Fout=1824.20 (A=033, B=142)
-Fout=1824.40 (A=034, B=142)
-Fout=1824.60 (A=035, B=142)
-Fout=1824.80 (A=036, B=142)
-Fout=1825.00 (A=037, B=142)
-Fout=1825.20 (A=038, B=142)
-Fout=1825.40 (A=039, B=142)
-Fout=1825.60 (A=040, B=142)
-Fout=1825.80 (A=041, B=142)
-Fout=1826.00 (A=042, B=142)
-Fout=1826.20 (A=043, B=142)
-Fout=1826.40 (A=044, B=142)
-Fout=1826.60 (A=045, B=142)
-Fout=1826.80 (A=046, B=142)
-Fout=1827.00 (A=047, B=142)
-Fout=1827.20 (A=048, B=142)
-Fout=1827.40 (A=049, B=142)
-Fout=1827.60 (A=050, B=142)
-Fout=1827.80 (A=051, B=142)
-Fout=1828.00 (A=052, B=142)
-Fout=1828.20 (A=053, B=142)
-Fout=1828.40 (A=054, B=142)
-Fout=1828.60 (A=055, B=142)
-Fout=1828.80 (A=056, B=142)
-Fout=1829.00 (A=057, B=142)
-Fout=1829.20 (A=058, B=142)
-Fout=1829.40 (A=059, B=142)
-Fout=1829.60 (A=060, B=142)
-Fout=1829.80 (A=061, B=142)
-Fout=1830.00 (A=062, B=142)
-Fout=1830.40 (A=000, B=143)
-Fout=1830.60 (A=001, B=143)
-Fout=1830.80 (A=002, B=143)
-Fout=1831.00 (A=003, B=143)
-Fout=1831.20 (A=004, B=143)
-Fout=1831.40 (A=005, B=143)
-Fout=1831.60 (A=006, B=143)
-Fout=1831.80 (A=007, B=143)
-Fout=1832.00 (A=008, B=143)
-Fout=1832.20 (A=009, B=143)
-Fout=1832.40 (A=010, B=143)
-Fout=1832.60 (A=011, B=143)
-Fout=1832.80 (A=012, B=143)
-Fout=1833.00 (A=013, B=143)
-Fout=1833.20 (A=014, B=143)
-Fout=1833.40 (A=015, B=143)
-Fout=1833.60 (A=016, B=143)
-Fout=1833.80 (A=017, B=143)
-Fout=1834.00 (A=018, B=143)
-Fout=1834.20 (A=019, B=143)
-Fout=1834.40 (A=020, B=143)
-Fout=1834.60 (A=021, B=143)
-Fout=1834.80 (A=022, B=143)
-Fout=1835.00 (A=023, B=143)
-Fout=1835.20 (A=024, B=143)
-Fout=1835.40 (A=025, B=143)
-Fout=1835.60 (A=026, B=143)
-Fout=1835.80 (A=027, B=143)
-Fout=1836.00 (A=028, B=143)
-Fout=1836.20 (A=029, B=143)
-Fout=1836.40 (A=030, B=143)
-Fout=1836.60 (A=031, B=143)
-Fout=1836.80 (A=032, B=143)
-Fout=1837.00 (A=033, B=143)
-Fout=1837.20 (A=034, B=143)
-Fout=1837.40 (A=035, B=143)
-Fout=1837.60 (A=036, B=143)
-Fout=1837.80 (A=037, B=143)
-Fout=1838.00 (A=038, B=143)
-Fout=1838.20 (A=039, B=143)
-Fout=1838.40 (A=040, B=143)
-Fout=1838.60 (A=041, B=143)
-Fout=1838.80 (A=042, B=143)
-Fout=1839.00 (A=043, B=143)
-Fout=1839.20 (A=044, B=143)
-Fout=1839.40 (A=045, B=143)
-Fout=1839.60 (A=046, B=143)
-Fout=1839.80 (A=047, B=143)
-Fout=1840.00 (A=048, B=143)
-Fout=1840.20 (A=049, B=143)
-Fout=1840.40 (A=050, B=143)
-Fout=1840.60 (A=051, B=143)
-Fout=1840.80 (A=052, B=143)
-Fout=1841.00 (A=053, B=143)
-Fout=1841.20 (A=054, B=143)
-Fout=1841.40 (A=055, B=143)
-Fout=1841.60 (A=056, B=143)
-Fout=1841.80 (A=057, B=143)
-Fout=1842.00 (A=058, B=143)
-Fout=1842.20 (A=059, B=143)
-Fout=1842.40 (A=060, B=143)
-Fout=1842.60 (A=061, B=143)
-Fout=1842.80 (A=062, B=143)
-Fout=1843.20 (A=000, B=144)
-Fout=1843.40 (A=001, B=144)
-Fout=1843.60 (A=002, B=144)
-Fout=1843.80 (A=003, B=144)
-Fout=1844.00 (A=004, B=144)
-Fout=1844.20 (A=005, B=144)
-Fout=1844.40 (A=006, B=144)
-Fout=1844.60 (A=007, B=144)
-Fout=1844.80 (A=008, B=144)
-Fout=1845.00 (A=009, B=144)
-Fout=1845.20 (A=010, B=144)
-Fout=1845.40 (A=011, B=144)
-Fout=1845.60 (A=012, B=144)
-Fout=1845.80 (A=013, B=144)
-Fout=1846.00 (A=014, B=144)
-Fout=1846.20 (A=015, B=144)
-Fout=1846.40 (A=016, B=144)
-Fout=1846.60 (A=017, B=144)
-Fout=1846.80 (A=018, B=144)
-Fout=1847.00 (A=019, B=144)
-Fout=1847.20 (A=020, B=144)
-Fout=1847.40 (A=021, B=144)
-Fout=1847.60 (A=022, B=144)
-Fout=1847.80 (A=023, B=144)
-Fout=1848.00 (A=024, B=144)
-Fout=1848.20 (A=025, B=144)
-Fout=1848.40 (A=026, B=144)
-Fout=1848.60 (A=027, B=144)
-Fout=1848.80 (A=028, B=144)
-Fout=1849.00 (A=029, B=144)
-Fout=1849.20 (A=030, B=144)
-Fout=1849.40 (A=031, B=144)
-Fout=1849.60 (A=032, B=144)
-Fout=1849.80 (A=033, B=144)
-Fout=1850.00 (A=034, B=144)
-Fout=1850.20 (A=035, B=144)
-Fout=1850.40 (A=036, B=144)
-Fout=1850.60 (A=037, B=144)
-Fout=1850.80 (A=038, B=144)
-Fout=1851.00 (A=039, B=144)
-Fout=1851.20 (A=040, B=144)
-Fout=1851.40 (A=041, B=144)
-Fout=1851.60 (A=042, B=144)
-Fout=1851.80 (A=043, B=144)
-Fout=1852.00 (A=044, B=144)
-Fout=1852.20 (A=045, B=144)
-Fout=1852.40 (A=046, B=144)
-Fout=1852.60 (A=047, B=144)
-Fout=1852.80 (A=048, B=144)
-Fout=1853.00 (A=049, B=144)
-Fout=1853.20 (A=050, B=144)
-Fout=1853.40 (A=051, B=144)
-Fout=1853.60 (A=052, B=144)
-Fout=1853.80 (A=053, B=144)
-Fout=1854.00 (A=054, B=144)
-Fout=1854.20 (A=055, B=144)
-Fout=1854.40 (A=056, B=144)
-Fout=1854.60 (A=057, B=144)
-Fout=1854.80 (A=058, B=144)
-Fout=1855.00 (A=059, B=144)
-Fout=1855.20 (A=060, B=144)
-Fout=1855.40 (A=061, B=144)
-Fout=1855.60 (A=062, B=144)
-Fout=1856.00 (A=000, B=145)
-Fout=1856.20 (A=001, B=145)
-Fout=1856.40 (A=002, B=145)
-Fout=1856.60 (A=003, B=145)
-Fout=1856.80 (A=004, B=145)
-Fout=1857.00 (A=005, B=145)
-Fout=1857.20 (A=006, B=145)
-Fout=1857.40 (A=007, B=145)
-Fout=1857.60 (A=008, B=145)
-Fout=1857.80 (A=009, B=145)
-Fout=1858.00 (A=010, B=145)
-Fout=1858.20 (A=011, B=145)
-Fout=1858.40 (A=012, B=145)
-Fout=1858.60 (A=013, B=145)
-Fout=1858.80 (A=014, B=145)
-Fout=1859.00 (A=015, B=145)
-Fout=1859.20 (A=016, B=145)
-Fout=1859.40 (A=017, B=145)
-Fout=1859.60 (A=018, B=145)
-Fout=1859.80 (A=019, B=145)
-Fout=1860.00 (A=020, B=145)
-Fout=1860.20 (A=021, B=145)
-Fout=1860.40 (A=022, B=145)
-Fout=1860.60 (A=023, B=145)
-Fout=1860.80 (A=024, B=145)
-Fout=1861.00 (A=025, B=145)
-Fout=1861.20 (A=026, B=145)
-Fout=1861.40 (A=027, B=145)
-Fout=1861.60 (A=028, B=145)
-Fout=1861.80 (A=029, B=145)
-Fout=1862.00 (A=030, B=145)
-Fout=1862.20 (A=031, B=145)
-Fout=1862.40 (A=032, B=145)
-Fout=1862.60 (A=033, B=145)
-Fout=1862.80 (A=034, B=145)
-Fout=1863.00 (A=035, B=145)
-Fout=1863.20 (A=036, B=145)
-Fout=1863.40 (A=037, B=145)
-Fout=1863.60 (A=038, B=145)
-Fout=1863.80 (A=039, B=145)
-Fout=1864.00 (A=040, B=145)
-Fout=1864.20 (A=041, B=145)
-Fout=1864.40 (A=042, B=145)
-Fout=1864.60 (A=043, B=145)
-Fout=1864.80 (A=044, B=145)
-Fout=1865.00 (A=045, B=145)
-Fout=1865.20 (A=046, B=145)
-Fout=1865.40 (A=047, B=145)
-Fout=1865.60 (A=048, B=145)
-Fout=1865.80 (A=049, B=145)
-Fout=1866.00 (A=050, B=145)
-Fout=1866.20 (A=051, B=145)
-Fout=1866.40 (A=052, B=145)
-Fout=1866.60 (A=053, B=145)
-Fout=1866.80 (A=054, B=145)
-Fout=1867.00 (A=055, B=145)
-Fout=1867.20 (A=056, B=145)
-Fout=1867.40 (A=057, B=145)
-Fout=1867.60 (A=058, B=145)
-Fout=1867.80 (A=059, B=145)
-Fout=1868.00 (A=060, B=145)
-Fout=1868.20 (A=061, B=145)
-Fout=1868.40 (A=062, B=145)
-Fout=1868.80 (A=000, B=146)
-Fout=1869.00 (A=001, B=146)
-Fout=1869.20 (A=002, B=146)
-Fout=1869.40 (A=003, B=146)
-Fout=1869.60 (A=004, B=146)
-Fout=1869.80 (A=005, B=146)
-Fout=1870.00 (A=006, B=146)
-Fout=1870.20 (A=007, B=146)
-Fout=1870.40 (A=008, B=146)
-Fout=1870.60 (A=009, B=146)
-Fout=1870.80 (A=010, B=146)
-Fout=1871.00 (A=011, B=146)
-Fout=1871.20 (A=012, B=146)
-Fout=1871.40 (A=013, B=146)
-Fout=1871.60 (A=014, B=146)
-Fout=1871.80 (A=015, B=146)
-Fout=1872.00 (A=016, B=146)
-Fout=1872.20 (A=017, B=146)
-Fout=1872.40 (A=018, B=146)
-Fout=1872.60 (A=019, B=146)
-Fout=1872.80 (A=020, B=146)
-Fout=1873.00 (A=021, B=146)
-Fout=1873.20 (A=022, B=146)
-Fout=1873.40 (A=023, B=146)
-Fout=1873.60 (A=024, B=146)
-Fout=1873.80 (A=025, B=146)
-Fout=1874.00 (A=026, B=146)
-Fout=1874.20 (A=027, B=146)
-Fout=1874.40 (A=028, B=146)
-Fout=1874.60 (A=029, B=146)
-Fout=1874.80 (A=030, B=146)
-Fout=1875.00 (A=031, B=146)
-Fout=1875.20 (A=032, B=146)
-Fout=1875.40 (A=033, B=146)
-Fout=1875.60 (A=034, B=146)
-Fout=1875.80 (A=035, B=146)
-Fout=1876.00 (A=036, B=146)
-Fout=1876.20 (A=037, B=146)
-Fout=1876.40 (A=038, B=146)
-Fout=1876.60 (A=039, B=146)
-Fout=1876.80 (A=040, B=146)
-Fout=1877.00 (A=041, B=146)
-Fout=1877.20 (A=042, B=146)
-Fout=1877.40 (A=043, B=146)
-Fout=1877.60 (A=044, B=146)
-Fout=1877.80 (A=045, B=146)
-Fout=1878.00 (A=046, B=146)
-Fout=1878.20 (A=047, B=146)
-Fout=1878.40 (A=048, B=146)
-Fout=1878.60 (A=049, B=146)
-Fout=1878.80 (A=050, B=146)
-Fout=1879.00 (A=051, B=146)
-Fout=1879.20 (A=052, B=146)
-Fout=1879.40 (A=053, B=146)
-Fout=1879.60 (A=054, B=146)
-Fout=1879.80 (A=055, B=146)
-Fout=1880.00 (A=056, B=146)
-Fout=1880.20 (A=057, B=146)
-Fout=1880.40 (A=058, B=146)
-Fout=1880.60 (A=059, B=146)
-Fout=1880.80 (A=060, B=146)
-Fout=1881.00 (A=061, B=146)
-Fout=1881.20 (A=062, B=146)
-Fout=1881.60 (A=000, B=147)
-Fout=1881.80 (A=001, B=147)
-Fout=1882.00 (A=002, B=147)
-Fout=1882.20 (A=003, B=147)
-Fout=1882.40 (A=004, B=147)
-Fout=1882.60 (A=005, B=147)
-Fout=1882.80 (A=006, B=147)
-Fout=1883.00 (A=007, B=147)
-Fout=1883.20 (A=008, B=147)
-Fout=1883.40 (A=009, B=147)
-Fout=1883.60 (A=010, B=147)
-Fout=1883.80 (A=011, B=147)
-Fout=1884.00 (A=012, B=147)
-Fout=1884.20 (A=013, B=147)
-Fout=1884.40 (A=014, B=147)
-Fout=1884.60 (A=015, B=147)
-Fout=1884.80 (A=016, B=147)
-Fout=1885.00 (A=017, B=147)
-Fout=1885.20 (A=018, B=147)
-Fout=1885.40 (A=019, B=147)
-Fout=1885.60 (A=020, B=147)
-Fout=1885.80 (A=021, B=147)
-Fout=1886.00 (A=022, B=147)
-Fout=1886.20 (A=023, B=147)
-Fout=1886.40 (A=024, B=147)
-Fout=1886.60 (A=025, B=147)
-Fout=1886.80 (A=026, B=147)
-Fout=1887.00 (A=027, B=147)
-Fout=1887.20 (A=028, B=147)
-Fout=1887.40 (A=029, B=147)
-Fout=1887.60 (A=030, B=147)
-Fout=1887.80 (A=031, B=147)
-Fout=1888.00 (A=032, B=147)
-Fout=1888.20 (A=033, B=147)
-Fout=1888.40 (A=034, B=147)
-Fout=1888.60 (A=035, B=147)
-Fout=1888.80 (A=036, B=147)
-Fout=1889.00 (A=037, B=147)
-Fout=1889.20 (A=038, B=147)
-Fout=1889.40 (A=039, B=147)
-Fout=1889.60 (A=040, B=147)
-Fout=1889.80 (A=041, B=147)
-Fout=1890.00 (A=042, B=147)
-Fout=1890.20 (A=043, B=147)
-Fout=1890.40 (A=044, B=147)
-Fout=1890.60 (A=045, B=147)
-Fout=1890.80 (A=046, B=147)
-Fout=1891.00 (A=047, B=147)
-Fout=1891.20 (A=048, B=147)
-Fout=1891.40 (A=049, B=147)
-Fout=1891.60 (A=050, B=147)
-Fout=1891.80 (A=051, B=147)
-Fout=1892.00 (A=052, B=147)
-Fout=1892.20 (A=053, B=147)
-Fout=1892.40 (A=054, B=147)
-Fout=1892.60 (A=055, B=147)
-Fout=1892.80 (A=056, B=147)
-Fout=1893.00 (A=057, B=147)
-Fout=1893.20 (A=058, B=147)
-Fout=1893.40 (A=059, B=147)
-Fout=1893.60 (A=060, B=147)
-Fout=1893.80 (A=061, B=147)
-Fout=1894.00 (A=062, B=147)
-Fout=1894.40 (A=000, B=148)
-Fout=1894.60 (A=001, B=148)
-Fout=1894.80 (A=002, B=148)
-Fout=1895.00 (A=003, B=148)
-Fout=1895.20 (A=004, B=148)
-Fout=1895.40 (A=005, B=148)
-Fout=1895.60 (A=006, B=148)
-Fout=1895.80 (A=007, B=148)
-Fout=1896.00 (A=008, B=148)
-Fout=1896.20 (A=009, B=148)
-Fout=1896.40 (A=010, B=148)
-Fout=1896.60 (A=011, B=148)
-Fout=1896.80 (A=012, B=148)
-Fout=1897.00 (A=013, B=148)
-Fout=1897.20 (A=014, B=148)
-Fout=1897.40 (A=015, B=148)
-Fout=1897.60 (A=016, B=148)
-Fout=1897.80 (A=017, B=148)
-Fout=1898.00 (A=018, B=148)
-Fout=1898.20 (A=019, B=148)
-Fout=1898.40 (A=020, B=148)
-Fout=1898.60 (A=021, B=148)
-Fout=1898.80 (A=022, B=148)
-Fout=1899.00 (A=023, B=148)
-Fout=1899.20 (A=024, B=148)
-Fout=1899.40 (A=025, B=148)
-Fout=1899.60 (A=026, B=148)
-Fout=1899.80 (A=027, B=148)
-Fout=1900.00 (A=028, B=148)
-Fout=1900.20 (A=029, B=148)
-Fout=1900.40 (A=030, B=148)
-Fout=1900.60 (A=031, B=148)
-Fout=1900.80 (A=032, B=148)
-Fout=1901.00 (A=033, B=148)
-Fout=1901.20 (A=034, B=148)
-Fout=1901.40 (A=035, B=148)
-Fout=1901.60 (A=036, B=148)
-Fout=1901.80 (A=037, B=148)
-Fout=1902.00 (A=038, B=148)
-Fout=1902.20 (A=039, B=148)
-Fout=1902.40 (A=040, B=148)
-Fout=1902.60 (A=041, B=148)
-Fout=1902.80 (A=042, B=148)
-Fout=1903.00 (A=043, B=148)
-Fout=1903.20 (A=044, B=148)
-Fout=1903.40 (A=045, B=148)
-Fout=1903.60 (A=046, B=148)
-Fout=1903.80 (A=047, B=148)
-Fout=1904.00 (A=048, B=148)
-Fout=1904.20 (A=049, B=148)
-Fout=1904.40 (A=050, B=148)
-Fout=1904.60 (A=051, B=148)
-Fout=1904.80 (A=052, B=148)
-Fout=1905.00 (A=053, B=148)
-Fout=1905.20 (A=054, B=148)
-Fout=1905.40 (A=055, B=148)
-Fout=1905.60 (A=056, B=148)
-Fout=1905.80 (A=057, B=148)
-Fout=1906.00 (A=058, B=148)
-Fout=1906.20 (A=059, B=148)
-Fout=1906.40 (A=060, B=148)
-Fout=1906.60 (A=061, B=148)
-Fout=1906.80 (A=062, B=148)
-Fout=1907.20 (A=000, B=149)
-Fout=1907.40 (A=001, B=149)
-Fout=1907.60 (A=002, B=149)
-Fout=1907.80 (A=003, B=149)
-Fout=1908.00 (A=004, B=149)
-Fout=1908.20 (A=005, B=149)
-Fout=1908.40 (A=006, B=149)
-Fout=1908.60 (A=007, B=149)
-Fout=1908.80 (A=008, B=149)
-Fout=1909.00 (A=009, B=149)
-Fout=1909.20 (A=010, B=149)
-Fout=1909.40 (A=011, B=149)
-Fout=1909.60 (A=012, B=149)
-Fout=1909.80 (A=013, B=149)
-Fout=1910.00 (A=014, B=149)
-Fout=1910.20 (A=015, B=149)
-Fout=1910.40 (A=016, B=149)
-Fout=1910.60 (A=017, B=149)
-Fout=1910.80 (A=018, B=149)
-Fout=1911.00 (A=019, B=149)
-Fout=1911.20 (A=020, B=149)
-Fout=1911.40 (A=021, B=149)
-Fout=1911.60 (A=022, B=149)
-Fout=1911.80 (A=023, B=149)
-Fout=1912.00 (A=024, B=149)
-Fout=1912.20 (A=025, B=149)
-Fout=1912.40 (A=026, B=149)
-Fout=1912.60 (A=027, B=149)
-Fout=1912.80 (A=028, B=149)
-Fout=1913.00 (A=029, B=149)
-Fout=1913.20 (A=030, B=149)
-Fout=1913.40 (A=031, B=149)
-Fout=1913.60 (A=032, B=149)
-Fout=1913.80 (A=033, B=149)
-Fout=1914.00 (A=034, B=149)
-Fout=1914.20 (A=035, B=149)
-Fout=1914.40 (A=036, B=149)
-Fout=1914.60 (A=037, B=149)
-Fout=1914.80 (A=038, B=149)
-Fout=1915.00 (A=039, B=149)
-Fout=1915.20 (A=040, B=149)
-Fout=1915.40 (A=041, B=149)
-Fout=1915.60 (A=042, B=149)
-Fout=1915.80 (A=043, B=149)
-Fout=1916.00 (A=044, B=149)
-Fout=1916.20 (A=045, B=149)
-Fout=1916.40 (A=046, B=149)
-Fout=1916.60 (A=047, B=149)
-Fout=1916.80 (A=048, B=149)
-Fout=1917.00 (A=049, B=149)
-Fout=1917.20 (A=050, B=149)
-Fout=1917.40 (A=051, B=149)
-Fout=1917.60 (A=052, B=149)
-Fout=1917.80 (A=053, B=149)
-Fout=1918.00 (A=054, B=149)
-Fout=1918.20 (A=055, B=149)
-Fout=1918.40 (A=056, B=149)
-Fout=1918.60 (A=057, B=149)
-Fout=1918.80 (A=058, B=149)
-Fout=1919.00 (A=059, B=149)
-Fout=1919.20 (A=060, B=149)
-Fout=1919.40 (A=061, B=149)
-Fout=1919.60 (A=062, B=149)
-Fout=1920.00 (A=000, B=150)
-Fout=1920.20 (A=001, B=150)
-Fout=1920.40 (A=002, B=150)
-Fout=1920.60 (A=003, B=150)
-Fout=1920.80 (A=004, B=150)
-Fout=1921.00 (A=005, B=150)
-Fout=1921.20 (A=006, B=150)
-Fout=1921.40 (A=007, B=150)
-Fout=1921.60 (A=008, B=150)
-Fout=1921.80 (A=009, B=150)
-Fout=1922.00 (A=010, B=150)
-Fout=1922.20 (A=011, B=150)
-Fout=1922.40 (A=012, B=150)
-Fout=1922.60 (A=013, B=150)
-Fout=1922.80 (A=014, B=150)
-Fout=1923.00 (A=015, B=150)
-Fout=1923.20 (A=016, B=150)
-Fout=1923.40 (A=017, B=150)
-Fout=1923.60 (A=018, B=150)
-Fout=1923.80 (A=019, B=150)
-Fout=1924.00 (A=020, B=150)
-Fout=1924.20 (A=021, B=150)
-Fout=1924.40 (A=022, B=150)
-Fout=1924.60 (A=023, B=150)
-Fout=1924.80 (A=024, B=150)
-Fout=1925.00 (A=025, B=150)
-Fout=1925.20 (A=026, B=150)
-Fout=1925.40 (A=027, B=150)
-Fout=1925.60 (A=028, B=150)
-Fout=1925.80 (A=029, B=150)
-Fout=1926.00 (A=030, B=150)
-Fout=1926.20 (A=031, B=150)
-Fout=1926.40 (A=032, B=150)
-Fout=1926.60 (A=033, B=150)
-Fout=1926.80 (A=034, B=150)
-Fout=1927.00 (A=035, B=150)
-Fout=1927.20 (A=036, B=150)
-Fout=1927.40 (A=037, B=150)
-Fout=1927.60 (A=038, B=150)
-Fout=1927.80 (A=039, B=150)
-Fout=1928.00 (A=040, B=150)
-Fout=1928.20 (A=041, B=150)
-Fout=1928.40 (A=042, B=150)
-Fout=1928.60 (A=043, B=150)
-Fout=1928.80 (A=044, B=150)
-Fout=1929.00 (A=045, B=150)
-Fout=1929.20 (A=046, B=150)
-Fout=1929.40 (A=047, B=150)
-Fout=1929.60 (A=048, B=150)
-Fout=1929.80 (A=049, B=150)
-Fout=1930.00 (A=050, B=150)
-Fout=1930.20 (A=051, B=150)
-Fout=1930.40 (A=052, B=150)
-Fout=1930.60 (A=053, B=150)
-Fout=1930.80 (A=054, B=150)
-Fout=1931.00 (A=055, B=150)
-Fout=1931.20 (A=056, B=150)
-Fout=1931.40 (A=057, B=150)
-Fout=1931.60 (A=058, B=150)
-Fout=1931.80 (A=059, B=150)
-Fout=1932.00 (A=060, B=150)
-Fout=1932.20 (A=061, B=150)
-Fout=1932.40 (A=062, B=150)
-Fout=1932.80 (A=000, B=151)
-Fout=1933.00 (A=001, B=151)
-Fout=1933.20 (A=002, B=151)
-Fout=1933.40 (A=003, B=151)
-Fout=1933.60 (A=004, B=151)
-Fout=1933.80 (A=005, B=151)
-Fout=1934.00 (A=006, B=151)
-Fout=1934.20 (A=007, B=151)
-Fout=1934.40 (A=008, B=151)
-Fout=1934.60 (A=009, B=151)
-Fout=1934.80 (A=010, B=151)
-Fout=1935.00 (A=011, B=151)
-Fout=1935.20 (A=012, B=151)
-Fout=1935.40 (A=013, B=151)
-Fout=1935.60 (A=014, B=151)
-Fout=1935.80 (A=015, B=151)
-Fout=1936.00 (A=016, B=151)
-Fout=1936.20 (A=017, B=151)
-Fout=1936.40 (A=018, B=151)
-Fout=1936.60 (A=019, B=151)
-Fout=1936.80 (A=020, B=151)
-Fout=1937.00 (A=021, B=151)
-Fout=1937.20 (A=022, B=151)
-Fout=1937.40 (A=023, B=151)
-Fout=1937.60 (A=024, B=151)
-Fout=1937.80 (A=025, B=151)
-Fout=1938.00 (A=026, B=151)
-Fout=1938.20 (A=027, B=151)
-Fout=1938.40 (A=028, B=151)
-Fout=1938.60 (A=029, B=151)
-Fout=1938.80 (A=030, B=151)
-Fout=1939.00 (A=031, B=151)
-Fout=1939.20 (A=032, B=151)
-Fout=1939.40 (A=033, B=151)
-Fout=1939.60 (A=034, B=151)
-Fout=1939.80 (A=035, B=151)
-Fout=1940.00 (A=036, B=151)
-Fout=1940.20 (A=037, B=151)
-Fout=1940.40 (A=038, B=151)
-Fout=1940.60 (A=039, B=151)
-Fout=1940.80 (A=040, B=151)
-Fout=1941.00 (A=041, B=151)
-Fout=1941.20 (A=042, B=151)
-Fout=1941.40 (A=043, B=151)
-Fout=1941.60 (A=044, B=151)
-Fout=1941.80 (A=045, B=151)
-Fout=1942.00 (A=046, B=151)
-Fout=1942.20 (A=047, B=151)
-Fout=1942.40 (A=048, B=151)
-Fout=1942.60 (A=049, B=151)
-Fout=1942.80 (A=050, B=151)
-Fout=1943.00 (A=051, B=151)
-Fout=1943.20 (A=052, B=151)
-Fout=1943.40 (A=053, B=151)
-Fout=1943.60 (A=054, B=151)
-Fout=1943.80 (A=055, B=151)
-Fout=1944.00 (A=056, B=151)
-Fout=1944.20 (A=057, B=151)
-Fout=1944.40 (A=058, B=151)
-Fout=1944.60 (A=059, B=151)
-Fout=1944.80 (A=060, B=151)
-Fout=1945.00 (A=061, B=151)
-Fout=1945.20 (A=062, B=151)
-Fout=1945.60 (A=000, B=152)
-Fout=1945.80 (A=001, B=152)
-Fout=1946.00 (A=002, B=152)
-Fout=1946.20 (A=003, B=152)
-Fout=1946.40 (A=004, B=152)
-Fout=1946.60 (A=005, B=152)
-Fout=1946.80 (A=006, B=152)
-Fout=1947.00 (A=007, B=152)
-Fout=1947.20 (A=008, B=152)
-Fout=1947.40 (A=009, B=152)
-Fout=1947.60 (A=010, B=152)
-Fout=1947.80 (A=011, B=152)
-Fout=1948.00 (A=012, B=152)
-Fout=1948.20 (A=013, B=152)
-Fout=1948.40 (A=014, B=152)
-Fout=1948.60 (A=015, B=152)
-Fout=1948.80 (A=016, B=152)
-Fout=1949.00 (A=017, B=152)
-Fout=1949.20 (A=018, B=152)
-Fout=1949.40 (A=019, B=152)
-Fout=1949.60 (A=020, B=152)
-Fout=1949.80 (A=021, B=152)
-Fout=1950.00 (A=022, B=152)
-Fout=1950.20 (A=023, B=152)
-Fout=1950.40 (A=024, B=152)
-Fout=1950.60 (A=025, B=152)
-Fout=1950.80 (A=026, B=152)
-Fout=1951.00 (A=027, B=152)
-Fout=1951.20 (A=028, B=152)
-Fout=1951.40 (A=029, B=152)
-Fout=1951.60 (A=030, B=152)
-Fout=1951.80 (A=031, B=152)
-Fout=1952.00 (A=032, B=152)
-Fout=1952.20 (A=033, B=152)
-Fout=1952.40 (A=034, B=152)
-Fout=1952.60 (A=035, B=152)
-Fout=1952.80 (A=036, B=152)
-Fout=1953.00 (A=037, B=152)
-Fout=1953.20 (A=038, B=152)
-Fout=1953.40 (A=039, B=152)
-Fout=1953.60 (A=040, B=152)
-Fout=1953.80 (A=041, B=152)
-Fout=1954.00 (A=042, B=152)
-Fout=1954.20 (A=043, B=152)
-Fout=1954.40 (A=044, B=152)
-Fout=1954.60 (A=045, B=152)
-Fout=1954.80 (A=046, B=152)
-Fout=1955.00 (A=047, B=152)
-Fout=1955.20 (A=048, B=152)
-Fout=1955.40 (A=049, B=152)
-Fout=1955.60 (A=050, B=152)
-Fout=1955.80 (A=051, B=152)
-Fout=1956.00 (A=052, B=152)
-Fout=1956.20 (A=053, B=152)
-Fout=1956.40 (A=054, B=152)
-Fout=1956.60 (A=055, B=152)
-Fout=1956.80 (A=056, B=152)
-Fout=1957.00 (A=057, B=152)
-Fout=1957.20 (A=058, B=152)
-Fout=1957.40 (A=059, B=152)
-Fout=1957.60 (A=060, B=152)
-Fout=1957.80 (A=061, B=152)
-Fout=1958.00 (A=062, B=152)
-Fout=1958.40 (A=000, B=153)
-Fout=1958.60 (A=001, B=153)
-Fout=1958.80 (A=002, B=153)
-Fout=1959.00 (A=003, B=153)
-Fout=1959.20 (A=004, B=153)
-Fout=1959.40 (A=005, B=153)
-Fout=1959.60 (A=006, B=153)
-Fout=1959.80 (A=007, B=153)
-Fout=1960.00 (A=008, B=153)
-Fout=1960.20 (A=009, B=153)
-Fout=1960.40 (A=010, B=153)
-Fout=1960.60 (A=011, B=153)
-Fout=1960.80 (A=012, B=153)
-Fout=1961.00 (A=013, B=153)
-Fout=1961.20 (A=014, B=153)
-Fout=1961.40 (A=015, B=153)
-Fout=1961.60 (A=016, B=153)
-Fout=1961.80 (A=017, B=153)
-Fout=1962.00 (A=018, B=153)
-Fout=1962.20 (A=019, B=153)
-Fout=1962.40 (A=020, B=153)
-Fout=1962.60 (A=021, B=153)
-Fout=1962.80 (A=022, B=153)
-Fout=1963.00 (A=023, B=153)
-Fout=1963.20 (A=024, B=153)
-Fout=1963.40 (A=025, B=153)
-Fout=1963.60 (A=026, B=153)
-Fout=1963.80 (A=027, B=153)
-Fout=1964.00 (A=028, B=153)
-Fout=1964.20 (A=029, B=153)
-Fout=1964.40 (A=030, B=153)
-Fout=1964.60 (A=031, B=153)
-Fout=1964.80 (A=032, B=153)
-Fout=1965.00 (A=033, B=153)
-Fout=1965.20 (A=034, B=153)
-Fout=1965.40 (A=035, B=153)
-Fout=1965.60 (A=036, B=153)
-Fout=1965.80 (A=037, B=153)
-Fout=1966.00 (A=038, B=153)
-Fout=1966.20 (A=039, B=153)
-Fout=1966.40 (A=040, B=153)
-Fout=1966.60 (A=041, B=153)
-Fout=1966.80 (A=042, B=153)
-Fout=1967.00 (A=043, B=153)
-Fout=1967.20 (A=044, B=153)
-Fout=1967.40 (A=045, B=153)
-Fout=1967.60 (A=046, B=153)
-Fout=1967.80 (A=047, B=153)
-Fout=1968.00 (A=048, B=153)
-Fout=1968.20 (A=049, B=153)
-Fout=1968.40 (A=050, B=153)
-Fout=1968.60 (A=051, B=153)
-Fout=1968.80 (A=052, B=153)
-Fout=1969.00 (A=053, B=153)
-Fout=1969.20 (A=054, B=153)
-Fout=1969.40 (A=055, B=153)
-Fout=1969.60 (A=056, B=153)
-Fout=1969.80 (A=057, B=153)
-Fout=1970.00 (A=058, B=153)
-Fout=1970.20 (A=059, B=153)
-Fout=1970.40 (A=060, B=153)
-Fout=1970.60 (A=061, B=153)
-Fout=1970.80 (A=062, B=153)
-Fout=1971.20 (A=000, B=154)
-Fout=1971.40 (A=001, B=154)
-Fout=1971.60 (A=002, B=154)
-Fout=1971.80 (A=003, B=154)
-Fout=1972.00 (A=004, B=154)
-Fout=1972.20 (A=005, B=154)
-Fout=1972.40 (A=006, B=154)
-Fout=1972.60 (A=007, B=154)
-Fout=1972.80 (A=008, B=154)
-Fout=1973.00 (A=009, B=154)
-Fout=1973.20 (A=010, B=154)
-Fout=1973.40 (A=011, B=154)
-Fout=1973.60 (A=012, B=154)
-Fout=1973.80 (A=013, B=154)
-Fout=1974.00 (A=014, B=154)
-Fout=1974.20 (A=015, B=154)
-Fout=1974.40 (A=016, B=154)
-Fout=1974.60 (A=017, B=154)
-Fout=1974.80 (A=018, B=154)
-Fout=1975.00 (A=019, B=154)
-Fout=1975.20 (A=020, B=154)
-Fout=1975.40 (A=021, B=154)
-Fout=1975.60 (A=022, B=154)
-Fout=1975.80 (A=023, B=154)
-Fout=1976.00 (A=024, B=154)
-Fout=1976.20 (A=025, B=154)
-Fout=1976.40 (A=026, B=154)
-Fout=1976.60 (A=027, B=154)
-Fout=1976.80 (A=028, B=154)
-Fout=1977.00 (A=029, B=154)
-Fout=1977.20 (A=030, B=154)
-Fout=1977.40 (A=031, B=154)
-Fout=1977.60 (A=032, B=154)
-Fout=1977.80 (A=033, B=154)
-Fout=1978.00 (A=034, B=154)
-Fout=1978.20 (A=035, B=154)
-Fout=1978.40 (A=036, B=154)
-Fout=1978.60 (A=037, B=154)
-Fout=1978.80 (A=038, B=154)
-Fout=1979.00 (A=039, B=154)
-Fout=1979.20 (A=040, B=154)
-Fout=1979.40 (A=041, B=154)
-Fout=1979.60 (A=042, B=154)
-Fout=1979.80 (A=043, B=154)
-Fout=1980.00 (A=044, B=154)
-Fout=1980.20 (A=045, B=154)
-Fout=1980.40 (A=046, B=154)
-Fout=1980.60 (A=047, B=154)
-Fout=1980.80 (A=048, B=154)
-Fout=1981.00 (A=049, B=154)
-Fout=1981.20 (A=050, B=154)
-Fout=1981.40 (A=051, B=154)
-Fout=1981.60 (A=052, B=154)
-Fout=1981.80 (A=053, B=154)
-Fout=1982.00 (A=054, B=154)
-Fout=1982.20 (A=055, B=154)
-Fout=1982.40 (A=056, B=154)
-Fout=1982.60 (A=057, B=154)
-Fout=1982.80 (A=058, B=154)
-Fout=1983.00 (A=059, B=154)
-Fout=1983.20 (A=060, B=154)
-Fout=1983.40 (A=061, B=154)
-Fout=1983.60 (A=062, B=154)
-Fout=1984.00 (A=000, B=155)
-Fout=1984.20 (A=001, B=155)
-Fout=1984.40 (A=002, B=155)
-Fout=1984.60 (A=003, B=155)
-Fout=1984.80 (A=004, B=155)
-Fout=1985.00 (A=005, B=155)
-Fout=1985.20 (A=006, B=155)
-Fout=1985.40 (A=007, B=155)
-Fout=1985.60 (A=008, B=155)
-Fout=1985.80 (A=009, B=155)
-Fout=1986.00 (A=010, B=155)
-Fout=1986.20 (A=011, B=155)
-Fout=1986.40 (A=012, B=155)
-Fout=1986.60 (A=013, B=155)
-Fout=1986.80 (A=014, B=155)
-Fout=1987.00 (A=015, B=155)
-Fout=1987.20 (A=016, B=155)
-Fout=1987.40 (A=017, B=155)
-Fout=1987.60 (A=018, B=155)
-Fout=1987.80 (A=019, B=155)
-Fout=1988.00 (A=020, B=155)
-Fout=1988.20 (A=021, B=155)
-Fout=1988.40 (A=022, B=155)
-Fout=1988.60 (A=023, B=155)
-Fout=1988.80 (A=024, B=155)
-Fout=1989.00 (A=025, B=155)
-Fout=1989.20 (A=026, B=155)
-Fout=1989.40 (A=027, B=155)
-Fout=1989.60 (A=028, B=155)
-Fout=1989.80 (A=029, B=155)
-Fout=1990.00 (A=030, B=155)
-Fout=1990.20 (A=031, B=155)
-Fout=1990.40 (A=032, B=155)
-Fout=1990.60 (A=033, B=155)
-Fout=1990.80 (A=034, B=155)
-Fout=1991.00 (A=035, B=155)
-Fout=1991.20 (A=036, B=155)
-Fout=1991.40 (A=037, B=155)
-Fout=1991.60 (A=038, B=155)
-Fout=1991.80 (A=039, B=155)
-Fout=1992.00 (A=040, B=155)
-Fout=1992.20 (A=041, B=155)
-Fout=1992.40 (A=042, B=155)
-Fout=1992.60 (A=043, B=155)
-Fout=1992.80 (A=044, B=155)
-Fout=1993.00 (A=045, B=155)
-Fout=1993.20 (A=046, B=155)
-Fout=1993.40 (A=047, B=155)
-Fout=1993.60 (A=048, B=155)
-Fout=1993.80 (A=049, B=155)
-Fout=1994.00 (A=050, B=155)
-Fout=1994.20 (A=051, B=155)
-Fout=1994.40 (A=052, B=155)
-Fout=1994.60 (A=053, B=155)
-Fout=1994.80 (A=054, B=155)
-Fout=1995.00 (A=055, B=155)
-Fout=1995.20 (A=056, B=155)
-Fout=1995.40 (A=057, B=155)
-Fout=1995.60 (A=058, B=155)
-Fout=1995.80 (A=059, B=155)
-Fout=1996.00 (A=060, B=155)
-Fout=1996.20 (A=061, B=155)
-Fout=1996.40 (A=062, B=155)
-======================================================================
-PLL Tx GSM850_1
-Fout=819.20 (A=000, B=128)
-Fout=819.30 (A=001, B=128)
-Fout=819.40 (A=002, B=128)
-Fout=819.50 (A=003, B=128)
-Fout=819.60 (A=004, B=128)
-Fout=819.70 (A=005, B=128)
-Fout=819.80 (A=006, B=128)
-Fout=819.90 (A=007, B=128)
-Fout=820.00 (A=008, B=128)
-Fout=820.10 (A=009, B=128)
-Fout=820.20 (A=010, B=128)
-Fout=820.30 (A=011, B=128)
-Fout=820.40 (A=012, B=128)
-Fout=820.50 (A=013, B=128)
-Fout=820.60 (A=014, B=128)
-Fout=820.70 (A=015, B=128)
-Fout=820.80 (A=016, B=128)
-Fout=820.90 (A=017, B=128)
-Fout=821.00 (A=018, B=128)
-Fout=821.10 (A=019, B=128)
-Fout=821.20 (A=020, B=128)
-Fout=821.30 (A=021, B=128)
-Fout=821.40 (A=022, B=128)
-Fout=821.50 (A=023, B=128)
-Fout=821.60 (A=024, B=128)
-Fout=821.70 (A=025, B=128)
-Fout=821.80 (A=026, B=128)
-Fout=821.90 (A=027, B=128)
-Fout=822.00 (A=028, B=128)
-Fout=822.10 (A=029, B=128)
-Fout=822.20 (A=030, B=128)
-Fout=822.30 (A=031, B=128)
-Fout=822.40 (A=032, B=128)
-Fout=822.50 (A=033, B=128)
-Fout=822.60 (A=034, B=128)
-Fout=822.70 (A=035, B=128)
-Fout=822.80 (A=036, B=128)
-Fout=822.90 (A=037, B=128)
-Fout=823.00 (A=038, B=128)
-Fout=823.10 (A=039, B=128)
-Fout=823.20 (A=040, B=128)
-Fout=823.30 (A=041, B=128)
-Fout=823.40 (A=042, B=128)
-Fout=823.50 (A=043, B=128)
-Fout=823.60 (A=044, B=128)
-Fout=823.70 (A=045, B=128)
-Fout=823.80 (A=046, B=128)
-Fout=823.90 (A=047, B=128)
-Fout=824.00 (A=048, B=128)
-Fout=824.10 (A=049, B=128)
-Fout=824.20 (A=050, B=128)
-Fout=824.30 (A=051, B=128)
-Fout=824.40 (A=052, B=128)
-Fout=824.50 (A=053, B=128)
-Fout=824.60 (A=054, B=128)
-Fout=824.70 (A=055, B=128)
-Fout=824.80 (A=056, B=128)
-Fout=824.90 (A=057, B=128)
-Fout=825.00 (A=058, B=128)
-Fout=825.10 (A=059, B=128)
-Fout=825.20 (A=060, B=128)
-Fout=825.30 (A=061, B=128)
-Fout=825.40 (A=062, B=128)
-Fout=825.60 (A=000, B=129)
-Fout=825.70 (A=001, B=129)
-Fout=825.80 (A=002, B=129)
-Fout=825.90 (A=003, B=129)
-Fout=826.00 (A=004, B=129)
-Fout=826.10 (A=005, B=129)
-Fout=826.20 (A=006, B=129)
-Fout=826.30 (A=007, B=129)
-Fout=826.40 (A=008, B=129)
-Fout=826.50 (A=009, B=129)
-Fout=826.60 (A=010, B=129)
-Fout=826.70 (A=011, B=129)
-Fout=826.80 (A=012, B=129)
-Fout=826.90 (A=013, B=129)
-Fout=827.00 (A=014, B=129)
-Fout=827.10 (A=015, B=129)
-Fout=827.20 (A=016, B=129)
-Fout=827.30 (A=017, B=129)
-Fout=827.40 (A=018, B=129)
-Fout=827.50 (A=019, B=129)
-Fout=827.60 (A=020, B=129)
-Fout=827.70 (A=021, B=129)
-Fout=827.80 (A=022, B=129)
-Fout=827.90 (A=023, B=129)
-Fout=828.00 (A=024, B=129)
-Fout=828.10 (A=025, B=129)
-Fout=828.20 (A=026, B=129)
-Fout=828.30 (A=027, B=129)
-Fout=828.40 (A=028, B=129)
-Fout=828.50 (A=029, B=129)
-Fout=828.60 (A=030, B=129)
-Fout=828.70 (A=031, B=129)
-Fout=828.80 (A=032, B=129)
-Fout=828.90 (A=033, B=129)
-Fout=829.00 (A=034, B=129)
-Fout=829.10 (A=035, B=129)
-Fout=829.20 (A=036, B=129)
-Fout=829.30 (A=037, B=129)
-Fout=829.40 (A=038, B=129)
-Fout=829.50 (A=039, B=129)
-Fout=829.60 (A=040, B=129)
-Fout=829.70 (A=041, B=129)
-Fout=829.80 (A=042, B=129)
-Fout=829.90 (A=043, B=129)
-Fout=830.00 (A=044, B=129)
-Fout=830.10 (A=045, B=129)
-Fout=830.20 (A=046, B=129)
-Fout=830.30 (A=047, B=129)
-Fout=830.40 (A=048, B=129)
-Fout=830.50 (A=049, B=129)
-Fout=830.60 (A=050, B=129)
-Fout=830.70 (A=051, B=129)
-Fout=830.80 (A=052, B=129)
-Fout=830.90 (A=053, B=129)
-Fout=831.00 (A=054, B=129)
-Fout=831.10 (A=055, B=129)
-Fout=831.20 (A=056, B=129)
-Fout=831.30 (A=057, B=129)
-Fout=831.40 (A=058, B=129)
-Fout=831.50 (A=059, B=129)
-Fout=831.60 (A=060, B=129)
-Fout=831.70 (A=061, B=129)
-Fout=831.80 (A=062, B=129)
-Fout=832.00 (A=000, B=130)
-Fout=832.10 (A=001, B=130)
-Fout=832.20 (A=002, B=130)
-Fout=832.30 (A=003, B=130)
-Fout=832.40 (A=004, B=130)
-Fout=832.50 (A=005, B=130)
-Fout=832.60 (A=006, B=130)
-Fout=832.70 (A=007, B=130)
-Fout=832.80 (A=008, B=130)
-Fout=832.90 (A=009, B=130)
-Fout=833.00 (A=010, B=130)
-Fout=833.10 (A=011, B=130)
-Fout=833.20 (A=012, B=130)
-Fout=833.30 (A=013, B=130)
-Fout=833.40 (A=014, B=130)
-Fout=833.50 (A=015, B=130)
-Fout=833.60 (A=016, B=130)
-Fout=833.70 (A=017, B=130)
-Fout=833.80 (A=018, B=130)
-Fout=833.90 (A=019, B=130)
-Fout=834.00 (A=020, B=130)
-Fout=834.10 (A=021, B=130)
-Fout=834.20 (A=022, B=130)
-Fout=834.30 (A=023, B=130)
-Fout=834.40 (A=024, B=130)
-Fout=834.50 (A=025, B=130)
-Fout=834.60 (A=026, B=130)
-Fout=834.70 (A=027, B=130)
-Fout=834.80 (A=028, B=130)
-Fout=834.90 (A=029, B=130)
-Fout=835.00 (A=030, B=130)
-Fout=835.10 (A=031, B=130)
-Fout=835.20 (A=032, B=130)
-Fout=835.30 (A=033, B=130)
-Fout=835.40 (A=034, B=130)
-Fout=835.50 (A=035, B=130)
-Fout=835.60 (A=036, B=130)
-Fout=835.70 (A=037, B=130)
-Fout=835.80 (A=038, B=130)
-Fout=835.90 (A=039, B=130)
-Fout=836.00 (A=040, B=130)
-Fout=836.10 (A=041, B=130)
-Fout=836.20 (A=042, B=130)
-Fout=836.30 (A=043, B=130)
-Fout=836.40 (A=044, B=130)
-Fout=836.50 (A=045, B=130)
-Fout=836.60 (A=046, B=130)
-Fout=836.70 (A=047, B=130)
-Fout=836.80 (A=048, B=130)
-Fout=836.90 (A=049, B=130)
-Fout=837.00 (A=050, B=130)
-Fout=837.10 (A=051, B=130)
-Fout=837.20 (A=052, B=130)
-Fout=837.30 (A=053, B=130)
-Fout=837.40 (A=054, B=130)
-Fout=837.50 (A=055, B=130)
-Fout=837.60 (A=056, B=130)
-Fout=837.70 (A=057, B=130)
-Fout=837.80 (A=058, B=130)
-Fout=837.90 (A=059, B=130)
-Fout=838.00 (A=060, B=130)
-Fout=838.10 (A=061, B=130)
-Fout=838.20 (A=062, B=130)
-======================================================================
-PLL Tx GSM850_2
-Fout=832.00 (A=000, B=065)
-Fout=832.20 (A=001, B=065)
-Fout=832.40 (A=002, B=065)
-Fout=832.60 (A=003, B=065)
-Fout=832.80 (A=004, B=065)
-Fout=833.00 (A=005, B=065)
-Fout=833.20 (A=006, B=065)
-Fout=833.40 (A=007, B=065)
-Fout=833.60 (A=008, B=065)
-Fout=833.80 (A=009, B=065)
-Fout=834.00 (A=010, B=065)
-Fout=834.20 (A=011, B=065)
-Fout=834.40 (A=012, B=065)
-Fout=834.60 (A=013, B=065)
-Fout=834.80 (A=014, B=065)
-Fout=835.00 (A=015, B=065)
-Fout=835.20 (A=016, B=065)
-Fout=835.40 (A=017, B=065)
-Fout=835.60 (A=018, B=065)
-Fout=835.80 (A=019, B=065)
-Fout=836.00 (A=020, B=065)
-Fout=836.20 (A=021, B=065)
-Fout=836.40 (A=022, B=065)
-Fout=836.60 (A=023, B=065)
-Fout=836.80 (A=024, B=065)
-Fout=837.00 (A=025, B=065)
-Fout=837.20 (A=026, B=065)
-Fout=837.40 (A=027, B=065)
-Fout=837.60 (A=028, B=065)
-Fout=837.80 (A=029, B=065)
-Fout=838.00 (A=030, B=065)
-Fout=838.20 (A=031, B=065)
-Fout=838.40 (A=032, B=065)
-Fout=838.60 (A=033, B=065)
-Fout=838.80 (A=034, B=065)
-Fout=839.00 (A=035, B=065)
-Fout=839.20 (A=036, B=065)
-Fout=839.40 (A=037, B=065)
-Fout=839.60 (A=038, B=065)
-Fout=839.80 (A=039, B=065)
-Fout=840.00 (A=040, B=065)
-Fout=840.20 (A=041, B=065)
-Fout=840.40 (A=042, B=065)
-Fout=840.60 (A=043, B=065)
-Fout=840.80 (A=044, B=065)
-Fout=841.00 (A=045, B=065)
-Fout=841.20 (A=046, B=065)
-Fout=841.40 (A=047, B=065)
-Fout=841.60 (A=048, B=065)
-Fout=841.80 (A=049, B=065)
-Fout=842.00 (A=050, B=065)
-Fout=842.20 (A=051, B=065)
-Fout=842.40 (A=052, B=065)
-Fout=842.60 (A=053, B=065)
-Fout=842.80 (A=054, B=065)
-Fout=843.00 (A=055, B=065)
-Fout=843.20 (A=056, B=065)
-Fout=843.40 (A=057, B=065)
-Fout=843.60 (A=058, B=065)
-Fout=843.80 (A=059, B=065)
-Fout=844.00 (A=060, B=065)
-Fout=844.20 (A=061, B=065)
-Fout=844.40 (A=062, B=065)
-Fout=844.60 (A=063, B=065)
-Fout=844.80 (A=000, B=066)
-Fout=845.00 (A=001, B=066)
-Fout=845.20 (A=002, B=066)
-Fout=845.40 (A=003, B=066)
-Fout=845.60 (A=004, B=066)
-Fout=845.80 (A=005, B=066)
-Fout=846.00 (A=006, B=066)
-Fout=846.20 (A=007, B=066)
-Fout=846.40 (A=008, B=066)
-Fout=846.60 (A=009, B=066)
-Fout=846.80 (A=010, B=066)
-Fout=847.00 (A=011, B=066)
-Fout=847.20 (A=012, B=066)
-Fout=847.40 (A=013, B=066)
-Fout=847.60 (A=014, B=066)
-Fout=847.80 (A=015, B=066)
-Fout=848.00 (A=016, B=066)
-Fout=848.20 (A=017, B=066)
-Fout=848.40 (A=018, B=066)
-Fout=848.60 (A=019, B=066)
-Fout=848.80 (A=020, B=066)
-Fout=849.00 (A=021, B=066)
-Fout=849.20 (A=022, B=066)
-Fout=849.40 (A=023, B=066)
-Fout=849.60 (A=024, B=066)
-Fout=849.80 (A=025, B=066)
-Fout=850.00 (A=026, B=066)
-Fout=850.20 (A=027, B=066)
-Fout=850.40 (A=028, B=066)
-Fout=850.60 (A=029, B=066)
-Fout=850.80 (A=030, B=066)
-Fout=851.00 (A=031, B=066)
-Fout=851.20 (A=032, B=066)
-Fout=851.40 (A=033, B=066)
-Fout=851.60 (A=034, B=066)
-Fout=851.80 (A=035, B=066)
-Fout=852.00 (A=036, B=066)
-Fout=852.20 (A=037, B=066)
-Fout=852.40 (A=038, B=066)
-Fout=852.60 (A=039, B=066)
-Fout=852.80 (A=040, B=066)
-Fout=853.00 (A=041, B=066)
-Fout=853.20 (A=042, B=066)
-Fout=853.40 (A=043, B=066)
-Fout=853.60 (A=044, B=066)
-Fout=853.80 (A=045, B=066)
-Fout=854.00 (A=046, B=066)
-Fout=854.20 (A=047, B=066)
-Fout=854.40 (A=048, B=066)
-Fout=854.60 (A=049, B=066)
-Fout=854.80 (A=050, B=066)
-Fout=855.00 (A=051, B=066)
-Fout=855.20 (A=052, B=066)
-Fout=855.40 (A=053, B=066)
-Fout=855.60 (A=054, B=066)
-Fout=855.80 (A=055, B=066)
-Fout=856.00 (A=056, B=066)
-Fout=856.20 (A=057, B=066)
-Fout=856.40 (A=058, B=066)
-Fout=856.60 (A=059, B=066)
-Fout=856.80 (A=060, B=066)
-Fout=857.00 (A=061, B=066)
-Fout=857.20 (A=062, B=066)
-Fout=857.40 (A=063, B=066)
-======================================================================
-PLL Tx GSM900
-Fout=870.40 (A=000, B=068)
-Fout=870.60 (A=001, B=068)
-Fout=870.80 (A=002, B=068)
-Fout=871.00 (A=003, B=068)
-Fout=871.20 (A=004, B=068)
-Fout=871.40 (A=005, B=068)
-Fout=871.60 (A=006, B=068)
-Fout=871.80 (A=007, B=068)
-Fout=872.00 (A=008, B=068)
-Fout=872.20 (A=009, B=068)
-Fout=872.40 (A=010, B=068)
-Fout=872.60 (A=011, B=068)
-Fout=872.80 (A=012, B=068)
-Fout=873.00 (A=013, B=068)
-Fout=873.20 (A=014, B=068)
-Fout=873.40 (A=015, B=068)
-Fout=873.60 (A=016, B=068)
-Fout=873.80 (A=017, B=068)
-Fout=874.00 (A=018, B=068)
-Fout=874.20 (A=019, B=068)
-Fout=874.40 (A=020, B=068)
-Fout=874.60 (A=021, B=068)
-Fout=874.80 (A=022, B=068)
-Fout=875.00 (A=023, B=068)
-Fout=875.20 (A=024, B=068)
-Fout=875.40 (A=025, B=068)
-Fout=875.60 (A=026, B=068)
-Fout=875.80 (A=027, B=068)
-Fout=876.00 (A=028, B=068)
-Fout=876.20 (A=029, B=068)
-Fout=876.40 (A=030, B=068)
-Fout=876.60 (A=031, B=068)
-Fout=876.80 (A=032, B=068)
-Fout=877.00 (A=033, B=068)
-Fout=877.20 (A=034, B=068)
-Fout=877.40 (A=035, B=068)
-Fout=877.60 (A=036, B=068)
-Fout=877.80 (A=037, B=068)
-Fout=878.00 (A=038, B=068)
-Fout=878.20 (A=039, B=068)
-Fout=878.40 (A=040, B=068)
-Fout=878.60 (A=041, B=068)
-Fout=878.80 (A=042, B=068)
-Fout=879.00 (A=043, B=068)
-Fout=879.20 (A=044, B=068)
-Fout=879.40 (A=045, B=068)
-Fout=879.60 (A=046, B=068)
-Fout=879.80 (A=047, B=068)
-Fout=880.00 (A=048, B=068)
-Fout=880.20 (A=049, B=068)
-Fout=880.40 (A=050, B=068)
-Fout=880.60 (A=051, B=068)
-Fout=880.80 (A=052, B=068)
-Fout=881.00 (A=053, B=068)
-Fout=881.20 (A=054, B=068)
-Fout=881.40 (A=055, B=068)
-Fout=881.60 (A=056, B=068)
-Fout=881.80 (A=057, B=068)
-Fout=882.00 (A=058, B=068)
-Fout=882.20 (A=059, B=068)
-Fout=882.40 (A=060, B=068)
-Fout=882.60 (A=061, B=068)
-Fout=882.80 (A=062, B=068)
-Fout=883.00 (A=063, B=068)
-Fout=883.20 (A=000, B=069)
-Fout=883.40 (A=001, B=069)
-Fout=883.60 (A=002, B=069)
-Fout=883.80 (A=003, B=069)
-Fout=884.00 (A=004, B=069)
-Fout=884.20 (A=005, B=069)
-Fout=884.40 (A=006, B=069)
-Fout=884.60 (A=007, B=069)
-Fout=884.80 (A=008, B=069)
-Fout=885.00 (A=009, B=069)
-Fout=885.20 (A=010, B=069)
-Fout=885.40 (A=011, B=069)
-Fout=885.60 (A=012, B=069)
-Fout=885.80 (A=013, B=069)
-Fout=886.00 (A=014, B=069)
-Fout=886.20 (A=015, B=069)
-Fout=886.40 (A=016, B=069)
-Fout=886.60 (A=017, B=069)
-Fout=886.80 (A=018, B=069)
-Fout=887.00 (A=019, B=069)
-Fout=887.20 (A=020, B=069)
-Fout=887.40 (A=021, B=069)
-Fout=887.60 (A=022, B=069)
-Fout=887.80 (A=023, B=069)
-Fout=888.00 (A=024, B=069)
-Fout=888.20 (A=025, B=069)
-Fout=888.40 (A=026, B=069)
-Fout=888.60 (A=027, B=069)
-Fout=888.80 (A=028, B=069)
-Fout=889.00 (A=029, B=069)
-Fout=889.20 (A=030, B=069)
-Fout=889.40 (A=031, B=069)
-Fout=889.60 (A=032, B=069)
-Fout=889.80 (A=033, B=069)
-Fout=890.00 (A=034, B=069)
-Fout=890.20 (A=035, B=069)
-Fout=890.40 (A=036, B=069)
-Fout=890.60 (A=037, B=069)
-Fout=890.80 (A=038, B=069)
-Fout=891.00 (A=039, B=069)
-Fout=891.20 (A=040, B=069)
-Fout=891.40 (A=041, B=069)
-Fout=891.60 (A=042, B=069)
-Fout=891.80 (A=043, B=069)
-Fout=892.00 (A=044, B=069)
-Fout=892.20 (A=045, B=069)
-Fout=892.40 (A=046, B=069)
-Fout=892.60 (A=047, B=069)
-Fout=892.80 (A=048, B=069)
-Fout=893.00 (A=049, B=069)
-Fout=893.20 (A=050, B=069)
-Fout=893.40 (A=051, B=069)
-Fout=893.60 (A=052, B=069)
-Fout=893.80 (A=053, B=069)
-Fout=894.00 (A=054, B=069)
-Fout=894.20 (A=055, B=069)
-Fout=894.40 (A=056, B=069)
-Fout=894.60 (A=057, B=069)
-Fout=894.80 (A=058, B=069)
-Fout=895.00 (A=059, B=069)
-Fout=895.20 (A=060, B=069)
-Fout=895.40 (A=061, B=069)
-Fout=895.60 (A=062, B=069)
-Fout=895.80 (A=063, B=069)
-Fout=896.00 (A=000, B=070)
-Fout=896.20 (A=001, B=070)
-Fout=896.40 (A=002, B=070)
-Fout=896.60 (A=003, B=070)
-Fout=896.80 (A=004, B=070)
-Fout=897.00 (A=005, B=070)
-Fout=897.20 (A=006, B=070)
-Fout=897.40 (A=007, B=070)
-Fout=897.60 (A=008, B=070)
-Fout=897.80 (A=009, B=070)
-Fout=898.00 (A=010, B=070)
-Fout=898.20 (A=011, B=070)
-Fout=898.40 (A=012, B=070)
-Fout=898.60 (A=013, B=070)
-Fout=898.80 (A=014, B=070)
-Fout=899.00 (A=015, B=070)
-Fout=899.20 (A=016, B=070)
-Fout=899.40 (A=017, B=070)
-Fout=899.60 (A=018, B=070)
-Fout=899.80 (A=019, B=070)
-Fout=900.00 (A=020, B=070)
-Fout=900.20 (A=021, B=070)
-Fout=900.40 (A=022, B=070)
-Fout=900.60 (A=023, B=070)
-Fout=900.80 (A=024, B=070)
-Fout=901.00 (A=025, B=070)
-Fout=901.20 (A=026, B=070)
-Fout=901.40 (A=027, B=070)
-Fout=901.60 (A=028, B=070)
-Fout=901.80 (A=029, B=070)
-Fout=902.00 (A=030, B=070)
-Fout=902.20 (A=031, B=070)
-Fout=902.40 (A=032, B=070)
-Fout=902.60 (A=033, B=070)
-Fout=902.80 (A=034, B=070)
-Fout=903.00 (A=035, B=070)
-Fout=903.20 (A=036, B=070)
-Fout=903.40 (A=037, B=070)
-Fout=903.60 (A=038, B=070)
-Fout=903.80 (A=039, B=070)
-Fout=904.00 (A=040, B=070)
-Fout=904.20 (A=041, B=070)
-Fout=904.40 (A=042, B=070)
-Fout=904.60 (A=043, B=070)
-Fout=904.80 (A=044, B=070)
-Fout=905.00 (A=045, B=070)
-Fout=905.20 (A=046, B=070)
-Fout=905.40 (A=047, B=070)
-Fout=905.60 (A=048, B=070)
-Fout=905.80 (A=049, B=070)
-Fout=906.00 (A=050, B=070)
-Fout=906.20 (A=051, B=070)
-Fout=906.40 (A=052, B=070)
-Fout=906.60 (A=053, B=070)
-Fout=906.80 (A=054, B=070)
-Fout=907.00 (A=055, B=070)
-Fout=907.20 (A=056, B=070)
-Fout=907.40 (A=057, B=070)
-Fout=907.60 (A=058, B=070)
-Fout=907.80 (A=059, B=070)
-Fout=908.00 (A=060, B=070)
-Fout=908.20 (A=061, B=070)
-Fout=908.40 (A=062, B=070)
-Fout=908.60 (A=063, B=070)
-Fout=908.80 (A=000, B=071)
-Fout=909.00 (A=001, B=071)
-Fout=909.20 (A=002, B=071)
-Fout=909.40 (A=003, B=071)
-Fout=909.60 (A=004, B=071)
-Fout=909.80 (A=005, B=071)
-Fout=910.00 (A=006, B=071)
-Fout=910.20 (A=007, B=071)
-Fout=910.40 (A=008, B=071)
-Fout=910.60 (A=009, B=071)
-Fout=910.80 (A=010, B=071)
-Fout=911.00 (A=011, B=071)
-Fout=911.20 (A=012, B=071)
-Fout=911.40 (A=013, B=071)
-Fout=911.60 (A=014, B=071)
-Fout=911.80 (A=015, B=071)
-Fout=912.00 (A=016, B=071)
-Fout=912.20 (A=017, B=071)
-Fout=912.40 (A=018, B=071)
-Fout=912.60 (A=019, B=071)
-Fout=912.80 (A=020, B=071)
-Fout=913.00 (A=021, B=071)
-Fout=913.20 (A=022, B=071)
-Fout=913.40 (A=023, B=071)
-Fout=913.60 (A=024, B=071)
-Fout=913.80 (A=025, B=071)
-Fout=914.00 (A=026, B=071)
-Fout=914.20 (A=027, B=071)
-Fout=914.40 (A=028, B=071)
-Fout=914.60 (A=029, B=071)
-Fout=914.80 (A=030, B=071)
-Fout=915.00 (A=031, B=071)
-Fout=915.20 (A=032, B=071)
-Fout=915.40 (A=033, B=071)
-Fout=915.60 (A=034, B=071)
-Fout=915.80 (A=035, B=071)
-Fout=916.00 (A=036, B=071)
-Fout=916.20 (A=037, B=071)
-Fout=916.40 (A=038, B=071)
-Fout=916.60 (A=039, B=071)
-Fout=916.80 (A=040, B=071)
-Fout=917.00 (A=041, B=071)
-Fout=917.20 (A=042, B=071)
-Fout=917.40 (A=043, B=071)
-Fout=917.60 (A=044, B=071)
-Fout=917.80 (A=045, B=071)
-Fout=918.00 (A=046, B=071)
-Fout=918.20 (A=047, B=071)
-Fout=918.40 (A=048, B=071)
-Fout=918.60 (A=049, B=071)
-Fout=918.80 (A=050, B=071)
-Fout=919.00 (A=051, B=071)
-Fout=919.20 (A=052, B=071)
-Fout=919.40 (A=053, B=071)
-Fout=919.60 (A=054, B=071)
-Fout=919.80 (A=055, B=071)
-Fout=920.00 (A=056, B=071)
-Fout=920.20 (A=057, B=071)
-Fout=920.40 (A=058, B=071)
-Fout=920.60 (A=059, B=071)
-Fout=920.80 (A=060, B=071)
-Fout=921.00 (A=061, B=071)
-Fout=921.20 (A=062, B=071)
-Fout=921.40 (A=063, B=071)
-======================================================================
-PLL Tx GSM1800/1900
-Fout=1702.40 (A=000, B=133)
-Fout=1702.60 (A=001, B=133)
-Fout=1702.80 (A=002, B=133)
-Fout=1703.00 (A=003, B=133)
-Fout=1703.20 (A=004, B=133)
-Fout=1703.40 (A=005, B=133)
-Fout=1703.60 (A=006, B=133)
-Fout=1703.80 (A=007, B=133)
-Fout=1704.00 (A=008, B=133)
-Fout=1704.20 (A=009, B=133)
-Fout=1704.40 (A=010, B=133)
-Fout=1704.60 (A=011, B=133)
-Fout=1704.80 (A=012, B=133)
-Fout=1705.00 (A=013, B=133)
-Fout=1705.20 (A=014, B=133)
-Fout=1705.40 (A=015, B=133)
-Fout=1705.60 (A=016, B=133)
-Fout=1705.80 (A=017, B=133)
-Fout=1706.00 (A=018, B=133)
-Fout=1706.20 (A=019, B=133)
-Fout=1706.40 (A=020, B=133)
-Fout=1706.60 (A=021, B=133)
-Fout=1706.80 (A=022, B=133)
-Fout=1707.00 (A=023, B=133)
-Fout=1707.20 (A=024, B=133)
-Fout=1707.40 (A=025, B=133)
-Fout=1707.60 (A=026, B=133)
-Fout=1707.80 (A=027, B=133)
-Fout=1708.00 (A=028, B=133)
-Fout=1708.20 (A=029, B=133)
-Fout=1708.40 (A=030, B=133)
-Fout=1708.60 (A=031, B=133)
-Fout=1708.80 (A=032, B=133)
-Fout=1709.00 (A=033, B=133)
-Fout=1709.20 (A=034, B=133)
-Fout=1709.40 (A=035, B=133)
-Fout=1709.60 (A=036, B=133)
-Fout=1709.80 (A=037, B=133)
-Fout=1710.00 (A=038, B=133)
-Fout=1710.20 (A=039, B=133)
-Fout=1710.40 (A=040, B=133)
-Fout=1710.60 (A=041, B=133)
-Fout=1710.80 (A=042, B=133)
-Fout=1711.00 (A=043, B=133)
-Fout=1711.20 (A=044, B=133)
-Fout=1711.40 (A=045, B=133)
-Fout=1711.60 (A=046, B=133)
-Fout=1711.80 (A=047, B=133)
-Fout=1712.00 (A=048, B=133)
-Fout=1712.20 (A=049, B=133)
-Fout=1712.40 (A=050, B=133)
-Fout=1712.60 (A=051, B=133)
-Fout=1712.80 (A=052, B=133)
-Fout=1713.00 (A=053, B=133)
-Fout=1713.20 (A=054, B=133)
-Fout=1713.40 (A=055, B=133)
-Fout=1713.60 (A=056, B=133)
-Fout=1713.80 (A=057, B=133)
-Fout=1714.00 (A=058, B=133)
-Fout=1714.20 (A=059, B=133)
-Fout=1714.40 (A=060, B=133)
-Fout=1714.60 (A=061, B=133)
-Fout=1714.80 (A=062, B=133)
-Fout=1715.00 (A=063, B=133)
-Fout=1715.20 (A=000, B=134)
-Fout=1715.40 (A=001, B=134)
-Fout=1715.60 (A=002, B=134)
-Fout=1715.80 (A=003, B=134)
-Fout=1716.00 (A=004, B=134)
-Fout=1716.20 (A=005, B=134)
-Fout=1716.40 (A=006, B=134)
-Fout=1716.60 (A=007, B=134)
-Fout=1716.80 (A=008, B=134)
-Fout=1717.00 (A=009, B=134)
-Fout=1717.20 (A=010, B=134)
-Fout=1717.40 (A=011, B=134)
-Fout=1717.60 (A=012, B=134)
-Fout=1717.80 (A=013, B=134)
-Fout=1718.00 (A=014, B=134)
-Fout=1718.20 (A=015, B=134)
-Fout=1718.40 (A=016, B=134)
-Fout=1718.60 (A=017, B=134)
-Fout=1718.80 (A=018, B=134)
-Fout=1719.00 (A=019, B=134)
-Fout=1719.20 (A=020, B=134)
-Fout=1719.40 (A=021, B=134)
-Fout=1719.60 (A=022, B=134)
-Fout=1719.80 (A=023, B=134)
-Fout=1720.00 (A=024, B=134)
-Fout=1720.20 (A=025, B=134)
-Fout=1720.40 (A=026, B=134)
-Fout=1720.60 (A=027, B=134)
-Fout=1720.80 (A=028, B=134)
-Fout=1721.00 (A=029, B=134)
-Fout=1721.20 (A=030, B=134)
-Fout=1721.40 (A=031, B=134)
-Fout=1721.60 (A=032, B=134)
-Fout=1721.80 (A=033, B=134)
-Fout=1722.00 (A=034, B=134)
-Fout=1722.20 (A=035, B=134)
-Fout=1722.40 (A=036, B=134)
-Fout=1722.60 (A=037, B=134)
-Fout=1722.80 (A=038, B=134)
-Fout=1723.00 (A=039, B=134)
-Fout=1723.20 (A=040, B=134)
-Fout=1723.40 (A=041, B=134)
-Fout=1723.60 (A=042, B=134)
-Fout=1723.80 (A=043, B=134)
-Fout=1724.00 (A=044, B=134)
-Fout=1724.20 (A=045, B=134)
-Fout=1724.40 (A=046, B=134)
-Fout=1724.60 (A=047, B=134)
-Fout=1724.80 (A=048, B=134)
-Fout=1725.00 (A=049, B=134)
-Fout=1725.20 (A=050, B=134)
-Fout=1725.40 (A=051, B=134)
-Fout=1725.60 (A=052, B=134)
-Fout=1725.80 (A=053, B=134)
-Fout=1726.00 (A=054, B=134)
-Fout=1726.20 (A=055, B=134)
-Fout=1726.40 (A=056, B=134)
-Fout=1726.60 (A=057, B=134)
-Fout=1726.80 (A=058, B=134)
-Fout=1727.00 (A=059, B=134)
-Fout=1727.20 (A=060, B=134)
-Fout=1727.40 (A=061, B=134)
-Fout=1727.60 (A=062, B=134)
-Fout=1727.80 (A=063, B=134)
-Fout=1728.00 (A=000, B=135)
-Fout=1728.20 (A=001, B=135)
-Fout=1728.40 (A=002, B=135)
-Fout=1728.60 (A=003, B=135)
-Fout=1728.80 (A=004, B=135)
-Fout=1729.00 (A=005, B=135)
-Fout=1729.20 (A=006, B=135)
-Fout=1729.40 (A=007, B=135)
-Fout=1729.60 (A=008, B=135)
-Fout=1729.80 (A=009, B=135)
-Fout=1730.00 (A=010, B=135)
-Fout=1730.20 (A=011, B=135)
-Fout=1730.40 (A=012, B=135)
-Fout=1730.60 (A=013, B=135)
-Fout=1730.80 (A=014, B=135)
-Fout=1731.00 (A=015, B=135)
-Fout=1731.20 (A=016, B=135)
-Fout=1731.40 (A=017, B=135)
-Fout=1731.60 (A=018, B=135)
-Fout=1731.80 (A=019, B=135)
-Fout=1732.00 (A=020, B=135)
-Fout=1732.20 (A=021, B=135)
-Fout=1732.40 (A=022, B=135)
-Fout=1732.60 (A=023, B=135)
-Fout=1732.80 (A=024, B=135)
-Fout=1733.00 (A=025, B=135)
-Fout=1733.20 (A=026, B=135)
-Fout=1733.40 (A=027, B=135)
-Fout=1733.60 (A=028, B=135)
-Fout=1733.80 (A=029, B=135)
-Fout=1734.00 (A=030, B=135)
-Fout=1734.20 (A=031, B=135)
-Fout=1734.40 (A=032, B=135)
-Fout=1734.60 (A=033, B=135)
-Fout=1734.80 (A=034, B=135)
-Fout=1735.00 (A=035, B=135)
-Fout=1735.20 (A=036, B=135)
-Fout=1735.40 (A=037, B=135)
-Fout=1735.60 (A=038, B=135)
-Fout=1735.80 (A=039, B=135)
-Fout=1736.00 (A=040, B=135)
-Fout=1736.20 (A=041, B=135)
-Fout=1736.40 (A=042, B=135)
-Fout=1736.60 (A=043, B=135)
-Fout=1736.80 (A=044, B=135)
-Fout=1737.00 (A=045, B=135)
-Fout=1737.20 (A=046, B=135)
-Fout=1737.40 (A=047, B=135)
-Fout=1737.60 (A=048, B=135)
-Fout=1737.80 (A=049, B=135)
-Fout=1738.00 (A=050, B=135)
-Fout=1738.20 (A=051, B=135)
-Fout=1738.40 (A=052, B=135)
-Fout=1738.60 (A=053, B=135)
-Fout=1738.80 (A=054, B=135)
-Fout=1739.00 (A=055, B=135)
-Fout=1739.20 (A=056, B=135)
-Fout=1739.40 (A=057, B=135)
-Fout=1739.60 (A=058, B=135)
-Fout=1739.80 (A=059, B=135)
-Fout=1740.00 (A=060, B=135)
-Fout=1740.20 (A=061, B=135)
-Fout=1740.40 (A=062, B=135)
-Fout=1740.60 (A=063, B=135)
-Fout=1740.80 (A=000, B=136)
-Fout=1741.00 (A=001, B=136)
-Fout=1741.20 (A=002, B=136)
-Fout=1741.40 (A=003, B=136)
-Fout=1741.60 (A=004, B=136)
-Fout=1741.80 (A=005, B=136)
-Fout=1742.00 (A=006, B=136)
-Fout=1742.20 (A=007, B=136)
-Fout=1742.40 (A=008, B=136)
-Fout=1742.60 (A=009, B=136)
-Fout=1742.80 (A=010, B=136)
-Fout=1743.00 (A=011, B=136)
-Fout=1743.20 (A=012, B=136)
-Fout=1743.40 (A=013, B=136)
-Fout=1743.60 (A=014, B=136)
-Fout=1743.80 (A=015, B=136)
-Fout=1744.00 (A=016, B=136)
-Fout=1744.20 (A=017, B=136)
-Fout=1744.40 (A=018, B=136)
-Fout=1744.60 (A=019, B=136)
-Fout=1744.80 (A=020, B=136)
-Fout=1745.00 (A=021, B=136)
-Fout=1745.20 (A=022, B=136)
-Fout=1745.40 (A=023, B=136)
-Fout=1745.60 (A=024, B=136)
-Fout=1745.80 (A=025, B=136)
-Fout=1746.00 (A=026, B=136)
-Fout=1746.20 (A=027, B=136)
-Fout=1746.40 (A=028, B=136)
-Fout=1746.60 (A=029, B=136)
-Fout=1746.80 (A=030, B=136)
-Fout=1747.00 (A=031, B=136)
-Fout=1747.20 (A=032, B=136)
-Fout=1747.40 (A=033, B=136)
-Fout=1747.60 (A=034, B=136)
-Fout=1747.80 (A=035, B=136)
-Fout=1748.00 (A=036, B=136)
-Fout=1748.20 (A=037, B=136)
-Fout=1748.40 (A=038, B=136)
-Fout=1748.60 (A=039, B=136)
-Fout=1748.80 (A=040, B=136)
-Fout=1749.00 (A=041, B=136)
-Fout=1749.20 (A=042, B=136)
-Fout=1749.40 (A=043, B=136)
-Fout=1749.60 (A=044, B=136)
-Fout=1749.80 (A=045, B=136)
-Fout=1750.00 (A=046, B=136)
-Fout=1750.20 (A=047, B=136)
-Fout=1750.40 (A=048, B=136)
-Fout=1750.60 (A=049, B=136)
-Fout=1750.80 (A=050, B=136)
-Fout=1751.00 (A=051, B=136)
-Fout=1751.20 (A=052, B=136)
-Fout=1751.40 (A=053, B=136)
-Fout=1751.60 (A=054, B=136)
-Fout=1751.80 (A=055, B=136)
-Fout=1752.00 (A=056, B=136)
-Fout=1752.20 (A=057, B=136)
-Fout=1752.40 (A=058, B=136)
-Fout=1752.60 (A=059, B=136)
-Fout=1752.80 (A=060, B=136)
-Fout=1753.00 (A=061, B=136)
-Fout=1753.20 (A=062, B=136)
-Fout=1753.40 (A=063, B=136)
-Fout=1753.60 (A=000, B=137)
-Fout=1753.80 (A=001, B=137)
-Fout=1754.00 (A=002, B=137)
-Fout=1754.20 (A=003, B=137)
-Fout=1754.40 (A=004, B=137)
-Fout=1754.60 (A=005, B=137)
-Fout=1754.80 (A=006, B=137)
-Fout=1755.00 (A=007, B=137)
-Fout=1755.20 (A=008, B=137)
-Fout=1755.40 (A=009, B=137)
-Fout=1755.60 (A=010, B=137)
-Fout=1755.80 (A=011, B=137)
-Fout=1756.00 (A=012, B=137)
-Fout=1756.20 (A=013, B=137)
-Fout=1756.40 (A=014, B=137)
-Fout=1756.60 (A=015, B=137)
-Fout=1756.80 (A=016, B=137)
-Fout=1757.00 (A=017, B=137)
-Fout=1757.20 (A=018, B=137)
-Fout=1757.40 (A=019, B=137)
-Fout=1757.60 (A=020, B=137)
-Fout=1757.80 (A=021, B=137)
-Fout=1758.00 (A=022, B=137)
-Fout=1758.20 (A=023, B=137)
-Fout=1758.40 (A=024, B=137)
-Fout=1758.60 (A=025, B=137)
-Fout=1758.80 (A=026, B=137)
-Fout=1759.00 (A=027, B=137)
-Fout=1759.20 (A=028, B=137)
-Fout=1759.40 (A=029, B=137)
-Fout=1759.60 (A=030, B=137)
-Fout=1759.80 (A=031, B=137)
-Fout=1760.00 (A=032, B=137)
-Fout=1760.20 (A=033, B=137)
-Fout=1760.40 (A=034, B=137)
-Fout=1760.60 (A=035, B=137)
-Fout=1760.80 (A=036, B=137)
-Fout=1761.00 (A=037, B=137)
-Fout=1761.20 (A=038, B=137)
-Fout=1761.40 (A=039, B=137)
-Fout=1761.60 (A=040, B=137)
-Fout=1761.80 (A=041, B=137)
-Fout=1762.00 (A=042, B=137)
-Fout=1762.20 (A=043, B=137)
-Fout=1762.40 (A=044, B=137)
-Fout=1762.60 (A=045, B=137)
-Fout=1762.80 (A=046, B=137)
-Fout=1763.00 (A=047, B=137)
-Fout=1763.20 (A=048, B=137)
-Fout=1763.40 (A=049, B=137)
-Fout=1763.60 (A=050, B=137)
-Fout=1763.80 (A=051, B=137)
-Fout=1764.00 (A=052, B=137)
-Fout=1764.20 (A=053, B=137)
-Fout=1764.40 (A=054, B=137)
-Fout=1764.60 (A=055, B=137)
-Fout=1764.80 (A=056, B=137)
-Fout=1765.00 (A=057, B=137)
-Fout=1765.20 (A=058, B=137)
-Fout=1765.40 (A=059, B=137)
-Fout=1765.60 (A=060, B=137)
-Fout=1765.80 (A=061, B=137)
-Fout=1766.00 (A=062, B=137)
-Fout=1766.20 (A=063, B=137)
-Fout=1766.40 (A=000, B=138)
-Fout=1766.60 (A=001, B=138)
-Fout=1766.80 (A=002, B=138)
-Fout=1767.00 (A=003, B=138)
-Fout=1767.20 (A=004, B=138)
-Fout=1767.40 (A=005, B=138)
-Fout=1767.60 (A=006, B=138)
-Fout=1767.80 (A=007, B=138)
-Fout=1768.00 (A=008, B=138)
-Fout=1768.20 (A=009, B=138)
-Fout=1768.40 (A=010, B=138)
-Fout=1768.60 (A=011, B=138)
-Fout=1768.80 (A=012, B=138)
-Fout=1769.00 (A=013, B=138)
-Fout=1769.20 (A=014, B=138)
-Fout=1769.40 (A=015, B=138)
-Fout=1769.60 (A=016, B=138)
-Fout=1769.80 (A=017, B=138)
-Fout=1770.00 (A=018, B=138)
-Fout=1770.20 (A=019, B=138)
-Fout=1770.40 (A=020, B=138)
-Fout=1770.60 (A=021, B=138)
-Fout=1770.80 (A=022, B=138)
-Fout=1771.00 (A=023, B=138)
-Fout=1771.20 (A=024, B=138)
-Fout=1771.40 (A=025, B=138)
-Fout=1771.60 (A=026, B=138)
-Fout=1771.80 (A=027, B=138)
-Fout=1772.00 (A=028, B=138)
-Fout=1772.20 (A=029, B=138)
-Fout=1772.40 (A=030, B=138)
-Fout=1772.60 (A=031, B=138)
-Fout=1772.80 (A=032, B=138)
-Fout=1773.00 (A=033, B=138)
-Fout=1773.20 (A=034, B=138)
-Fout=1773.40 (A=035, B=138)
-Fout=1773.60 (A=036, B=138)
-Fout=1773.80 (A=037, B=138)
-Fout=1774.00 (A=038, B=138)
-Fout=1774.20 (A=039, B=138)
-Fout=1774.40 (A=040, B=138)
-Fout=1774.60 (A=041, B=138)
-Fout=1774.80 (A=042, B=138)
-Fout=1775.00 (A=043, B=138)
-Fout=1775.20 (A=044, B=138)
-Fout=1775.40 (A=045, B=138)
-Fout=1775.60 (A=046, B=138)
-Fout=1775.80 (A=047, B=138)
-Fout=1776.00 (A=048, B=138)
-Fout=1776.20 (A=049, B=138)
-Fout=1776.40 (A=050, B=138)
-Fout=1776.60 (A=051, B=138)
-Fout=1776.80 (A=052, B=138)
-Fout=1777.00 (A=053, B=138)
-Fout=1777.20 (A=054, B=138)
-Fout=1777.40 (A=055, B=138)
-Fout=1777.60 (A=056, B=138)
-Fout=1777.80 (A=057, B=138)
-Fout=1778.00 (A=058, B=138)
-Fout=1778.20 (A=059, B=138)
-Fout=1778.40 (A=060, B=138)
-Fout=1778.60 (A=061, B=138)
-Fout=1778.80 (A=062, B=138)
-Fout=1779.00 (A=063, B=138)
-Fout=1779.20 (A=000, B=139)
-Fout=1779.40 (A=001, B=139)
-Fout=1779.60 (A=002, B=139)
-Fout=1779.80 (A=003, B=139)
-Fout=1780.00 (A=004, B=139)
-Fout=1780.20 (A=005, B=139)
-Fout=1780.40 (A=006, B=139)
-Fout=1780.60 (A=007, B=139)
-Fout=1780.80 (A=008, B=139)
-Fout=1781.00 (A=009, B=139)
-Fout=1781.20 (A=010, B=139)
-Fout=1781.40 (A=011, B=139)
-Fout=1781.60 (A=012, B=139)
-Fout=1781.80 (A=013, B=139)
-Fout=1782.00 (A=014, B=139)
-Fout=1782.20 (A=015, B=139)
-Fout=1782.40 (A=016, B=139)
-Fout=1782.60 (A=017, B=139)
-Fout=1782.80 (A=018, B=139)
-Fout=1783.00 (A=019, B=139)
-Fout=1783.20 (A=020, B=139)
-Fout=1783.40 (A=021, B=139)
-Fout=1783.60 (A=022, B=139)
-Fout=1783.80 (A=023, B=139)
-Fout=1784.00 (A=024, B=139)
-Fout=1784.20 (A=025, B=139)
-Fout=1784.40 (A=026, B=139)
-Fout=1784.60 (A=027, B=139)
-Fout=1784.80 (A=028, B=139)
-Fout=1785.00 (A=029, B=139)
-Fout=1785.20 (A=030, B=139)
-Fout=1785.40 (A=031, B=139)
-Fout=1785.60 (A=032, B=139)
-Fout=1785.80 (A=033, B=139)
-Fout=1786.00 (A=034, B=139)
-Fout=1786.20 (A=035, B=139)
-Fout=1786.40 (A=036, B=139)
-Fout=1786.60 (A=037, B=139)
-Fout=1786.80 (A=038, B=139)
-Fout=1787.00 (A=039, B=139)
-Fout=1787.20 (A=040, B=139)
-Fout=1787.40 (A=041, B=139)
-Fout=1787.60 (A=042, B=139)
-Fout=1787.80 (A=043, B=139)
-Fout=1788.00 (A=044, B=139)
-Fout=1788.20 (A=045, B=139)
-Fout=1788.40 (A=046, B=139)
-Fout=1788.60 (A=047, B=139)
-Fout=1788.80 (A=048, B=139)
-Fout=1789.00 (A=049, B=139)
-Fout=1789.20 (A=050, B=139)
-Fout=1789.40 (A=051, B=139)
-Fout=1789.60 (A=052, B=139)
-Fout=1789.80 (A=053, B=139)
-Fout=1790.00 (A=054, B=139)
-Fout=1790.20 (A=055, B=139)
-Fout=1790.40 (A=056, B=139)
-Fout=1790.60 (A=057, B=139)
-Fout=1790.80 (A=058, B=139)
-Fout=1791.00 (A=059, B=139)
-Fout=1791.20 (A=060, B=139)
-Fout=1791.40 (A=061, B=139)
-Fout=1791.60 (A=062, B=139)
-Fout=1791.80 (A=063, B=139)
-Fout=1792.00 (A=000, B=140)
-Fout=1792.20 (A=001, B=140)
-Fout=1792.40 (A=002, B=140)
-Fout=1792.60 (A=003, B=140)
-Fout=1792.80 (A=004, B=140)
-Fout=1793.00 (A=005, B=140)
-Fout=1793.20 (A=006, B=140)
-Fout=1793.40 (A=007, B=140)
-Fout=1793.60 (A=008, B=140)
-Fout=1793.80 (A=009, B=140)
-Fout=1794.00 (A=010, B=140)
-Fout=1794.20 (A=011, B=140)
-Fout=1794.40 (A=012, B=140)
-Fout=1794.60 (A=013, B=140)
-Fout=1794.80 (A=014, B=140)
-Fout=1795.00 (A=015, B=140)
-Fout=1795.20 (A=016, B=140)
-Fout=1795.40 (A=017, B=140)
-Fout=1795.60 (A=018, B=140)
-Fout=1795.80 (A=019, B=140)
-Fout=1796.00 (A=020, B=140)
-Fout=1796.20 (A=021, B=140)
-Fout=1796.40 (A=022, B=140)
-Fout=1796.60 (A=023, B=140)
-Fout=1796.80 (A=024, B=140)
-Fout=1797.00 (A=025, B=140)
-Fout=1797.20 (A=026, B=140)
-Fout=1797.40 (A=027, B=140)
-Fout=1797.60 (A=028, B=140)
-Fout=1797.80 (A=029, B=140)
-Fout=1798.00 (A=030, B=140)
-Fout=1798.20 (A=031, B=140)
-Fout=1798.40 (A=032, B=140)
-Fout=1798.60 (A=033, B=140)
-Fout=1798.80 (A=034, B=140)
-Fout=1799.00 (A=035, B=140)
-Fout=1799.20 (A=036, B=140)
-Fout=1799.40 (A=037, B=140)
-Fout=1799.60 (A=038, B=140)
-Fout=1799.80 (A=039, B=140)
-Fout=1800.00 (A=040, B=140)
-Fout=1800.20 (A=041, B=140)
-Fout=1800.40 (A=042, B=140)
-Fout=1800.60 (A=043, B=140)
-Fout=1800.80 (A=044, B=140)
-Fout=1801.00 (A=045, B=140)
-Fout=1801.20 (A=046, B=140)
-Fout=1801.40 (A=047, B=140)
-Fout=1801.60 (A=048, B=140)
-Fout=1801.80 (A=049, B=140)
-Fout=1802.00 (A=050, B=140)
-Fout=1802.20 (A=051, B=140)
-Fout=1802.40 (A=052, B=140)
-Fout=1802.60 (A=053, B=140)
-Fout=1802.80 (A=054, B=140)
-Fout=1803.00 (A=055, B=140)
-Fout=1803.20 (A=056, B=140)
-Fout=1803.40 (A=057, B=140)
-Fout=1803.60 (A=058, B=140)
-Fout=1803.80 (A=059, B=140)
-Fout=1804.00 (A=060, B=140)
-Fout=1804.20 (A=061, B=140)
-Fout=1804.40 (A=062, B=140)
-Fout=1804.60 (A=063, B=140)
-Fout=1804.80 (A=000, B=141)
-Fout=1805.00 (A=001, B=141)
-Fout=1805.20 (A=002, B=141)
-Fout=1805.40 (A=003, B=141)
-Fout=1805.60 (A=004, B=141)
-Fout=1805.80 (A=005, B=141)
-Fout=1806.00 (A=006, B=141)
-Fout=1806.20 (A=007, B=141)
-Fout=1806.40 (A=008, B=141)
-Fout=1806.60 (A=009, B=141)
-Fout=1806.80 (A=010, B=141)
-Fout=1807.00 (A=011, B=141)
-Fout=1807.20 (A=012, B=141)
-Fout=1807.40 (A=013, B=141)
-Fout=1807.60 (A=014, B=141)
-Fout=1807.80 (A=015, B=141)
-Fout=1808.00 (A=016, B=141)
-Fout=1808.20 (A=017, B=141)
-Fout=1808.40 (A=018, B=141)
-Fout=1808.60 (A=019, B=141)
-Fout=1808.80 (A=020, B=141)
-Fout=1809.00 (A=021, B=141)
-Fout=1809.20 (A=022, B=141)
-Fout=1809.40 (A=023, B=141)
-Fout=1809.60 (A=024, B=141)
-Fout=1809.80 (A=025, B=141)
-Fout=1810.00 (A=026, B=141)
-Fout=1810.20 (A=027, B=141)
-Fout=1810.40 (A=028, B=141)
-Fout=1810.60 (A=029, B=141)
-Fout=1810.80 (A=030, B=141)
-Fout=1811.00 (A=031, B=141)
-Fout=1811.20 (A=032, B=141)
-Fout=1811.40 (A=033, B=141)
-Fout=1811.60 (A=034, B=141)
-Fout=1811.80 (A=035, B=141)
-Fout=1812.00 (A=036, B=141)
-Fout=1812.20 (A=037, B=141)
-Fout=1812.40 (A=038, B=141)
-Fout=1812.60 (A=039, B=141)
-Fout=1812.80 (A=040, B=141)
-Fout=1813.00 (A=041, B=141)
-Fout=1813.20 (A=042, B=141)
-Fout=1813.40 (A=043, B=141)
-Fout=1813.60 (A=044, B=141)
-Fout=1813.80 (A=045, B=141)
-Fout=1814.00 (A=046, B=141)
-Fout=1814.20 (A=047, B=141)
-Fout=1814.40 (A=048, B=141)
-Fout=1814.60 (A=049, B=141)
-Fout=1814.80 (A=050, B=141)
-Fout=1815.00 (A=051, B=141)
-Fout=1815.20 (A=052, B=141)
-Fout=1815.40 (A=053, B=141)
-Fout=1815.60 (A=054, B=141)
-Fout=1815.80 (A=055, B=141)
-Fout=1816.00 (A=056, B=141)
-Fout=1816.20 (A=057, B=141)
-Fout=1816.40 (A=058, B=141)
-Fout=1816.60 (A=059, B=141)
-Fout=1816.80 (A=060, B=141)
-Fout=1817.00 (A=061, B=141)
-Fout=1817.20 (A=062, B=141)
-Fout=1817.40 (A=063, B=141)
-Fout=1817.60 (A=000, B=142)
-Fout=1817.80 (A=001, B=142)
-Fout=1818.00 (A=002, B=142)
-Fout=1818.20 (A=003, B=142)
-Fout=1818.40 (A=004, B=142)
-Fout=1818.60 (A=005, B=142)
-Fout=1818.80 (A=006, B=142)
-Fout=1819.00 (A=007, B=142)
-Fout=1819.20 (A=008, B=142)
-Fout=1819.40 (A=009, B=142)
-Fout=1819.60 (A=010, B=142)
-Fout=1819.80 (A=011, B=142)
-Fout=1820.00 (A=012, B=142)
-Fout=1820.20 (A=013, B=142)
-Fout=1820.40 (A=014, B=142)
-Fout=1820.60 (A=015, B=142)
-Fout=1820.80 (A=016, B=142)
-Fout=1821.00 (A=017, B=142)
-Fout=1821.20 (A=018, B=142)
-Fout=1821.40 (A=019, B=142)
-Fout=1821.60 (A=020, B=142)
-Fout=1821.80 (A=021, B=142)
-Fout=1822.00 (A=022, B=142)
-Fout=1822.20 (A=023, B=142)
-Fout=1822.40 (A=024, B=142)
-Fout=1822.60 (A=025, B=142)
-Fout=1822.80 (A=026, B=142)
-Fout=1823.00 (A=027, B=142)
-Fout=1823.20 (A=028, B=142)
-Fout=1823.40 (A=029, B=142)
-Fout=1823.60 (A=030, B=142)
-Fout=1823.80 (A=031, B=142)
-Fout=1824.00 (A=032, B=142)
-Fout=1824.20 (A=033, B=142)
-Fout=1824.40 (A=034, B=142)
-Fout=1824.60 (A=035, B=142)
-Fout=1824.80 (A=036, B=142)
-Fout=1825.00 (A=037, B=142)
-Fout=1825.20 (A=038, B=142)
-Fout=1825.40 (A=039, B=142)
-Fout=1825.60 (A=040, B=142)
-Fout=1825.80 (A=041, B=142)
-Fout=1826.00 (A=042, B=142)
-Fout=1826.20 (A=043, B=142)
-Fout=1826.40 (A=044, B=142)
-Fout=1826.60 (A=045, B=142)
-Fout=1826.80 (A=046, B=142)
-Fout=1827.00 (A=047, B=142)
-Fout=1827.20 (A=048, B=142)
-Fout=1827.40 (A=049, B=142)
-Fout=1827.60 (A=050, B=142)
-Fout=1827.80 (A=051, B=142)
-Fout=1828.00 (A=052, B=142)
-Fout=1828.20 (A=053, B=142)
-Fout=1828.40 (A=054, B=142)
-Fout=1828.60 (A=055, B=142)
-Fout=1828.80 (A=056, B=142)
-Fout=1829.00 (A=057, B=142)
-Fout=1829.20 (A=058, B=142)
-Fout=1829.40 (A=059, B=142)
-Fout=1829.60 (A=060, B=142)
-Fout=1829.80 (A=061, B=142)
-Fout=1830.00 (A=062, B=142)
-Fout=1830.20 (A=063, B=142)
-Fout=1830.40 (A=000, B=143)
-Fout=1830.60 (A=001, B=143)
-Fout=1830.80 (A=002, B=143)
-Fout=1831.00 (A=003, B=143)
-Fout=1831.20 (A=004, B=143)
-Fout=1831.40 (A=005, B=143)
-Fout=1831.60 (A=006, B=143)
-Fout=1831.80 (A=007, B=143)
-Fout=1832.00 (A=008, B=143)
-Fout=1832.20 (A=009, B=143)
-Fout=1832.40 (A=010, B=143)
-Fout=1832.60 (A=011, B=143)
-Fout=1832.80 (A=012, B=143)
-Fout=1833.00 (A=013, B=143)
-Fout=1833.20 (A=014, B=143)
-Fout=1833.40 (A=015, B=143)
-Fout=1833.60 (A=016, B=143)
-Fout=1833.80 (A=017, B=143)
-Fout=1834.00 (A=018, B=143)
-Fout=1834.20 (A=019, B=143)
-Fout=1834.40 (A=020, B=143)
-Fout=1834.60 (A=021, B=143)
-Fout=1834.80 (A=022, B=143)
-Fout=1835.00 (A=023, B=143)
-Fout=1835.20 (A=024, B=143)
-Fout=1835.40 (A=025, B=143)
-Fout=1835.60 (A=026, B=143)
-Fout=1835.80 (A=027, B=143)
-Fout=1836.00 (A=028, B=143)
-Fout=1836.20 (A=029, B=143)
-Fout=1836.40 (A=030, B=143)
-Fout=1836.60 (A=031, B=143)
-Fout=1836.80 (A=032, B=143)
-Fout=1837.00 (A=033, B=143)
-Fout=1837.20 (A=034, B=143)
-Fout=1837.40 (A=035, B=143)
-Fout=1837.60 (A=036, B=143)
-Fout=1837.80 (A=037, B=143)
-Fout=1838.00 (A=038, B=143)
-Fout=1838.20 (A=039, B=143)
-Fout=1838.40 (A=040, B=143)
-Fout=1838.60 (A=041, B=143)
-Fout=1838.80 (A=042, B=143)
-Fout=1839.00 (A=043, B=143)
-Fout=1839.20 (A=044, B=143)
-Fout=1839.40 (A=045, B=143)
-Fout=1839.60 (A=046, B=143)
-Fout=1839.80 (A=047, B=143)
-Fout=1840.00 (A=048, B=143)
-Fout=1840.20 (A=049, B=143)
-Fout=1840.40 (A=050, B=143)
-Fout=1840.60 (A=051, B=143)
-Fout=1840.80 (A=052, B=143)
-Fout=1841.00 (A=053, B=143)
-Fout=1841.20 (A=054, B=143)
-Fout=1841.40 (A=055, B=143)
-Fout=1841.60 (A=056, B=143)
-Fout=1841.80 (A=057, B=143)
-Fout=1842.00 (A=058, B=143)
-Fout=1842.20 (A=059, B=143)
-Fout=1842.40 (A=060, B=143)
-Fout=1842.60 (A=061, B=143)
-Fout=1842.80 (A=062, B=143)
-Fout=1843.00 (A=063, B=143)
-Fout=1843.20 (A=000, B=144)
-Fout=1843.40 (A=001, B=144)
-Fout=1843.60 (A=002, B=144)
-Fout=1843.80 (A=003, B=144)
-Fout=1844.00 (A=004, B=144)
-Fout=1844.20 (A=005, B=144)
-Fout=1844.40 (A=006, B=144)
-Fout=1844.60 (A=007, B=144)
-Fout=1844.80 (A=008, B=144)
-Fout=1845.00 (A=009, B=144)
-Fout=1845.20 (A=010, B=144)
-Fout=1845.40 (A=011, B=144)
-Fout=1845.60 (A=012, B=144)
-Fout=1845.80 (A=013, B=144)
-Fout=1846.00 (A=014, B=144)
-Fout=1846.20 (A=015, B=144)
-Fout=1846.40 (A=016, B=144)
-Fout=1846.60 (A=017, B=144)
-Fout=1846.80 (A=018, B=144)
-Fout=1847.00 (A=019, B=144)
-Fout=1847.20 (A=020, B=144)
-Fout=1847.40 (A=021, B=144)
-Fout=1847.60 (A=022, B=144)
-Fout=1847.80 (A=023, B=144)
-Fout=1848.00 (A=024, B=144)
-Fout=1848.20 (A=025, B=144)
-Fout=1848.40 (A=026, B=144)
-Fout=1848.60 (A=027, B=144)
-Fout=1848.80 (A=028, B=144)
-Fout=1849.00 (A=029, B=144)
-Fout=1849.20 (A=030, B=144)
-Fout=1849.40 (A=031, B=144)
-Fout=1849.60 (A=032, B=144)
-Fout=1849.80 (A=033, B=144)
-Fout=1850.00 (A=034, B=144)
-Fout=1850.20 (A=035, B=144)
-Fout=1850.40 (A=036, B=144)
-Fout=1850.60 (A=037, B=144)
-Fout=1850.80 (A=038, B=144)
-Fout=1851.00 (A=039, B=144)
-Fout=1851.20 (A=040, B=144)
-Fout=1851.40 (A=041, B=144)
-Fout=1851.60 (A=042, B=144)
-Fout=1851.80 (A=043, B=144)
-Fout=1852.00 (A=044, B=144)
-Fout=1852.20 (A=045, B=144)
-Fout=1852.40 (A=046, B=144)
-Fout=1852.60 (A=047, B=144)
-Fout=1852.80 (A=048, B=144)
-Fout=1853.00 (A=049, B=144)
-Fout=1853.20 (A=050, B=144)
-Fout=1853.40 (A=051, B=144)
-Fout=1853.60 (A=052, B=144)
-Fout=1853.80 (A=053, B=144)
-Fout=1854.00 (A=054, B=144)
-Fout=1854.20 (A=055, B=144)
-Fout=1854.40 (A=056, B=144)
-Fout=1854.60 (A=057, B=144)
-Fout=1854.80 (A=058, B=144)
-Fout=1855.00 (A=059, B=144)
-Fout=1855.20 (A=060, B=144)
-Fout=1855.40 (A=061, B=144)
-Fout=1855.60 (A=062, B=144)
-Fout=1855.80 (A=063, B=144)
-Fout=1856.00 (A=000, B=145)
-Fout=1856.20 (A=001, B=145)
-Fout=1856.40 (A=002, B=145)
-Fout=1856.60 (A=003, B=145)
-Fout=1856.80 (A=004, B=145)
-Fout=1857.00 (A=005, B=145)
-Fout=1857.20 (A=006, B=145)
-Fout=1857.40 (A=007, B=145)
-Fout=1857.60 (A=008, B=145)
-Fout=1857.80 (A=009, B=145)
-Fout=1858.00 (A=010, B=145)
-Fout=1858.20 (A=011, B=145)
-Fout=1858.40 (A=012, B=145)
-Fout=1858.60 (A=013, B=145)
-Fout=1858.80 (A=014, B=145)
-Fout=1859.00 (A=015, B=145)
-Fout=1859.20 (A=016, B=145)
-Fout=1859.40 (A=017, B=145)
-Fout=1859.60 (A=018, B=145)
-Fout=1859.80 (A=019, B=145)
-Fout=1860.00 (A=020, B=145)
-Fout=1860.20 (A=021, B=145)
-Fout=1860.40 (A=022, B=145)
-Fout=1860.60 (A=023, B=145)
-Fout=1860.80 (A=024, B=145)
-Fout=1861.00 (A=025, B=145)
-Fout=1861.20 (A=026, B=145)
-Fout=1861.40 (A=027, B=145)
-Fout=1861.60 (A=028, B=145)
-Fout=1861.80 (A=029, B=145)
-Fout=1862.00 (A=030, B=145)
-Fout=1862.20 (A=031, B=145)
-Fout=1862.40 (A=032, B=145)
-Fout=1862.60 (A=033, B=145)
-Fout=1862.80 (A=034, B=145)
-Fout=1863.00 (A=035, B=145)
-Fout=1863.20 (A=036, B=145)
-Fout=1863.40 (A=037, B=145)
-Fout=1863.60 (A=038, B=145)
-Fout=1863.80 (A=039, B=145)
-Fout=1864.00 (A=040, B=145)
-Fout=1864.20 (A=041, B=145)
-Fout=1864.40 (A=042, B=145)
-Fout=1864.60 (A=043, B=145)
-Fout=1864.80 (A=044, B=145)
-Fout=1865.00 (A=045, B=145)
-Fout=1865.20 (A=046, B=145)
-Fout=1865.40 (A=047, B=145)
-Fout=1865.60 (A=048, B=145)
-Fout=1865.80 (A=049, B=145)
-Fout=1866.00 (A=050, B=145)
-Fout=1866.20 (A=051, B=145)
-Fout=1866.40 (A=052, B=145)
-Fout=1866.60 (A=053, B=145)
-Fout=1866.80 (A=054, B=145)
-Fout=1867.00 (A=055, B=145)
-Fout=1867.20 (A=056, B=145)
-Fout=1867.40 (A=057, B=145)
-Fout=1867.60 (A=058, B=145)
-Fout=1867.80 (A=059, B=145)
-Fout=1868.00 (A=060, B=145)
-Fout=1868.20 (A=061, B=145)
-Fout=1868.40 (A=062, B=145)
-Fout=1868.60 (A=063, B=145)
-Fout=1868.80 (A=000, B=146)
-Fout=1869.00 (A=001, B=146)
-Fout=1869.20 (A=002, B=146)
-Fout=1869.40 (A=003, B=146)
-Fout=1869.60 (A=004, B=146)
-Fout=1869.80 (A=005, B=146)
-Fout=1870.00 (A=006, B=146)
-Fout=1870.20 (A=007, B=146)
-Fout=1870.40 (A=008, B=146)
-Fout=1870.60 (A=009, B=146)
-Fout=1870.80 (A=010, B=146)
-Fout=1871.00 (A=011, B=146)
-Fout=1871.20 (A=012, B=146)
-Fout=1871.40 (A=013, B=146)
-Fout=1871.60 (A=014, B=146)
-Fout=1871.80 (A=015, B=146)
-Fout=1872.00 (A=016, B=146)
-Fout=1872.20 (A=017, B=146)
-Fout=1872.40 (A=018, B=146)
-Fout=1872.60 (A=019, B=146)
-Fout=1872.80 (A=020, B=146)
-Fout=1873.00 (A=021, B=146)
-Fout=1873.20 (A=022, B=146)
-Fout=1873.40 (A=023, B=146)
-Fout=1873.60 (A=024, B=146)
-Fout=1873.80 (A=025, B=146)
-Fout=1874.00 (A=026, B=146)
-Fout=1874.20 (A=027, B=146)
-Fout=1874.40 (A=028, B=146)
-Fout=1874.60 (A=029, B=146)
-Fout=1874.80 (A=030, B=146)
-Fout=1875.00 (A=031, B=146)
-Fout=1875.20 (A=032, B=146)
-Fout=1875.40 (A=033, B=146)
-Fout=1875.60 (A=034, B=146)
-Fout=1875.80 (A=035, B=146)
-Fout=1876.00 (A=036, B=146)
-Fout=1876.20 (A=037, B=146)
-Fout=1876.40 (A=038, B=146)
-Fout=1876.60 (A=039, B=146)
-Fout=1876.80 (A=040, B=146)
-Fout=1877.00 (A=041, B=146)
-Fout=1877.20 (A=042, B=146)
-Fout=1877.40 (A=043, B=146)
-Fout=1877.60 (A=044, B=146)
-Fout=1877.80 (A=045, B=146)
-Fout=1878.00 (A=046, B=146)
-Fout=1878.20 (A=047, B=146)
-Fout=1878.40 (A=048, B=146)
-Fout=1878.60 (A=049, B=146)
-Fout=1878.80 (A=050, B=146)
-Fout=1879.00 (A=051, B=146)
-Fout=1879.20 (A=052, B=146)
-Fout=1879.40 (A=053, B=146)
-Fout=1879.60 (A=054, B=146)
-Fout=1879.80 (A=055, B=146)
-Fout=1880.00 (A=056, B=146)
-Fout=1880.20 (A=057, B=146)
-Fout=1880.40 (A=058, B=146)
-Fout=1880.60 (A=059, B=146)
-Fout=1880.80 (A=060, B=146)
-Fout=1881.00 (A=061, B=146)
-Fout=1881.20 (A=062, B=146)
-Fout=1881.40 (A=063, B=146)
-Fout=1881.60 (A=000, B=147)
-Fout=1881.80 (A=001, B=147)
-Fout=1882.00 (A=002, B=147)
-Fout=1882.20 (A=003, B=147)
-Fout=1882.40 (A=004, B=147)
-Fout=1882.60 (A=005, B=147)
-Fout=1882.80 (A=006, B=147)
-Fout=1883.00 (A=007, B=147)
-Fout=1883.20 (A=008, B=147)
-Fout=1883.40 (A=009, B=147)
-Fout=1883.60 (A=010, B=147)
-Fout=1883.80 (A=011, B=147)
-Fout=1884.00 (A=012, B=147)
-Fout=1884.20 (A=013, B=147)
-Fout=1884.40 (A=014, B=147)
-Fout=1884.60 (A=015, B=147)
-Fout=1884.80 (A=016, B=147)
-Fout=1885.00 (A=017, B=147)
-Fout=1885.20 (A=018, B=147)
-Fout=1885.40 (A=019, B=147)
-Fout=1885.60 (A=020, B=147)
-Fout=1885.80 (A=021, B=147)
-Fout=1886.00 (A=022, B=147)
-Fout=1886.20 (A=023, B=147)
-Fout=1886.40 (A=024, B=147)
-Fout=1886.60 (A=025, B=147)
-Fout=1886.80 (A=026, B=147)
-Fout=1887.00 (A=027, B=147)
-Fout=1887.20 (A=028, B=147)
-Fout=1887.40 (A=029, B=147)
-Fout=1887.60 (A=030, B=147)
-Fout=1887.80 (A=031, B=147)
-Fout=1888.00 (A=032, B=147)
-Fout=1888.20 (A=033, B=147)
-Fout=1888.40 (A=034, B=147)
-Fout=1888.60 (A=035, B=147)
-Fout=1888.80 (A=036, B=147)
-Fout=1889.00 (A=037, B=147)
-Fout=1889.20 (A=038, B=147)
-Fout=1889.40 (A=039, B=147)
-Fout=1889.60 (A=040, B=147)
-Fout=1889.80 (A=041, B=147)
-Fout=1890.00 (A=042, B=147)
-Fout=1890.20 (A=043, B=147)
-Fout=1890.40 (A=044, B=147)
-Fout=1890.60 (A=045, B=147)
-Fout=1890.80 (A=046, B=147)
-Fout=1891.00 (A=047, B=147)
-Fout=1891.20 (A=048, B=147)
-Fout=1891.40 (A=049, B=147)
-Fout=1891.60 (A=050, B=147)
-Fout=1891.80 (A=051, B=147)
-Fout=1892.00 (A=052, B=147)
-Fout=1892.20 (A=053, B=147)
-Fout=1892.40 (A=054, B=147)
-Fout=1892.60 (A=055, B=147)
-Fout=1892.80 (A=056, B=147)
-Fout=1893.00 (A=057, B=147)
-Fout=1893.20 (A=058, B=147)
-Fout=1893.40 (A=059, B=147)
-Fout=1893.60 (A=060, B=147)
-Fout=1893.80 (A=061, B=147)
-Fout=1894.00 (A=062, B=147)
-Fout=1894.20 (A=063, B=147)
-Fout=1894.40 (A=000, B=148)
-Fout=1894.60 (A=001, B=148)
-Fout=1894.80 (A=002, B=148)
-Fout=1895.00 (A=003, B=148)
-Fout=1895.20 (A=004, B=148)
-Fout=1895.40 (A=005, B=148)
-Fout=1895.60 (A=006, B=148)
-Fout=1895.80 (A=007, B=148)
-Fout=1896.00 (A=008, B=148)
-Fout=1896.20 (A=009, B=148)
-Fout=1896.40 (A=010, B=148)
-Fout=1896.60 (A=011, B=148)
-Fout=1896.80 (A=012, B=148)
-Fout=1897.00 (A=013, B=148)
-Fout=1897.20 (A=014, B=148)
-Fout=1897.40 (A=015, B=148)
-Fout=1897.60 (A=016, B=148)
-Fout=1897.80 (A=017, B=148)
-Fout=1898.00 (A=018, B=148)
-Fout=1898.20 (A=019, B=148)
-Fout=1898.40 (A=020, B=148)
-Fout=1898.60 (A=021, B=148)
-Fout=1898.80 (A=022, B=148)
-Fout=1899.00 (A=023, B=148)
-Fout=1899.20 (A=024, B=148)
-Fout=1899.40 (A=025, B=148)
-Fout=1899.60 (A=026, B=148)
-Fout=1899.80 (A=027, B=148)
-Fout=1900.00 (A=028, B=148)
-Fout=1900.20 (A=029, B=148)
-Fout=1900.40 (A=030, B=148)
-Fout=1900.60 (A=031, B=148)
-Fout=1900.80 (A=032, B=148)
-Fout=1901.00 (A=033, B=148)
-Fout=1901.20 (A=034, B=148)
-Fout=1901.40 (A=035, B=148)
-Fout=1901.60 (A=036, B=148)
-Fout=1901.80 (A=037, B=148)
-Fout=1902.00 (A=038, B=148)
-Fout=1902.20 (A=039, B=148)
-Fout=1902.40 (A=040, B=148)
-Fout=1902.60 (A=041, B=148)
-Fout=1902.80 (A=042, B=148)
-Fout=1903.00 (A=043, B=148)
-Fout=1903.20 (A=044, B=148)
-Fout=1903.40 (A=045, B=148)
-Fout=1903.60 (A=046, B=148)
-Fout=1903.80 (A=047, B=148)
-Fout=1904.00 (A=048, B=148)
-Fout=1904.20 (A=049, B=148)
-Fout=1904.40 (A=050, B=148)
-Fout=1904.60 (A=051, B=148)
-Fout=1904.80 (A=052, B=148)
-Fout=1905.00 (A=053, B=148)
-Fout=1905.20 (A=054, B=148)
-Fout=1905.40 (A=055, B=148)
-Fout=1905.60 (A=056, B=148)
-Fout=1905.80 (A=057, B=148)
-Fout=1906.00 (A=058, B=148)
-Fout=1906.20 (A=059, B=148)
-Fout=1906.40 (A=060, B=148)
-Fout=1906.60 (A=061, B=148)
-Fout=1906.80 (A=062, B=148)
-Fout=1907.00 (A=063, B=148)
-Fout=1907.20 (A=000, B=149)
-Fout=1907.40 (A=001, B=149)
-Fout=1907.60 (A=002, B=149)
-Fout=1907.80 (A=003, B=149)
-Fout=1908.00 (A=004, B=149)
-Fout=1908.20 (A=005, B=149)
-Fout=1908.40 (A=006, B=149)
-Fout=1908.60 (A=007, B=149)
-Fout=1908.80 (A=008, B=149)
-Fout=1909.00 (A=009, B=149)
-Fout=1909.20 (A=010, B=149)
-Fout=1909.40 (A=011, B=149)
-Fout=1909.60 (A=012, B=149)
-Fout=1909.80 (A=013, B=149)
-Fout=1910.00 (A=014, B=149)
-Fout=1910.20 (A=015, B=149)
-Fout=1910.40 (A=016, B=149)
-Fout=1910.60 (A=017, B=149)
-Fout=1910.80 (A=018, B=149)
-Fout=1911.00 (A=019, B=149)
-Fout=1911.20 (A=020, B=149)
-Fout=1911.40 (A=021, B=149)
-Fout=1911.60 (A=022, B=149)
-Fout=1911.80 (A=023, B=149)
-Fout=1912.00 (A=024, B=149)
-Fout=1912.20 (A=025, B=149)
-Fout=1912.40 (A=026, B=149)
-Fout=1912.60 (A=027, B=149)
-Fout=1912.80 (A=028, B=149)
-Fout=1913.00 (A=029, B=149)
-Fout=1913.20 (A=030, B=149)
-Fout=1913.40 (A=031, B=149)
-Fout=1913.60 (A=032, B=149)
-Fout=1913.80 (A=033, B=149)
-Fout=1914.00 (A=034, B=149)
-Fout=1914.20 (A=035, B=149)
-Fout=1914.40 (A=036, B=149)
-Fout=1914.60 (A=037, B=149)
-Fout=1914.80 (A=038, B=149)
-Fout=1915.00 (A=039, B=149)
-Fout=1915.20 (A=040, B=149)
-Fout=1915.40 (A=041, B=149)
-Fout=1915.60 (A=042, B=149)
-Fout=1915.80 (A=043, B=149)
-Fout=1916.00 (A=044, B=149)
-Fout=1916.20 (A=045, B=149)
-Fout=1916.40 (A=046, B=149)
-Fout=1916.60 (A=047, B=149)
-Fout=1916.80 (A=048, B=149)
-Fout=1917.00 (A=049, B=149)
-Fout=1917.20 (A=050, B=149)
-Fout=1917.40 (A=051, B=149)
-Fout=1917.60 (A=052, B=149)
-Fout=1917.80 (A=053, B=149)
-Fout=1918.00 (A=054, B=149)
-Fout=1918.20 (A=055, B=149)
-Fout=1918.40 (A=056, B=149)
-Fout=1918.60 (A=057, B=149)
-Fout=1918.80 (A=058, B=149)
-Fout=1919.00 (A=059, B=149)
-Fout=1919.20 (A=060, B=149)
-Fout=1919.40 (A=061, B=149)
-Fout=1919.60 (A=062, B=149)
-Fout=1919.80 (A=063, B=149)
diff --git a/Src/osmoconbb/src/host/rita_pll/rita_pll_notes.txt b/Src/osmoconbb/src/host/rita_pll/rita_pll_notes.txt
deleted file mode 100644
index 7df03f5..0000000
--- a/Src/osmoconbb/src/host/rita_pll/rita_pll_notes.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-
-Regular Operation as per DS GSM SPEC
-
-GSM900 Tx: 870.4 ... 921.4 MHz 880.0 ... 914.8
-GSM900 Rx: 864.4 ... 966.2 MHz 925.0 ... 959.8
-
-GSM1800 Tx: 1702.4 ... 1919.8 MHz 1710.2 ... 1784.8
-GSM1800 Rx: 1804.8 ... 1996.4 MHz 1805.2 ... 1879.8
-
-GSM850 Tx:
-
-[824.2 ~ 837.0 MHz]
-[837.2 ~ 848.8 MHz]
-
-
-GSM810 Tx: 806.0 ... 821.0
-* modify B value to go down to 125 (A = 60)
-GSM810 Rx: 851.0 ... 866.0
-* modify B value to go down to 132 (A = 62)